clawGoogle Workspace via ClawEmail — Gmail, Drive, Docs, Sheets, Slides, Calendar, Forms. Use PROACTIVELY when the user asks to send email, create documents, manage files, schedule events, or work with any Google service.
Install via ClawdBot CLI:
clawdbot install cto1/clawUse claw for Gmail, Drive, Docs, Sheets, Slides, Calendar, and Forms via your @clawemail.com account.
~/.config/clawemail/credentials.jsonexport CLAWEMAIL_CREDENTIALS=~/.config/clawemail/credentials.jsonGet credentials at https://clawemail.com — sign up, then visit /connect/YOUR_PREFIX to authorize OAuth.
All API calls need a Bearer token. Use the helper script to refresh and cache it:
TOKEN=$(~/.openclaw/skills/claw/scripts/token.sh)
The script caches tokens for 50 minutes. Always assign to TOKEN before making API calls.
TOKEN=$(~/.openclaw/skills/claw/scripts/token.sh)
curl -s -H "Authorization: Bearer $TOKEN" \
"https://gmail.googleapis.com/gmail/v1/users/me/messages?q=newer_than:7d&maxResults=10" | python3 -m json.tool
Common query operators: from:, to:, subject:, newer_than:, older_than:, is:unread, has:attachment, label:, in:inbox.
curl -s -H "Authorization: Bearer $TOKEN" \
"https://gmail.googleapis.com/gmail/v1/users/me/messages/MESSAGE_ID?format=full" | python3 -m json.tool
For plain text body only, use format=minimal and decode the payload. For readable output:
curl -s -H "Authorization: Bearer $TOKEN" \
"https://gmail.googleapis.com/gmail/v1/users/me/messages/MESSAGE_ID?format=full" \
| python3 -c "
import json,sys,base64
m=json.load(sys.stdin)
hdrs={h['name']:h['value'] for h in m['payload']['headers']}
print(f\"From: {hdrs.get('From','')}\nTo: {hdrs.get('To','')}\nSubject: {hdrs.get('Subject','')}\nDate: {hdrs.get('Date','')}\n\")
def get_body(part):
if part.get('body',{}).get('data'):
return base64.urlsafe_b64decode(part['body']['data']).decode('utf-8','replace')
for p in part.get('parts',[]):
if p['mimeType']=='text/plain': return get_body(p)
for p in part.get('parts',[]):
b=get_body(p)
if b: return b
return ''
print(get_body(m['payload']))
"
TOKEN=$(~/.openclaw/skills/claw/scripts/token.sh)
python3 -c "
import base64,json
raw = base64.urlsafe_b64encode(
b'To: recipient@example.com\r\nSubject: Hello\r\nContent-Type: text/plain; charset=utf-8\r\n\r\nMessage body here'
).decode()
print(json.dumps({'raw': raw}))
" | curl -s -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d @- \
"https://gmail.googleapis.com/gmail/v1/users/me/messages/send"
For HTML emails, replace Content-Type: text/plain with Content-Type: text/html and use HTML in the body.
Same as send, but add In-Reply-To: and References: headers from the original message, and include threadId in the JSON body:
python3 -c "
import base64,json
raw = base64.urlsafe_b64encode(
b'To: recipient@example.com\r\nSubject: Re: Original Subject\r\nIn-Reply-To: <original-message-id>\r\nReferences: <original-message-id>\r\nContent-Type: text/plain; charset=utf-8\r\n\r\nReply body'
).decode()
print(json.dumps({'raw': raw, 'threadId': 'THREAD_ID'}))
" | curl -s -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d @- \
"https://gmail.googleapis.com/gmail/v1/users/me/messages/send"
curl -s -H "Authorization: Bearer $TOKEN" \
"https://gmail.googleapis.com/gmail/v1/users/me/labels" | python3 -m json.tool
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"addLabelIds":["LABEL_ID"],"removeLabelIds":["INBOX"]}' \
"https://gmail.googleapis.com/gmail/v1/users/me/messages/MESSAGE_ID/modify"
TOKEN=$(~/.openclaw/skills/claw/scripts/token.sh)
curl -s -H "Authorization: Bearer $TOKEN" \
"https://www.googleapis.com/drive/v3/files?pageSize=20&fields=files(id,name,mimeType,modifiedTime,size)&orderBy=modifiedTime desc" | python3 -m json.tool
curl -s -H "Authorization: Bearer $TOKEN" \
"https://www.googleapis.com/drive/v3/files?q=name+contains+'report'&fields=files(id,name,mimeType,modifiedTime)" | python3 -m json.tool
Query operators: name contains 'term', mimeType='application/vnd.google-apps.document', 'FOLDER_ID' in parents, trashed=false, modifiedTime > '2025-01-01'.
Common MIME types:
application/vnd.google-apps.documentapplication/vnd.google-apps.spreadsheetapplication/vnd.google-apps.presentationapplication/vnd.google-apps.folderapplication/vnd.google-apps.formcurl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"My Folder","mimeType":"application/vnd.google-apps.folder"}' \
"https://www.googleapis.com/drive/v3/files?fields=id,name" | python3 -m json.tool
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-F "metadata={\"name\":\"report.pdf\"};type=application/json" \
-F "file=@/path/to/report.pdf;type=application/pdf" \
"https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id,name" | python3 -m json.tool
For Google Docs/Sheets/Slides (export):
curl -s -H "Authorization: Bearer $TOKEN" \
"https://www.googleapis.com/drive/v3/files/FILE_ID/export?mimeType=application/pdf" -o output.pdf
Export formats: text/plain, text/html, application/pdf, application/vnd.openxmlformats-officedocument.wordprocessingml.document (docx), text/csv (sheets).
For binary files (download):
curl -s -H "Authorization: Bearer $TOKEN" \
"https://www.googleapis.com/drive/v3/files/FILE_ID?alt=media" -o output.file
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"role":"writer","type":"user","emailAddress":"user@example.com"}' \
"https://www.googleapis.com/drive/v3/files/FILE_ID/permissions"
Roles: reader, commenter, writer, owner. Types: user, group, domain, anyone.
curl -s -X DELETE -H "Authorization: Bearer $TOKEN" \
"https://www.googleapis.com/drive/v3/files/FILE_ID"
TOKEN=$(~/.openclaw/skills/claw/scripts/token.sh)
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"My Document"}' \
"https://docs.googleapis.com/v1/documents" | python3 -m json.tool
curl -s -H "Authorization: Bearer $TOKEN" \
"https://docs.googleapis.com/v1/documents/DOCUMENT_ID" | python3 -m json.tool
For plain text extraction:
curl -s -H "Authorization: Bearer $TOKEN" \
"https://docs.googleapis.com/v1/documents/DOCUMENT_ID" \
| python3 -c "
import json,sys
doc=json.load(sys.stdin)
text=''
for el in doc.get('body',{}).get('content',[]):
for p in el.get('paragraph',{}).get('elements',[]):
text+=p.get('textRun',{}).get('content','')
print(text)
"
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"requests":[{"insertText":{"location":{"index":1},"text":"Hello, world!\n"}}]}' \
"https://docs.googleapis.com/v1/documents/DOCUMENT_ID:batchUpdate"
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"requests":[{"replaceAllText":{"containsText":{"text":"OLD_TEXT","matchCase":true},"replaceText":"NEW_TEXT"}}]}' \
"https://docs.googleapis.com/v1/documents/DOCUMENT_ID:batchUpdate"
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"requests":[{"insertText":{"location":{"index":1},"text":"My Heading\n"}},{"updateParagraphStyle":{"range":{"startIndex":1,"endIndex":12},"paragraphStyle":{"namedStyleType":"HEADING_1"},"fields":"namedStyleType"}}]}' \
"https://docs.googleapis.com/v1/documents/DOCUMENT_ID:batchUpdate"
Heading styles: HEADING_1 through HEADING_6, TITLE, SUBTITLE, NORMAL_TEXT.
TOKEN=$(~/.openclaw/skills/claw/scripts/token.sh)
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"properties":{"title":"My Spreadsheet"}}' \
"https://sheets.googleapis.com/v4/spreadsheets" | python3 -m json.tool
curl -s -H "Authorization: Bearer $TOKEN" \
"https://sheets.googleapis.com/v4/spreadsheets/SPREADSHEET_ID/values/Sheet1!A1:D10" | python3 -m json.tool
curl -s -X PUT -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"values":[["Name","Age","City"],["Alice","30","NYC"],["Bob","25","LA"]]}' \
"https://sheets.googleapis.com/v4/spreadsheets/SPREADSHEET_ID/values/Sheet1!A1:C3?valueInputOption=USER_ENTERED" | python3 -m json.tool
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"values":[["Charlie","35","Chicago"]]}' \
"https://sheets.googleapis.com/v4/spreadsheets/SPREADSHEET_ID/values/Sheet1!A:C:append?valueInputOption=USER_ENTERED&insertDataOption=INSERT_ROWS" | python3 -m json.tool
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
"https://sheets.googleapis.com/v4/spreadsheets/SPREADSHEET_ID/values/Sheet1!A1:D10:clear"
curl -s -H "Authorization: Bearer $TOKEN" \
"https://sheets.googleapis.com/v4/spreadsheets/SPREADSHEET_ID?fields=properties.title,sheets.properties" | python3 -m json.tool
TOKEN=$(~/.openclaw/skills/claw/scripts/token.sh)
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"My Presentation"}' \
"https://slides.googleapis.com/v1/presentations" | python3 -m json.tool
curl -s -H "Authorization: Bearer $TOKEN" \
"https://slides.googleapis.com/v1/presentations/PRESENTATION_ID" | python3 -m json.tool
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"requests":[{"createSlide":{"slideLayoutReference":{"predefinedLayout":"TITLE_AND_BODY"}}}]}' \
"https://slides.googleapis.com/v1/presentations/PRESENTATION_ID:batchUpdate" | python3 -m json.tool
Layouts: BLANK, TITLE, TITLE_AND_BODY, TITLE_AND_TWO_COLUMNS, TITLE_ONLY, SECTION_HEADER, ONE_COLUMN_TEXT, MAIN_POINT, BIG_NUMBER.
First get the slide's page object IDs, then insert text into a placeholder:
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"requests":[{"insertText":{"objectId":"PLACEHOLDER_OBJECT_ID","text":"Hello from ClawEmail!","insertionIndex":0}}]}' \
"https://slides.googleapis.com/v1/presentations/PRESENTATION_ID:batchUpdate"
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"requests":[{"createImage":{"url":"https://example.com/image.png","elementProperties":{"pageObjectId":"SLIDE_ID","size":{"width":{"magnitude":3000000,"unit":"EMU"},"height":{"magnitude":2000000,"unit":"EMU"}},"transform":{"scaleX":1,"scaleY":1,"translateX":1000000,"translateY":1500000,"unit":"EMU"}}}}]}' \
"https://slides.googleapis.com/v1/presentations/PRESENTATION_ID:batchUpdate"
TOKEN=$(~/.openclaw/skills/claw/scripts/token.sh)
curl -s -H "Authorization: Bearer $TOKEN" \
"https://www.googleapis.com/calendar/v3/calendars/primary/events?timeMin=$(date -u +%Y-%m-%dT%H:%M:%SZ)&maxResults=10&singleEvents=true&orderBy=startTime" | python3 -m json.tool
curl -s -H "Authorization: Bearer $TOKEN" \
"https://www.googleapis.com/calendar/v3/calendars/primary/events?timeMin=2025-03-01T00:00:00Z&timeMax=2025-03-31T23:59:59Z&singleEvents=true&orderBy=startTime" | python3 -m json.tool
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"summary": "Team Meeting",
"description": "Weekly standup",
"start": {"dateTime": "2025-03-15T10:00:00-05:00", "timeZone": "America/New_York"},
"end": {"dateTime": "2025-03-15T11:00:00-05:00", "timeZone": "America/New_York"},
"attendees": [{"email": "colleague@example.com"}]
}' \
"https://www.googleapis.com/calendar/v3/calendars/primary/events" | python3 -m json.tool
curl -s -X PATCH -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"summary":"Updated Meeting Title","location":"Conference Room A"}' \
"https://www.googleapis.com/calendar/v3/calendars/primary/events/EVENT_ID" | python3 -m json.tool
curl -s -X DELETE -H "Authorization: Bearer $TOKEN" \
"https://www.googleapis.com/calendar/v3/calendars/primary/events/EVENT_ID"
curl -s -H "Authorization: Bearer $TOKEN" \
"https://www.googleapis.com/calendar/v3/users/me/calendarList" | python3 -m json.tool
TOKEN=$(~/.openclaw/skills/claw/scripts/token.sh)
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"info":{"title":"Feedback Form"}}' \
"https://forms.googleapis.com/v1/forms" | python3 -m json.tool
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"requests":[{"createItem":{"item":{"title":"How would you rate this?","questionItem":{"question":{"required":true,"scaleQuestion":{"low":1,"high":5,"lowLabel":"Poor","highLabel":"Excellent"}}}},"location":{"index":0}}}]}' \
"https://forms.googleapis.com/v1/forms/FORM_ID:batchUpdate"
curl -s -H "Authorization: Bearer $TOKEN" \
"https://forms.googleapis.com/v1/forms/FORM_ID/responses" | python3 -m json.tool
TOKEN=$(~/.openclaw/skills/claw/scripts/token.sh)python3 -m json.tool for readable output, or | python3 -c "import json,sys;..." for extractionnextPageToken. Pass it as ?pageToken=TOKEN for the next pagebatchUpdate — send multiple operations in one requesttoken.sh to refreshhttps://docs.google.com/document/d/FILE_ID/editGenerated Mar 1, 2026
A small e-commerce business uses the ClawEmail skill to automatically categorize and respond to customer inquiries. It searches for unread emails with keywords like 'refund' or 'order issue', labels them as 'Urgent', and drafts templated replies, streamlining support workflows and reducing response times.
A marketing agency leverages the skill to create and share Google Docs for campaign briefs, upload files to Drive, and schedule team meetings via Calendar. It proactively organizes project assets and sends email updates to clients, enhancing collaboration and project tracking.
A finance team uses the skill to generate monthly reports in Google Sheets, export them as PDFs, and email them to stakeholders. It automates data compilation, file uploads to Drive, and scheduled email sends, ensuring timely and accurate financial communication.
An online education platform employs the skill to manage course materials in Drive, create Google Forms for student feedback, and send enrollment reminders via email. It automates content updates and communication, improving administrative efficiency and student engagement.
An event planning company uses the skill to schedule meetings in Calendar, create event agendas in Google Docs, and send invitations via email. It manages RSVPs by searching and labeling emails, streamlining event logistics and attendee communication.
Offer a subscription-based service that integrates ClawEmail with existing business tools for automated email handling and document management. Clients pay monthly for setup, maintenance, and custom automation scripts, targeting small to medium enterprises seeking efficiency gains.
Provide one-time or ongoing consultancy to businesses looking to automate Google Workspace tasks. Revenue comes from project-based fees for implementing the skill, training staff, and optimizing workflows, with potential upsells for advanced features like AI-driven email sorting.
License the ClawEmail skill as part of a white-label productivity suite for other software providers. Revenue is generated through licensing fees and partnerships, allowing resellers to embed Google Workspace automation into their own platforms for end-users.
💬 Integration Tip
Ensure the CLAWEMAIL_CREDENTIALS environment variable is correctly set and test token refresh scripts in a staging environment before deployment to avoid authentication issues in production.
Google Workspace CLI for Gmail, Calendar, Drive, Contacts, Sheets, and Docs.
Query Google Places API (New) via the goplaces CLI for text search, place details, resolve, and reviews. Use for human-friendly place lookup or JSON output for scripts.
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Gmail, Calendar, Drive, Docs, Sheets — NO Google Cloud Console required. Just OAuth sign-in. Zero setup complexity vs traditional Google API integrations.
Google Drive API integration with managed OAuth. List, search, create, and manage files and folders. Use this skill when users want to interact with Google D...
Google Sheets API integration with managed OAuth. Read and write spreadsheet data, create sheets, apply formatting, and manage ranges. Use this skill when users want to read from or write to Google Sheets. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway).