Requirements
- Target platform
- OpenClaw
- Install method
- Manual import
- Extraction
- Extract archive
- Prerequisites
- OpenClaw
- Primary doc
- SKILL.md
Google 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.
Google 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.
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete.
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run.
Use claw for Gmail, Drive, Docs, Sheets, Slides, Calendar, and Forms via your @clawemail.com account.
Save your ClawEmail credentials JSON to ~/.config/clawemail/credentials.json Set the environment variable: export CLAWEMAIL_CREDENTIALS=~/.config/clawemail/credentials.json Get 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: Document: application/vnd.google-apps.document Spreadsheet: application/vnd.google-apps.spreadsheet Presentation: application/vnd.google-apps.presentation Folder: application/vnd.google-apps.folder Form: application/vnd.google-apps.form
curl -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
Always refresh token first: Start every sequence with TOKEN=$(~/.openclaw/skills/claw/scripts/token.sh) JSON output: Pipe through python3 -m json.tool for readable output, or | python3 -c "import json,sys;..." for extraction Pagination: Most list endpoints return nextPageToken. Pass it as ?pageToken=TOKEN for the next page Batch operations: Docs, Sheets, and Slides support batchUpdate — send multiple operations in one request Error 401: Token expired. Re-run token.sh to refresh Error 403: Scope not authorized. The ClawEmail OAuth includes Gmail, Drive, Docs, Sheets, Slides, Calendar, and Forms scopes Rate limits: Google APIs have per-user rate limits. Add brief delays between rapid successive calls File IDs: Google Docs/Sheets/Slides URLs contain the file ID: https://docs.google.com/document/d/FILE_ID/edit
User asks to send, read, or search email User wants to create or edit documents, spreadsheets, or presentations User needs to manage files in Google Drive User wants to schedule or check calendar events User asks to create forms or review form responses Any task involving Google Workspace services
Workflow acceleration for inboxes, docs, calendars, planning, and execution loops.
Largest current source with strong distribution and engagement signals.