P0 fixes: - agent register: upsert by agent_id (no duplicate rows) - daemon poll-once: extract _gmail_poll_cycle, run synchronously - garc_core.py: suppress urllib3/googleapiclient DeprecationWarnings P1 fixes: - OAuth: detect RefreshError → delete stale token → re-auth flow - OAuth: scope coverage check before returning valid creds - ingress: add stale-reset subcommand (reset in_progress > N min) - sheets: trim-sheet / clean-all — deleteDimension for empty rows - approval gate: send Gmail notification to GARC_APPROVAL_EMAIL P2 additions: - Google Chat: garc-chat-helper.py + garc send chat subcommands - Service Account: garc auth service-account verify + DWD support - Audit log: Sheets audit tab + garc audit list + bin/garc async hook - garc auth revoke: POST /revoke + delete token file - kg: pagination fix, shell injection fix, garc-kg-query.py - docs: _doc_insert_text / append_doc / garc drive append-doc P3 additions: - Multi-tenant: lib/profile.sh (list/use/add/show/remove/current) bin/garc: auto-load profile config.env and token.json - Google Forms pipeline: garc-forms-helper.py + lib/forms.sh garc forms list/responses/watch - systemd: _daemon_install_service OS-detect → launchd or systemd units - Python version gate (>=3.10) in bin/garc + pyproject.toml - garc doctor command for environment diagnostics Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
90 lines
2.3 KiB
Bash
90 lines
2.3 KiB
Bash
#!/usr/bin/env bash
|
|
# GARC forms.sh — Google Forms response pipeline
|
|
# Polls Forms for new responses and auto-enqueues them via garc ingress.
|
|
|
|
FORMS_HELPER="${GARC_DIR}/scripts/garc-forms-helper.py"
|
|
|
|
garc_forms() {
|
|
local subcommand="${1:-help}"
|
|
shift || true
|
|
|
|
case "${subcommand}" in
|
|
list) garc_forms_list "$@" ;;
|
|
responses) garc_forms_responses "$@" ;;
|
|
watch) garc_forms_watch "$@" ;;
|
|
*)
|
|
cat <<EOF
|
|
Usage: garc forms <subcommand>
|
|
|
|
Subcommands:
|
|
list List accessible Google Forms
|
|
responses <form_id> [--max N] List responses for a form
|
|
watch <form_id> --agent <id> Poll form and auto-enqueue new responses
|
|
[--interval <sec>] Poll interval (default: 60)
|
|
[--max <N>] Max responses per cycle (default: 10)
|
|
|
|
Examples:
|
|
garc forms list
|
|
garc forms responses 1xxxxxxxxxxxxxxxx
|
|
garc forms watch 1xxxxxxxxxxxxxxxx --agent main --interval 30
|
|
EOF
|
|
return 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
garc_forms_list() {
|
|
python3 "${FORMS_HELPER}" list-forms
|
|
}
|
|
|
|
garc_forms_responses() {
|
|
local form_id="${1:-}"
|
|
shift || true
|
|
local max=50 since="" fmt="table"
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--max|-n) max="$2"; shift 2 ;;
|
|
--since) since="$2"; shift 2 ;;
|
|
--format) fmt="$2"; shift 2 ;;
|
|
*) shift ;;
|
|
esac
|
|
done
|
|
|
|
[[ -z "${form_id}" ]] && { echo "Usage: garc forms responses <form_id> [--max N]"; return 1; }
|
|
|
|
python3 "${FORMS_HELPER}" list-responses "${form_id}" \
|
|
--max "${max}" \
|
|
${since:+--since "${since}"} \
|
|
--format "${fmt}"
|
|
}
|
|
|
|
garc_forms_watch() {
|
|
local form_id="${1:-}"
|
|
shift || true
|
|
local agent="${GARC_DEFAULT_AGENT:-main}" interval=60 max=10
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--agent|-a) agent="$2"; shift 2 ;;
|
|
--interval|-i) interval="$2"; shift 2 ;;
|
|
--max|-n) max="$2"; shift 2 ;;
|
|
*) form_id="${form_id:-$1}"; shift ;;
|
|
esac
|
|
done
|
|
|
|
[[ -z "${form_id}" ]] && {
|
|
echo "Usage: garc forms watch <form_id> --agent <id> [--interval <sec>]"
|
|
return 1
|
|
}
|
|
|
|
echo "👁 Watching form: ${form_id}"
|
|
echo " Agent: ${agent} Interval: ${interval}s"
|
|
echo " Press Ctrl+C to stop."
|
|
echo ""
|
|
|
|
python3 "${FORMS_HELPER}" watch "${form_id}" \
|
|
--agent "${agent}" \
|
|
--interval "${interval}" \
|
|
--max "${max}"
|
|
}
|