crewly 1.20.34 → 1.20.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/skills/_common/lib.sh +6 -0
- package/config/skills/agent/core/calendar-create/SKILL.md +10 -0
- package/config/skills/agent/core/calendar-create/execute.sh +6 -0
- package/config/skills/agent/core/calendar-list/SKILL.md +10 -0
- package/config/skills/agent/core/calendar-list/execute.sh +6 -0
- package/config/skills/agent/core/docs-read/SKILL.md +10 -0
- package/config/skills/agent/core/docs-read/execute.sh +6 -1
- package/config/skills/agent/core/docs-write/SKILL.md +10 -0
- package/config/skills/agent/core/docs-write/execute.sh +6 -1
- package/config/skills/agent/core/drive-read/SKILL.md +10 -0
- package/config/skills/agent/core/drive-read/execute.sh +6 -1
- package/config/skills/agent/core/drive-search/SKILL.md +10 -0
- package/config/skills/agent/core/drive-search/execute.sh +6 -1
- package/config/skills/agent/core/drive-upload/SKILL.md +10 -0
- package/config/skills/agent/core/drive-upload/execute.sh +6 -1
- package/config/skills/agent/core/gmail-read/SKILL.md +10 -0
- package/config/skills/agent/core/gmail-read/execute.sh +6 -0
- package/config/skills/agent/core/gmail-search/SKILL.md +10 -0
- package/config/skills/agent/core/gmail-search/execute.sh +6 -0
- package/config/skills/agent/core/gmail-send/SKILL.md +10 -0
- package/config/skills/agent/core/gmail-send/execute.sh +6 -0
- package/config/skills/agent/core/sheets-read/SKILL.md +10 -0
- package/config/skills/agent/core/sheets-read/execute.sh +6 -1
- package/config/skills/agent/core/sheets-write/SKILL.md +10 -0
- package/config/skills/agent/core/sheets-write/execute.sh +6 -1
- package/config/skills/agent/core/slides-create/SKILL.md +10 -0
- package/config/skills/agent/core/slides-create/execute.sh +6 -1
- package/config/skills/agent/core/slides-read/SKILL.md +10 -0
- package/config/skills/agent/core/slides-read/execute.sh +6 -1
- package/config/slack-app-manifest.json +16 -9
- package/dist/backend/backend/src/constants.d.ts +18 -4
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +16 -4
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/google/google.controller.d.ts +8 -0
- package/dist/backend/backend/src/controllers/google/google.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/google/google.controller.js +137 -37
- package/dist/backend/backend/src/controllers/google/google.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/google/google.routes.d.ts +2 -1
- package/dist/backend/backend/src/controllers/google/google.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/google/google.routes.js +4 -2
- package/dist/backend/backend/src/controllers/google/google.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/slack/slack-error.utils.d.ts +46 -0
- package/dist/backend/backend/src/controllers/slack/slack-error.utils.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/slack/slack-error.utils.js +54 -0
- package/dist/backend/backend/src/controllers/slack/slack-error.utils.js.map +1 -0
- package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/slack/slack.controller.js +5 -12
- package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
- package/dist/backend/backend/src/services/google/google-api.client.d.ts +23 -2
- package/dist/backend/backend/src/services/google/google-api.client.d.ts.map +1 -1
- package/dist/backend/backend/src/services/google/google-api.client.js +5 -2
- package/dist/backend/backend/src/services/google/google-api.client.js.map +1 -1
- package/dist/backend/backend/src/services/google/google-workspace-token.service.d.ts +61 -11
- package/dist/backend/backend/src/services/google/google-workspace-token.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/google/google-workspace-token.service.js +108 -31
- package/dist/backend/backend/src/services/google/google-workspace-token.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +27 -4
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +18 -4
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +16 -4
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +27 -4
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/frontend/dist/assets/{index-e079a375.js → index-e7785269.js} +267 -267
- package/frontend/dist/index.html +1 -1
- package/package.json +1 -1
- package/packages/crewly-agent/src/runtime/agent-runner.service.test.ts +10 -1
- package/packages/crewly-agent/src/runtime/agent-runner.service.ts +321 -1
- package/packages/crewly-agent/src/runtime/finish-recovery.test.ts +177 -0
- package/packages/crewly-agent/src/runtime/text-tool-calls.test.ts +144 -0
- package/packages/crewly-agent/src/runtime/text-tool-calls.ts +316 -0
- package/packages/crewly-agent/src/runtime/text-tool-salvage.test.ts +190 -0
- package/packages/crewly-agent/src/runtime/types.ts +38 -0
|
@@ -231,6 +231,12 @@ api_call() {
|
|
|
231
231
|
# Tank: every reply-channel call 404'd for want of this variable).
|
|
232
232
|
echo '{"warning":"CREWLY_SESSION_NAME is not set in this shell — the request is sent without X-Agent-Session; channel replies and heartbeats will not be attributed to you. Prefix the call with CREWLY_SESSION_NAME=<your session name> or restart the agent."}' >&2
|
|
233
233
|
fi
|
|
234
|
+
# Which connected Google account the call acts as. One Crewly account can
|
|
235
|
+
# connect several (two Gmail logins, say); without this the backend uses
|
|
236
|
+
# whichever is the default, which is what a single-account install wants.
|
|
237
|
+
if [ -n "${CREWLY_GOOGLE_ACCOUNT:-}" ]; then
|
|
238
|
+
args+=(-H "X-Google-Account: $CREWLY_GOOGLE_ACCOUNT")
|
|
239
|
+
fi
|
|
234
240
|
[ -n "$body" ] && args+=(-d "$body")
|
|
235
241
|
|
|
236
242
|
local response
|
|
@@ -60,3 +60,13 @@ bash execute.sh '{"summary":"Standup","start":"2026-09-21T09:00:00Z","end":"2026
|
|
|
60
60
|
Missing `--summary` / `--start` / `--end` → `{"error":"Missing required parameter: …"}` on stderr, exit 1.
|
|
61
61
|
`{"success":false,"reason":"not_connected","hint":"<connect URL>"}` (exit 1) when the owner has not connected Google Workspace;
|
|
62
62
|
`reason` `validation` when Google cannot parse a time.
|
|
63
|
+
|
|
64
|
+
## Choosing a Google account
|
|
65
|
+
|
|
66
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever you marked default on the Connections page). Name one explicitly when it matters:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
bash execute.sh --account work@company.com ...
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The account must be connected *for this product* — Google consent is per product (Gmail / Calendar / Drive), so an account connected only for Calendar cannot read Drive.
|
|
@@ -28,6 +28,7 @@ Options:
|
|
|
28
28
|
--description Body text
|
|
29
29
|
--attendee Attendee email (repeat for several)
|
|
30
30
|
--calendar Calendar id (default: primary)
|
|
31
|
+
--account Which connected Google account to act as (default: your primary)
|
|
31
32
|
--help | -h Show this help
|
|
32
33
|
EOF_USAGE
|
|
33
34
|
}
|
|
@@ -41,6 +42,7 @@ if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
|
|
|
41
42
|
shift || true
|
|
42
43
|
fi
|
|
43
44
|
|
|
45
|
+
ACCOUNT=""
|
|
44
46
|
while [[ $# -gt 0 ]]; do
|
|
45
47
|
case "$1" in
|
|
46
48
|
--summary|--title) [ $# -ge 2 ] || error_exit "--summary requires a value"; SUMMARY="$2"; shift 2 ;;
|
|
@@ -51,6 +53,7 @@ while [[ $# -gt 0 ]]; do
|
|
|
51
53
|
--calendar|-c) [ $# -ge 2 ] || error_exit "--calendar requires a value"; CALENDAR="$2"; shift 2 ;;
|
|
52
54
|
--attendee) [ $# -ge 2 ] || error_exit "--attendee requires a value"
|
|
53
55
|
ATTENDEES_JSON=$(jq -cn --argjson arr "$ATTENDEES_JSON" --arg v "$2" '$arr + [$v]'); shift 2 ;;
|
|
56
|
+
--account) [ $# -ge 2 ] || error_exit "--account requires a value"; ACCOUNT="$2"; shift 2 ;;
|
|
54
57
|
--help|-h) print_usage; exit 0 ;;
|
|
55
58
|
*) error_exit "Unknown option: $1" ;;
|
|
56
59
|
esac
|
|
@@ -67,7 +70,10 @@ if [ -n "$INPUT_JSON" ]; then
|
|
|
67
70
|
if [ "$(printf '%s' "$ATTENDEES_JSON" | jq 'length')" -eq 0 ]; then
|
|
68
71
|
ATTENDEES_JSON=$(printf '%s' "$INPUT" | jq -c '(.attendees // []) | if type == "string" then split(",") | map(gsub("^\\s+|\\s+$"; "")) | map(select(. != "")) else . end')
|
|
69
72
|
fi
|
|
73
|
+
[ -z "$ACCOUNT" ] && ACCOUNT=$(printf '%s' "$INPUT" | jq -r '.account // empty')
|
|
70
74
|
fi
|
|
75
|
+
# Route the call at one connected Google account; unset means the default.
|
|
76
|
+
[ -n "$ACCOUNT" ] && export CREWLY_GOOGLE_ACCOUNT="$ACCOUNT"
|
|
71
77
|
|
|
72
78
|
require_param "summary (--summary)" "$SUMMARY"
|
|
73
79
|
require_param "start (--start)" "$START"
|
|
@@ -56,3 +56,13 @@ bash execute.sh '{"calendarId":"team@group.calendar.google.com","from":"…","to
|
|
|
56
56
|
|
|
57
57
|
`{"success":false,"reason":"not_connected","hint":"<connect URL>"}` (exit 1)
|
|
58
58
|
when the owner has not connected Google Workspace.
|
|
59
|
+
|
|
60
|
+
## Choosing a Google account
|
|
61
|
+
|
|
62
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever you marked default on the Connections page). Name one explicitly when it matters:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
bash execute.sh --account work@company.com ...
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The account must be connected *for this product* — Google consent is per product (Gmail / Calendar / Drive), so an account connected only for Calendar cannot read Drive.
|
|
@@ -24,6 +24,7 @@ Options:
|
|
|
24
24
|
--to Upper bound (default: now + 7 days)
|
|
25
25
|
--calendar Calendar id (default: primary)
|
|
26
26
|
--max Result cap (default 50, max 250)
|
|
27
|
+
--account Which connected Google account to act as (default: your primary)
|
|
27
28
|
--help | -h Show this help
|
|
28
29
|
EOF_USAGE
|
|
29
30
|
}
|
|
@@ -48,12 +49,14 @@ if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
|
|
|
48
49
|
shift || true
|
|
49
50
|
fi
|
|
50
51
|
|
|
52
|
+
ACCOUNT=""
|
|
51
53
|
while [[ $# -gt 0 ]]; do
|
|
52
54
|
case "$1" in
|
|
53
55
|
--from) [ $# -ge 2 ] || error_exit "--from requires a value"; FROM="$2"; shift 2 ;;
|
|
54
56
|
--to) [ $# -ge 2 ] || error_exit "--to requires a value"; TO="$2"; shift 2 ;;
|
|
55
57
|
--calendar|-c) [ $# -ge 2 ] || error_exit "--calendar requires a value"; CALENDAR="$2"; shift 2 ;;
|
|
56
58
|
--max|-n) [ $# -ge 2 ] || error_exit "--max requires a value"; MAX="$2"; shift 2 ;;
|
|
59
|
+
--account) [ $# -ge 2 ] || error_exit "--account requires a value"; ACCOUNT="$2"; shift 2 ;;
|
|
57
60
|
--help|-h) print_usage; exit 0 ;;
|
|
58
61
|
*) error_exit "Unknown option: $1" ;;
|
|
59
62
|
esac
|
|
@@ -65,7 +68,10 @@ if [ -n "$INPUT_JSON" ]; then
|
|
|
65
68
|
[ -z "$TO" ] && TO=$(printf '%s' "$INPUT" | jq -r '.to // .timeMax // empty')
|
|
66
69
|
[ -z "$CALENDAR" ] && CALENDAR=$(printf '%s' "$INPUT" | jq -r '.calendarId // .calendar // empty')
|
|
67
70
|
[ -z "$MAX" ] && MAX=$(printf '%s' "$INPUT" | jq -r '.max // empty')
|
|
71
|
+
[ -z "$ACCOUNT" ] && ACCOUNT=$(printf '%s' "$INPUT" | jq -r '.account // empty')
|
|
68
72
|
fi
|
|
73
|
+
# Route the call at one connected Google account; unset means the default.
|
|
74
|
+
[ -n "$ACCOUNT" ] && export CREWLY_GOOGLE_ACCOUNT="$ACCOUNT"
|
|
69
75
|
|
|
70
76
|
[ -z "$FROM" ] && FROM=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
71
77
|
[ -z "$TO" ] && TO=$(iso_now_plus_days "$DEFAULT_WINDOW_DAYS")
|
|
@@ -48,3 +48,13 @@ bash execute.sh --id "https://docs.google.com/document/d/1AbC…/edit"
|
|
|
48
48
|
when the owner has not connected Google Workspace (Settings → Integrations).
|
|
49
49
|
A `403` with `reason: "google_error"` on a write means the file was not
|
|
50
50
|
created by Crewly — the grant only edits files Crewly made (`drive.file`).
|
|
51
|
+
|
|
52
|
+
## Choosing a Google account
|
|
53
|
+
|
|
54
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever you marked default on the Connections page). Name one explicitly when it matters:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
bash execute.sh --account work@company.com ...
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The account must be connected *for this product* — Google consent is per product (Gmail / Calendar / Drive), so an account connected only for Calendar cannot read Drive.
|
|
@@ -20,6 +20,7 @@ Usage:
|
|
|
20
20
|
|
|
21
21
|
Options:
|
|
22
22
|
--id Document id (from drive-search or the docs.google.com URL)
|
|
23
|
+
--account Which connected Google account to act as (default: your primary)
|
|
23
24
|
--help | -h Show this help
|
|
24
25
|
EOF_USAGE
|
|
25
26
|
}
|
|
@@ -48,10 +49,11 @@ if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
|
|
|
48
49
|
INPUT_JSON="$1"
|
|
49
50
|
shift || true
|
|
50
51
|
fi
|
|
51
|
-
ID=""
|
|
52
|
+
ID=""; ACCOUNT=""
|
|
52
53
|
while [[ $# -gt 0 ]]; do
|
|
53
54
|
case "$1" in
|
|
54
55
|
--id) [ $# -ge 2 ] || error_exit "--id requires a value"; ID="$2"; shift 2 ;;
|
|
56
|
+
--account) [ $# -ge 2 ] || error_exit "--account requires a value"; ACCOUNT="$2"; shift 2 ;;
|
|
55
57
|
--help|-h) print_usage; exit 0 ;;
|
|
56
58
|
*) error_exit "Unknown option: $1" ;;
|
|
57
59
|
esac
|
|
@@ -59,7 +61,10 @@ done
|
|
|
59
61
|
if [ -n "$INPUT_JSON" ]; then
|
|
60
62
|
INPUT=$(read_json_input "$INPUT_JSON")
|
|
61
63
|
[ -z "$ID" ] && ID=$(printf '%s' "$INPUT" | jq -r '.id // .documentId // empty')
|
|
64
|
+
[ -z "$ACCOUNT" ] && ACCOUNT=$(printf '%s' "$INPUT" | jq -r '.account // empty')
|
|
62
65
|
fi
|
|
66
|
+
# Route the call at one connected Google account; unset means the default.
|
|
67
|
+
[ -n "$ACCOUNT" ] && export CREWLY_GOOGLE_ACCOUNT="$ACCOUNT"
|
|
63
68
|
# Accept a full docs.google.com URL too.
|
|
64
69
|
ID=$(printf '%s' "$ID" | sed -E 's#.*/document/d/([^/?]+).*#\1#')
|
|
65
70
|
require_param "id (--id)" "$ID"
|
|
@@ -53,3 +53,13 @@ re-connect Google Workspace once the scope is enabled".
|
|
|
53
53
|
when the owner has not connected Google Workspace (Settings → Integrations).
|
|
54
54
|
A `403` with `reason: "google_error"` on a write means the file was not
|
|
55
55
|
created by Crewly — the grant only edits files Crewly made (`drive.file`).
|
|
56
|
+
|
|
57
|
+
## Choosing a Google account
|
|
58
|
+
|
|
59
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever you marked default on the Connections page). Name one explicitly when it matters:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
bash execute.sh --account work@company.com ...
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The account must be connected *for this product* — Google consent is per product (Gmail / Calendar / Drive), so an account connected only for Calendar cannot read Drive.
|
|
@@ -27,6 +27,7 @@ Options:
|
|
|
27
27
|
--id Append to this document instead (must be one Crewly created, or the grant needs the Docs scope)
|
|
28
28
|
--text Body text (plain; blank line = new paragraph)
|
|
29
29
|
--text-file Read the body from a file
|
|
30
|
+
--account Which connected Google account to act as (default: your primary)
|
|
30
31
|
--help | -h Show this help
|
|
31
32
|
EOF_USAGE
|
|
32
33
|
}
|
|
@@ -55,13 +56,14 @@ if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
|
|
|
55
56
|
INPUT_JSON="$1"
|
|
56
57
|
shift || true
|
|
57
58
|
fi
|
|
58
|
-
TITLE=""; ID=""; TEXT=""; TEXT_FILE=""
|
|
59
|
+
TITLE=""; ID=""; TEXT=""; TEXT_FILE=""; ACCOUNT=""
|
|
59
60
|
while [[ $# -gt 0 ]]; do
|
|
60
61
|
case "$1" in
|
|
61
62
|
--title) [ $# -ge 2 ] || error_exit "--title requires a value"; TITLE="$2"; shift 2 ;;
|
|
62
63
|
--id) [ $# -ge 2 ] || error_exit "--id requires a value"; ID="$2"; shift 2 ;;
|
|
63
64
|
--text) [ $# -ge 2 ] || error_exit "--text requires a value"; TEXT="$2"; shift 2 ;;
|
|
64
65
|
--text-file) [ $# -ge 2 ] || error_exit "--text-file requires a value"; TEXT_FILE="$2"; shift 2 ;;
|
|
66
|
+
--account) [ $# -ge 2 ] || error_exit "--account requires a value"; ACCOUNT="$2"; shift 2 ;;
|
|
65
67
|
--help|-h) print_usage; exit 0 ;;
|
|
66
68
|
*) error_exit "Unknown option: $1" ;;
|
|
67
69
|
esac
|
|
@@ -71,7 +73,10 @@ if [ -n "$INPUT_JSON" ]; then
|
|
|
71
73
|
[ -z "$TITLE" ] && TITLE=$(printf '%s' "$INPUT" | jq -r '.title // empty')
|
|
72
74
|
[ -z "$ID" ] && ID=$(printf '%s' "$INPUT" | jq -r '.id // .documentId // empty')
|
|
73
75
|
[ -z "$TEXT" ] && TEXT=$(printf '%s' "$INPUT" | jq -r '.text // .body // empty')
|
|
76
|
+
[ -z "$ACCOUNT" ] && ACCOUNT=$(printf '%s' "$INPUT" | jq -r '.account // empty')
|
|
74
77
|
fi
|
|
78
|
+
# Route the call at one connected Google account; unset means the default.
|
|
79
|
+
[ -n "$ACCOUNT" ] && export CREWLY_GOOGLE_ACCOUNT="$ACCOUNT"
|
|
75
80
|
if [ -n "$TEXT_FILE" ]; then
|
|
76
81
|
[ -f "$TEXT_FILE" ] || error_exit "text file not found: $TEXT_FILE"
|
|
77
82
|
TEXT=$(cat "$TEXT_FILE")
|
|
@@ -51,3 +51,13 @@ Files over 10 MB are refused with a `webViewLink` to open instead.
|
|
|
51
51
|
when the owner has not connected Google Workspace (Settings → Integrations).
|
|
52
52
|
A `403` with `reason: "google_error"` on a write means the file was not
|
|
53
53
|
created by Crewly — the grant only edits files Crewly made (`drive.file`).
|
|
54
|
+
|
|
55
|
+
## Choosing a Google account
|
|
56
|
+
|
|
57
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever you marked default on the Connections page). Name one explicitly when it matters:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
bash execute.sh --account work@company.com ...
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The account must be connected *for this product* — Google consent is per product (Gmail / Calendar / Drive), so an account connected only for Calendar cannot read Drive.
|
|
@@ -21,6 +21,7 @@ Usage:
|
|
|
21
21
|
Options:
|
|
22
22
|
--id Drive file id (required; from drive-search)
|
|
23
23
|
--out Save the content to this path instead of printing it (binary files are decoded)
|
|
24
|
+
--account Which connected Google account to act as (default: your primary)
|
|
24
25
|
--help | -h Show this help
|
|
25
26
|
EOF_USAGE
|
|
26
27
|
}
|
|
@@ -49,11 +50,12 @@ if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
|
|
|
49
50
|
INPUT_JSON="$1"
|
|
50
51
|
shift || true
|
|
51
52
|
fi
|
|
52
|
-
ID=""; OUT_PATH=""
|
|
53
|
+
ID=""; OUT_PATH=""; ACCOUNT=""
|
|
53
54
|
while [[ $# -gt 0 ]]; do
|
|
54
55
|
case "$1" in
|
|
55
56
|
--id) [ $# -ge 2 ] || error_exit "--id requires a value"; ID="$2"; shift 2 ;;
|
|
56
57
|
--out|-o) [ $# -ge 2 ] || error_exit "--out requires a value"; OUT_PATH="$2"; shift 2 ;;
|
|
58
|
+
--account) [ $# -ge 2 ] || error_exit "--account requires a value"; ACCOUNT="$2"; shift 2 ;;
|
|
57
59
|
--help|-h) print_usage; exit 0 ;;
|
|
58
60
|
*) error_exit "Unknown option: $1" ;;
|
|
59
61
|
esac
|
|
@@ -62,7 +64,10 @@ if [ -n "$INPUT_JSON" ]; then
|
|
|
62
64
|
INPUT=$(read_json_input "$INPUT_JSON")
|
|
63
65
|
[ -z "$ID" ] && ID=$(printf '%s' "$INPUT" | jq -r '.id // .fileId // empty')
|
|
64
66
|
[ -z "$OUT_PATH" ] && OUT_PATH=$(printf '%s' "$INPUT" | jq -r '.out // empty')
|
|
67
|
+
[ -z "$ACCOUNT" ] && ACCOUNT=$(printf '%s' "$INPUT" | jq -r '.account // empty')
|
|
65
68
|
fi
|
|
69
|
+
# Route the call at one connected Google account; unset means the default.
|
|
70
|
+
[ -n "$ACCOUNT" ] && export CREWLY_GOOGLE_ACCOUNT="$ACCOUNT"
|
|
66
71
|
require_param "id (--id)" "$ID"
|
|
67
72
|
RESPONSE=$(call GET "/google/drive/files/$(uri "$ID")/content") || { printf '%s\n' "$RESPONSE"; exit 1; }
|
|
68
73
|
if printf '%s' "$RESPONSE" | jq -e '.truncated == true' >/dev/null 2>&1; then printf '%s\n' "$RESPONSE"; exit 0; fi
|
|
@@ -53,3 +53,13 @@ else → `drive-read`.
|
|
|
53
53
|
when the owner has not connected Google Workspace (Settings → Integrations).
|
|
54
54
|
A `403` with `reason: "google_error"` on a write means the file was not
|
|
55
55
|
created by Crewly — the grant only edits files Crewly made (`drive.file`).
|
|
56
|
+
|
|
57
|
+
## Choosing a Google account
|
|
58
|
+
|
|
59
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever you marked default on the Connections page). Name one explicitly when it matters:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
bash execute.sh --account work@company.com ...
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The account must be connected *for this product* — Google consent is per product (Gmail / Calendar / Drive), so an account connected only for Calendar cannot read Drive.
|
|
@@ -23,6 +23,7 @@ Options:
|
|
|
23
23
|
--mime Restrict to a type: doc | sheet | slides | pdf | folder | any MIME type
|
|
24
24
|
--folder Restrict to a Drive folder id
|
|
25
25
|
--max Result cap (default 20, max 100)
|
|
26
|
+
--account Which connected Google account to act as (default: your primary)
|
|
26
27
|
--help | -h Show this help
|
|
27
28
|
EOF_USAGE
|
|
28
29
|
}
|
|
@@ -51,13 +52,14 @@ if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
|
|
|
51
52
|
INPUT_JSON="$1"
|
|
52
53
|
shift || true
|
|
53
54
|
fi
|
|
54
|
-
QUERY=""; MIME=""; FOLDER=""; MAX=""
|
|
55
|
+
QUERY=""; MIME=""; FOLDER=""; MAX=""; ACCOUNT=""
|
|
55
56
|
while [[ $# -gt 0 ]]; do
|
|
56
57
|
case "$1" in
|
|
57
58
|
--query|-q) [ $# -ge 2 ] || error_exit "--query requires a value"; QUERY="$2"; shift 2 ;;
|
|
58
59
|
--mime) [ $# -ge 2 ] || error_exit "--mime requires a value"; MIME="$2"; shift 2 ;;
|
|
59
60
|
--folder) [ $# -ge 2 ] || error_exit "--folder requires a value"; FOLDER="$2"; shift 2 ;;
|
|
60
61
|
--max|-n) [ $# -ge 2 ] || error_exit "--max requires a value"; MAX="$2"; shift 2 ;;
|
|
62
|
+
--account) [ $# -ge 2 ] || error_exit "--account requires a value"; ACCOUNT="$2"; shift 2 ;;
|
|
61
63
|
--help|-h) print_usage; exit 0 ;;
|
|
62
64
|
*) error_exit "Unknown option: $1" ;;
|
|
63
65
|
esac
|
|
@@ -68,7 +70,10 @@ if [ -n "$INPUT_JSON" ]; then
|
|
|
68
70
|
[ -z "$MIME" ] && MIME=$(printf '%s' "$INPUT" | jq -r '.mime // .mimeType // empty')
|
|
69
71
|
[ -z "$FOLDER" ] && FOLDER=$(printf '%s' "$INPUT" | jq -r '.folder // .folderId // empty')
|
|
70
72
|
[ -z "$MAX" ] && MAX=$(printf '%s' "$INPUT" | jq -r '.max // empty')
|
|
73
|
+
[ -z "$ACCOUNT" ] && ACCOUNT=$(printf '%s' "$INPUT" | jq -r '.account // empty')
|
|
71
74
|
fi
|
|
75
|
+
# Route the call at one connected Google account; unset means the default.
|
|
76
|
+
[ -n "$ACCOUNT" ] && export CREWLY_GOOGLE_ACCOUNT="$ACCOUNT"
|
|
72
77
|
case "$MIME" in
|
|
73
78
|
doc|docs) MIME="application/vnd.google-apps.document" ;;
|
|
74
79
|
sheet|sheets) MIME="application/vnd.google-apps.spreadsheet" ;;
|
|
@@ -52,3 +52,13 @@ permissions are the owner's — this skill does not change sharing).
|
|
|
52
52
|
when the owner has not connected Google Workspace (Settings → Integrations).
|
|
53
53
|
A `403` with `reason: "google_error"` on a write means the file was not
|
|
54
54
|
created by Crewly — the grant only edits files Crewly made (`drive.file`).
|
|
55
|
+
|
|
56
|
+
## Choosing a Google account
|
|
57
|
+
|
|
58
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever you marked default on the Connections page). Name one explicitly when it matters:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
bash execute.sh --account work@company.com ...
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The account must be connected *for this product* — Google consent is per product (Gmail / Calendar / Drive), so an account connected only for Calendar cannot read Drive.
|
|
@@ -28,6 +28,7 @@ Options:
|
|
|
28
28
|
--mime MIME type override
|
|
29
29
|
--folder Destination folder id (default: My Drive root)
|
|
30
30
|
--convert Convert on upload: doc | sheet | slides (e.g. a .docx/.csv/.pptx becomes a Google-native file)
|
|
31
|
+
--account Which connected Google account to act as (default: your primary)
|
|
31
32
|
--help | -h Show this help
|
|
32
33
|
EOF_USAGE
|
|
33
34
|
}
|
|
@@ -56,7 +57,7 @@ if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
|
|
|
56
57
|
INPUT_JSON="$1"
|
|
57
58
|
shift || true
|
|
58
59
|
fi
|
|
59
|
-
FILE=""; NAME=""; TEXT=""; MIME=""; FOLDER=""; CONVERT=""
|
|
60
|
+
FILE=""; NAME=""; TEXT=""; MIME=""; FOLDER=""; CONVERT=""; ACCOUNT=""
|
|
60
61
|
while [[ $# -gt 0 ]]; do
|
|
61
62
|
case "$1" in
|
|
62
63
|
--path|-p) [ $# -ge 2 ] || error_exit "--path requires a value"; FILE="$2"; shift 2 ;;
|
|
@@ -65,6 +66,7 @@ while [[ $# -gt 0 ]]; do
|
|
|
65
66
|
--mime) [ $# -ge 2 ] || error_exit "--mime requires a value"; MIME="$2"; shift 2 ;;
|
|
66
67
|
--folder) [ $# -ge 2 ] || error_exit "--folder requires a value"; FOLDER="$2"; shift 2 ;;
|
|
67
68
|
--convert) [ $# -ge 2 ] || error_exit "--convert requires a value"; CONVERT="$2"; shift 2 ;;
|
|
69
|
+
--account) [ $# -ge 2 ] || error_exit "--account requires a value"; ACCOUNT="$2"; shift 2 ;;
|
|
68
70
|
--help|-h) print_usage; exit 0 ;;
|
|
69
71
|
*) error_exit "Unknown option: $1" ;;
|
|
70
72
|
esac
|
|
@@ -77,7 +79,10 @@ if [ -n "$INPUT_JSON" ]; then
|
|
|
77
79
|
[ -z "$MIME" ] && MIME=$(printf '%s' "$INPUT" | jq -r '.mime // .mimeType // empty')
|
|
78
80
|
[ -z "$FOLDER" ] && FOLDER=$(printf '%s' "$INPUT" | jq -r '.folder // .folderId // empty')
|
|
79
81
|
[ -z "$CONVERT" ] && CONVERT=$(printf '%s' "$INPUT" | jq -r '.convert // .convertTo // empty')
|
|
82
|
+
[ -z "$ACCOUNT" ] && ACCOUNT=$(printf '%s' "$INPUT" | jq -r '.account // empty')
|
|
80
83
|
fi
|
|
84
|
+
# Route the call at one connected Google account; unset means the default.
|
|
85
|
+
[ -n "$ACCOUNT" ] && export CREWLY_GOOGLE_ACCOUNT="$ACCOUNT"
|
|
81
86
|
case "$CONVERT" in
|
|
82
87
|
doc|docs) CONVERT="application/vnd.google-apps.document" ;;
|
|
83
88
|
sheet|sheets) CONVERT="application/vnd.google-apps.spreadsheet" ;;
|
|
@@ -59,3 +59,13 @@ pass `threadId` and `messageId` to `gmail-send`.
|
|
|
59
59
|
`{"success":false,"reason":"not_connected","hint":"<connect URL>"}` (exit 1)
|
|
60
60
|
when the owner has not connected Google Workspace; `reason` `google_error`
|
|
61
61
|
with a 404 message when the id is unknown.
|
|
62
|
+
|
|
63
|
+
## Choosing a Google account
|
|
64
|
+
|
|
65
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever you marked default on the Connections page). Name one explicitly when it matters:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
bash execute.sh --account work@company.com ...
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The account must be connected *for this product* — Google consent is per product (Gmail / Calendar / Drive), so an account connected only for Calendar cannot read Drive.
|
|
@@ -20,6 +20,7 @@ Usage:
|
|
|
20
20
|
|
|
21
21
|
Options:
|
|
22
22
|
--id | -i Gmail message id (required; from gmail-search)
|
|
23
|
+
--account Which connected Google account to act as (default: your primary)
|
|
23
24
|
--help | -h Show this help
|
|
24
25
|
EOF_USAGE
|
|
25
26
|
}
|
|
@@ -32,9 +33,11 @@ if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
|
|
|
32
33
|
shift || true
|
|
33
34
|
fi
|
|
34
35
|
|
|
36
|
+
ACCOUNT=""
|
|
35
37
|
while [[ $# -gt 0 ]]; do
|
|
36
38
|
case "$1" in
|
|
37
39
|
--id|-i) [ $# -ge 2 ] || error_exit "--id requires a value"; ID="$2"; shift 2 ;;
|
|
40
|
+
--account) [ $# -ge 2 ] || error_exit "--account requires a value"; ACCOUNT="$2"; shift 2 ;;
|
|
38
41
|
--help|-h) print_usage; exit 0 ;;
|
|
39
42
|
*) error_exit "Unknown option: $1" ;;
|
|
40
43
|
esac
|
|
@@ -43,7 +46,10 @@ done
|
|
|
43
46
|
if [ -n "$INPUT_JSON" ]; then
|
|
44
47
|
INPUT=$(read_json_input "$INPUT_JSON")
|
|
45
48
|
[ -z "$ID" ] && ID=$(printf '%s' "$INPUT" | jq -r '.id // .messageId // empty')
|
|
49
|
+
[ -z "$ACCOUNT" ] && ACCOUNT=$(printf '%s' "$INPUT" | jq -r '.account // empty')
|
|
46
50
|
fi
|
|
51
|
+
# Route the call at one connected Google account; unset means the default.
|
|
52
|
+
[ -n "$ACCOUNT" ] && export CREWLY_GOOGLE_ACCOUNT="$ACCOUNT"
|
|
47
53
|
|
|
48
54
|
require_param "id (--id)" "$ID"
|
|
49
55
|
|
|
@@ -62,3 +62,13 @@ Use the `id` with `gmail-read` to get the body; `threadId` + `gmail-read`'s
|
|
|
62
62
|
`{"success":false,"reason":"not_connected","hint":"<connect URL>"}` — the
|
|
63
63
|
owner has not connected Google Workspace yet; hand them the hint URL (or
|
|
64
64
|
point them to Settings → Integrations → Google Workspace). Exit code 1.
|
|
65
|
+
|
|
66
|
+
## Choosing a Google account
|
|
67
|
+
|
|
68
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever you marked default on the Connections page). Name one explicitly when it matters:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
bash execute.sh --account work@company.com ...
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The account must be connected *for this product* — Google consent is per product (Gmail / Calendar / Drive), so an account connected only for Calendar cannot read Drive.
|
|
@@ -23,6 +23,7 @@ Options:
|
|
|
23
23
|
--query | -q Gmail search query (required)
|
|
24
24
|
--max | -n Result cap (default 20, max 100)
|
|
25
25
|
--help | -h Show this help
|
|
26
|
+
--account Which connected Google account to act as (default: your primary)
|
|
26
27
|
EOF_USAGE
|
|
27
28
|
}
|
|
28
29
|
|
|
@@ -35,10 +36,12 @@ if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
|
|
|
35
36
|
shift || true
|
|
36
37
|
fi
|
|
37
38
|
|
|
39
|
+
ACCOUNT=""
|
|
38
40
|
while [[ $# -gt 0 ]]; do
|
|
39
41
|
case "$1" in
|
|
40
42
|
--query|-q) [ $# -ge 2 ] || error_exit "--query requires a value"; QUERY="$2"; shift 2 ;;
|
|
41
43
|
--max|-n) [ $# -ge 2 ] || error_exit "--max requires a value"; MAX="$2"; shift 2 ;;
|
|
44
|
+
--account) [ $# -ge 2 ] || error_exit "--account requires a value"; ACCOUNT="$2"; shift 2 ;;
|
|
42
45
|
--help|-h) print_usage; exit 0 ;;
|
|
43
46
|
*) error_exit "Unknown option: $1" ;;
|
|
44
47
|
esac
|
|
@@ -48,7 +51,10 @@ if [ -n "$INPUT_JSON" ]; then
|
|
|
48
51
|
INPUT=$(read_json_input "$INPUT_JSON")
|
|
49
52
|
[ -z "$QUERY" ] && QUERY=$(printf '%s' "$INPUT" | jq -r '.query // .q // empty')
|
|
50
53
|
[ -z "$MAX" ] && MAX=$(printf '%s' "$INPUT" | jq -r '.max // empty')
|
|
54
|
+
[ -z "$ACCOUNT" ] && ACCOUNT=$(printf '%s' "$INPUT" | jq -r '.account // empty')
|
|
51
55
|
fi
|
|
56
|
+
# Route the call at one connected Google account; unset means the default.
|
|
57
|
+
[ -n "$ACCOUNT" ] && export CREWLY_GOOGLE_ACCOUNT="$ACCOUNT"
|
|
52
58
|
|
|
53
59
|
require_param "query (--query)" "$QUERY"
|
|
54
60
|
|
|
@@ -67,3 +67,13 @@ Dry run: `{"success":true,"dryRun":true,"preview":"To: …\nSubject: …\n\n<bod
|
|
|
67
67
|
|
|
68
68
|
Missing `--to` / `--subject` / body → `{"error":"Missing required parameter: …"}` on stderr, exit 1, nothing sent.
|
|
69
69
|
`{"success":false,"reason":"not_connected","hint":"<connect URL>"}` (exit 1) when the owner has not connected Google Workspace.
|
|
70
|
+
|
|
71
|
+
## Choosing a Google account
|
|
72
|
+
|
|
73
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever you marked default on the Connections page). Name one explicitly when it matters:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
bash execute.sh --account work@company.com ...
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The account must be connected *for this product* — Google consent is per product (Gmail / Calendar / Drive), so an account connected only for Calendar cannot read Drive.
|
|
@@ -31,6 +31,7 @@ Options:
|
|
|
31
31
|
--thread-id Reply inside this Gmail thread
|
|
32
32
|
--in-reply-to Message-ID being answered (sets In-Reply-To / References)
|
|
33
33
|
--dry-run Preview only; nothing is sent (also: CREWLY_GMAIL_SEND_DRY_RUN=1)
|
|
34
|
+
--account Which connected Google account to act as (default: your primary)
|
|
34
35
|
--help | -h Show this help
|
|
35
36
|
EOF_USAGE
|
|
36
37
|
}
|
|
@@ -44,6 +45,7 @@ if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
|
|
|
44
45
|
shift || true
|
|
45
46
|
fi
|
|
46
47
|
|
|
48
|
+
ACCOUNT=""
|
|
47
49
|
while [[ $# -gt 0 ]]; do
|
|
48
50
|
case "$1" in
|
|
49
51
|
--to) [ $# -ge 2 ] || error_exit "--to requires a value"; TO="$2"; shift 2 ;;
|
|
@@ -54,6 +56,7 @@ while [[ $# -gt 0 ]]; do
|
|
|
54
56
|
--thread-id) [ $# -ge 2 ] || error_exit "--thread-id requires a value"; THREAD_ID="$2"; shift 2 ;;
|
|
55
57
|
--in-reply-to) [ $# -ge 2 ] || error_exit "--in-reply-to requires a value"; IN_REPLY_TO="$2"; shift 2 ;;
|
|
56
58
|
--dry-run) DRY_RUN=1; shift ;;
|
|
59
|
+
--account) [ $# -ge 2 ] || error_exit "--account requires a value"; ACCOUNT="$2"; shift 2 ;;
|
|
57
60
|
--help|-h) print_usage; exit 0 ;;
|
|
58
61
|
*) error_exit "Unknown option: $1" ;;
|
|
59
62
|
esac
|
|
@@ -68,7 +71,10 @@ if [ -n "$INPUT_JSON" ]; then
|
|
|
68
71
|
[ -z "$THREAD_ID" ] && THREAD_ID=$(printf '%s' "$INPUT" | jq -r '.threadId // empty')
|
|
69
72
|
[ -z "$IN_REPLY_TO" ] && IN_REPLY_TO=$(printf '%s' "$INPUT" | jq -r '.inReplyTo // empty')
|
|
70
73
|
[ -z "$DRY_RUN" ] && DRY_RUN=$(printf '%s' "$INPUT" | jq -r 'if .dryRun == true then "1" else "" end')
|
|
74
|
+
[ -z "$ACCOUNT" ] && ACCOUNT=$(printf '%s' "$INPUT" | jq -r '.account // empty')
|
|
71
75
|
fi
|
|
76
|
+
# Route the call at one connected Google account; unset means the default.
|
|
77
|
+
[ -n "$ACCOUNT" ] && export CREWLY_GOOGLE_ACCOUNT="$ACCOUNT"
|
|
72
78
|
|
|
73
79
|
if [ -n "$TEXT_FILE" ]; then
|
|
74
80
|
[ -f "$TEXT_FILE" ] || error_exit "text file not found: $TEXT_FILE"
|
|
@@ -51,3 +51,13 @@ come back as numbers, dates as the sheet's formatted string.
|
|
|
51
51
|
when the owner has not connected Google Workspace (Settings → Integrations).
|
|
52
52
|
A `403` with `reason: "google_error"` on a write means the file was not
|
|
53
53
|
created by Crewly — the grant only edits files Crewly made (`drive.file`).
|
|
54
|
+
|
|
55
|
+
## Choosing a Google account
|
|
56
|
+
|
|
57
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever you marked default on the Connections page). Name one explicitly when it matters:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
bash execute.sh --account work@company.com ...
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The account must be connected *for this product* — Google consent is per product (Gmail / Calendar / Drive), so an account connected only for Calendar cannot read Drive.
|
|
@@ -24,6 +24,7 @@ Options:
|
|
|
24
24
|
--id Spreadsheet id (or its URL)
|
|
25
25
|
--range A1 range, e.g. "Q3!A1:D50" (default A1:Z1000 on the first tab)
|
|
26
26
|
--info Print the title and tab names instead of values
|
|
27
|
+
--account Which connected Google account to act as (default: your primary)
|
|
27
28
|
--help | -h Show this help
|
|
28
29
|
EOF_USAGE
|
|
29
30
|
}
|
|
@@ -52,12 +53,13 @@ if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
|
|
|
52
53
|
INPUT_JSON="$1"
|
|
53
54
|
shift || true
|
|
54
55
|
fi
|
|
55
|
-
ID=""; RANGE=""; INFO=""
|
|
56
|
+
ID=""; RANGE=""; INFO=""; ACCOUNT=""
|
|
56
57
|
while [[ $# -gt 0 ]]; do
|
|
57
58
|
case "$1" in
|
|
58
59
|
--id) [ $# -ge 2 ] || error_exit "--id requires a value"; ID="$2"; shift 2 ;;
|
|
59
60
|
--range) [ $# -ge 2 ] || error_exit "--range requires a value"; RANGE="$2"; shift 2 ;;
|
|
60
61
|
--info) INFO=1; shift ;;
|
|
62
|
+
--account) [ $# -ge 2 ] || error_exit "--account requires a value"; ACCOUNT="$2"; shift 2 ;;
|
|
61
63
|
--help|-h) print_usage; exit 0 ;;
|
|
62
64
|
*) error_exit "Unknown option: $1" ;;
|
|
63
65
|
esac
|
|
@@ -67,7 +69,10 @@ if [ -n "$INPUT_JSON" ]; then
|
|
|
67
69
|
[ -z "$ID" ] && ID=$(printf '%s' "$INPUT" | jq -r '.id // .spreadsheetId // empty')
|
|
68
70
|
[ -z "$RANGE" ] && RANGE=$(printf '%s' "$INPUT" | jq -r '.range // empty')
|
|
69
71
|
[ -z "$INFO" ] && INFO=$(printf '%s' "$INPUT" | jq -r 'if .info == true then "1" else "" end')
|
|
72
|
+
[ -z "$ACCOUNT" ] && ACCOUNT=$(printf '%s' "$INPUT" | jq -r '.account // empty')
|
|
70
73
|
fi
|
|
74
|
+
# Route the call at one connected Google account; unset means the default.
|
|
75
|
+
[ -n "$ACCOUNT" ] && export CREWLY_GOOGLE_ACCOUNT="$ACCOUNT"
|
|
71
76
|
ID=$(printf '%s' "$ID" | sed -E 's#.*/spreadsheets/d/([^/?]+).*#\1#')
|
|
72
77
|
require_param "id (--id)" "$ID"
|
|
73
78
|
if [ -n "$INFO" ]; then
|
|
@@ -54,3 +54,13 @@ the owner made outside Crewly needs the Sheets write scope (`403 google_error`).
|
|
|
54
54
|
when the owner has not connected Google Workspace (Settings → Integrations).
|
|
55
55
|
A `403` with `reason: "google_error"` on a write means the file was not
|
|
56
56
|
created by Crewly — the grant only edits files Crewly made (`drive.file`).
|
|
57
|
+
|
|
58
|
+
## Choosing a Google account
|
|
59
|
+
|
|
60
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever you marked default on the Connections page). Name one explicitly when it matters:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
bash execute.sh --account work@company.com ...
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The account must be connected *for this product* — Google consent is per product (Gmail / Calendar / Drive), so an account connected only for Calendar cannot read Drive.
|
|
@@ -30,6 +30,7 @@ Options:
|
|
|
30
30
|
--csv-file Rows from a CSV file (simple: comma-separated, quotes stripped)
|
|
31
31
|
--range A1 anchor: the table to append to, or the top-left cell to overwrite (default A1)
|
|
32
32
|
--mode append (default) | update
|
|
33
|
+
--account Which connected Google account to act as (default: your primary)
|
|
33
34
|
--help | -h Show this help
|
|
34
35
|
EOF_USAGE
|
|
35
36
|
}
|
|
@@ -58,7 +59,7 @@ if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
|
|
|
58
59
|
INPUT_JSON="$1"
|
|
59
60
|
shift || true
|
|
60
61
|
fi
|
|
61
|
-
TITLE=""; SHEET=""; ID=""; ROWS=""; CSV_FILE=""; RANGE=""; MODE=""
|
|
62
|
+
TITLE=""; SHEET=""; ID=""; ROWS=""; CSV_FILE=""; RANGE=""; MODE=""; ACCOUNT=""
|
|
62
63
|
while [[ $# -gt 0 ]]; do
|
|
63
64
|
case "$1" in
|
|
64
65
|
--title) [ $# -ge 2 ] || error_exit "--title requires a value"; TITLE="$2"; shift 2 ;;
|
|
@@ -68,6 +69,7 @@ while [[ $# -gt 0 ]]; do
|
|
|
68
69
|
--csv-file) [ $# -ge 2 ] || error_exit "--csv-file requires a value"; CSV_FILE="$2"; shift 2 ;;
|
|
69
70
|
--range) [ $# -ge 2 ] || error_exit "--range requires a value"; RANGE="$2"; shift 2 ;;
|
|
70
71
|
--mode) [ $# -ge 2 ] || error_exit "--mode requires a value"; MODE="$2"; shift 2 ;;
|
|
72
|
+
--account) [ $# -ge 2 ] || error_exit "--account requires a value"; ACCOUNT="$2"; shift 2 ;;
|
|
71
73
|
--help|-h) print_usage; exit 0 ;;
|
|
72
74
|
*) error_exit "Unknown option: $1" ;;
|
|
73
75
|
esac
|
|
@@ -80,7 +82,10 @@ if [ -n "$INPUT_JSON" ]; then
|
|
|
80
82
|
[ -z "$ROWS" ] && ROWS=$(printf '%s' "$INPUT" | jq -c '.rows // empty')
|
|
81
83
|
[ -z "$RANGE" ] && RANGE=$(printf '%s' "$INPUT" | jq -r '.range // empty')
|
|
82
84
|
[ -z "$MODE" ] && MODE=$(printf '%s' "$INPUT" | jq -r '.mode // empty')
|
|
85
|
+
[ -z "$ACCOUNT" ] && ACCOUNT=$(printf '%s' "$INPUT" | jq -r '.account // empty')
|
|
83
86
|
fi
|
|
87
|
+
# Route the call at one connected Google account; unset means the default.
|
|
88
|
+
[ -n "$ACCOUNT" ] && export CREWLY_GOOGLE_ACCOUNT="$ACCOUNT"
|
|
84
89
|
if [ -n "$CSV_FILE" ]; then
|
|
85
90
|
[ -f "$CSV_FILE" ] || error_exit "csv file not found: $CSV_FILE"
|
|
86
91
|
ROWS=$(python3 -c 'import csv,json,sys; print(json.dumps(list(csv.reader(open(sys.argv[1], newline="")))))' "$CSV_FILE")
|
|
@@ -59,3 +59,13 @@ For designed decks (brand templates, images, video) use the Canva skills.
|
|
|
59
59
|
when the owner has not connected Google Workspace (Settings → Integrations).
|
|
60
60
|
A `403` with `reason: "google_error"` on a write means the file was not
|
|
61
61
|
created by Crewly — the grant only edits files Crewly made (`drive.file`).
|
|
62
|
+
|
|
63
|
+
## Choosing a Google account
|
|
64
|
+
|
|
65
|
+
Several Google accounts can be connected at once. Without `--account` the call uses the default one (the first you connected, or whichever you marked default on the Connections page). Name one explicitly when it matters:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
bash execute.sh --account work@company.com ...
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The account must be connected *for this product* — Google consent is per product (Gmail / Calendar / Drive), so an account connected only for Calendar cannot read Drive.
|