원클릭으로
gmail
Use when the user asks to read, search, or list Gmail messages, threads, or labels. Readonly access only — no sending or modifying.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Use when the user asks to read, search, or list Gmail messages, threads, or labels. Readonly access only — no sending or modifying.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Enforces explicit user approval before implementing any plan. Use when presenting a plan, receiving plan feedback, or about to delegate implementation.
CharlieBot repo structure, architecture, and development conventions. Use when modifying charlie-bot code.
How to write effective improve loop goal prompts — for the master CC agent that writes the --goal-file content.
methodology for iterative improve loop workers.
CharlieBot skill directory layout, sync rules, and CLI tool mappings. Use when creating, installing, or syncing skills across Claude Code, Codex, Gemini, OpenCode, and Antigravity.
This skill should be used when the user asks to read, create, or edit Feishu/Lark documents, search docs in their Feishu workspace, or fetch content from a Feishu wiki or docx URL.
| name | gmail |
| description | Use when the user asks to read, search, or list Gmail messages, threads, or labels. Readonly access only — no sending or modifying. |
| version | 1.0.0 |
Read and search Gmail messages using the Gmail API with a user refresh token. Readonly scope only.
Note: This account uses Gmailify, so emails from linked external accounts are also accessible.
~/.charliebot/config.yamlgoogle_client_idgoogle_client_secretgoogle_refresh_tokengoogle_refresh_token in config. Access tokens are minted at runtime and discarded after use.All Gmail API requests use:
-H "Authorization: Bearer $ACCESS_TOKEN"
read GOOGLE_CLIENT_ID GOOGLE_CLIENT_SECRET GOOGLE_REFRESH_TOKEN < <(python3 -c "
import yaml
c = yaml.safe_load(open('$HOME/.charliebot/config.yaml'))
print(c['google_client_id'], c['google_client_secret'], c['google_refresh_token'])
")
ACCESS_TOKEN=$(curl -s -X POST https://oauth2.googleapis.com/token \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "client_id=$GOOGLE_CLIENT_ID" \
--data-urlencode "client_secret=$GOOGLE_CLIENT_SECRET" \
--data-urlencode "refresh_token=$GOOGLE_REFRESH_TOKEN" \
--data-urlencode "grant_type=refresh_token" | jq -r '.access_token')
curl -s "https://gmail.googleapis.com/gmail/v1/users/me/messages?maxResults=10" \
-H "Authorization: Bearer $ACCESS_TOKEN"
With search query (Gmail search syntax):
curl -s "https://gmail.googleapis.com/gmail/v1/users/me/messages?q=from%3Aexample%40gmail.com&maxResults=10" \
-H "Authorization: Bearer $ACCESS_TOKEN"
curl -s "https://gmail.googleapis.com/gmail/v1/users/me/messages/MESSAGE_ID?format=full" \
-H "Authorization: Bearer $ACCESS_TOKEN"
To extract readable text from the response:
payload.body.data (base64url-encoded) for simple messages.payload.parts[] and find the part with mimeType: text/plain (or text/html as fallback). The text is in parts[].body.data.echo "$DATA" | tr '_-' '/+' | base64 -dcurl -s "https://gmail.googleapis.com/gmail/v1/users/me/threads/THREAD_ID?format=full" \
-H "Authorization: Bearer $ACCESS_TOKEN"
Returns all messages in the thread.
curl -s "https://gmail.googleapis.com/gmail/v1/users/me/labels" \
-H "Authorization: Bearer $ACCESS_TOKEN"
All Google integrations (Gmail, Docs, Sheets, Drive, Calendar) share a single OAuth client and refresh token stored under the unified google_* config keys.
One-time setup to obtain a refresh token for the desktop-app OAuth flow:
redirect_uri=http://localhost (not http://127.0.0.1:PORT):response_type=code
client_id=CLIENT_ID
redirect_uri=http://localhost
scope=https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/documents https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/gmail.readonly https://www.googleapis.com/auth/calendar
access_type=offline
prompt=consent
code from the redirect, and exchange it for tokens:curl -s -X POST https://oauth2.googleapis.com/token \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "client_id=CLIENT_ID" \
--data-urlencode "client_secret=CLIENT_SECRET" \
--data-urlencode "code=AUTH_CODE" \
--data-urlencode "grant_type=authorization_code" \
--data-urlencode "redirect_uri=http://localhost"
refresh_token to google_refresh_token in ~/.charliebot/config.yaml.Note: If the GCP project is in Testing mode, the refresh token expires in ~7 days. Publish the OAuth consent screen to Production for non-expiring tokens.
~/.charliebot/config.yaml.q= parameter).from:someone@example.com — from a specific senderto:someone@example.com — to a specific recipientsubject:keyword — subject contains keywordis:unread — unread messagesnewer_than:2d — messages from the last 2 dayshas:attachment — messages with attachmentslabel:LABEL_NAME — messages with a specific labelOR: from:a@b.com subject:invoice