{"id":"062f03d9-d2eb-42ee-87d0-7d639465cb10","entityType":"agent","slug":"clawhub-kesslerio-google-messages","name":"Google Messages","canonicalUrl":"https://www.xpersona.co/agent/clawhub-kesslerio-google-messages","canonicalPath":"/agent/clawhub-kesslerio-google-messages","generatedAt":"2026-10-09T16:10:29.778Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T08:10:08.809Z","emptyReason":null},"description":"Send and receive SMS/RCS via Google Messages web interface (messages.google.com). Use when asked to \"send a text\", \"check texts\", \"SMS\", \"text message\", \"Google Messages\", or forward incoming texts to other channels.","descriptionLabel":"Source description","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 3.4K downloads reported by the source. Last updated 10/9/2026.","installCommand":"clawhub skill install s174s08qgy6zjyxgxgabbt9mrs87h4q8:google-messages","sourceUrl":"https://clawhub.ai/kesslerio/google-messages","homepage":"https://clawhub.ai/kesslerio/skills/google-messages","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/kesslerio/google-messages","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/kesslerio/skills/google-messages","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":71,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Google Messages technical dossier on Xpersona with agent coverage, OPENCLEW support, and live trust metadata."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-09T08:10:08.809Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T08:10:08.809Z","emptyReason":null},"stars":null,"forks":null,"downloads":3422,"packageName":null,"latestVersion":"0.1.0","tractionLabel":"3.4K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T08:10:08.782Z","emptyReason":null},"lastUpdatedAt":"2026-10-09T08:10:08.809Z","lastCrawledAt":"2026-10-09T08:10:08.782Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-10T08:10:08.782Z","lastVerifiedAt":null,"highlights":[{"version":"0.1.0","createdAt":"2026-02-01T06:50:44.580Z","changelog":"Initial release of google-messages-openclaw-skill. - Enables sending and receiving SMS/RCS via Google Messages web interface. - Automates message workflow: pairing, sending, and receiving texts using the browser tool. - Provides real-time incoming SMS notifications via webhook forwarding. - Includes setup instructions for QR pairing, persistent session, and systemd service. - Details command references, selectors, troubleshooting, and security practices.","fileCount":10,"zipByteSize":13849}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s174s08qgy6zjyxgxgabbt9mrs87h4q8:google-messages","setupComplexity":"low","setupSteps":["Install using `clawhub skill install s174s08qgy6zjyxgxgabbt9mrs87h4q8:google-messages` in an isolated environment before connecting it to live workloads.","No published capability contract is available yet, so validate auth and request/response behavior manually.","Review the upstream CLAWHUB listing at https://clawhub.ai/kesslerio/google-messages before using production credentials."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-kesslerio-google-messages/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-kesslerio-google-messages/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-kesslerio-google-messages/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-kesslerio-google-messages/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-kesslerio-google-messages/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-kesslerio-google-messages/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-09T16:10:29.778Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-kesslerio-google-messages/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-kesslerio-google-messages/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-kesslerio-google-messages/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-kesslerio-google-messages/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T08:10:08.809Z","emptyReason":null},"readme":"Skill: Google Messages\n\nOwner: kesslerio\n\nSummary: Send and receive SMS/RCS via Google Messages web interface (messages.google.com). Use when asked to \"send a text\", \"check texts\", \"SMS\", \"text message\", \"Google Messages\", or forward incoming texts to other channels.\n\nTags: latest:0.1.0\n\nVersion history:\n\nv0.1.0 | 2026-02-01T06:50:44.580Z | auto\n\nInitial release of google-messages-openclaw-skill.\n\n- Enables sending and receiving SMS/RCS via Google Messages web interface.\n- Automates message workflow: pairing, sending, and receiving texts using the browser tool.\n- Provides real-time incoming SMS notifications via webhook forwarding.\n- Includes setup instructions for QR pairing, persistent session, and systemd service.\n- Details command references, selectors, troubleshooting, and security practices.\n\nArchive index:\n\nArchive v0.1.0: 10 files, 13849 bytes\n\nFiles: package.json (593b), README.md (3861b), references/observer-injection.md (3955b), references/snippets.md (2412b), scripts/start-webhook.sh (1039b), skill-card.md (2420b), SKILL.md (5099b), sms-observer.js (6923b), sms-webhook-server.js (4597b), _meta.json (134b)\n\nFile v0.1.0:SKILL.md\n\n---\nname: google-messages\ndescription: Send and receive SMS/RCS via Google Messages web interface (messages.google.com). Use when asked to \"send a text\", \"check texts\", \"SMS\", \"text message\", \"Google Messages\", or forward incoming texts to other channels.\nmetadata: {\"openclaw\": {\"emoji\": \"💬\", \"requires\": {\"tools\": [\"browser\"], \"bins\": [\"node\"], \"env\": [\"SMS_NOTIFICATION_TARGET\", \"SMS_NOTIFICATION_CHANNEL\"]}}}\n---\n\n# Google Messages Browser Skill\n\nAutomate SMS/RCS messaging via messages.google.com using the `browser` tool.\n\n## Overview\n\nGoogle Messages for Web allows you to send/receive texts from your Android phone via browser. This skill automates that interface.\n\n**Requirements:**\n- Android phone with Google Messages app\n- Phone and computer on same network (for initial QR pairing)\n- Browser profile with persistent session (use `openclaw` or your preferred profile)\n\n**Note:** Replace `profile=openclaw` in examples with your preferred browser profile if different.\n\n---\n\n## Quick Reference\n\n| Action | Command |\n|--------|---------|\n| Open pairing page | `browser action=open profile=openclaw targetUrl=\"https://messages.google.com/web/authentication\"` |\n| Check session | `browser action=snapshot profile=openclaw` — look for conversation list vs QR code |\n| Take screenshot | `browser action=screenshot profile=openclaw` |\n\n---\n\n## Initial Setup (QR Pairing)\n\nFirst-time setup requires scanning a QR code:\n\n1. **Open Google Messages Web**\n   ```\n   browser action=open profile=openclaw targetUrl=\"https://messages.google.com/web/authentication\"\n   ```\n\n2. **Screenshot the QR code** and share with user\n   ```\n   browser action=screenshot profile=openclaw\n   ```\n\n3. **User scans with phone:**\n   - Open Google Messages app on Android\n   - Tap ⋮ menu → \"Device pairing\" → \"QR code scanner\"\n   - Scan the QR code\n\n4. **Verify connection** — snapshot should show conversation list, not QR code\n\n**Important:** Enable \"Remember this computer\" to persist the session.\n\n---\n\n## Sending Messages\n\n1. **Navigate to conversations**\n   ```\n   browser action=navigate profile=openclaw targetUrl=\"https://messages.google.com/web/conversations\"\n   ```\n\n2. **Take snapshot and find conversation**\n   ```\n   browser action=snapshot profile=openclaw\n   ```\n   Look for the contact in the conversation list, note the `ref`.\n\n3. **Click conversation**\n   ```\n   browser action=act profile=openclaw request={\"kind\": \"click\", \"ref\": \"<ref>\"}\n   ```\n\n4. **Type message** (find textarea ref from snapshot)\n   ```\n   browser action=act profile=openclaw request={\"kind\": \"type\", \"ref\": \"<input_ref>\", \"text\": \"Your message\"}\n   ```\n\n5. **Click send** (find send button ref)\n   ```\n   browser action=act profile=openclaw request={\"kind\": \"click\", \"ref\": \"<send_ref>\"}\n   ```\n\n---\n\n## Receiving Messages (Real-time Notifications)\n\nThis skill includes a webhook system for real-time incoming SMS notifications.\n\n### Components\n\n1. **sms-webhook-server.js** — receives notifications, forwards to OpenClaw channels\n2. **sms-observer.js** — browser script that watches for new messages\n\n### Setup\n\n1. **Set environment variables:**\n   ```bash\n   export SMS_NOTIFICATION_TARGET=\"telegram:YOUR_CHAT_ID\"\n   export SMS_NOTIFICATION_CHANNEL=\"telegram\"\n   ```\n\n2. **Start webhook server:**\n   ```bash\n   node <skill>/sms-webhook-server.js\n   ```\n\n3. **Inject observer into browser** (see `references/observer-injection.md`)\n\n### Systemd Service (Persistent)\n\n```bash\ncp <skill>/systemd/google-messages-webhook.service ~/.config/systemd/user/\n# Edit service file: set SMS_NOTIFICATION_TARGET in Environment=\nsystemctl --user daemon-reload\nsystemctl --user enable --now google-messages-webhook\n```\n\n---\n\n## Reading Messages\n\nSee `references/snippets.md` for JavaScript snippets to:\n- Get recent conversations\n- Get messages in current conversation\n- Check session status\n\n---\n\n## Troubleshooting\n\n| Problem | Solution |\n|---------|----------|\n| QR code shown | Session expired, re-pair |\n| Elements not found | Google updated UI, check snapshot for new selectors |\n| Send button disabled | Message input empty or phone disconnected |\n| Observer not detecting | Check browser console for `[SMS Observer]` logs |\n| Webhook not receiving | Verify server running: `curl http://127.0.0.1:19888/health` |\n\n---\n\n## Selectors Reference\n\nGoogle Messages uses Angular components. These may change with updates.\n\n| Element | Selector |\n|---------|----------|\n| Conversation list | `mws-conversations-list` |\n| Conversation item | `mws-conversation-list-item` |\n| Message input | `textarea[aria-label*=\"message\"]` |\n| Send button | `button[aria-label*=\"Send\"]` |\n| QR code | `mw-qr-code` |\n\n---\n\n## Limitations\n\n- Phone must be online (messages sync through phone)\n- Browser tab must stay open for notifications\n- Session expires after ~14 days of inactivity\n- Observer lost on page reload (re-inject needed)\n\n---\n\n## Security\n\n- Webhook listens on localhost only (127.0.0.1)\n- No credentials stored (session in browser cookies)\n- QR pairing links to your phone — treat as sensitive\n\n---\n\n## License\n\nApache-2.0\n\nFile v0.1.0:README.md\n\n# Google Messages Skill for OpenClaw\n\nSend and receive SMS/RCS messages via Google Messages web interface using browser automation.\n\n## Features\n\n- 📤 **Send SMS** — Compose and send text messages\n- 📥 **Receive notifications** — Real-time alerts when new messages arrive\n- 🔍 **Read conversations** — Query recent messages and conversation history\n- 🔗 **OpenClaw integration** — Forward incoming SMS to Telegram, WhatsApp, or other channels\n\n## Requirements\n\n- [OpenClaw](https://github.com/openclaw/openclaw) with browser automation\n- Android phone with Google Messages app\n- Node.js 18+\n\n## Quick Start\n\n### 1. Install the skill\n\n```bash\n# Clone to your skills directory\ngit clone https://github.com/kesslerio/google-messages-openclaw-skill.git ~/.openclaw/skills/google-messages\n```\n\n### 2. Pair with your phone\n\nAsk your OpenClaw agent:\n```\n\"Open Google Messages and show me the QR code\"\n```\n\nOr manually:\n1. Go to https://messages.google.com/web\n2. Open Google Messages on your phone\n3. Tap ⋮ → Device pairing → QR code scanner\n4. Scan the code\n\n### 3. Enable notifications (optional)\n\nStart the webhook server to receive incoming message alerts:\n\n```bash\n# Set your notification target\nexport SMS_NOTIFICATION_TARGET=\"telegram:YOUR_CHAT_ID\"\nexport SMS_NOTIFICATION_CHANNEL=\"telegram\"\n\n# Start the server\nnode ~/.openclaw/skills/google-messages/sms-webhook-server.js\n```\n\nThen inject the observer into the browser tab. See `references/observer-injection.md` for details.\n\n## Usage\n\n### Sending messages\n\nAsk your OpenClaw agent:\n- \"Text John that I'm running late\"\n- \"Send an SMS to 555-1234 saying hello\"\n- \"Message Mom on Google Messages\"\n\n### Checking messages\n\n- \"Check my texts\"\n- \"Any new SMS messages?\"\n- \"What did John text me?\"\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `SMS_WEBHOOK_PORT` | Port for webhook server | `19888` |\n| `SMS_NOTIFICATION_TARGET` | OpenClaw target (e.g., `telegram:123456`) | _(none)_ |\n| `SMS_NOTIFICATION_CHANNEL` | Channel type | `telegram` |\n\n### Systemd Service\n\nFor persistent notifications, install as a user service:\n\n```bash\ncp systemd/google-messages-webhook.service ~/.config/systemd/user/\n# Edit service file: uncomment and set Environment= lines\nsystemctl --user daemon-reload\nsystemctl --user enable --now google-messages-webhook\n```\n\n## How It Works\n\n1. **Browser automation** — Uses OpenClaw's browser tool to control messages.google.com\n2. **MutationObserver** — Injects a script that watches the DOM for new messages\n3. **Webhook** — When new messages arrive, POSTs to a local server\n4. **Forwarding** — Webhook server uses `openclaw message send` to forward to your preferred channel\n\n## Files\n\n```\ngoogle-messages-skill/\n├── SKILL.md                    # OpenClaw skill definition\n├── sms-webhook-server.js       # Webhook server for notifications\n├── sms-observer.js             # Browser injection script (full version)\n├── references/\n│   ├── snippets.md             # JavaScript helper snippets\n│   └── observer-injection.md   # How to inject the observer\n├── scripts/\n│   └── start-webhook.sh        # Helper to start webhook\n└── systemd/\n    └── google-messages-webhook.service\n```\n\n## Limitations\n\n- Phone must be online (messages sync through phone)\n- Browser tab must stay open for notifications\n- Session expires after ~14 days of inactivity\n- QR re-pairing needed after session expiry\n- Observer lost on page reload\n\n## Security\n\n- Webhook server listens only on localhost\n- No credentials stored (session in browser profile cookies)\n- Observer script runs only on messages.google.com\n\n## License\n\nApache-2.0\n\n## Contributing\n\nIssues and PRs welcome at https://github.com/kesslerio/google-messages-openclaw-skill\n\nFile v0.1.0:_meta.json\n\n{\n  \"ownerId\": \"kn7fmw4ybcy50qzp1d2dvb1h517znaes\",\n  \"slug\": \"google-messages\",\n  \"version\": \"0.1.0\",\n  \"publishedAt\": 1769928644580\n}\n\nFile v0.1.0:references/observer-injection.md\n\n# Injecting the SMS Observer\n\nThe SMS observer watches for incoming messages and forwards them to the webhook server.\n\n## Prerequisites\n\n1. Webhook server running: `node <skill>/sms-webhook-server.js`\n2. Google Messages page loaded and paired\n3. Browser tab open at messages.google.com\n\n## Injection Command\n\nUse the browser tool to inject the observer script:\n\n```\nbrowser action=act profile=openclaw request={\"kind\": \"evaluate\", \"fn\": \"<minified_observer>\"}\n```\n\n## Minified Observer Script\n\nCopy this entire script for the `fn` parameter:\n\n```javascript\n(function(){var WEBHOOK_URL='http://127.0.0.1:19888/sms-inbound',CHECK_INTERVAL=2000,lastSeenMessages=new Map,initialized=false,observerAttached=false;function logAlways(){console.log.apply(console,['[SMS Observer]'].concat(Array.prototype.slice.call(arguments)))}function getConversations(){var convos=[],items=document.querySelectorAll('mws-conversation-list-item,[data-e2e-conversation],[role=\"option\"]');items.forEach(function(item,i){var nameEl=item.querySelector('h2,[data-e2e-conversation-name],.name'),previewEl=item.querySelector('[data-e2e-conversation-snippet],.snippet'),timeEl=item.querySelector('[data-e2e-conversation-timestamp],.timestamp,time'),preview='';if(previewEl)preview=previewEl.innerText||'';if(!preview){var divs=item.querySelectorAll('div');for(var j=0;j<divs.length;j++){var t=divs[j].innerText;if(t&&t.trim().length>5&&t.trim().length<200){preview=t.trim();break}}}convos.push({contact:nameEl?nameEl.innerText.trim():'Unknown',preview:preview.substring(0,150),time:timeEl?timeEl.innerText.trim():''})});return convos}function checkForNewMessages(){var conversations=getConversations();if(!initialized){conversations.forEach(function(c){lastSeenMessages.set(c.contact,{preview:c.preview,time:c.time})});initialized=true;logAlways('Initialized with',conversations.length,'conversations');return}conversations.forEach(function(c){var lastSeen=lastSeenMessages.get(c.contact);var isNew=!lastSeen||(lastSeen.preview!==c.preview&&c.preview);var isIncoming=c.preview&&!c.preview.startsWith('You:');if(isNew&&isIncoming){logAlways('New message:',c.contact,'-',c.preview.substring(0,50));fetch(WEBHOOK_URL,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({contact:c.contact,preview:c.preview,time:c.time,timestamp:Date.now()})}).then(function(r){if(!r.ok)logAlways('Webhook error',r.status)}).catch(function(e){logAlways('Webhook error:',e.message)})}lastSeenMessages.set(c.contact,{preview:c.preview,time:c.time})})}function setupObserver(){if(observerAttached)return;var target=document.querySelector('mws-conversations-list,[data-e2e-conversation-list],nav,main');if(!target){setTimeout(setupObserver,2000);return}var observer=new MutationObserver(function(){clearTimeout(window._smsTO);window._smsTO=setTimeout(checkForNewMessages,500)});observer.observe(target,{childList:true,subtree:true,characterData:true});observerAttached=true;logAlways('Observer attached to',target.tagName);checkForNewMessages();setInterval(checkForNewMessages,CHECK_INTERVAL)}logAlways('Starting...');logAlways('Webhook:',WEBHOOK_URL);if(document.readyState==='complete')setupObserver();else window.addEventListener('load',setupObserver);window._smsObserver={check:checkForNewMessages,getConversations:getConversations};return'SMS Observer injected'})()\n```\n\n## Verifying Injection\n\nAfter injection, check the browser console for:\n```\n[SMS Observer] Starting...\n[SMS Observer] Webhook: http://127.0.0.1:19888/sms-inbound\n[SMS Observer] Observer attached to MAIN\n[SMS Observer] Initialized with N conversations\n```\n\n## Debugging\n\nAccess the observer API in browser console:\n```javascript\nwindow._smsObserver.check()           // Force check for new messages\nwindow._smsObserver.getConversations() // Get current conversation list\n```\n\n## Re-injection\n\nThe observer is lost when the page reloads. Re-inject after:\n- Page refresh\n- Browser restart\n- Session re-pairing\n\nFile v0.1.0:references/snippets.md\n\n# JavaScript Snippets for Google Messages\n\nUse with `browser action=act request={\"kind\": \"evaluate\", \"fn\": \"...\"}`.\n\n## Check Session Status\n\n```javascript\n(() => {\n  if (document.querySelector('mw-qr-code, [data-e2e-qr-code]')) return 'QR_REQUIRED';\n  if (document.querySelector('mws-conversations-list, [data-e2e-conversation-list]')) return 'SESSION_ACTIVE';\n  if (document.querySelector('mat-spinner, .loading')) return 'LOADING';\n  return 'UNKNOWN';\n})()\n```\n\n## Get Recent Conversations\n\n```javascript\n(() => {\n  const convos = document.querySelectorAll('mws-conversation-list-item');\n  const results = [];\n  \n  for (let i = 0; i < Math.min(convos.length, 10); i++) {\n    const name = convos[i].querySelector('h2')?.innerText || 'Unknown';\n    const preview = convos[i].querySelector('[data-e2e-conversation-snippet]')?.innerText || '';\n    const time = convos[i].querySelector('[data-e2e-conversation-timestamp]')?.innerText || '';\n    \n    results.push({ \n      name: name.trim(), \n      preview: preview.trim().substring(0, 50), \n      time: time.trim() \n    });\n  }\n  \n  return JSON.stringify(results, null, 2);\n})()\n```\n\n## Get Messages in Current Conversation\n\n```javascript\n(() => {\n  const messages = document.querySelectorAll('mws-message-wrapper');\n  const results = [];\n  const start = Math.max(0, messages.length - 10);\n  \n  for (let i = start; i < messages.length; i++) {\n    const msg = messages[i];\n    const text = msg.querySelector('[data-e2e-message-text]')?.innerText || '';\n    const time = msg.querySelector('[data-e2e-message-timestamp]')?.innerText || '';\n    const isOutgoing = msg.classList.contains('outgoing');\n    \n    if (text) {\n      results.push({ \n        text: text.trim(), \n        time: time.trim(), \n        direction: isOutgoing ? 'sent' : 'received' \n      });\n    }\n  }\n  \n  return JSON.stringify(results, null, 2);\n})()\n```\n\n## Open Conversation by Contact Name\n\n```javascript\n(async () => {\n  const CONTACT = 'John Doe';  // Change this\n  const sleep = ms => new Promise(r => setTimeout(r, ms));\n  \n  const convos = document.querySelectorAll('mws-conversation-list-item');\n  \n  for (const convo of convos) {\n    const name = convo.querySelector('h2')?.innerText || '';\n    if (name.toLowerCase().includes(CONTACT.toLowerCase())) {\n      convo.click();\n      await sleep(500);\n      return 'OPENED: ' + name;\n    }\n  }\n  \n  return 'NOT_FOUND: ' + CONTACT;\n})()\n```\n\nFile v0.1.0:skill-card.md\n\n## Description:\n\nSend and receive SMS/RCS via Google Messages web interface (messages.google.com). Use when asked to \"send a text\", \"check texts\", \"SMS\", \"text message\", \"Google Messages\", or forward incoming texts to other channels.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[kesslerio](https://clawhub.ai/user/kesslerio)\n\n### License/Terms of Use:\n\nApache-2.0\n\n## Use Case:\n\nDevelopers and OpenClaw users use this skill to automate Google Messages for Web, including sending texts, checking conversations, and optionally forwarding incoming SMS/RCS notifications.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill handles private SMS/RCS content and can forward message previews outside Google Messages.\n\nMitigation: Use it only with conversations approved for forwarding, set notification targets deliberately, and keep paired browser sessions private.\n\nRisk: The supplied security evidence reports a serious command-injection risk in webhook forwarding.\n\nMitigation: Do not run the current webhook server with real forwarding targets until the webhook command construction is fixed and reviewed.\n\nRisk: Persistent notification forwarding can expose incoming messages continuously.\n\nMitigation: Avoid enabling persistent notification services unless the security issues are resolved and the forwarding destination is trusted.\n\n## Reference(s):\n\n- [ClawHub Skill Page](https://clawhub.ai/kesslerio/skills/google-messages)\n- [OpenClaw](https://github.com/openclaw/openclaw)\n- [Google Messages for Web](https://messages.google.com/web)\n- [Observer Injection](references/observer-injection.md)\n- [JavaScript Snippets](references/snippets.md)\n\n## Skill Output:\n\n**Output Type(s):** [Guidance, Shell commands, Code, Configuration]\n\n**Output Format:** [Markdown with browser automation commands, shell commands, and JavaScript snippets]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Requires browser automation, Node.js, Google Messages pairing, and optional notification environment variables.]\n\n## Skill Version(s):\n\n0.1.0 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v0.1.0:package.json\n\n{\n  \"name\": \"google-messages-skill\",\n  \"version\": \"1.0.0\",\n  \"description\": \"OpenClaw skill for Google Messages SMS/RCS automation\",\n  \"main\": \"sms-webhook-server.js\",\n  \"scripts\": {\n    \"start\": \"node sms-webhook-server.js\",\n    \"webhook\": \"node sms-webhook-server.js\"\n  },\n  \"keywords\": [\n    \"openclaw\",\n    \"sms\",\n    \"google-messages\",\n    \"rcs\",\n    \"automation\",\n    \"browser\"\n  ],\n  \"author\": \"OpenClaw\",\n  \"license\": \"Apache-2.0\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/openclaw/google-messages-skill.git\"\n  },\n  \"engines\": {\n    \"node\": \">=18.0.0\"\n  }\n}","readmeExcerpt":"Skill: Google Messages Owner: kesslerio Summary: Send and receive SMS/RCS via Google Messages web interface (messages.google.com). Use when asked to \"send a text\", \"check texts\", \"SMS\", \"text message\", \"Google Messages\", or forward incoming texts to other channels. Tags: latest:0.1.0 Version history: v0.1.0 | 2026-02-01T06:50:44.580Z | auto Initial release of google-messages-openclaw-skill. - Enables sending and rece","codeSnippets":[],"executableExamples":[{"language":"text","snippet":"browser action=open profile=openclaw targetUrl=\"https://messages.google.com/web/authentication\""},{"language":"text","snippet":"browser action=screenshot profile=openclaw"},{"language":"text","snippet":"browser action=navigate profile=openclaw targetUrl=\"https://messages.google.com/web/conversations\""},{"language":"text","snippet":"browser action=snapshot profile=openclaw"},{"language":"text","snippet":"browser action=act profile=openclaw request={\"kind\": \"click\", \"ref\": \"<ref>\"}"},{"language":"text","snippet":"browser action=act profile=openclaw request={\"kind\": \"type\", \"ref\": \"<input_ref>\", \"text\": \"Your message\"}"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: google-messages\ndescription: Send and receive SMS/RCS via Google Messages web interface (messages.google.com). Use when asked to \"send a text\", \"check texts\", \"SMS\", \"text message\", \"Google Messages\", or forward incoming texts to other channels.\nmetadata: {\"openclaw\": {\"emoji\": \"💬\", \"requires\": {\"tools\": [\"browser\"], \"bins\": [\"node\"], \"env\": [\"SMS_NOTIFICATION_TARGET\", \"SMS_NOTIFICATION_CHANNEL\"]}}}\n---\n\n# Google Messages Browser Skill\n\nAutomate SMS/RCS messaging via messages.google.com using the `browser` tool.\n\n## Overview\n\nGoogle Messages for Web allows you to send/receive texts from your Android phone via browser. This skill automates that interface.\n\n**Requirements:**\n- Android phone with Google Messages app\n- Phone and computer on same network (for initial QR pairing)\n- Browser profile with persistent session (use `openclaw` or your preferred profile)\n\n**Note:** Replace `profile=openclaw` in examples with your preferred browser profile if different.\n\n---\n\n## Quick Reference\n\n| Action | Command |\n|--------|---------|\n| Open pairing page | `browser action=open profile=openclaw targetUrl=\"https://messages.google.com/web/authentication\"` |\n| Check session | `browser action=snapshot profile=openclaw` — look for conversation list vs QR code |\n| Take screenshot | `browser action=screenshot profile=openclaw` |\n\n---\n\n## Initial Setup (QR Pairing)\n\nFirst-time setup requires scanning a QR code:\n\n1. **Open Google Messages Web**\n   ```\n   browser action=open profile=openclaw targetUrl=\"https://messages.google.com/web/authentication\"\n   ```\n\n2. **Screenshot the QR code** and share with user\n   ```\n   browser action=screenshot profile=openclaw\n   ```\n\n3. **User scans with phone:**\n   - Open Google Messages app on Android\n   - Tap ⋮ menu → \"Device pairing\" → \"QR code scanner\"\n   - Scan the QR code\n\n4. **Verify connection** — snapshot should show conversation list, not QR code\n\n**Important:** Enable \"Remember this computer\" to persist the session.\n\n---\n\n## Sending Messages\n\n1. **Navigate to conversations**\n   ```\n   browser action=navigate profile=openclaw targetUrl=\"https://messages.google.com/web/conversations\"\n   ```\n\n2. **Take snapshot and find conversation**\n   ```\n   browser action=snapshot profile=openclaw\n   ```\n   Look for the contact in the conversation list, note the `ref`.\n\n3. **Click conversation**\n   ```\n   browser action=act profile=openclaw request={\"kind\": \"click\", \"ref\": \"<ref>\"}\n   ```\n\n4. **Type message** (find textarea ref from snapshot)\n   ```\n   browser action=act profile=openclaw request={\"kind\": \"type\", \"ref\": \"<input_ref>\", \"text\": \"Your message\"}\n   ```\n\n5. **Click send** (find send button ref)\n   ```\n   browser action=act profile=openclaw request={\"kind\": \"click\", \"ref\": \"<send_ref>\"}\n   ```\n\n---\n\n## Receiving Messages (Real-time Notifications)\n\nThis skill includes a webhook system for real-time incoming SMS notifications.\n\n### Components\n\n1. **sms-webhook-server.js** — receives notifications, forwards to OpenClaw chan"},{"path":"README.md","content":"# Google Messages Skill for OpenClaw\n\nSend and receive SMS/RCS messages via Google Messages web interface using browser automation.\n\n## Features\n\n- 📤 **Send SMS** — Compose and send text messages\n- 📥 **Receive notifications** — Real-time alerts when new messages arrive\n- 🔍 **Read conversations** — Query recent messages and conversation history\n- 🔗 **OpenClaw integration** — Forward incoming SMS to Telegram, WhatsApp, or other channels\n\n## Requirements\n\n- [OpenClaw](https://github.com/openclaw/openclaw) with browser automation\n- Android phone with Google Messages app\n- Node.js 18+\n\n## Quick Start\n\n### 1. Install the skill\n\n```bash\n# Clone to your skills directory\ngit clone https://github.com/kesslerio/google-messages-openclaw-skill.git ~/.openclaw/skills/google-messages\n```\n\n### 2. Pair with your phone\n\nAsk your OpenClaw agent:\n```\n\"Open Google Messages and show me the QR code\"\n```\n\nOr manually:\n1. Go to https://messages.google.com/web\n2. Open Google Messages on your phone\n3. Tap ⋮ → Device pairing → QR code scanner\n4. Scan the code\n\n### 3. Enable notifications (optional)\n\nStart the webhook server to receive incoming message alerts:\n\n```bash\n# Set your notification target\nexport SMS_NOTIFICATION_TARGET=\"telegram:YOUR_CHAT_ID\"\nexport SMS_NOTIFICATION_CHANNEL=\"telegram\"\n\n# Start the server\nnode ~/.openclaw/skills/google-messages/sms-webhook-server.js\n```\n\nThen inject the observer into the browser tab. See `references/observer-injection.md` for details.\n\n## Usage\n\n### Sending messages\n\nAsk your OpenClaw agent:\n- \"Text John that I'm running late\"\n- \"Send an SMS to 555-1234 saying hello\"\n- \"Message Mom on Google Messages\"\n\n### Checking messages\n\n- \"Check my texts\"\n- \"Any new SMS messages?\"\n- \"What did John text me?\"\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `SMS_WEBHOOK_PORT` | Port for webhook server | `19888` |\n| `SMS_NOTIFICATION_TARGET` | OpenClaw target (e.g., `telegram:123456`) | _(none)_ |\n| `SMS_NOTIFICATION_CHANNEL` | Channel type | `telegram` |\n\n### Systemd Service\n\nFor persistent notifications, install as a user service:\n\n```bash\ncp systemd/google-messages-webhook.service ~/.config/systemd/user/\n# Edit service file: uncomment and set Environment= lines\nsystemctl --user daemon-reload\nsystemctl --user enable --now google-messages-webhook\n```\n\n## How It Works\n\n1. **Browser automation** — Uses OpenClaw's browser tool to control messages.google.com\n2. **MutationObserver** — Injects a script that watches the DOM for new messages\n3. **Webhook** — When new messages arrive, POSTs to a local server\n4. **Forwarding** — Webhook server uses `openclaw message send` to forward to your preferred channel\n\n## Files\n\n```\ngoogle-messages-skill/\n├── SKILL.md                    # OpenClaw skill definition\n├── sms-webhook-server.js       # Webhook server for notifications\n├── sms-observer.js             # Browser injection script (full version)\n├── references/\n│   ├── snippets.md  "},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7fmw4ybcy50qzp1d2dvb1h517znaes\",\n  \"slug\": \"google-messages\",\n  \"version\": \"0.1.0\",\n  \"publishedAt\": 1769928644580\n}"},{"path":"references/observer-injection.md","content":"# Injecting the SMS Observer\n\nThe SMS observer watches for incoming messages and forwards them to the webhook server.\n\n## Prerequisites\n\n1. Webhook server running: `node <skill>/sms-webhook-server.js`\n2. Google Messages page loaded and paired\n3. Browser tab open at messages.google.com\n\n## Injection Command\n\nUse the browser tool to inject the observer script:\n\n```\nbrowser action=act profile=openclaw request={\"kind\": \"evaluate\", \"fn\": \"<minified_observer>\"}\n```\n\n## Minified Observer Script\n\nCopy this entire script for the `fn` parameter:\n\n```javascript\n(function(){var WEBHOOK_URL='http://127.0.0.1:19888/sms-inbound',CHECK_INTERVAL=2000,lastSeenMessages=new Map,initialized=false,observerAttached=false;function logAlways(){console.log.apply(console,['[SMS Observer]'].concat(Array.prototype.slice.call(arguments)))}function getConversations(){var convos=[],items=document.querySelectorAll('mws-conversation-list-item,[data-e2e-conversation],[role=\"option\"]');items.forEach(function(item,i){var nameEl=item.querySelector('h2,[data-e2e-conversation-name],.name'),previewEl=item.querySelector('[data-e2e-conversation-snippet],.snippet'),timeEl=item.querySelector('[data-e2e-conversation-timestamp],.timestamp,time'),preview='';if(previewEl)preview=previewEl.innerText||'';if(!preview){var divs=item.querySelectorAll('div');for(var j=0;j<divs.length;j++){var t=divs[j].innerText;if(t&&t.trim().length>5&&t.trim().length<200){preview=t.trim();break}}}convos.push({contact:nameEl?nameEl.innerText.trim():'Unknown',preview:preview.substring(0,150),time:timeEl?timeEl.innerText.trim():''})});return convos}function checkForNewMessages(){var conversations=getConversations();if(!initialized){conversations.forEach(function(c){lastSeenMessages.set(c.contact,{preview:c.preview,time:c.time})});initialized=true;logAlways('Initialized with',conversations.length,'conversations');return}conversations.forEach(function(c){var lastSeen=lastSeenMessages.get(c.contact);var isNew=!lastSeen||(lastSeen.preview!==c.preview&&c.preview);var isIncoming=c.preview&&!c.preview.startsWith('You:');if(isNew&&isIncoming){logAlways('New message:',c.contact,'-',c.preview.substring(0,50));fetch(WEBHOOK_URL,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({contact:c.contact,preview:c.preview,time:c.time,timestamp:Date.now()})}).then(function(r){if(!r.ok)logAlways('Webhook error',r.status)}).catch(function(e){logAlways('Webhook error:',e.message)})}lastSeenMessages.set(c.contact,{preview:c.preview,time:c.time})})}function setupObserver(){if(observerAttached)return;var target=document.querySelector('mws-conversations-list,[data-e2e-conversation-list],nav,main');if(!target){setTimeout(setupObserver,2000);return}var observer=new MutationObserver(function(){clearTimeout(window._smsTO);window._smsTO=setTimeout(checkForNewMessages,500)});observer.observe(target,{childList:true,subtree:true,characterData:true});observerAttached=true;logAlways('Observer attached to',target.tagName);check"},{"path":"references/snippets.md","content":"# JavaScript Snippets for Google Messages\n\nUse with `browser action=act request={\"kind\": \"evaluate\", \"fn\": \"...\"}`.\n\n## Check Session Status\n\n```javascript\n(() => {\n  if (document.querySelector('mw-qr-code, [data-e2e-qr-code]')) return 'QR_REQUIRED';\n  if (document.querySelector('mws-conversations-list, [data-e2e-conversation-list]')) return 'SESSION_ACTIVE';\n  if (document.querySelector('mat-spinner, .loading')) return 'LOADING';\n  return 'UNKNOWN';\n})()\n```\n\n## Get Recent Conversations\n\n```javascript\n(() => {\n  const convos = document.querySelectorAll('mws-conversation-list-item');\n  const results = [];\n  \n  for (let i = 0; i < Math.min(convos.length, 10); i++) {\n    const name = convos[i].querySelector('h2')?.innerText || 'Unknown';\n    const preview = convos[i].querySelector('[data-e2e-conversation-snippet]')?.innerText || '';\n    const time = convos[i].querySelector('[data-e2e-conversation-timestamp]')?.innerText || '';\n    \n    results.push({ \n      name: name.trim(), \n      preview: preview.trim().substring(0, 50), \n      time: time.trim() \n    });\n  }\n  \n  return JSON.stringify(results, null, 2);\n})()\n```\n\n## Get Messages in Current Conversation\n\n```javascript\n(() => {\n  const messages = document.querySelectorAll('mws-message-wrapper');\n  const results = [];\n  const start = Math.max(0, messages.length - 10);\n  \n  for (let i = start; i < messages.length; i++) {\n    const msg = messages[i];\n    const text = msg.querySelector('[data-e2e-message-text]')?.innerText || '';\n    const time = msg.querySelector('[data-e2e-message-timestamp]')?.innerText || '';\n    const isOutgoing = msg.classList.contains('outgoing');\n    \n    if (text) {\n      results.push({ \n        text: text.trim(), \n        time: time.trim(), \n        direction: isOutgoing ? 'sent' : 'received' \n      });\n    }\n  }\n  \n  return JSON.stringify(results, null, 2);\n})()\n```\n\n## Open Conversation by Contact Name\n\n```javascript\n(async () => {\n  const CONTACT = 'John Doe';  // Change this\n  const sleep = ms => new Promise(r => setTimeout(r, ms));\n  \n  const convos = document.querySelectorAll('mws-conversation-list-item');\n  \n  for (const convo of convos) {\n    const name = convo.querySelector('h2')?.innerText || '';\n    if (name.toLowerCase().includes(CONTACT.toLowerCase())) {\n      convo.click();\n      await sleep(500);\n      return 'OPENED: ' + name;\n    }\n  }\n  \n  return 'NOT_FOUND: ' + CONTACT;\n})()\n```"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":1335,"uniquenessScore":42,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-09T08:10:08.809Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-09T08:10:08.809Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-09T16:10:29.778Z","emptyReason":null},"items":[{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-10T18:48:31.762Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}