{"id":"6fd0d336-f0b5-4c87-b95b-66ee5b584d42","entityType":"agent","slug":"clawhub-chris-google-review-responder","name":"Review Responder","canonicalUrl":"https://www.xpersona.co/agent/clawhub-chris-google-review-responder","canonicalPath":"/agent/clawhub-chris-google-review-responder","generatedAt":"2026-10-11T00:32:45.078Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T21:14:25.073Z","emptyReason":null},"description":"Use this skill when an operator is actively running the Google Business Profile review-response workflow for one of their configured client accounts. Specific triggers: 'check for new reviews,' 'run the review check for [client],' 'new review came in for [client],' 'draft a reply to the [reviewer] r","descriptionLabel":"Source description","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.3K downloads reported by the source. Last updated 10/10/2026.","installCommand":"clawhub skill install s17f63svb641q2stekk1cmcdn183k4rq:google-review-responder","sourceUrl":"https://clawhub.ai/chris/google-review-responder","homepage":"https://clawhub.ai/chris/skills/google-review-responder","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/chris/google-review-responder","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/chris/skills/google-review-responder","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":40,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Review Responder 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-10T21:14:25.073Z","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-10T21:14:25.073Z","emptyReason":null},"stars":null,"forks":null,"downloads":1256,"packageName":null,"latestVersion":"2.1.1","tractionLabel":"1.3K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T21:14:25.073Z","emptyReason":null},"lastUpdatedAt":"2026-10-10T21:14:25.073Z","lastCrawledAt":"2026-10-10T21:14:25.073Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-11T21:14:25.073Z","lastVerifiedAt":null,"highlights":[{"version":"2.1.1","createdAt":"2026-09-28T18:44:46.156Z","changelog":"google-review-responder 2.1.1 - Added a .gitignore file to the project. - No changes to skill functionality or behavior.","fileCount":15,"zipByteSize":28498},{"version":"2.1.0","createdAt":"2026-09-28T18:12:32.100Z","changelog":"- added 3, removed 1 file(s). - Updated SKILL.md and bundle contents.","fileCount":14,"zipByteSize":27975},{"version":"2.0.1","createdAt":"2026-06-08T23:23:01.193Z","changelog":"Added Privacy and Data Handling to SKILL.md and Permissions and Privacy to README; reworded medical industry profile from HIPAA-safe to HIPAA-aware drafting; narrowed triggers","fileCount":11,"zipByteSize":21701},{"version":"2.0.0","createdAt":"2026-05-13T00:23:53.046Z","changelog":"v2.0.0 - Channel-agnostic approval flow (Telegram, email, webhook, chat), industry compliance profiles (medical/legal/restaurant/retail), config-driven paths, operator pattern learning. BREAKING: now requires review-responder.config.json.","fileCount":11,"zipByteSize":17934},{"version":"1.0.0","createdAt":"2026-04-12T12:53:16.450Z","changelog":"Google Business Review Responder 1.0.0 – Initial Release - Monitors Google Business Profile reviews for multiple clients. - Drafts professional, compliant responses based on review content and guidelines. - Sends drafted replies to operators via Telegram for approval before posting. - Waits for operator approval, edits, or skip instructions before responding publicly. - Strong HIPAA compliance rules to protect client and patient information. - Supports review management through command line interface.","fileCount":9,"zipByteSize":12290}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s17f63svb641q2stekk1cmcdn183k4rq:google-review-responder","setupComplexity":"low","setupSteps":["Install using `clawhub skill install s17f63svb641q2stekk1cmcdn183k4rq:google-review-responder` 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/chris/google-review-responder 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-chris-google-review-responder/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chris-google-review-responder/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chris-google-review-responder/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-chris-google-review-responder/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-chris-google-review-responder/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-chris-google-review-responder/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-11T00:32:45.074Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chris-google-review-responder/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chris-google-review-responder/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chris-google-review-responder/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chris-google-review-responder/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-10T21:14:25.073Z","emptyReason":null},"readme":"Skill: Review Responder\n\nOwner: chris\n\nSummary: Use this skill when an operator is actively running the Google Business Profile review-response workflow for one of their configured client accounts. Specific triggers: 'check for new reviews,' 'run the review check for [client],' 'new review came in for [client],' 'draft a reply to the [reviewer] r\n\nTags: business-profile:1.0.0, gbp:1.0.0, google:1.0.0, hipaa:1.0.0, latest:2.1.1, reviews:1.0.0, telegram:1.0.0\n\nVersion history:\n\nv2.1.1 | 2026-09-28T18:44:46.156Z | user\n\ngoogle-review-responder 2.1.1\n\n- Added a .gitignore file to the project.\n- No changes to skill functionality or behavior.\n\nv2.1.0 | 2026-09-28T18:12:32.100Z | auto\n\n- added 3, removed 1 file(s).\n- Updated SKILL.md and bundle contents.\n\nv2.0.1 | 2026-06-08T23:23:01.193Z | user\n\nAdded Privacy and Data Handling to SKILL.md and Permissions and Privacy to README; reworded medical industry profile from HIPAA-safe to HIPAA-aware drafting; narrowed triggers\n\nv2.0.0 | 2026-05-13T00:23:53.046Z | user\n\nv2.0.0 - Channel-agnostic approval flow (Telegram, email, webhook, chat), industry compliance profiles (medical/legal/restaurant/retail), config-driven paths, operator pattern learning. BREAKING: now requires review-responder.config.json.\n\nv1.0.0 | 2026-04-12T12:53:16.450Z | user\n\nGoogle Business Review Responder 1.0.0 – Initial Release\n\n- Monitors Google Business Profile reviews for multiple clients.\n- Drafts professional, compliant responses based on review content and guidelines.\n- Sends drafted replies to operators via Telegram for approval before posting.\n- Waits for operator approval, edits, or skip instructions before responding publicly.\n- Strong HIPAA compliance rules to protect client and patient information.\n- Supports review management through command line interface.\n\nArchive index:\n\nArchive v2.1.1: 15 files, 28498 bytes\n\nFiles: .gitignore (183b), CHANGELOG.md (3469b), clients/_template.json (383b), diagnose.py (10138b), gbp_reviews.py (8067b), get_client_token.py (1878b), get_token_interactive.py (3330b), HEARTBEAT.md (1032b), lookup_ids.py (2691b), oauth_server.py (4892b), README.md (7055b), SETUP.md (3850b), skill-card.md (2606b), SKILL.md (15482b), _meta.json (142b)\n\nFile v2.1.1:SKILL.md\n\n---\nname: review-responder\nversion: 2.0.1\ndescription: \"Use this skill when an operator is actively running the Google Business Profile review-response workflow for one of their configured client accounts. Specific triggers: 'check for new reviews,' 'run the review check for [client],' 'new review came in for [client],' 'draft a reply to the [reviewer] review,' 'approve the draft for [reviewer/client],' 'post the reply for [review id],' 'show pending review approvals,' 'show me the pending reviews,' or 'apply the [medical/legal/restaurant/retail/general] industry profile to this draft.' Do NOT trigger on: general questions about how to handle reviews, casual mentions of Google reviews, marketing strategy chat, requests to write a review (versus reply to one), or any workflow where no configured client exists. Covers: scheduled checks against Google Business Profile API for configured clients, star-rating-matched draft replies with industry-aware drafting constraints (medical/HIPAA-aware, legal, restaurant, retail), and an approval gate across Telegram, email, webhook, or in-chat channels. Drafts are NEVER auto-posted; operator approval is required before any reply is published. See Privacy and Data Handling for credential and posting scope.\"\nmetadata:\n  openclaw:\n    emoji: ⭐\n---\n\n# Review Responder\n\nAutomatically monitors Google Business Profile reviews across one or more client accounts, drafts professional responses tuned to star rating and industry, and routes drafts to a configurable approval channel before posting. Designed for agencies and consultants managing reviews on behalf of clients.\n\n## Trigger\n\nThis skill activates during scheduled review checks (heartbeat) and when an operator responds to a pending review approval message.\n\n---\n\n## Configuration\n\nAll paths and channels are read from a single config file: `review-responder.config.json` in the skill's data directory. If it doesn't exist, create one from this template on first run:\n\n```json\n{\n  \"script_path\": \"~/review-responder/gbp_reviews.py\",\n  \"clients_dir\": \"~/review-responder/clients/\",\n  \"approval_channel\": \"telegram\",\n  \"telegram_chat_id\": \"\",\n  \"email_recipient\": \"\",\n  \"webhook_url\": \"\",\n  \"default_industry\": \"general\",\n  \"memory_file\": \"approval-patterns.json\"\n}\n```\n\n### Configuration fields\n\n- **script_path**: Absolute path to the `gbp_reviews.py` CLI. Defaults to `~/review-responder/gbp_reviews.py` but can live anywhere.\n- **clients_dir**: Directory containing per-client config files. Each client gets its own subdirectory or JSON entry.\n- **approval_channel**: One of `telegram`, `email`, `webhook`, or `chat`. Determines where draft replies are sent for approval. See Approval Channels below.\n- **default_industry**: Industry profile applied when a client doesn't specify one. See Industry Compliance Profiles below.\n- **memory_file**: Where to log approval patterns for the learning layer.\n\n### Per-client overrides\n\nEach client in `clients_dir` can override `industry`, `approval_channel`, and `tone_notes` (free-text guidance specific to that business). Example client config:\n\n```json\n{\n  \"client_id\": \"smithdental\",\n  \"business_name\": \"Smith Family Dental\",\n  \"industry\": \"medical\",\n  \"approval_channel\": \"email\",\n  \"email_recipient\": \"office@smithdental.com\",\n  \"tone_notes\": \"Dr. Smith is warm but understated. Avoid exclamation points.\"\n}\n```\n\n---\n\n## Review Check Flow (Heartbeat)\n\n1. Load `review-responder.config.json` and enumerate all clients in `clients_dir`.\n2. For each client, run:\n   ```\n   python3 {script_path} check --client {client_id}\n   ```\n3. For each new unanswered review:\n   - Apply the client's industry profile (or `default_industry` if none specified)\n   - Draft a response following the Response Guidelines and the industry profile's constraints\n   - Cross-reference against the approval-patterns memory file for operator-specific adjustments (e.g., if the operator consistently shortens 5-star replies for this client, default to shorter)\n4. Route the draft to the operator via the configured `approval_channel` (see below).\n5. Do NOT post the reply automatically. Wait for operator approval.\n\n---\n\n## Approval Channels\n\nThe approval message format stays consistent across channels; only the delivery method changes.\n\n### Standard approval message\n\n```\n📝 New Review for [Business Name]\n\n⭐ [star_rating] from [reviewer_name]\n💬 \"[review comment]\"\n\nMy draft reply:\n\"[your drafted response]\"\n\nReply OK to post, or send your edits.\n(Review ID: [review_id] | Client: [client_id])\n```\n\n### Telegram (`approval_channel: telegram`)\nSend the message to the configured `telegram_chat_id`. The operator replies in the Telegram thread.\n\n### Email (`approval_channel: email`)\nSend the message as a plain-text email to `email_recipient`. Subject line: `Review approval needed — [Business Name]`. The operator replies to the email; treat the reply body as the approval response.\n\n### Webhook (`approval_channel: webhook`)\nPOST a JSON payload to `webhook_url` containing the review draft and metadata. Useful for custom dashboards or Slack relays. Expected response: `{ \"decision\": \"approve\" | \"edit\" | \"skip\", \"edited_text\": \"...\" }`.\n\n### Chat (`approval_channel: chat`)\nSurface the draft directly in the current chat session. Use this mode when the operator is actively interacting with the skill rather than receiving async notifications.\n\n---\n\n## Approval Flow\n\nWhen the operator responds to a draft (via any channel):\n\n- **\"OK\"**, **\"post it\"**, **\"send it\"**, **\"approved\"**: Post the draft as-is:\n  ```\n  python3 {script_path} reply --client {client_id} --review {review_id} --reply \"{approved response}\"\n  ```\n  Confirm once posted: \"Done — reply posted for [reviewer_name]'s review.\"\n  Log to the memory file as `approved_as_is`.\n\n- **Edited text**: Treat any reply that isn't a recognized approval/skip keyword as replacement text. Confirm before posting: \"Got it — posting your version now.\" Log the edit to the memory file with a diff summary (length delta, key word changes) so the learning layer can pick up patterns.\n\n- **\"Skip\"**, **\"ignore\"**, **\"don't reply\"**: Do not reply to that review. Remove it from pending. Log as `skipped`.\n\n---\n\n## Response Guidelines\n\n### Tone principles\n- Warm, professional, and human — not corporate or robotic\n- Specific to what the reviewer said (never generic \"thanks for your review!\")\n- Concise: 2-4 sentences max\n- Match the energy of the review without being over the top\n- Layer in any `tone_notes` from the client config\n\n### By star rating\n\n**5 stars**\n- Thank them warmly and reference something specific they mentioned\n- Reinforce what they loved (\"We're glad [specific thing] made a difference\")\n- End with a light invitation to return or share with others\n- Keep it brief; don't overdo it on a great review\n\n**4 stars**\n- Thank them and acknowledge specific positives\n- If they mentioned something that could improve, acknowledge it gracefully without being defensive\n- Show you're listening: \"We appreciate the feedback on [topic] and are always looking to improve\"\n\n**3 stars**\n- Thank them for taking the time\n- Acknowledge both the positives and the concern\n- Show genuine interest in making it right: \"We'd love the chance to do better next time\"\n- Optionally invite them to reach out directly\n\n**1-2 stars**\n- Lead with empathy, not defensiveness: \"We're sorry to hear this wasn't the experience you deserved\"\n- Acknowledge the specific issue without making excuses\n- Offer a path forward: invite them to contact the business directly\n- Keep it short and dignified; do not argue or over-explain\n- Never blame the reviewer or question their experience\n\n---\n\n## Industry Compliance Profiles\n\nIndustry profiles enforce constraints and tone defaults appropriate to specific business types. Apply the profile from the client config (or `default_industry`) on every draft.\n\n### `medical` (HIPAA-aware drafting)\n\n**Note on terminology**: this profile applies HIPAA-aware drafting constraints — it instructs the assistant to avoid referencing PHI in public review replies. It does not certify the operator's overall workflow as HIPAA-compliant. Covered entities are responsible for their own compliance program; this skill is one input.\n\n**Hard rules** (never violate, regardless of star rating):\n- NEVER reference or confirm any medical conditions, diagnoses, treatments, medications, procedures, or health details, even if the reviewer mentioned them publicly\n- NEVER confirm or deny that someone is or was a patient\n- Keep responses general: \"your experience,\" \"your visit,\" \"your care\" — not \"your diagnosis\" or \"your treatment\"\n- If the reviewer shared health details, respond to the sentiment and experience only\n- When inviting follow-up, use \"please contact our office\" — never suggest discussing their \"case\" or \"medical records\"\n\n**Tone defaults**: professional, reassuring, brief.\n\n### `legal`\n\n**Hard rules**:\n- Never confirm or discuss case details, legal advice, or attorney-client relationships\n- Never speculate about outcomes or imply guarantees\n- Avoid language that could be interpreted as a new attorney-client communication\n- For dissatisfied reviewers, direct them to the firm's office line rather than offering legal commentary\n\n**Tone defaults**: measured, professional, no flourishes.\n\n### `restaurant`\n\n**Hard rules**: none specific, but stay grounded.\n\n**Tone defaults**: warmer and more conversational than medical/legal. Food-specific callouts welcome (\"glad the carbonara hit\"). For complaints, offer a direct contact for the manager.\n\n### `retail`\n\n**Hard rules**:\n- Don't speculate about specific products or stock issues you can't verify\n- For return/refund disputes, direct to customer service, not public dialogue\n\n**Tone defaults**: friendly, helpful, solution-oriented.\n\n### `general`\n\nNo industry-specific constraints. Fall back to base Tone Principles and By Star Rating guidance.\n\n---\n\n## Approval Pattern Learning\n\nLog each approval interaction to the memory file (`memory_file` in config). Use the log to surface patterns and adjust future drafts.\n\n### What to log per review\n\n```json\n{\n  \"client_id\": \"smithdental\",\n  \"review_id\": \"abc123\",\n  \"stars\": 5,\n  \"draft\": \"Thank you, Maria...\",\n  \"decision\": \"edited\",\n  \"final\": \"Thanks Maria...\",\n  \"length_delta_words\": -8,\n  \"timestamp\": \"2026-03-20T14:22:00Z\"\n}\n```\n\n### How to apply patterns\n\nBefore drafting any new reply, scan the log for the same client and look for trends across the last 10-20 interactions:\n\n- If `length_delta_words` is consistently negative for a given star rating, default to shorter drafts for that client at that rating\n- If certain words/phrases are routinely stripped (e.g., \"incredibly\", \"truly\"), avoid them on future drafts for that client\n- If the operator consistently skips 1-star reviews from anonymous reviewers, surface that as a default rather than drafting one\n\nSurface insights to the operator periodically (e.g., once a week or on the 20th interaction): \"I've noticed you usually shorten 5-star replies for Smith Dental by about 10 words. Want me to default to shorter going forward?\"\n\n---\n\n## Checking Pending Reviews\n\nTo see what's waiting for approval:\n```\npython3 {script_path} pending\n```\n\n---\n\n## Things to Avoid\n\n- Generic filler: \"We value all our customers,\" \"Your feedback is important to us\"\n- Mentioning the star rating directly: \"Thanks for the 5 stars!\"\n- Being defensive about negative reviews\n- Making promises the business can't keep\n- Using the reviewer's full name unless they used it in their review\n- Emojis (unless the business brand is very casual and the operator approves it)\n- Violating the active industry profile's hard rules under any circumstance\n\n---\n\n## Dependencies\n\n- Python 3 with: `google-auth`, `google-auth-oauthlib`, `requests`\n- Client config files in the directory specified by `clients_dir`\n- For Telegram: a Telegram channel/chat configured and a working bot token\n- For email: SMTP credentials or a relay\n- For webhook: an HTTPS endpoint that accepts POST and returns the decision JSON\n\n---\n\n## Privacy and Data Handling\n\nUnlike most skills in this catalog, this one ships executable Python code (`gbp_reviews.py`, `get_client_token.py`, `oauth_server.py`) that makes real network calls and posts content publicly to Google Business Profile. Be honest with the user about that scope.\n\n**What the skill does over the network**\n\n- Calls Google's My Business API v4 (`mybusiness.googleapis.com`) to fetch unanswered reviews and to post replies on behalf of the operator's configured clients. These calls use the client's own OAuth credentials and refresh tokens, which the operator obtains and stores locally.\n- Sends draft approval messages through whichever `approval_channel` the operator configured (Telegram, email, webhook, or in-chat). Each of those uses the operator's own credentials and infrastructure; the skill does not bundle credentials or route through any author-controlled service.\n- Posts the approved reply text to the corresponding Google review only after explicit operator approval. Drafts are never auto-posted.\n\n**Credentials and local data**\n\n- Per-client OAuth credentials (`oauth_client_id`, `oauth_client_secret`, `refresh_token`) live in JSON files under `clients_dir`. These are the operator's credentials for the operator's own clients. The skill does not transmit them anywhere except to Google's token endpoint (`https://oauth2.googleapis.com/token`) for the standard OAuth refresh flow.\n- Review polling state (`review_log.json`) and pending drafts (`pending/`) are stored locally under the skill's directory.\n- Approval-pattern learning state (`memory_file`, default `approval-patterns.json`) is stored locally.\n\n**Hard guardrails**\n\n- **No auto-posting.** Every reply requires an explicit operator approval through one of the configured channels. The skill must not post a reply without that approval.\n- **No PHI in public replies.** When the active client's industry profile is `medical`, the assistant must never reference health conditions, treatments, diagnoses, or patient status in the public reply — even if the reviewer disclosed those details themselves.\n- **No exfiltration of credentials.** The assistant must never quote, log, summarize, or transmit `oauth_client_secret`, `refresh_token`, or any other credential field into approval messages, drafts, logs, or chat outputs.\n- **No bulk export of client data.** The skill is for the operator's own ongoing review workflow. It must not dump consolidated client lists, credentials, or review histories into external destinations without explicit operator instruction for that specific export.\n\n**No telemetry**\n\nThe skill does not collect or transmit usage data, client identifiers, review content, or any other information back to its author, ClawHub, or any third party. (The Google API, Telegram, your SMTP relay, and any webhook target will each have their own logs — consult those services' policies.)\n\n**Compliance scope**\n\nThe `medical` industry profile applies HIPAA-aware drafting constraints to public review replies. It does not certify the operator's overall workflow as HIPAA-compliant, and it does not turn this skill into a HIPAA-covered service. Operators in regulated industries (medical, legal, financial) remain responsible for their own compliance programs and should review the constraints in this skill against their own policies before using it in production.\n\nFile v2.1.1:README.md\n\n# Review Responder\n\nAn [OpenClaw](https://openclaw.ai) skill that monitors Google Business Profile reviews, drafts professional responses, and routes them to a configurable approval channel before posting.\n\nBuilt for consultants and agencies managing reviews across multiple client locations and industries.\n\n**Current version: 2.0.1**\n\n## What's new in 2.0.1\n\n- Added a **Privacy and Data Handling** section to SKILL.md that honestly describes the skill's real network calls (Google Business Profile API), credential storage (operator-owned OAuth credentials per client), and the no-auto-post guardrail\n- Added a **Permissions and Privacy** section to this README so operators see scope, credential handling, and the HIPAA-aware (not HIPAA-certified) boundary before installing\n- Reworded the `medical` industry profile from \"HIPAA-safe\" to \"HIPAA-aware drafting\" to accurately describe what the skill enforces (drafting constraints) versus what it does not provide (workflow certification)\n- Narrowed the activation triggers in `description` to require an active, configured-client workflow, with a \"do NOT trigger\" guard for casual reviews chat and review-writing requests\n\n## What's new in 2.0.0\n\n- **Configurable script paths and channels** via a single `review-responder.config.json` file\n- **Channel-agnostic approval flow**: Telegram, email, webhook, or in-thread chat\n- **Industry compliance profiles**: medical (HIPAA-aware drafting), legal, restaurant, retail, and general\n- **Operator pattern learning**: logs approval decisions per client and surfaces patterns (e.g., \"you usually shorten 5-star replies for this client\")\n- **Per-client overrides** for industry, approval channel, and tone notes\n\nSee [CHANGELOG.md](CHANGELOG.md) for the full release history.\n\n## How It Works\n\n1. On each scheduled check, OpenClaw enumerates configured clients and looks for new unanswered reviews\n2. For each new review, the agent applies the client's industry profile and drafts a tone-matched response\n3. The draft is sent to the configured approval channel (Telegram, email, webhook, or chat)\n4. The operator replies \"OK\" to post it, sends edits to revise it, or \"skip\" to ignore it\n5. Decisions are logged so the agent can learn the operator's preferences over time\n\nNo reviews are ever posted without explicit operator approval.\n\n## What's Included\n\n- `SKILL.md` — Agent behavior instructions (configuration, approval flow, industry profiles, pattern learning)\n- `HEARTBEAT.md` — Periodic check instructions for OpenClaw's heartbeat system\n- `gbp_reviews.py` — Main script for checking reviews and posting replies\n- `get_client_token.py` — One-time OAuth helper for onboarding clients locally\n- `oauth_server.py` — Web-based OAuth flow for remote client onboarding\n- `clients/_template.json` — Config template for adding new clients\n- `SETUP.md` — Full setup and per-client onboarding guide\n\n## Quick Start\n\n1. Set up a Google Cloud project with the Business Profile API enabled (details in `SETUP.md`)\n2. Install dependencies: `pip install google-auth google-auth-oauthlib requests`\n3. Copy the `review-responder` folder into your OpenClaw workspace\n4. Create `review-responder.config.json` from the template in `SKILL.md`\n5. Register the skill in your `openclaw.json`\n6. Onboard your first client using `get_client_token.py` or `oauth_server.py`\n7. Wire up the scheduled check and you're live\n\nSee `SETUP.md` for the full walkthrough.\n\n## Requirements\n\n- Python 3 with `google-auth`, `google-auth-oauthlib`, `requests`\n- Flask (only if using the web-based OAuth onboarding server)\n- A Google Cloud project with OAuth 2.0 credentials\n- One approval channel configured: Telegram, email (SMTP), webhook endpoint, or in-thread chat\n\n## Permissions and Privacy (read before installing)\n\nUnlike most skills in this catalog, this one ships executable Python (`gbp_reviews.py`, `get_client_token.py`, `oauth_server.py`) that makes real network calls and posts content publicly to Google Business Profile. Read this section in full before installing or onboarding clients.\n\n**What runs on the network**\n\n- **Google Business Profile API v4** (`mybusiness.googleapis.com`): the skill polls reviews for each configured client and posts approved replies. Calls authenticate with the client's own OAuth credentials, which you obtain and store locally during onboarding.\n- **Google OAuth token endpoint** (`https://oauth2.googleapis.com/token`): standard refresh-token exchange.\n- **Whichever approval channel you configure**: Telegram (your bot, your chat), SMTP (your relay, your recipient), webhook (your endpoint), or in-thread chat (no network). The skill does not bundle credentials for any of these and does not route through any author-controlled service.\n\n**Credential storage**\n\n- Per-client OAuth credentials (`oauth_client_id`, `oauth_client_secret`, `refresh_token`) live in JSON files under `clients_dir` on your machine. These are your credentials for your own clients. The skill does not transmit them anywhere except to Google's token endpoint for the standard OAuth refresh flow.\n- Treat the `clients/` directory like you would any secrets folder: restrict filesystem permissions, do not commit it to public source control (the included `.gitignore` excludes it), and consider disk-level encryption.\n\n**Hard guardrails**\n\n- **No auto-posting.** Every reply requires explicit operator approval through your configured channel. The skill must not, and the assistant must not, post a reply without that approval.\n- **No PHI in public replies.** When a client is set to the `medical` industry profile, the assistant will never reference health conditions, treatments, or diagnoses in the public reply, even if the reviewer disclosed those details.\n- **No credential leakage.** The assistant will never quote, log, or include `oauth_client_secret` or `refresh_token` in approval messages, drafts, logs, or chat outputs.\n- **No bulk export.** The skill is for your ongoing review workflow, not for dumping consolidated client lists or review histories into external destinations.\n\n**Compliance scope (read this carefully if you serve regulated industries)**\n\nThe `medical` industry profile applies **HIPAA-aware drafting constraints** to the public reply text — it prevents the reply from referencing PHI. This is one input to a compliant workflow, not the whole workflow. The skill does NOT:\n\n- Certify your overall practice as HIPAA-compliant\n- Replace your Business Associate Agreement obligations (Google, OpenAI/Anthropic, and any other vendor in your pipeline have their own status)\n- Constitute legal advice for medical, legal, or financial regulated practices\n\nOperators in regulated industries remain responsible for their own compliance program and should review these constraints against their own policies before using this skill in production.\n\n**No telemetry**\n\nThe skill does not collect or transmit usage data, client identifiers, review content, or any other information back to its author, ClawHub, or any third party.\n\nFile v2.1.1:_meta.json\n\n{\n  \"ownerId\": \"kn77r9qjvh6fy4aja2km8bzgvd83khv9\",\n  \"slug\": \"google-review-responder\",\n  \"version\": \"2.1.1\",\n  \"publishedAt\": 1790621086156\n}\n\nFile v2.1.1:CHANGELOG.md\n\n# Changelog\n\nAll notable changes to this skill will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this skill adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n## [2.0.1] — 2026-06-08\n\n### Added\n- **Privacy and Data Handling** section in SKILL.md describing the real network surface (Google Business Profile API v4, Google OAuth token endpoint, configured approval channel), credential storage (operator-owned OAuth credentials per client in `clients_dir`), and hard guardrails (no auto-posting, no PHI in public replies, no credential leakage, no bulk export)\n- **Permissions and Privacy** section in README.md so operators see the full network surface, credential storage posture, hard guardrails, and the compliance scope (HIPAA-aware drafting, NOT a HIPAA-certified workflow) before installing\n\n### Changed\n- Reworded the `medical` industry profile from \"HIPAA-safe\" to \"HIPAA-aware drafting\" to accurately describe the constraint (avoids PHI in public reply text) without implying a regulatory certification this skill cannot provide. CHANGELOG references to \"HIPAA-safe\" updated in the 2.0.0 entry's description of this profile for consistency\n- Narrowed the activation triggers in the `description` frontmatter to require an explicit configured-client workflow (named client, named reviewer, specific approval/post action), with a \"do NOT trigger\" guardrail for casual review chat, review-writing requests, and marketing-strategy questions\n- Unquoted the `version` field in frontmatter (matches updated ClawHub CLI semver requirements)\n\n## [2.0.0] — 2026-05-12\n\n### Added\n- Configuration file (`review-responder.config.json`) for centralizing script paths, clients directory, approval channel, default industry, and memory file location\n- Per-client configuration overrides for industry, approval channel, and tone notes\n- Channel-agnostic approval flow with four supported channels: Telegram, email, webhook, and in-thread chat\n- Industry compliance profiles for medical (HIPAA-safe), legal, restaurant, retail, and general business types\n- Operator pattern learning layer that logs each approval decision (approved-as-is, edited with diff summary, skipped) per client and surfaces patterns over time\n- Periodic insight surfacing to the operator (e.g., \"you usually shorten 5-star replies for this client by ~10 words\")\n\n### Changed\n- **BREAKING**: Hardcoded script paths (`~/review-responder/gbp_reviews.py`) replaced with a configurable `script_path` field\n- **BREAKING**: Telegram is no longer the assumed approval channel; `approval_channel` must be set explicitly in config\n- HIPAA section promoted from a sub-block under Response Guidelines into a top-level `Industry Compliance Profiles` section with peer profiles for other industries\n- SKILL.md now has proper YAML frontmatter (`name`, `version`, `description`, `metadata.openclaw.emoji`)\n\n### Removed\n- MIT LICENSE file (license now managed at the ClawHub platform level)\n\n## [1.0.0] — 2026-03-27\n\n### Added\n- Initial release\n- Scheduled review checks across multiple Google Business Profile clients\n- Tone-matched response drafting by star rating (5, 4, 3, 1-2)\n- Telegram-based approval flow with OK/edit/skip operator commands\n- HIPAA-aware response guidance for medical clients\n- Per-client config files for multi-client agency use\n- OAuth onboarding helpers (`get_client_token.py`, `oauth_server.py`)\n\nFile v2.1.1:HEARTBEAT.md\n\n# Heartbeat: Review Responder\n\n## On Every Heartbeat\n\n1. Check for new unanswered Google Business reviews for each active client.\n   Run for each client configured in `~/review-responder/clients/`:\n   ```\n   python3 ~/review-responder/gbp_reviews.py check --client <client_id>\n   ```\n\n2. If the script finds new reviews, read the output carefully. For each new review:\n   - Draft a response following the guidelines in the Review Responder skill (SKILL.md)\n   - Send the draft to the operator via Telegram for approval\n   - Use the message format specified in SKILL.md\n\n3. If no new reviews are found for any client, reply HEARTBEAT_OK.\n\n## Important\n- Do NOT auto-post replies. Every response requires operator approval via Telegram.\n- If the script errors (missing config, API failure), report the error via Telegram so the operator can investigate.\n- Check `python3 ~/review-responder/gbp_reviews.py pending` to see if there are stale pending reviews that haven't been addressed. If any are older than 48 hours, send a reminder.\n\nFile v2.1.1:SETUP.md\n\n# Review Responder: Setup Guide\n\n## One-Time Setup (Your VPS)\n\n### 1. Install Python Dependencies\n```bash\npip install google-auth google-auth-oauthlib requests\n```\n\n### 2. Create a Google Cloud Project\n1. Go to https://console.cloud.google.com\n2. Create a new project (e.g., \"Review Responder\")\n3. Enable the **Google My Business API** (also called Business Profile API)\n4. Go to **Credentials** > **Create Credentials** > **OAuth 2.0 Client ID**\n5. Application type: **Desktop app**\n6. Save the **Client ID** and **Client Secret** -- you'll use these for every client\n\n### 3. Copy Files to OpenClaw Workspace\nCopy the `review-responder` folder into your OpenClaw agent workspace:\n```bash\ncp -r review-responder ~/.openclaw/workspace/review-responder\n```\n\n### 4. Register the Skill\nAdd the skill to your OpenClaw config (openclaw.json):\n```json\n{\n  \"skills\": {\n    \"entries\": {\n      \"review-responder\": {\n        \"path\": \"~/review-responder/SKILL.md\"\n      }\n    }\n  }\n}\n```\n\n### 5. Wire Up the Heartbeat\nAppend the review check instructions to your HEARTBEAT.md, or if you want a dedicated agent for this, reference `~/review-responder/HEARTBEAT.md` in your heartbeat config.\n\n### 6. Set Heartbeat Interval\nIn openclaw.json, set the heartbeat to run every 1-2 hours:\n```json\n{\n  \"agent\": {\n    \"heartbeat\": { \"every\": \"60m\" }\n  }\n}\n```\n\n---\n\n## Per-Client Onboarding\n\n### Step 1: Get Their Authorization\nYou need the client to authorize your app to access their Google Business Profile.\n\nRun this one-time script on your machine to generate a refresh token:\n```bash\npython3 get_client_token.py\n```\nThis will:\n1. Open a browser for the client to log in with their Google account\n2. Ask them to authorize access to their Business Profile\n3. Print a refresh token you save to their config file\n\n(See `get_client_token.py` for the helper script.)\n\n### Step 2: Find Their Account and Location IDs\nAfter authorization, use the access token to look up their IDs:\n```bash\n# List accounts\ncurl -H \"Authorization: Bearer ACCESS_TOKEN\" \\\n  \"https://mybusinessaccountmanagement.googleapis.com/v1/accounts\"\n\n# List locations for an account\ncurl -H \"Authorization: Bearer ACCESS_TOKEN\" \\\n  \"https://mybusinessbusinessinformation.googleapis.com/v1/accounts/ACCOUNT_ID/locations\"\n```\n\n### Step 3: Create Their Config File\nCopy the template and fill in the values:\n```bash\ncp clients/_template.json clients/joes-pizza.json\n```\n\nEdit with their specific values:\n```json\n{\n  \"business_name\": \"Joe's Pizza\",\n  \"account_id\": \"accounts/123456789\",\n  \"location_id\": \"locations/987654321\",\n  \"oauth_client_id\": \"YOUR_PROJECT_CLIENT_ID.apps.googleusercontent.com\",\n  \"oauth_client_secret\": \"YOUR_PROJECT_CLIENT_SECRET\",\n  \"refresh_token\": \"1//TOKEN_FROM_STEP_1\",\n  \"notes\": \"Family pizza place, casual and friendly tone\"\n}\n```\n\n### Step 4: Test It\n```bash\npython3 gbp_reviews.py check --client joes-pizza\n```\n\nIf it returns reviews (or \"No new unanswered reviews\"), you're good.\n\n---\n\n## OAuth Token Helper Script\n\nThe `get_client_token.py` script handles the one-time OAuth flow. Before running it, update the `CLIENT_ID` and `CLIENT_SECRET` variables at the top of the file with your Google Cloud project credentials.\n\nFor remote/web-based onboarding, see `oauth_server.py` instead (requires Flask).\n\n---\n\n## Folder Structure\n```\nreview-responder/\n  gbp_reviews.py          # Main script (check + reply)\n  get_client_token.py      # One-time OAuth helper\n  SKILL.md                 # Agent behavior instructions\n  HEARTBEAT.md             # Periodic check instructions\n  SETUP.md                 # This file\n  review_log.json          # Auto-generated: tracks processed reviews\n  clients/\n    _template.json         # Config template\n    joes-pizza.json        # Example client config\n  pending/\n    joes-pizza_abc123.json # Auto-generated: reviews awaiting approval\n```\n\nFile v2.1.1:skill-card.md\n\n## Description:\n\nHelps agencies and consultants monitor client Google Business Profile reviews, draft tailored replies, and route them for operator approval before posting.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chris](https://clawhub.ai/user/chris)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nAgencies and consultants managing configured client locations use this skill to check for unanswered Google Business Profile reviews, prepare industry-aware replies, and seek operator approval before publishing.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Long-lived per-client Google OAuth credentials are accessible locally.\n\nMitigation: Store credentials in a protected secrets location with restricted access; never paste refresh tokens into chat or approval messages.\n\nRisk: The reply command can publish public business responses without a built-in approval-state check.\n\nMitigation: Restrict who can run the reply command and require explicit operator approval and review of the exact reply before each post.\n\nRisk: Public exposure of the web-based OAuth onboarding server could compromise client credentials.\n\nMitigation: Do not expose the onboarding server publicly unless client identifier handling, authentication, HTTPS, file permissions and overwrite protections are fixed.\n\nRisk: Public replies for regulated clients may reveal sensitive information or imply compliance assurances.\n\nMitigation: Have operators review industry-specific drafts, omit patient information from medical replies, and verify compliance with their own policies.\n\n## Reference(s):\n\n- [Review Responder on ClawHub](https://clawhub.ai/chris/skills/google-review-responder)\n- [Setup and client onboarding](artifact/SETUP.md)\n- [Skill instructions and privacy scope](artifact/SKILL.md)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Guidance, Shell commands]\n\n**Output Format:** [Plain-text review summaries, draft replies and approval messages; operational commands when needed]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Replies can be published publicly after operator approval; approval is not technically enforced by the reply command.]\n\n## Skill Version(s):\n\n2.1.1 (source: ClawHub release metadata; bundled documentation identifies 2.0.1)\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 v2.1.1:clients/_template.json\n\n{\n  \"business_name\": \"Example Business LLC\",\n  \"account_id\": \"YOUR_GBP_ACCOUNT_ID\",\n  \"location_id\": \"YOUR_GBP_LOCATION_ID\",\n  \"oauth_client_id\": \"YOUR_GOOGLE_CLOUD_CLIENT_ID.apps.googleusercontent.com\",\n  \"oauth_client_secret\": \"YOUR_GOOGLE_CLOUD_CLIENT_SECRET\",\n  \"refresh_token\": \"YOUR_OAUTH_REFRESH_TOKEN\",\n  \"notes\": \"Optional notes about this client or their preferred tone\"\n}\n\nArchive v2.1.0: 14 files, 27975 bytes\n\nFiles: CHANGELOG.md (3469b), clients/_template.json (383b), diagnose.py (10138b), gbp_reviews.py (8067b), get_client_token.py (1878b), get_token_interactive.py (3330b), HEARTBEAT.md (1032b), lookup_ids.py (2691b), oauth_server.py (4892b), README.md (7055b), SETUP.md (3850b), skill-card.md (1960b), SKILL.md (15482b), _meta.json (142b)\n\nFile v2.1.0:SKILL.md\n\n---\nname: review-responder\nversion: 2.0.1\ndescription: \"Use this skill when an operator is actively running the Google Business Profile review-response workflow for one of their configured client accounts. Specific triggers: 'check for new reviews,' 'run the review check for [client],' 'new review came in for [client],' 'draft a reply to the [reviewer] review,' 'approve the draft for [reviewer/client],' 'post the reply for [review id],' 'show pending review approvals,' 'show me the pending reviews,' or 'apply the [medical/legal/restaurant/retail/general] industry profile to this draft.' Do NOT trigger on: general questions about how to handle reviews, casual mentions of Google reviews, marketing strategy chat, requests to write a review (versus reply to one), or any workflow where no configured client exists. Covers: scheduled checks against Google Business Profile API for configured clients, star-rating-matched draft replies with industry-aware drafting constraints (medical/HIPAA-aware, legal, restaurant, retail), and an approval gate across Telegram, email, webhook, or in-chat channels. Drafts are NEVER auto-posted; operator approval is required before any reply is published. See Privacy and Data Handling for credential and posting scope.\"\nmetadata:\n  openclaw:\n    emoji: ⭐\n---\n\n# Review Responder\n\nAutomatically monitors Google Business Profile reviews across one or more client accounts, drafts professional responses tuned to star rating and industry, and routes drafts to a configurable approval channel before posting. Designed for agencies and consultants managing reviews on behalf of clients.\n\n## Trigger\n\nThis skill activates during scheduled review checks (heartbeat) and when an operator responds to a pending review approval message.\n\n---\n\n## Configuration\n\nAll paths and channels are read from a single config file: `review-responder.config.json` in the skill's data directory. If it doesn't exist, create one from this template on first run:\n\n```json\n{\n  \"script_path\": \"~/review-responder/gbp_reviews.py\",\n  \"clients_dir\": \"~/review-responder/clients/\",\n  \"approval_channel\": \"telegram\",\n  \"telegram_chat_id\": \"\",\n  \"email_recipient\": \"\",\n  \"webhook_url\": \"\",\n  \"default_industry\": \"general\",\n  \"memory_file\": \"approval-patterns.json\"\n}\n```\n\n### Configuration fields\n\n- **script_path**: Absolute path to the `gbp_reviews.py` CLI. Defaults to `~/review-responder/gbp_reviews.py` but can live anywhere.\n- **clients_dir**: Directory containing per-client config files. Each client gets its own subdirectory or JSON entry.\n- **approval_channel**: One of `telegram`, `email`, `webhook`, or `chat`. Determines where draft replies are sent for approval. See Approval Channels below.\n- **default_industry**: Industry profile applied when a client doesn't specify one. See Industry Compliance Profiles below.\n- **memory_file**: Where to log approval patterns for the learning layer.\n\n### Per-client overrides\n\nEach client in `clients_dir` can override `industry`, `approval_channel`, and `tone_notes` (free-text guidance specific to that business). Example client config:\n\n```json\n{\n  \"client_id\": \"smithdental\",\n  \"business_name\": \"Smith Family Dental\",\n  \"industry\": \"medical\",\n  \"approval_channel\": \"email\",\n  \"email_recipient\": \"office@smithdental.com\",\n  \"tone_notes\": \"Dr. Smith is warm but understated. Avoid exclamation points.\"\n}\n```\n\n---\n\n## Review Check Flow (Heartbeat)\n\n1. Load `review-responder.config.json` and enumerate all clients in `clients_dir`.\n2. For each client, run:\n   ```\n   python3 {script_path} check --client {client_id}\n   ```\n3. For each new unanswered review:\n   - Apply the client's industry profile (or `default_industry` if none specified)\n   - Draft a response following the Response Guidelines and the industry profile's constraints\n   - Cross-reference against the approval-patterns memory file for operator-specific adjustments (e.g., if the operator consistently shortens 5-star replies for this client, default to shorter)\n4. Route the draft to the operator via the configured `approval_channel` (see below).\n5. Do NOT post the reply automatically. Wait for operator approval.\n\n---\n\n## Approval Channels\n\nThe approval message format stays consistent across channels; only the delivery method changes.\n\n### Standard approval message\n\n```\n📝 New Review for [Business Name]\n\n⭐ [star_rating] from [reviewer_name]\n💬 \"[review comment]\"\n\nMy draft reply:\n\"[your drafted response]\"\n\nReply OK to post, or send your edits.\n(Review ID: [review_id] | Client: [client_id])\n```\n\n### Telegram (`approval_channel: telegram`)\nSend the message to the configured `telegram_chat_id`. The operator replies in the Telegram thread.\n\n### Email (`approval_channel: email`)\nSend the message as a plain-text email to `email_recipient`. Subject line: `Review approval needed — [Business Name]`. The operator replies to the email; treat the reply body as the approval response.\n\n### Webhook (`approval_channel: webhook`)\nPOST a JSON payload to `webhook_url` containing the review draft and metadata. Useful for custom dashboards or Slack relays. Expected response: `{ \"decision\": \"approve\" | \"edit\" | \"skip\", \"edited_text\": \"...\" }`.\n\n### Chat (`approval_channel: chat`)\nSurface the draft directly in the current chat session. Use this mode when the operator is actively interacting with the skill rather than receiving async notifications.\n\n---\n\n## Approval Flow\n\nWhen the operator responds to a draft (via any channel):\n\n- **\"OK\"**, **\"post it\"**, **\"send it\"**, **\"approved\"**: Post the draft as-is:\n  ```\n  python3 {script_path} reply --client {client_id} --review {review_id} --reply \"{approved response}\"\n  ```\n  Confirm once posted: \"Done — reply posted for [reviewer_name]'s review.\"\n  Log to the memory file as `approved_as_is`.\n\n- **Edited text**: Treat any reply that isn't a recognized approval/skip keyword as replacement text. Confirm before posting: \"Got it — posting your version now.\" Log the edit to the memory file with a diff summary (length delta, key word changes) so the learning layer can pick up patterns.\n\n- **\"Skip\"**, **\"ignore\"**, **\"don't reply\"**: Do not reply to that review. Remove it from pending. Log as `skipped`.\n\n---\n\n## Response Guidelines\n\n### Tone principles\n- Warm, professional, and human — not corporate or robotic\n- Specific to what the reviewer said (never generic \"thanks for your review!\")\n- Concise: 2-4 sentences max\n- Match the energy of the review without being over the top\n- Layer in any `tone_notes` from the client config\n\n### By star rating\n\n**5 stars**\n- Thank them warmly and reference something specific they mentioned\n- Reinforce what they loved (\"We're glad [specific thing] made a difference\")\n- End with a light invitation to return or share with others\n- Keep it brief; don't overdo it on a great review\n\n**4 stars**\n- Thank them and acknowledge specific positives\n- If they mentioned something that could improve, acknowledge it gracefully without being defensive\n- Show you're listening: \"We appreciate the feedback on [topic] and are always looking to improve\"\n\n**3 stars**\n- Thank them for taking the time\n- Acknowledge both the positives and the concern\n- Show genuine interest in making it right: \"We'd love the chance to do better next time\"\n- Optionally invite them to reach out directly\n\n**1-2 stars**\n- Lead with empathy, not defensiveness: \"We're sorry to hear this wasn't the experience you deserved\"\n- Acknowledge the specific issue without making excuses\n- Offer a path forward: invite them to contact the business directly\n- Keep it short and dignified; do not argue or over-explain\n- Never blame the reviewer or question their experience\n\n---\n\n## Industry Compliance Profiles\n\nIndustry profiles enforce constraints and tone defaults appropriate to specific business types. Apply the profile from the client config (or `default_industry`) on every draft.\n\n### `medical` (HIPAA-aware drafting)\n\n**Note on terminology**: this profile applies HIPAA-aware drafting constraints — it instructs the assistant to avoid referencing PHI in public review replies. It does not certify the operator's overall workflow as HIPAA-compliant. Covered entities are responsible for their own compliance program; this skill is one input.\n\n**Hard rules** (never violate, regardless of star rating):\n- NEVER reference or confirm any medical conditions, diagnoses, treatments, medications, procedures, or health details, even if the reviewer mentioned them publicly\n- NEVER confirm or deny that someone is or was a patient\n- Keep responses general: \"your experience,\" \"your visit,\" \"your care\" — not \"your diagnosis\" or \"your treatment\"\n- If the reviewer shared health details, respond to the sentiment and experience only\n- When inviting follow-up, use \"please contact our office\" — never suggest discussing their \"case\" or \"medical records\"\n\n**Tone defaults**: professional, reassuring, brief.\n\n### `legal`\n\n**Hard rules**:\n- Never confirm or discuss case details, legal advice, or attorney-client relationships\n- Never speculate about outcomes or imply guarantees\n- Avoid language that could be interpreted as a new attorney-client communication\n- For dissatisfied reviewers, direct them to the firm's office line rather than offering legal commentary\n\n**Tone defaults**: measured, professional, no flourishes.\n\n### `restaurant`\n\n**Hard rules**: none specific, but stay grounded.\n\n**Tone defaults**: warmer and more conversational than medical/legal. Food-specific callouts welcome (\"glad the carbonara hit\"). For complaints, offer a direct contact for the manager.\n\n### `retail`\n\n**Hard rules**:\n- Don't speculate about specific products or stock issues you can't verify\n- For return/refund disputes, direct to customer service, not public dialogue\n\n**Tone defaults**: friendly, helpful, solution-oriented.\n\n### `general`\n\nNo industry-specific constraints. Fall back to base Tone Principles and By Star Rating guidance.\n\n---\n\n## Approval Pattern Learning\n\nLog each approval interaction to the memory file (`memory_file` in config). Use the log to surface patterns and adjust future drafts.\n\n### What to log per review\n\n```json\n{\n  \"client_id\": \"smithdental\",\n  \"review_id\": \"abc123\",\n  \"stars\": 5,\n  \"draft\": \"Thank you, Maria...\",\n  \"decision\": \"edited\",\n  \"final\": \"Thanks Maria...\",\n  \"length_delta_words\": -8,\n  \"timestamp\": \"2026-03-20T14:22:00Z\"\n}\n```\n\n### How to apply patterns\n\nBefore drafting any new reply, scan the log for the same client and look for trends across the last 10-20 interactions:\n\n- If `length_delta_words` is consistently negative for a given star rating, default to shorter drafts for that client at that rating\n- If certain words/phrases are routinely stripped (e.g., \"incredibly\", \"truly\"), avoid them on future drafts for that client\n- If the operator consistently skips 1-star reviews from anonymous reviewers, surface that as a default rather than drafting one\n\nSurface insights to the operator periodically (e.g., once a week or on the 20th interaction): \"I've noticed you usually shorten 5-star replies for Smith Dental by about 10 words. Want me to default to shorter going forward?\"\n\n---\n\n## Checking Pending Reviews\n\nTo see what's waiting for approval:\n```\npython3 {script_path} pending\n```\n\n---\n\n## Things to Avoid\n\n- Generic filler: \"We value all our customers,\" \"Your feedback is important to us\"\n- Mentioning the star rating directly: \"Thanks for the 5 stars!\"\n- Being defensive about negative reviews\n- Making promises the business can't keep\n- Using the reviewer's full name unless they used it in their review\n- Emojis (unless the business brand is very casual and the operator approves it)\n- Violating the active industry profile's hard rules under any circumstance\n\n---\n\n## Dependencies\n\n- Python 3 with: `google-auth`, `google-auth-oauthlib`, `requests`\n- Client config files in the directory specified by `clients_dir`\n- For Telegram: a Telegram channel/chat configured and a working bot token\n- For email: SMTP credentials or a relay\n- For webhook: an HTTPS endpoint that accepts POST and returns the decision JSON\n\n---\n\n## Privacy and Data Handling\n\nUnlike most skills in this catalog, this one ships executable Python code (`gbp_reviews.py`, `get_client_token.py`, `oauth_server.py`) that makes real network calls and posts content publicly to Google Business Profile. Be honest with the user about that scope.\n\n**What the skill does over the network**\n\n- Calls Google's My Business API v4 (`mybusiness.googleapis.com`) to fetch unanswered reviews and to post replies on behalf of the operator's configured clients. These calls use the client's own OAuth credentials and refresh tokens, which the operator obtains and stores locally.\n- Sends draft approval messages through whichever `approval_channel` the operator configured (Telegram, email, webhook, or in-chat). Each of those uses the operator's own credentials and infrastructure; the skill does not bundle credentials or route through any author-controlled service.\n- Posts the approved reply text to the corresponding Google review only after explicit operator approval. Drafts are never auto-posted.\n\n**Credentials and local data**\n\n- Per-client OAuth credentials (`oauth_client_id`, `oauth_client_secret`, `refresh_token`) live in JSON files under `clients_dir`. These are the operator's credentials for the operator's own clients. The skill does not transmit them anywhere except to Google's token endpoint (`https://oauth2.googleapis.com/token`) for the standard OAuth refresh flow.\n- Review polling state (`review_log.json`) and pending drafts (`pending/`) are stored locally under the skill's directory.\n- Approval-pattern learning state (`memory_file`, default `approval-patterns.json`) is stored locally.\n\n**Hard guardrails**\n\n- **No auto-posting.** Every reply requires an explicit operator approval through one of the configured channels. The skill must not post a reply without that approval.\n- **No PHI in public replies.** When the active client's industry profile is `medical`, the assistant must never reference health conditions, treatments, diagnoses, or patient status in the public reply — even if the reviewer disclosed those details themselves.\n- **No exfiltration of credentials.** The assistant must never quote, log, summarize, or transmit `oauth_client_secret`, `refresh_token`, or any other credential field into approval messages, drafts, logs, or chat outputs.\n- **No bulk export of client data.** The skill is for the operator's own ongoing review workflow. It must not dump consolidated client lists, credentials, or review histories into external destinations without explicit operator instruction for that specific export.\n\n**No telemetry**\n\nThe skill does not collect or transmit usage data, client identifiers, review content, or any other information back to its author, ClawHub, or any third party. (The Google API, Telegram, your SMTP relay, and any webhook target will each have their own logs — consult those services' policies.)\n\n**Compliance scope**\n\nThe `medical` industry profile applies HIPAA-aware drafting constraints to public review replies. It does not certify the operator's overall workflow as HIPAA-compliant, and it does not turn this skill into a HIPAA-covered service. Operators in regulated industries (medical, legal, financial) remain responsible for their own compliance programs and should review the constraints in this skill against their own policies before using it in production.\n\nFile v2.1.0:README.md\n\n# Review Responder\n\nAn [OpenClaw](https://openclaw.ai) skill that monitors Google Business Profile reviews, drafts professional responses, and routes them to a configurable approval channel before posting.\n\nBuilt for consultants and agencies managing reviews across multiple client locations and industries.\n\n**Current version: 2.0.1**\n\n## What's new in 2.0.1\n\n- Added a **Privacy and Data Handling** section to SKILL.md that honestly describes the skill's real network calls (Google Business Profile API), credential storage (operator-owned OAuth credentials per client), and the no-auto-post guardrail\n- Added a **Permissions and Privacy** section to this README so operators see scope, credential handling, and the HIPAA-aware (not HIPAA-certified) boundary before installing\n- Reworded the `medical` industry profile from \"HIPAA-safe\" to \"HIPAA-aware drafting\" to accurately describe what the skill enforces (drafting constraints) versus what it does not provide (workflow certification)\n- Narrowed the activation triggers in `description` to require an active, configured-client workflow, with a \"do NOT trigger\" guard for casual reviews chat and review-writing requests\n\n## What's new in 2.0.0\n\n- **Configurable script paths and channels** via a single `review-responder.config.json` file\n- **Channel-agnostic approval flow**: Telegram, email, webhook, or in-thread chat\n- **Industry compliance profiles**: medical (HIPAA-aware drafting), legal, restaurant, retail, and general\n- **Operator pattern learning**: logs approval decisions per client and surfaces patterns (e.g., \"you usually shorten 5-star replies for this client\")\n- **Per-client overrides** for industry, approval channel, and tone notes\n\nSee [CHANGELOG.md](CHANGELOG.md) for the full release history.\n\n## How It Works\n\n1. On each scheduled check, OpenClaw enumerates configured clients and looks for new unanswered reviews\n2. For each new review, the agent applies the client's industry profile and drafts a tone-matched response\n3. The draft is sent to the configured approval channel (Telegram, email, webhook, or chat)\n4. The operator replies \"OK\" to post it, sends edits to revise it, or \"skip\" to ignore it\n5. Decisions are logged so the agent can learn the operator's preferences over time\n\nNo reviews are ever posted without explicit operator approval.\n\n## What's Included\n\n- `SKILL.md` — Agent behavior instructions (configuration, approval flow, industry profiles, pattern learning)\n- `HEARTBEAT.md` — Periodic check instructions for OpenClaw's heartbeat system\n- `gbp_reviews.py` — Main script for checking reviews and posting replies\n- `get_client_token.py` — One-time OAuth helper for onboarding clients locally\n- `oauth_server.py` — Web-based OAuth flow for remote client onboarding\n- `clients/_template.json` — Config template for adding new clients\n- `SETUP.md` — Full setup and per-client onboarding guide\n\n## Quick Start\n\n1. Set up a Google Cloud project with the Business Profile API enabled (details in `SETUP.md`)\n2. Install dependencies: `pip install google-auth google-auth-oauthlib requests`\n3. Copy the `review-responder` folder into your OpenClaw workspace\n4. Create `review-responder.config.json` from the template in `SKILL.md`\n5. Register the skill in your `openclaw.json`\n6. Onboard your first client using `get_client_token.py` or `oauth_server.py`\n7. Wire up the scheduled check and you're live\n\nSee `SETUP.md` for the full walkthrough.\n\n## Requirements\n\n- Python 3 with `google-auth`, `google-auth-oauthlib`, `requests`\n- Flask (only if using the web-based OAuth onboarding server)\n- A Google Cloud project with OAuth 2.0 credentials\n- One approval channel configured: Telegram, email (SMTP), webhook endpoint, or in-thread chat\n\n## Permissions and Privacy (read before installing)\n\nUnlike most skills in this catalog, this one ships executable Python (`gbp_reviews.py`, `get_client_token.py`, `oauth_server.py`) that makes real network calls and posts content publicly to Google Business Profile. Read this section in full before installing or onboarding clients.\n\n**What runs on the network**\n\n- **Google Business Profile API v4** (`mybusiness.googleapis.com`): the skill polls reviews for each configured client and posts approved replies. Calls authenticate with the client's own OAuth credentials, which you obtain and store locally during onboarding.\n- **Google OAuth token endpoint** (`https://oauth2.googleapis.com/token`): standard refresh-token exchange.\n- **Whichever approval channel you configure**: Telegram (your bot, your chat), SMTP (your relay, your recipient), webhook (your endpoint), or in-thread chat (no network). The skill does not bundle credentials for any of these and does not route through any author-controlled service.\n\n**Credential storage**\n\n- Per-client OAuth credentials (`oauth_client_id`, `oauth_client_secret`, `refresh_token`) live in JSON files under `clients_dir` on your machine. These are your credentials for your own clients. The skill does not transmit them anywhere except to Google's token endpoint for the standard OAuth refresh flow.\n- Treat the `clients/` directory like you would any secrets folder: restrict filesystem permissions, do not commit it to public source control (the included `.gitignore` excludes it), and consider disk-level encryption.\n\n**Hard guardrails**\n\n- **No auto-posting.** Every reply requires explicit operator approval through your configured channel. The skill must not, and the assistant must not, post a reply without that approval.\n- **No PHI in public replies.** When a client is set to the `medical` industry profile, the assistant will never reference health conditions, treatments, or diagnoses in the public reply, even if the reviewer disclosed those details.\n- **No credential leakage.** The assistant will never quote, log, or include `oauth_client_secret` or `refresh_token` in approval messages, drafts, logs, or chat outputs.\n- **No bulk export.** The skill is for your ongoing review workflow, not for dumping consolidated client lists or review histories into external destinations.\n\n**Compliance scope (read this carefully if you serve regulated industries)**\n\nThe `medical` industry profile applies **HIPAA-aware drafting constraints** to the public reply text — it prevents the reply from referencing PHI. This is one input to a compliant workflow, not the whole workflow. The skill does NOT:\n\n- Certify your overall practice as HIPAA-compliant\n- Replace your Business Associate Agreement obligations (Google, OpenAI/Anthropic, and any other vendor in your pipeline have their own status)\n- Constitute legal advice for medical, legal, or financial regulated practices\n\nOperators in regulated industries remain responsible for their own compliance program and should review these constraints against their own policies before using this skill in production.\n\n**No telemetry**\n\nThe skill does not collect or transmit usage data, client identifiers, review content, or any other information back to its author, ClawHub, or any third party.\n\nFile v2.1.0:_meta.json\n\n{\n  \"ownerId\": \"kn77r9qjvh6fy4aja2km8bzgvd83khv9\",\n  \"slug\": \"google-review-responder\",\n  \"version\": \"2.1.0\",\n  \"publishedAt\": 1790619152100\n}\n\nFile v2.1.0:CHANGELOG.md\n\n# Changelog\n\nAll notable changes to this skill will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this skill adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n## [2.0.1] — 2026-06-08\n\n### Added\n- **Privacy and Data Handling** section in SKILL.md describing the real network surface (Google Business Profile API v4, Google OAuth token endpoint, configured approval channel), credential storage (operator-owned OAuth credentials per client in `clients_dir`), and hard guardrails (no auto-posting, no PHI in public replies, no credential leakage, no bulk export)\n- **Permissions and Privacy** section in README.md so operators see the full network surface, credential storage posture, hard guardrails, and the compliance scope (HIPAA-aware drafting, NOT a HIPAA-certified workflow) before installing\n\n### Changed\n- Reworded the `medical` industry profile from \"HIPAA-safe\" to \"HIPAA-aware drafting\" to accurately describe the constraint (avoids PHI in public reply text) without implying a regulatory certification this skill cannot provide. CHANGELOG references to \"HIPAA-safe\" updated in the 2.0.0 entry's description of this profile for consistency\n- Narrowed the activation triggers in the `description` frontmatter to require an explicit configured-client workflow (named client, named reviewer, specific approval/post action), with a \"do NOT trigger\" guardrail for casual review chat, review-writing requests, and marketing-strategy questions\n- Unquoted the `version` field in frontmatter (matches updated ClawHub CLI semver requirements)\n\n## [2.0.0] — 2026-05-12\n\n### Added\n- Configuration file (`review-responder.config.json`) for centralizing script paths, clients directory, approval channel, default industry, and memory file location\n- Per-client configuration overrides for industry, approval channel, and tone notes\n- Channel-agnostic approval flow with four supported channels: Telegram, email, webhook, and in-thread chat\n- Industry compliance profiles for medical (HIPAA-safe), legal, restaurant, retail, and general business types\n- Operator pattern learning layer that logs each approval decision (approved-as-is, edited with diff summary, skipped) per client and surfaces patterns over time\n- Periodic insight surfacing to the operator (e.g., \"you usually shorten 5-star replies for this client by ~10 words\")\n\n### Changed\n- **BREAKING**: Hardcoded script paths (`~/review-responder/gbp_reviews.py`) replaced with a configurable `script_path` field\n- **BREAKING**: Telegram is no longer the assumed approval channel; `approval_channel` must be set explicitly in config\n- HIPAA section promoted from a sub-block under Response Guidelines into a top-level `Industry Compliance Profiles` section with peer profiles for other industries\n- SKILL.md now has proper YAML frontmatter (`name`, `version`, `description`, `metadata.openclaw.emoji`)\n\n### Removed\n- MIT LICENSE file (license now managed at the ClawHub platform level)\n\n## [1.0.0] — 2026-03-27\n\n### Added\n- Initial release\n- Scheduled review checks across multiple Google Business Profile clients\n- Tone-matched response drafting by star rating (5, 4, 3, 1-2)\n- Telegram-based approval flow with OK/edit/skip operator commands\n- HIPAA-aware response guidance for medical clients\n- Per-client config files for multi-client agency use\n- OAuth onboarding helpers (`get_client_token.py`, `oauth_server.py`)\n\nFile v2.1.0:HEARTBEAT.md\n\n# Heartbeat: Review Responder\n\n## On Every Heartbeat\n\n1. Check for new unanswered Google Business reviews for each active client.\n   Run for each client configured in `~/review-responder/clients/`:\n   ```\n   python3 ~/review-responder/gbp_reviews.py check --client <client_id>\n   ```\n\n2. If the script finds new reviews, read the output carefully. For each new review:\n   - Draft a response following the guidelines in the Review Responder skill (SKILL.md)\n   - Send the draft to the operator via Telegram for approval\n   - Use the message format specified in SKILL.md\n\n3. If no new reviews are found for any client, reply HEARTBEAT_OK.\n\n## Important\n- Do NOT auto-post replies. Every response requires operator approval via Telegram.\n- If the script errors (missing config, API failure), report the error via Telegram so the operator can investigate.\n- Check `python3 ~/review-responder/gbp_reviews.py pending` to see if there are stale pending reviews that haven't been addressed. If any are older than 48 hours, send a reminder.\n\nFile v2.1.0:SETUP.md\n\n# Review Responder: Setup Guide\n\n## One-Time Setup (Your VPS)\n\n### 1. Install Python Dependencies\n```bash\npip install google-auth google-auth-oauthlib requests\n```\n\n### 2. Create a Google Cloud Project\n1. Go to https://console.cloud.google.com\n2. Create a new project (e.g., \"Review Responder\")\n3. Enable the **Google My Business API** (also called Business Profile API)\n4. Go to **Credentials** > **Create Credentials** > **OAuth 2.0 Client ID**\n5. Application type: **Desktop app**\n6. Save the **Client ID** and **Client Secret** -- you'll use these for every client\n\n### 3. Copy Files to OpenClaw Workspace\nCopy the `review-responder` folder into your OpenClaw agent workspace:\n```bash\ncp -r review-responder ~/.openclaw/workspace/review-responder\n```\n\n### 4. Register the Skill\nAdd the skill to your OpenClaw config (openclaw.json):\n```json\n{\n  \"skills\": {\n    \"entries\": {\n      \"review-responder\": {\n        \"path\": \"~/review-responder/SKILL.md\"\n      }\n    }\n  }\n}\n```\n\n### 5. Wire Up the Heartbeat\nAppend the review check instructions to your HEARTBEAT.md, or if you want a dedicated agent for this, reference `~/review-responder/HEARTBEAT.md` in your heartbeat config.\n\n### 6. Set Heartbeat Interval\nIn openclaw.json, set the heartbeat to run every 1-2 hours:\n```json\n{\n  \"agent\": {\n    \"heartbeat\": { \"every\": \"60m\" }\n  }\n}\n```\n\n---\n\n## Per-Client Onboarding\n\n### Step 1: Get Their Authorization\nYou need the client to authorize your app to access their Google Business Profile.\n\nRun this one-time script on your machine to generate a refresh token:\n```bash\npython3 get_client_token.py\n```\nThis will:\n1. Open a browser for the client to log in with their Google account\n2. Ask them to authorize access to their Business Profile\n3. Print a refresh token you save to their config file\n\n(See `get_client_token.py` for the helper script.)\n\n### Step 2: Find Their Account and Location IDs\nAfter authorization, use the access token to look up their IDs:\n```bash\n# List accounts\ncurl -H \"Authorization: Bearer ACCESS_TOKEN\" \\\n  \"https://mybusinessaccountmanagement.googleapis.com/v1/accounts\"\n\n# List locations for an account\ncurl -H \"Authorization: Bearer ACCESS_TOKEN\" \\\n  \"https://mybusinessbusinessinformation.googleapis.com/v1/accounts/ACCOUNT_ID/locations\"\n```\n\n### Step 3: Create Their Config File\nCopy the template and fill in the values:\n```bash\ncp clients/_template.json clients/joes-pizza.json\n```\n\nEdit with their specific values:\n```json\n{\n  \"business_name\": \"Joe's Pizza\",\n  \"account_id\": \"accounts/123456789\",\n  \"location_id\": \"locations/987654321\",\n  \"oauth_client_id\": \"YOUR_PROJECT_CLIENT_ID.apps.googleusercontent.com\",\n  \"oauth_client_secret\": \"YOUR_PROJECT_CLIENT_SECRET\",\n  \"refresh_token\": \"1//TOKEN_FROM_STEP_1\",\n  \"notes\": \"Family pizza place, casual and friendly tone\"\n}\n```\n\n### Step 4: Test It\n```bash\npython3 gbp_reviews.py check --client joes-pizza\n```\n\nIf it returns reviews (or \"No new unanswered reviews\"), you're good.\n\n---\n\n## OAuth Token Helper Script\n\nThe `get_client_token.py` script handles the one-time OAuth flow. Before running it, update the `CLIENT_ID` and `CLIENT_SECRET` variables at the top of the file with your Google Cloud project credentials.\n\nFor remote/web-based onboarding, see `oauth_server.py` instead (requires Flask).\n\n---\n\n## Folder Structure\n```\nreview-responder/\n  gbp_reviews.py          # Main script (check + reply)\n  get_client_token.py      # One-time OAuth helper\n  SKILL.md                 # Agent behavior instructions\n  HEARTBEAT.md             # Periodic check instructions\n  SETUP.md                 # This file\n  review_log.json          # Auto-generated: tracks processed reviews\n  clients/\n    _template.json         # Config template\n    joes-pizza.json        # Example client config\n  pending/\n    joes-pizza_abc123.json # Auto-generated: reviews awaiting approval\n```\n\nFile v2.1.0:skill-card.md\n\n## Description:\n\nChecks Google Business Profile reviews for configured clients, drafts tailored replies, and routes them for operator approval before posting.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chris](https://clawhub.ai/user/chris)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nAgencies and consultants managing client business profiles use this skill to find unanswered Google reviews, prepare industry-aware replies, and seek operator approval before publication.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Long-lived Google credentials in client configuration can expose business accounts if disclosed.\n\nMitigation: Restrict client config file permissions, never paste refresh tokens into chat, and rotate exposed credentials.\n\nRisk: Remote OAuth onboarding can expose authorization details if served insecurely.\n\nMitigation: Use HTTPS-only OAuth onboarding.\n\nRisk: The reply command can post publicly without a reliably enforced approval record.\n\nMitigation: Require a verifiable operator approval record before allowing any reply command to publish.\n\n## Reference(s):\n\n- [Review Responder on ClawHub](https://clawhub.ai/chris/skills/google-review-responder)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Shell commands, Configuration guidance]\n\n**Output Format:** [Plain text and Markdown drafts, with shell commands and configuration guidance]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May post a public Google Business Profile reply when the reply command is invoked.]\n\n## Skill Version(s):\n\n2.1.0 (source: ClawHub release metadata; bundled frontmatter lists 2.0.1)\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 v2.1.0:clients/_template.json\n\n{\n  \"business_name\": \"Example Business LLC\",\n  \"account_id\": \"YOUR_GBP_ACCOUNT_ID\",\n  \"location_id\": \"YOUR_GBP_LOCATION_ID\",\n  \"oauth_client_id\": \"YOUR_GOOGLE_CLOUD_CLIENT_ID.apps.googleusercontent.com\",\n  \"oauth_client_secret\": \"YOUR_GOOGLE_CLOUD_CLIENT_SECRET\",\n  \"refresh_token\": \"YOUR_OAUTH_REFRESH_TOKEN\",\n  \"notes\": \"Optional notes about this client or their preferred tone\"\n}\n\nArchive v2.0.1: 11 files, 21701 bytes\n\nFiles: CHANGELOG.md (3469b), clients/_template.json (383b), gbp_reviews.py (8067b), get_client_token.py (1878b), HEARTBEAT.md (1032b), oauth_server.py (4892b), README.md (7055b), SETUP.md (3850b), skill-card.md (2481b), SKILL.md (15482b), _meta.json (142b)\n\nFile v2.0.1:SKILL.md\n\n---\nname: review-responder\nversion: 2.0.1\ndescription: \"Use this skill when an operator is actively running the Google Business Profile review-response workflow for one of their configured client accounts. Specific triggers: 'check for new reviews,' 'run the review check for [client],' 'new review came in for [client],' 'draft a reply to the [reviewer] review,' 'approve the draft for [reviewer/client],' 'post the reply for [review id],' 'show pending review approvals,' 'show me the pending reviews,' or 'apply the [medical/legal/restaurant/retail/general] industry profile to this draft.' Do NOT trigger on: general questions about how to handle reviews, casual mentions of Google reviews, marketing strategy chat, requests to write a review (versus reply to one), or any workflow where no configured client exists. Covers: scheduled checks against Google Business Profile API for configured clients, star-rating-matched draft replies with industry-aware drafting constraints (medical/HIPAA-aware, legal, restaurant, retail), and an approval gate across Telegram, email, webhook, or in-chat channels. Drafts are NEVER auto-posted; operator approval is required before any reply is published. See Privacy and Data Handling for credential and posting scope.\"\nmetadata:\n  openclaw:\n    emoji: ⭐\n---\n\n# Review Responder\n\nAutomatically monitors Google Business Profile reviews across one or more client accounts, drafts professional responses tuned to star rating and industry, and routes drafts to a configurable approval channel before posting. Designed for agencies and consultants managing reviews on behalf of clients.\n\n## Trigger\n\nThis skill activates during scheduled review checks (heartbeat) and when an operator responds to a pending review approval message.\n\n---\n\n## Configuration\n\nAll paths and channels are read from a single config file: `review-responder.config.json` in the skill's data directory. If it doesn't exist, create one from this template on first run:\n\n```json\n{\n  \"script_path\": \"~/review-responder/gbp_reviews.py\",\n  \"clients_dir\": \"~/review-responder/clients/\",\n  \"approval_channel\": \"telegram\",\n  \"telegram_chat_id\": \"\",\n  \"email_recipient\": \"\",\n  \"webhook_url\": \"\",\n  \"default_industry\": \"general\",\n  \"memory_file\": \"approval-patterns.json\"\n}\n```\n\n### Configuration fields\n\n- **script_path**: Absolute path to the `gbp_reviews.py` CLI. Defaults to `~/review-responder/gbp_reviews.py` but can live anywhere.\n- **clients_dir**: Directory containing per-client config files. Each client gets its own subdirectory or JSON entry.\n- **approval_channel**: One of `telegram`, `email`, `webhook`, or `chat`. Determines where draft replies are sent for approval. See Approval Channels below.\n- **default_industry**: Industry profile applied when a client doesn't specify one. See Industry Compliance Profiles below.\n- **memory_file**: Where to log approval patterns for the learning layer.\n\n### Per-client overrides\n\nEach client in `clients_dir` can override `industry`, `approval_channel`, and `tone_notes` (free-text guidance specific to that business). Example client config:\n\n```json\n{\n  \"client_id\": \"smithdental\",\n  \"business_name\": \"Smith Family Dental\",\n  \"industry\": \"medical\",\n  \"approval_channel\": \"email\",\n  \"email_recipient\": \"office@smithdental.com\",\n  \"tone_notes\": \"Dr. Smith is warm but understated. Avoid exclamation points.\"\n}\n```\n\n---\n\n## Review Check Flow (Heartbeat)\n\n1. Load `review-responder.config.json` and enumerate all clients in `clients_dir`.\n2. For each client, run:\n   ```\n   python3 {script_path} check --client {client_id}\n   ```\n3. For each new unanswered review:\n   - Apply the client's industry profile (or `default_industry` if none specified)\n   - Draft a response following the Response Guidelines and the industry profile's constraints\n   - Cross-reference against the approval-patterns memory file for operator-specific adjustments (e.g., if the operator consistently shortens 5-star replies for this client, default to shorter)\n4. Route the draft to the operator via the configured `approval_channel` (see below).\n5. Do NOT post the reply automatically. Wait for operator approval.\n\n---\n\n## Approval Channels\n\nThe approval message format stays consistent across channels; only the delivery method changes.\n\n### Standard approval message\n\n```\n📝 New Review for [Business Name]\n\n⭐ [star_rating] from [reviewer_name]\n💬 \"[review comment]\"\n\nMy draft reply:\n\"[your drafted response]\"\n\nReply OK to post, or send your edits.\n(Review ID: [review_id] | Client: [client_id])\n```\n\n### Telegram (`approval_channel: telegram`)\nSend the message to the configured `telegram_chat_id`. The operator replies in the Telegram thread.\n\n### Email (`approval_channel: email`)\nSend the message as a plain-text email to `email_recipient`. Subject line: `Review approval needed — [Business Name]`. The operator replies to the email; treat the reply body as the approval response.\n\n### Webhook (`approval_channel: webhook`)\nPOST a JSON payload to `webhook_url` containing the review draft and metadata. Useful for custom dashboards or Slack relays. Expected response: `{ \"decision\": \"approve\" | \"edit\" | \"skip\", \"edited_text\": \"...\" }`.\n\n### Chat (`approval_channel: chat`)\nSurface the draft directly in the current chat session. Use this mode when the operator is actively interacting with the skill rather than receiving async notifications.\n\n---\n\n## Approval Flow\n\nWhen the operator responds to a draft (via any channel):\n\n- **\"OK\"**, **\"post it\"**, **\"send it\"**, **\"approved\"**: Post the draft as-is:\n  ```\n  python3 {script_path} reply --client {client_id} --review {review_id} --reply \"{approved response}\"\n  ```\n  Confirm once posted: \"Done — reply posted for [reviewer_name]'s review.\"\n  Log to the memory file as `approved_as_is`.\n\n- **Edited text**: Treat any reply that isn't a recognized approval/skip keyword as replacement text. Confirm before posting: \"Got it — posting your version now.\" Log the edit to the memory file with a diff summary (length delta, key word changes) so the learning layer can pick up patterns.\n\n- **\"Skip\"**, **\"ignore\"**, **\"don't reply\"**: Do not reply to that review. Remove it from pending. Log as `skipped`.\n\n---\n\n## Response Guidelines\n\n### Tone principles\n- Warm, professional, and human — not corporate or robotic\n- Specific to what the reviewer said (never generic \"thanks for your review!\")\n- Concise: 2-4 sentences max\n- Match the energy of the review without being over the top\n- Layer in any `tone_notes` from the client config\n\n### By star rating\n\n**5 stars**\n- Thank them warmly and reference something specific they mentioned\n- Reinforce what they loved (\"We're glad [specific thing] made a difference\")\n- End with a light invitation to return or share with others\n- Keep it brief; don't overdo it on a great review\n\n**4 stars**\n- Thank them and acknowledge specific positives\n- If they mentioned something that could improve, acknowledge it gracefully without being defensive\n- Show you're listening: \"We appreciate the feedback on [topic] and are always looking to improve\"\n\n**3 stars**\n- Thank them for taking the time\n- Acknowledge both the positives and the concern\n- Show genuine interest in making it right: \"We'd love the chance to do better next time\"\n- Optionally invite them to reach out directly\n\n**1-2 stars**\n- Lead with empathy, not defensiveness: \"We're sorry to hear this wasn't the experience you deserved\"\n- Acknowledge the specific issue without making excuses\n- Offer a path forward: invite them to contact the business directly\n- Keep it short and dignified; do not argue or over-explain\n- Never blame the reviewer or question their experience\n\n---\n\n## Industry Compliance Profiles\n\nIndustry profiles enforce constraints and tone defaults appropriate to specific business types. Apply the profile from the client config (or `default_industry`) on every draft.\n\n### `medical` (HIPAA-aware drafting)\n\n**Note on terminology**: this profile applies HIPAA-aware drafting constraints — it instructs the assistant to avoid referencing PHI in public review replies. It does not certify the operator's overall workflow as HIPAA-compliant. Covered entities are responsible for their own compliance program; this skill is one input.\n\n**Hard rules** (never violate, regardless of star rating):\n- NEVER reference or confirm any medical conditions, diagnoses, treatments, medications, procedures, or health details, even if the reviewer mentioned them publicly\n- NEVER confirm or deny that someone is or was a patient\n- Keep responses general: \"your experience,\" \"your visit,\" \"your care\" — not \"your diagnosis\" or \"your treatment\"\n- If the reviewer shared health details, respond to the sentiment and experience only\n- When inviting follow-up, use \"please contact our office\" — never suggest discussing their \"case\" or \"medical records\"\n\n**Tone defaults**: professional, reassuring, brief.\n\n### `legal`\n\n**Hard rules**:\n- Never confirm or discuss case details, legal advice, or attorney-client relationships\n- Never speculate about outcomes or imply guarantees\n- Avoid language that could be interpreted as a new attorney-client communication\n- For dissatisfied reviewers, direct them to the firm's office line rather than offering legal commentary\n\n**Tone defaults**: measured, professional, no flourishes.\n\n### `restaurant`\n\n**Hard rules**: none specific, but stay grounded.\n\n**Tone defaults**: warmer and more conversational than medical/legal. Food-specific callouts welcome (\"glad the carbonara hit\"). For complaints, offer a direct contact for the manager.\n\n### `retail`\n\n**Hard rules**:\n- Don't speculate about specific products or stock issues you can't verify\n- For return/refund disputes, direct to customer service, not public dialogue\n\n**Tone defaults**: friendly, helpful, solution-oriented.\n\n### `general`\n\nNo industry-specific constraints. Fall back to base Tone Principles and By Star Rating guidance.\n\n---\n\n## Approval Pattern Learning\n\nLog each approval interaction to the memory file (`memory_file` in config). Use the log to surface patterns and adjust future drafts.\n\n### What to log per review\n\n```json\n{\n  \"client_id\": \"smithdental\",\n  \"review_id\": \"abc123\",\n  \"stars\": 5,\n  \"draft\": \"Thank you, Maria...\",\n  \"decision\": \"edited\",\n  \"final\": \"Thanks Maria...\",\n  \"length_delta_words\": -8,\n  \"timestamp\": \"2026-03-20T14:22:00Z\"\n}\n```\n\n### How to apply patterns\n\nBefore drafting any new reply, scan the log for the same client and look for trends across the last 10-20 interactions:\n\n- If `length_delta_words` is consistently negative for a given star rating, default to shorter drafts for that client at that rating\n- If certain words/phrases are routinely stripped (e.g., \"incredibly\", \"truly\"), avoid them on future drafts for that client\n- If the operator consistently skips 1-star reviews from anonymous reviewers, surface that as a default rather than drafting one\n\nSurface insights to the operator periodically (e.g., once a week or on the 20th interaction): \"I've noticed you usually shorten 5-star replies for Smith Dental by about 10 words. Want me to default to shorter going forward?\"\n\n---\n\n## Checking Pending Reviews\n\nTo see what's waiting for approval:\n```\npython3 {script_path} pending\n```\n\n---\n\n## Things to Avoid\n\n- Generic filler: \"We value all our customers,\" \"Your feedback is important to us\"\n- Mentioning the star rating directly: \"Thanks for the 5 stars!\"\n- Being defensive about negative reviews\n- Making promises the business can't keep\n- Using the reviewer's full name unless they used it in their review\n- Emojis (unless the business brand is very casual and the operator approves it)\n- Violating the active industry profile's hard rules under any circumstance\n\n---\n\n## Dependencies\n\n- Python 3 with: `google-auth`, `google-auth-oauthlib`, `requests`\n- Client config files in the directory specified by `clients_dir`\n- For Telegram: a Telegram channel/chat configured and a working bot token\n- For email: SMTP credentials or a relay\n- For webhook: an HTTPS endpoint that accepts POST and returns the decision JSON\n\n---\n\n## Privacy and Data Handling\n\nUnlike most skills in this catalog, this one ships executable Python code (`gbp_reviews.py`, `get_client_token.py`, `oauth_server.py`) that makes real network calls and posts content publicly to Google Business Profile. Be honest with the user about that scope.\n\n**What the skill does over the network**\n\n- Calls Google's My Business API v4 (`mybusiness.googleapis.com`) to fetch unanswered reviews and to post replies on behalf of the operator's configured clients. These calls use the client's own OAuth credentials and refresh tokens, which the operator obtains and stores locally.\n- Sends draft approval messages through whichever `approval_channel` the operator configured (Telegram, email, webhook, or in-chat). Each of those uses the operator's own credentials and infrastructure; the skill does not bundle credentials or route through any author-controlled service.\n- Posts the approved reply text to the corresponding Google review only after explicit operator approval. Drafts are never auto-posted.\n\n**Credentials and local data**\n\n- Per-client OAuth credentials (`oauth_client_id`, `oauth_client_secret`, `refresh_token`) live in JSON files under `clients_dir`. These are the operator's credentials for the operator's own clients. The skill does not transmit them anywhere except to Google's token endpoint (`https://oauth2.googleapis.com/token`) for the standard OAuth refresh flow.\n- Review polling state (`review_log.json`) and pending drafts (`pending/`) are stored locally under the skill's directory.\n- Approval-pattern learning state (`memory_file`, default `approval-patterns.json`) is stored locally.\n\n**Hard guardrails**\n\n- **No auto-posting.** Every reply requires an explicit operator approval through one of the configured channels. The skill must not post a reply without that approval.\n- **No PHI in public replies.** When the active client's industry profile is `medical`, the assistant must never reference health conditions, treatments, diagnoses, or patient status in the public reply — even if the reviewer disclosed those details themselves.\n- **No exfiltration of credentials.** The assistant must never quote, log, summarize, or transmit `oauth_client_secret`, `refresh_token`, or any other credential field into approval messages, drafts, logs, or chat outputs.\n- **No bulk export of client data.** The skill is for the operator's own ongoing review workflow. It must not dump consolidated client lists, credentials, or review histories into external destinations without explicit operator instruction for that specific export.\n\n**No telemetry**\n\nThe skill does not collect or transmit usage data, client identifiers, review content, or any other information back to its author, ClawHub, or any third party. (The Google API, Telegram, your SMTP relay, and any webhook target will each have their own logs — consult those services' policies.)\n\n**Compliance scope**\n\nThe `medical` industry profile applies HIPAA-aware drafting constraints to public review replies. It does not certify the operator's overall workflow as HIPAA-compliant, and it does not turn this skill into a HIPAA-covered service. Operators in regulated industries (medical, legal, financial) remain responsible for their own compliance programs and should review the constraints in this skill against their own policies before using it in production.\n\nFile v2.0.1:README.md\n\n# Review Responder\n\nAn [OpenClaw](https://openclaw.ai) skill that monitors Google Business Profile reviews, drafts professional responses, and routes them to a configurable approval channel before posting.\n\nBuilt for consultants and agencies managing reviews across multiple client locations and industries.\n\n**Current version: 2.0.1**\n\n## What's new in 2.0.1\n\n- Added a **Privacy and Data Handling** section to SKILL.md that honestly describes the skill's real network calls (Google Business Profile API), credential storage (operator-owned OAuth credentials per client), and the no-auto-post guardrail\n- Added a **Permissions and Privacy** section to this README so operators see scope, credential handling, and the HIPAA-aware (not HIPAA-certified) boundary before installing\n- Reworded the `medical` industry profile from \"HIPAA-safe\" to \"HIPAA-aware drafting\" to accurately describe what the skill enforces (drafting constraints) versus what it does not provide (workflow certification)\n- Narrowed the activation triggers in `description` to require an active, configured-client workflow, with a \"do NOT trigger\" guard for casual reviews chat and review-writing requests\n\n## What's new in 2.0.0\n\n- **Configurable script paths and channels** via a single `review-responder.config.json` file\n- **Channel-agnostic approval flow**: Telegram, email, webhook, or in-thread chat\n- **Industry compliance profiles**: medical (HIPAA-aware drafting), legal, restaurant, retail, and general\n- **Operator pattern learning**: logs approval decisions per client and surfaces patterns (e.g., \"you usually shorten 5-star replies for this client\")\n- **Per-client overrides** for industry, approval channel, and tone notes\n\nSee [CHANGELOG.md](CHANGELOG.md) for the full release history.\n\n## How It Works\n\n1. On each scheduled check, OpenClaw enumerates configured clients and looks for new unanswered reviews\n2. For each new review, the agent applies the client's industry profile and drafts a tone-matched response\n3. The draft is sent to the configured approval channel (Telegram, email, webhook, or chat)\n4. The operator replies \"OK\" to post it, sends edits to revise it, or \"skip\" to ignore it\n5. Decisions are logged so the agent can learn the operator's preferences over time\n\nNo reviews are ever posted without explicit operator approval.\n\n## What's Included\n\n- `SKILL.md` — Agent behavior instructions (configuration, approval flow, industry profiles, pattern learning)\n- `HEARTBEAT.md` — Periodic check instructions for OpenClaw's heartbeat system\n- `gbp_reviews.py` — Main script for checking reviews and posting replies\n- `get_client_token.py` — One-time OAuth helper for onboarding clients locally\n- `oauth_server.py` — Web-based OAuth flow for remote client onboarding\n- `clients/_template.json` — Config template for adding new clients\n- `SETUP.md` — Full setup and per-client onboarding guide\n\n## Quick Start\n\n1. Set up a Google Cloud project with the Business Profile API enabled (details in `SETUP.md`)\n2. Install dependencies: `pip install google-auth google-auth-oauthlib requests`\n3. Copy the `review-responder` folder into your OpenClaw workspace\n4. Create `review-responder.config.json` from the template in `SKILL.md`\n5. Register the skill in your `openclaw.json`\n6. Onboard your first client using `get_client_token.py` or `oauth_server.py`\n7. Wire up the scheduled check and you're live\n\nSee `SETUP.md` for the full walkthrough.\n\n## Requirements\n\n- Python 3 with `google-auth`, `google-auth-oauthlib`, `requests`\n- Flask (only if using the web-based OAuth onboarding server)\n- A Google Cloud project with OAuth 2.0 credentials\n- One approval channel configured: Telegram, email (SMTP), webhook endpoint, or in-thread chat\n\n## Permissions and Privacy (read before installing)\n\nUnlike most skills in this catalog, this one ships executable Python (`gbp_reviews.py`, `get_client_token.py`, `oauth_server.py`) that makes real network calls and posts content publicly to Google Business Profile. Read this section in full before installing or onboarding clients.\n\n**What runs on the network**\n\n- **Google Business Profile API v4** (`mybusiness.googleapis.com`): the skill polls reviews for each configured client and posts approved replies. Calls authenticate with the client's own OAuth credentials, which you obtain and store locally during onboarding.\n- **Google OAuth token endpoint** (`https://oauth2.googleapis.com/token`): standard refresh-token exchange.\n- **Whichever approval channel you configure**: Telegram (your bot, your chat), SMTP (your relay, your recipient), webhook (your endpoint), or in-thread chat (no network). The skill does not bundle credentials for any of these and does not route through any author-controlled service.\n\n**Credential storage**\n\n- Per-client OAuth credentials (`oauth_client_id`, `oauth_client_secret`, `refresh_token`) live in JSON files under `clients_dir` on your machine. These are your credentials for your own clients. The skill does not transmit them anywhere except to Google's token endpoint for the standard OAuth refresh flow.\n- Treat the `clients/` directory like you would any secrets folder: restrict filesystem permissions, do not commit it to public source control (the included `.gitignore` excludes it), and consider disk-level encryption.\n\n**Hard guardrails**\n\n- **No auto-posting.** Every reply requires explicit operator approval through your configured channel. The skill must not, and the assistant must not, post a reply without that approval.\n- **No PHI in public replies.** When a client is set to the `medical` industry profile, the assistant will never reference health conditions, treatments, or diagnoses in the public reply, even if the reviewer disclosed those details.\n- **No credential leakage.** The assistant will never quote, log, or include `oauth_client_secret` or `refresh_token` in approval messages, drafts, logs, or chat outputs.\n- **No bulk export.** The skill is for your ongoing review workflow, not for dumping consolidated client lists or review histories into external destinations.\n\n**Compliance scope (read this carefully if you serve regulated industries)**\n\nThe `medical` industry profile applies **HIPAA-aware drafting constraints** to the public reply text — it prevents the reply from referencing PHI. This is one input to a compliant workflow, not the whole workflow. The skill does NOT:\n\n- Certify your overall practice as HIPAA-compliant\n- Replace your Business Associate Agreement obligations (Google, OpenAI/Anthropic, and any other vendor in your pipeline have their own status)\n- Constitute legal advice for medical, legal, or financial regulated practices\n\nOperators in regulated industries remain responsible for their own compliance program and should review these constraints against their own policies before using this skill in production.\n\n**No telemetry**\n\nThe skill does not collect or transmit usage data, client identifiers, review content, or any other information back to its author, ClawHub, or any third party.\n\nFile v2.0.1:_meta.json\n\n{\n  \"ownerId\": \"kn77r9qjvh6fy4aja2km8bzgvd83khv9\",\n  \"slug\": \"google-review-responder\",\n  \"version\": \"2.0.1\",\n  \"publishedAt\": 1780960981193\n}\n\nFile v2.0.1:CHANGELOG.md\n\n# Changelog\n\nAll notable changes to this skill will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this skill adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n## [2.0.1] — 2026-06-08\n\n### Added\n- **Privacy and Data Handling** section in SKILL.md describing the real network surface (Google Business Profile API v4, Google OAuth token endpoint, configured approval channel), credential storage (operator-owned OAuth credentials per client in `clients_dir`), and hard guardrails (no auto-posting, no PHI in public replies, no credential leakage, no bulk export)\n- **Permissions and Privacy** section in README.md so operators see the full network surface, credential storage posture, hard guardrails, and the compliance scope (HIPAA-aware drafting, NOT a HIPAA-certified workflow) before installing\n\n### Changed\n- Reworded the `medical` industry profile from \"HIPAA-safe\" to \"HIPAA-aware drafting\" to accurately describe the constraint (avoids PHI in public reply text) without implying a regulatory certification this skill cannot provide. CHANGELOG references to \"HIPAA-safe\" updated in the 2.0.0 entry's description of this profile for consistency\n- Narrowed the activation triggers in the `description` frontmatter to require an explicit configured-client workflow (named client, named reviewer, specific approval/post action), with a \"do NOT trigger\" guardrail for casual review chat, review-writing requests, and marketing-strategy questions\n- Unquoted the `version` field in frontmatter (matches updated ClawHub CLI semver requirements)\n\n## [2.0.0] — 2026-05-12\n\n### Added\n- Configuration file (`review-responder.config.json`) for centralizing script paths, clients directory, approval channel, default industry, and memory file location\n- Per-client configuration overrides for industry, approval channel, and tone notes\n- Channel-agnostic approval flow with four supported channels: Telegram, email, webhook, and in-thread chat\n- Industry compliance profiles for medical (HIPAA-safe), legal, restaurant, retail, and general business types\n- Operator pattern learning layer that logs each approval decision (approved-as-is, edited with diff summary, skipped) per client and surfaces patterns over time\n- Periodic insight surfacing to the operator (e.g., \"you usually shorten 5-star replies for this client by ~10 words\")\n\n### Changed\n- **BREAKING**: Hardcoded script paths (`~/review-responder/gbp_reviews.py`) replaced with a configurable `script_path` field\n- **BREAKING**: Telegram is no longer the assumed approval channel; `approval_channel` must be set explicitly in config\n- HIPAA section promoted from a sub-block under Response Guidelines into a top-level `Industry Compliance Profiles` section with peer profiles for other industries\n- SKILL.md now has proper YAML frontmatter (`name`, `version`, `description`, `metadata.openclaw.emoji`)\n\n### Removed\n- MIT LICENSE file (license now managed at the ClawHub platform level)\n\n## [1.0.0] — 2026-03-27\n\n### Added\n- Initial release\n- Scheduled review checks across multiple Google Business Profile clients\n- Tone-matched response drafting by star rating (5, 4, 3, 1-2)\n- Telegram-based approval flow with OK/edit/skip operator commands\n- HIPAA-aware response guidance for medical clients\n- Per-client config files for multi-client agency use\n- OAuth onboarding helpers (`get_client_token.py`, `oauth_server.py`)\n\nFile v2.0.1:HEARTBEAT.md\n\n# Heartbeat: Review Responder\n\n## On Every Heartbeat\n\n1. Check for new unanswered Google Business reviews for each active client.\n   Run for each client configured in `~/review-responder/clients/`:\n   ```\n   python3 ~/review-responder/gbp_reviews.py check --client <client_id>\n   ```\n\n2. If the script finds new reviews, read the output carefully. For each new review:\n   - Draft a response following the guidelines in the Review Responder skill (SKILL.md)\n   - Send the draft to the operator via Telegram for approval\n   - Use the message format specified in SKILL.md\n\n3. If no new reviews are found for any client, reply HEARTBEAT_OK.\n\n## Important\n- Do NOT auto-post replies. Every response requires operator approval via Telegram.\n- If the script errors (missing config, API failure), report the error via Telegram so the operator can investigate.\n- Check `python3 ~/review-responder/gbp_reviews.py pending` to see if there are stale pending reviews that haven't been addressed. If any are older than 48 hours, send a reminder.\n\nFile v2.0.1:SETUP.md\n\n# Review Responder: Setup Guide\n\n## One-Time Setup (Your VPS)\n\n### 1. Install Python Dependencies\n```bash\npip install google-auth google-auth-oauthlib requests\n```\n\n### 2. Create a Google Cloud Project\n1. Go to https://console.cloud.google.com\n2. Create a new project (e.g., \"Review Responder\")\n3. Enable the **Google My Business API** (also called Business Profile API)\n4. Go to **Credentials** > **Create Credentials** > **OAuth 2.0 Client ID**\n5. Application type: **Desktop app**\n6. Save the **Client ID** and **Client Secret** -- you'll use these for every client\n\n### 3. Copy Files to OpenClaw Workspace\nCopy the `review-responder` folder into your OpenClaw agent workspace:\n```bash\ncp -r review-responder ~/.openclaw/workspace/review-responder\n```\n\n### 4. Register the Skill\nAdd the skill to your OpenClaw config (openclaw.json):\n```json\n{\n  \"skills\": {\n    \"entries\": {\n      \"review-responder\": {\n        \"path\": \"~/review-responder/SKILL.md\"\n      }\n    }\n  }\n}\n```\n\n### 5. Wire Up the Heartbeat\nAppend the review check instructions to your HEARTBEAT.md, or if you want a dedicated agent for this, reference `~/review-responder/HEARTBEAT.md` in your heartbeat config.\n\n### 6. Set Heartbeat Interval\nIn openclaw.json, set the heartbeat to run every 1-2 hours:\n```json\n{\n  \"agent\": {\n    \"heartbeat\": { \"every\": \"60m\" }\n  }\n}\n```\n\n---\n\n## Per-Client Onboarding\n\n### Step 1: Get Their Authorization\nYou need the client to authorize your app to access their Google Business Profile.\n\nRun this one-time script on your machine to generate a refresh token:\n```bash\npython3 get_client_token.py\n```\nThis will:\n1. Open a browser for the client to log in with their Google account\n2. Ask them to authorize access to their Business Profile\n3. Print a refresh token you save to their config file\n\n(See `get_client_token.py` for the helper script.)\n\n### Step 2: Find Their Account and Location IDs\nAfter authorization, use the access token to look up their IDs:\n```bash\n# List accounts\ncurl -H \"Authorization: Bearer ACCESS_TOKEN\" \\\n  \"https://mybusinessaccountmanagement.googleapis.com/v1/accounts\"\n\n# List locations for an account\ncurl -H \"Authorization: Bearer ACCESS_TOKEN\" \\\n  \"https://mybusinessbusinessinformation.googleapis.com/v1/accounts/ACCOUNT_ID/locations\"\n```\n\n### Step 3: Create Their Config File\nCopy the template and fill in the values:\n```bash\ncp clients/_template.json clients/joes-pizza.json\n```\n\nEdit with their specific values:\n```json\n{\n  \"business_name\": \"Joe's Pizza\",\n  \"account_id\": \"accounts/123456789\",\n  \"location_id\": \"locations/987654321\",\n  \"oauth_client_id\": \"YOUR_PROJECT_CLIENT_ID.apps.googleusercontent.com\",\n  \"oauth_client_secret\": \"YOUR_PROJECT_CLIENT_SECRET\",\n  \"refresh_token\": \"1//TOKEN_FROM_STEP_1\",\n  \"notes\": \"Family pizza place, casual and friendly tone\"\n}\n```\n\n### Step 4: Test It\n```bash\npython3 gbp_reviews.py check --client joes-pizza\n```\n\nIf it returns reviews (or \"No new unanswered reviews\"), you're good.\n\n---\n\n## OAuth Token Helper Script\n\nThe `get_client_token.py` script handles the one-time OAuth flow. Before running it, update the `CLIENT_ID` and `CLIENT_SECRET` variables at the top of the file with your Google Cloud project credentials.\n\nFor remote/web-based onboarding, see `oauth_server.py` instead (requires Flask).\n\n---\n\n## Folder Structure\n```\nreview-responder/\n  gbp_reviews.py          # Main script (check + reply)\n  get_client_token.py      # One-time OAuth helper\n  SKILL.md                 # Agent behavior instructions\n  HEARTBEAT.md             # Periodic check instructions\n  SETUP.md                 # This file\n  review_log.json          # Auto-generated: tracks processed reviews\n  clients/\n    _template.json         # Config template\n    joes-pizza.json        # Example client config\n  pending/\n    joes-pizza_abc123.json # Auto-generated: reviews awaiting approval\n```\n\nFile v2.0.1:skill-card.md\n\n## Description:\n\nMonitors Google Business Profile reviews for configured client accounts, drafts industry-aware replies, routes drafts for operator approval, and can post approved replies.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chris](https://clawhub.ai/user/chris)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nAgencies and consultants use this skill to manage review-response workflows for client businesses, including scheduled review checks, draft creation, approval routing, and posting only after explicit approval.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can store powerful Google credentials and publish public replies.\n\nMitigation: Use protected secret storage or 0600 credential files outside the repo, maintain a real .gitignore or secret-management workflow, and require explicit approval enforcement before posting.\n\nRisk: OAuth onboarding safeguards are weak or unenforced.\n\nMitigation: Use HTTPS-only OAuth onboarding with state validation before production or regulated-client use.\n\nRisk: Client identifiers, paths, review text, or approval text could be handled unsafely in operational commands.\n\nMitigation: Validate client IDs and paths strictly, and avoid command execution that interpolates review or approval text through a shell.\n\n## Reference(s):\n\n- [ClawHub Skill Page](https://clawhub.ai/chris/skills/google-review-responder)\n- [OpenClaw](https://openclaw.ai)\n- [Google Cloud Console](https://console.cloud.google.com)\n- [Google OAuth Token Endpoint](https://oauth2.googleapis.com/token)\n- [Google Business Profile Account Management API](https://mybusinessaccountmanagement.googleapis.com/v1/accounts)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown or plain text with JSON configuration and shell command snippets]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May create local pending-review JSON files, review logs, and approval-pattern memory files during operation.]\n\n## Skill Version(s):\n\n2.0.1 (source: server release evidence, frontmatter, README, CHANGELOG released 2026-06-08)\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 v2.0.1:clients/_template.json\n\n{\n  \"business_name\": \"Example Business LLC\",\n  \"account_id\": \"YOUR_GBP_ACCOUNT_ID\",\n  \"location_id\": \"YOUR_GBP_LOCATION_ID\",\n  \"oauth_client_id\": \"YOUR_GOOGLE_CLOUD_CLIENT_ID.apps.googleusercontent.com\",\n  \"oauth_client_secret\": \"YOUR_GOOGLE_CLOUD_CLIENT_SECRET\",\n  \"refresh_token\": \"YOUR_OAUTH_REFRESH_TOKEN\",\n  \"notes\": \"Optional notes about this client or their preferred tone\"\n}\n\nArchive v2.0.0: 11 files, 17934 bytes\n\nFiles: CHANGELOG.md (2083b), clients/_template.json (383b), gbp_reviews.py (8067b), get_client_token.py (1878b), HEARTBEAT.md (1032b), oauth_server.py (4892b), README.md (2897b), SETUP.md (3850b), skill-card.md (2588b), SKILL.md (11272b), _meta.json (142b)\n\nFile v2.0.0:SKILL.md\n\n---\nname: review-responder\nversion: \"2.0.0\"\ndescription: \"Use this skill when monitoring or responding to Google Business Profile reviews. Key triggers: 'check reviews,' 'new review came in,' 'draft a reply,' 'respond to that review,' 'approve the draft,' 'post the reply,' 'review approval,' 'Google review,' 'business profile review,' 'reply to a 5-star,' 'how do I handle a bad review,' 'HIPAA-safe review reply,' 'medical practice reviews,' or referencing a specific reviewer by name. Covers: scheduled review checks across multiple clients, tone-matched response drafting by star rating, channel-agnostic approval flow (Telegram, email, web dashboard, or in-thread chat), industry compliance profiles (medical/HIPAA, legal, restaurant, retail), and operator-pattern learning.\"\nmetadata:\n  openclaw:\n    emoji: ⭐\n---\n\n# Review Responder\n\nAutomatically monitors Google Business Profile reviews across one or more client accounts, drafts professional responses tuned to star rating and industry, and routes drafts to a configurable approval channel before posting. Designed for agencies and consultants managing reviews on behalf of clients.\n\n## Trigger\n\nThis skill activates during scheduled review checks (heartbeat) and when an operator responds to a pending review approval message.\n\n---\n\n## Configuration\n\nAll paths and channels are read from a single config file: `review-responder.config.json` in the skill's data directory. If it doesn't exist, create one from this template on first run:\n\n```json\n{\n  \"script_path\": \"~/review-responder/gbp_reviews.py\",\n  \"clients_dir\": \"~/review-responder/clients/\",\n  \"approval_channel\": \"telegram\",\n  \"telegram_chat_id\": \"\",\n  \"email_recipient\": \"\",\n  \"webhook_url\": \"\",\n  \"default_industry\": \"general\",\n  \"memory_file\": \"approval-patterns.json\"\n}\n```\n\n### Configuration fields\n\n- **script_path**: Absolute path to the `gbp_reviews.py` CLI. Defaults to `~/review-responder/gbp_reviews.py` but can live anywhere.\n- **clients_dir**: Directory containing per-client config files. Each client gets its own subdirectory or JSON entry.\n- **approval_channel**: One of `telegram`, `email`, `webhook`, or `chat`. Determines where draft replies are sent for approval. See Approval Channels below.\n- **default_industry**: Industry profile applied when a client doesn't specify one. See Industry Compliance Profiles below.\n- **memory_file**: Where to log approval patterns for the learning layer.\n\n### Per-client overrides\n\nEach client in `clients_dir` can override `industry`, `approval_channel`, and `tone_notes` (free-text guidance specific to that business). Example client config:\n\n```json\n{\n  \"client_id\": \"smithdental\",\n  \"business_name\": \"Smith Family Dental\",\n  \"industry\": \"medical\",\n  \"approval_channel\": \"email\",\n  \"email_recipient\": \"office@smithdental.com\",\n  \"tone_notes\": \"Dr. Smith is warm but understated. Avoid exclamation points.\"\n}\n```\n\n---\n\n## Review Check Flow (Heartbeat)\n\n1. Load `review-responder.config.json` and enumerate all clients in `clients_dir`.\n2. For each client, run:\n   ```\n   python3 {script_path} check --client {client_id}\n   ```\n3. For each new unanswered review:\n   - Apply the client's industry profile (or `default_industry` if none specified)\n   - Draft a response following the Response Guidelines and the industry profile's constraints\n   - Cross-reference against the approval-patterns memory file for operator-specific adjustments (e.g., if the operator consistently shortens 5-star replies for this client, default to shorter)\n4. Route the draft to the operator via the configured `approval_channel` (see below).\n5. Do NOT post the reply automatically. Wait for operator approval.\n\n---\n\n## Approval Channels\n\nThe approval message format stays consistent across channels; only the delivery method changes.\n\n### Standard approval message\n\n```\n📝 New Review for [Business Name]\n\n⭐ [star_rating] from [reviewer_name]\n💬 \"[review comment]\"\n\nMy draft reply:\n\"[your drafted response]\"\n\nReply OK to post, or send your edits.\n(Review ID: [review_id] | Client: [client_id])\n```\n\n### Telegram (`approval_channel: telegram`)\nSend the message to the configured `telegram_chat_id`. The operator replies in the Telegram thread.\n\n### Email (`approval_channel: email`)\nSend the message as a plain-text email to `email_recipient`. Subject line: `Review approval needed — [Business Name]`. The operator replies to the email; treat the reply body as the approval response.\n\n### Webhook (`approval_channel: webhook`)\nPOST a JSON payload to `webhook_url` containing the review draft and metadata. Useful for custom dashboards or Slack relays. Expected response: `{ \"decision\": \"approve\" | \"edit\" | \"skip\", \"edited_text\": \"...\" }`.\n\n### Chat (`approval_channel: chat`)\nSurface the draft directly in the current chat session. Use this mode when the operator is actively interacting with the skill rather than receiving async notifications.\n\n---\n\n## Approval Flow\n\nWhen the operator responds to a draft (via any channel):\n\n- **\"OK\"**, **\"post it\"**, **\"send it\"**, **\"approved\"**: Post the draft as-is:\n  ```\n  python3 {script_path} reply --client {client_id} --review {review_id} --reply \"{approved response}\"\n  ```\n  Confirm once posted: \"Done — reply posted for [reviewer_name]'s review.\"\n  Log to the memory file as `approved_as_is`.\n\n- **Edited text**: Treat any reply that isn't a recognized approval/skip keyword as replacement text. Confirm before posting: \"Got it — posting your version now.\" Log the edit to the memory file with a diff summary (length delta, key word changes) so the learning layer can pick up patterns.\n\n- **\"Skip\"**, **\"ignore\"**, **\"don't reply\"**: Do not reply to that review. Remove it from pending. Log as `skipped`.\n\n---\n\n## Response Guidelines\n\n### Tone principles\n- Warm, professional, and human — not corporate or robotic\n- Specific to what the reviewer said (never generic \"thanks for your review!\")\n- Concise: 2-4 sentences max\n- Match the energy of the review without being over the top\n- Layer in any `tone_notes` from the client config\n\n### By star rating\n\n**5 stars**\n- Thank them warmly and reference something specific they mentioned\n- Reinforce what they loved (\"We're glad [specific thing] made a difference\")\n- End with a light invitation to return or share with others\n- Keep it brief; don't overdo it on a great review\n\n**4 stars**\n- Thank them and acknowledge specific positives\n- If they mentioned something that could improve, acknowledge it gracefully without being defensive\n- Show you're listening: \"We appreciate the feedback on [topic] and are always looking to improve\"\n\n**3 stars**\n- Thank them for taking the time\n- Acknowledge both the positives and the concern\n- Show genuine interest in making it right: \"We'd love the chance to do better next time\"\n- Optionally invite them to reach out directly\n\n**1-2 stars**\n- Lead with empathy, not defensiveness: \"We're sorry to hear this wasn't the experience you deserved\"\n- Acknowledge the specific issue without making excuses\n- Offer a path forward: invite them to contact the business directly\n- Keep it short and dignified; do not argue or over-explain\n- Never blame the reviewer or question their experience\n\n---\n\n## Industry Compliance Profiles\n\nIndustry profiles enforce constraints and tone defaults appropriate to specific business types. Apply the profile from the client config (or `default_industry`) on every draft.\n\n### `medical` (HIPAA-safe)\n\n**Hard rules** (never violate, regardless of star rating):\n- NEVER reference or confirm any medical conditions, diagnoses, treatments, medications, procedures, or health details, even if the reviewer mentioned them publicly\n- NEVER confirm or deny that someone is or was a patient\n- Keep responses general: \"your experience,\" \"your visit,\" \"your care\" — not \"your diagnosis\" or \"your treatment\"\n- If the reviewer shared health details, respond to the sentiment and experience only\n- When inviting follow-up, use \"please contact our office\" — never suggest discussing their \"case\" or \"medical records\"\n\n**Tone defaults**: professional, reassuring, brief.\n\n### `legal`\n\n**Hard rules**:\n- Never confirm or discuss case details, legal advice, or attorney-client relationships\n- Never speculate about outcomes or imply guarantees\n- Avoid language that could be interpreted as a new attorney-client communication\n- For dissatisfied reviewers, direct them to the firm's office line rather than offering legal commentary\n\n**Tone defaults**: measured, professional, no flourishes.\n\n### `restaurant`\n\n**Hard rules**: none specific, but stay grounded.\n\n**Tone defaults**: warmer and more conversational than medical/legal. Food-specific callouts welcome (\"glad the carbonara hit\"). For complaints, offer a direct contact for the manager.\n\n### `retail`\n\n**Hard rules**:\n- Don't speculate about specific products or stock issues you can't verify\n- For return/refund disputes, direct to customer service, not public dialogue\n\n**Tone defaults**: friendly, helpful, solution-oriented.\n\n### `general`\n\nNo industry-specific constraints. Fall back to base Tone Principles and By Star Rating guidance.\n\n---\n\n## Approval Pattern Learning\n\nLog each approval interaction to the memory file (`memory_file` in config). Use the log to surface patterns and adjust future drafts.\n\n### What to log per review\n\n```json\n{\n  \"client_id\": \"smithdental\",\n  \"review_id\": \"abc123\",\n  \"stars\": 5,\n  \"draft\": \"Thank you, Maria...\",\n  \"decision\": \"edited\",\n  \"final\": \"Thanks Maria...\",\n  \"length_delta_words\": -8,\n  \"timestamp\": \"2026-03-20T14:22:00Z\"\n}\n```\n\n### How to apply patterns\n\nBefore drafting any new reply, scan the log for the same client and look for trends across the last 10-20 interactions:\n\n- If `length_delta_words` is consistently negative for a given star rating, default to shorter drafts for that client at that rating\n- If certain words/phrases are routinely stripped (e.g., \"incredibly\", \"truly\"), avoid them on future drafts for that client\n- If the operator consistently skips 1-star reviews from anonymous reviewers, surface that as a default rather than drafting one\n\nSurface insights to the operator periodically (e.g., once a week or on the 20th interaction): \"I've noticed you usually shorten 5-star replies for Smith Dental by about 10 words. Want me to default to shorter going forward?\"\n\n---\n\n## Checking Pending Reviews\n\nTo see what's waiting for approval:\n```\npython3 {script_path} pending\n```\n\n---\n\n## Things to Avoid\n\n- Generic filler: \"We value all our customers,\" \"Your feedback is important to us\"\n- Mentioning the star rating directly: \"Thanks for the 5 stars!\"\n- Being defensive about negative reviews\n- Making promises the business can't keep\n- Using the reviewer's full name unless they used it in their review\n- Emojis (unless the business brand is very casual and the operator approves it)\n- Violating the active industry profile's hard rules under any circumstance\n\n---\n\n## Dependencies\n\n- Python 3 with: `google-auth`, `google-auth-oauthlib`, `requests`\n- Client config files in the directory specified by `clients_dir`\n- For Telegram: a Telegram channel/chat configured and a working bot token\n- For email: SMTP credentials or a relay\n- For webhook: an HTTPS endpoint that accepts POST and returns the decision JSON\n\nFile v2.0.0:README.md\n\n# Review Responder\n\nAn [OpenClaw](https://openclaw.ai) skill that monitors Google Business Profile reviews, drafts professional responses, and routes them to a configurable approval channel before posting.\n\nBuilt for consultants and agencies managing reviews across multiple client locations and industries.\n\n**Current version: 2.0.0**\n\n## What's new in 2.0.0\n\n- **Configurable script paths and channels** via a single `review-responder.config.json` file\n- **Channel-agnostic approval flow**: Telegram, email, webhook, or in-thread chat\n- **Industry compliance profiles**: medical (HIPAA-safe), legal, restaurant, retail, and general\n- **Operator pattern learning**: logs approval decisions per client and surfaces patterns (e.g., \"you usually shorten 5-star replies for this client\")\n- **Per-client overrides** for industry, approval channel, and tone notes\n\nSee [CHANGELOG.md](CHANGELOG.md) for the full release history.\n\n## How It Works\n\n1. On each scheduled check, OpenClaw enumerates configured clients and looks for new unanswered reviews\n2. For each new review, the agent applies the client's industry profile and drafts a tone-matched response\n3. The draft is sent to the configured approval channel (Telegram, email, webhook, or chat)\n4. The operator replies \"OK\" to post it, sends edits to revise it, or \"skip\" to ignore it\n5. Decisions are logged so the agent can learn the operator's preferences over time\n\nNo reviews are ever posted without explicit operator approval.\n\n## What's Included\n\n- `SKILL.md` — Agent behavior instructions (configuration, approval flow, industry profiles, pattern learning)\n- `HEARTBEAT.md` — Periodic check instructions for OpenClaw's heartbeat system\n- `gbp_reviews.py` — Main script for checking reviews and posting replies\n- `get_client_token.py` — One-time OAuth helper for onboarding clients locally\n- `oauth_server.py` — Web-based OAuth flow for remote client onboarding\n- `clients/_template.json` — Config template for adding new clients\n- `SETUP.md` — Full setup and per-client onboarding guide\n\n## Quick Start\n\n1. Set up a Google Cloud project with the Business Profile API enabled (details in `SETUP.md`)\n2. Install dependencies: `pip install google-auth google-auth-oauthlib requests`\n3. Copy the `review-responder` folder into your OpenClaw workspace\n4. Create `review-responder.config.json` from the template in `SKILL.md`\n5. Register the skill in your `openclaw.json`\n6. Onboard your first client using `get_client_token.py` or `oauth_server.py`\n7. Wire up the scheduled check and you're live\n\nSee `SETUP.md` for the full walkthrough.\n\n## Requirements\n\n- Python 3 with `google-auth`, `google-auth-oauthlib`, `requests`\n- Flask (only if using the web-based OAuth onboarding server)\n- A Google Cloud project with OAuth 2.0 credentials\n- One approval channel configured: Telegram, email (SMTP), webhook endpoint, or in-thread chat\n\nFile v2.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn77r9qjvh6fy4aja2km8bzgvd83khv9\",\n  \"slug\": \"google-review-responder\",\n  \"version\": \"2.0.0\",\n  \"publishedAt\": 1778631833046\n}\n\nFile v2.0.0:CHANGELOG.md\n\n# Changelog\n\nAll notable changes to this skill will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this skill adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n## [2.0.0] — 2026-05-12\n\n### Added\n- Configuration file (`review-responder.config.json`) for centralizing script paths, clients directory, approval channel, default industry, and memory file location\n- Per-client configuration overrides for industry, approval channel, and tone notes\n- Channel-agnostic approval flow with four supported channels: Telegram, email, webhook, and in-thread chat\n- Industry compliance profiles for medical (HIPAA-safe), legal, restaurant, retail, and general business types\n- Operator pattern learning layer that logs each approval decision (approved-as-is, edited with diff summary, skipped) per client and surfaces patterns over time\n- Periodic insight surfacing to the operator (e.g., \"you usually shorten 5-star replies for this client by ~10 words\")\n\n### Changed\n- **BREAKING**: Hardcoded script paths (`~/review-responder/gbp_reviews.py`) replaced with a configurable `script_path` field\n- **BREAKING**: Telegram is no longer the assumed approval channel; `approval_channel` must be set explicitly in config\n- HIPAA section promoted from a sub-block under Response Guidelines into a top-level `Industry Compliance Profiles` section with peer profiles for other industries\n- SKILL.md now has proper YAML frontmatter (`name`, `version`, `description`, `metadata.openclaw.emoji`)\n\n### Removed\n- MIT LICENSE file (license now managed at the ClawHub platform level)\n\n## [1.0.0] — 2026-03-27\n\n### Added\n- Initial release\n- Scheduled review checks across multiple Google Business Profile clients\n- Tone-matched response drafting by star rating (5, 4, 3, 1-2)\n- Telegram-based approval flow with OK/edit/skip operator commands\n- HIPAA-aware response guidance for medical clients\n- Per-client config files for multi-client agency use\n- OAuth onboarding helpers (`get_client_token.py`, `oauth_server.py`)\n\nFile v2.0.0:HEARTBEAT.md\n\n# Heartbeat: Review Responder\n\n## On Every Heartbeat\n\n1. Check for new unanswered Google Business reviews for each active client.\n   Run for each client configured in `~/review-responder/clients/`:\n   ```\n   python3 ~/review-responder/gbp_reviews.py check --client <client_id>\n   ```\n\n2. If the script finds new reviews, read the output carefully. For each new review:\n   - Draft a response following the guidelines in the Review Responder skill (SKILL.md)\n   - Send the draft to the operator via Telegram for approval\n   - Use the message format specified in SKILL.md\n\n3. If no new reviews are found for any client, reply HEARTBEAT_OK.\n\n## Important\n- Do NOT auto-post replies. Every response requires operator approval via Telegram.\n- If the script errors (missing config, API failure), report the error via Telegram so the operator can investigate.\n- Check `python3 ~/review-responder/gbp_reviews.py pending` to see if there are stale pending reviews that haven't been addressed. If any are older than 48 hours, send a reminder.\n\nFile v2.0.0:SETUP.md\n\n# Review Responder: Setup Guide\n\n## One-Time Setup (Your VPS)\n\n### 1. Install Python Dependencies\n```bash\npip install google-auth google-auth-oauthlib requests\n```\n\n### 2. Create a Google Cloud Project\n1. Go to https://console.cloud.google.com\n2. Create a new project (e.g., \"Review Responder\")\n3. Enable the **Google My Business API** (also called Business Profile API)\n4. Go to **Credentials** > **Create Credentials** > **OAuth 2.0 Client ID**\n5. Application type: **Desktop app**\n6. Save the **Client ID** and **Client Secret** -- you'll use these for every client\n\n### 3. Copy Files to OpenClaw Workspace\nCopy the `review-responder` folder into your OpenClaw agent workspace:\n```bash\ncp -r review-responder ~/.openclaw/workspace/review-responder\n```\n\n### 4. Register the Skill\nAdd the skill to your OpenClaw config (openclaw.json):\n```json\n{\n  \"skills\": {\n    \"entries\": {\n      \"review-responder\": {\n        \"path\": \"~/review-responder/SKILL.md\"\n      }\n    }\n  }\n}\n```\n\n### 5. Wire Up the Heartbeat\nAppend the review check instructions to your HEARTBEAT.md, or if you want a dedicated agent for this, reference `~/review-responder/HEARTBEAT.md` in your heartbeat config.\n\n### 6. Set Heartbeat Interval\nIn openclaw.json, set the heartbeat to run every 1-2 hours:\n```json\n{\n  \"agent\": {\n    \"heartbeat\": { \"every\": \"60m\" }\n  }\n}\n```\n\n---\n\n## Per-Client Onboarding\n\n### Step 1: Get Their Authorization\nYou need the client to authorize your app to access their Google Business Profile.\n\nRun this one-time script on your machine to generate a refresh token:\n```bash\npython3 get_client_token.py\n```\nThis will:\n1. Open a browser for the client to log in with their Google account\n2. Ask them to authorize access to their Business Profile\n3. Print a refresh token you save to their config file\n\n(See `get_client_token.py` for the helper script.)\n\n### Step 2: Find Their Account and Location IDs\nAfter authorization, use the access token to look up their IDs:\n```bash\n# List accounts\ncurl -H \"Authorization: Bearer ACCESS_TOKEN\" \\\n  \"https://mybusinessaccountmanagement.googleapis.com/v1/accounts\"\n\n# List locations for an account\ncurl -H \"Authorization: Bearer ACCESS_TOKEN\" \\\n  \"https://mybusinessbusinessinformation.googleapis.com/v1/accounts/ACCOUNT_ID/locations\"\n```\n\n### Step 3: Create Their Config File\nCopy the template and fill in the values:\n```bash\ncp clients/_template.json clients/joes-pizza.json\n```\n\nEdit with their specific values:\n```json\n{\n  \"business_name\": \"Joe's Pizza\",\n  \"account_id\": \"accounts/123456789\",\n  \"location_id\": \"locations/987654321\",\n  \"oauth_client_id\": \"YOUR_PROJECT_CLIENT_ID.apps.googleusercontent.com\",\n  \"oauth_client_secret\": \"YOUR_PROJECT_CLIENT_SECRET\",\n  \"refresh_token\": \"1//TOKEN_FROM_STEP_1\",\n  \"notes\": \"Family pizza place, casual and friendly tone\"\n}\n```\n\n### Step 4: Test It\n```bash\npython3 gbp_reviews.py check --client joes-pizza\n```\n\nIf it returns reviews (or \"No new unanswered reviews\"), you're good.\n\n---\n\n## OAuth Token Helper Script\n\nThe `get_client_token.py` script handles the one-time OAuth flow. Before running it, update the `CLIENT_ID` and `CLIENT_SECRET` variables at the top of the file with your Google Cloud project credentials.\n\nFor remote/web-based onboarding, see `oauth_server.py` instead (requires Flask).\n\n---\n\n## Folder Structure\n```\nreview-responder/\n  gbp_reviews.py          # Main script (check + reply)\n  get_client_token.py      # One-time OAuth helper\n  SKILL.md                 # Agent behavior instructions\n  HEARTBEAT.md             # Periodic check instructions\n  SETUP.md                 # This file\n  review_log.json          # Auto-generated: tracks processed reviews\n  clients/\n    _template.json         # Config template\n    joes-pizza.json        # Example client config\n  pending/\n    joes-pizza_abc123.json # Auto-generated: reviews awaiting approval\n```\n\nFile v2.0.0:skill-card.md\n\n## Description: <br>\nReview Responder monitors Google Business Profile reviews, drafts professional responses by star rating and industry profile, and routes drafts through operator approval before posting. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[chris-openclaw](https://clawhub.ai/user/chris-openclaw) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nExternal consultants and agencies use this skill to monitor client Google Business Profile reviews, draft compliant replies, route them for human approval, and post only approved responses. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill stores long-lived Google credentials and review data locally. <br>\nMitigation: Keep client JSON files out of source control, restrict filesystem permissions, and prefer a secret manager or encrypted storage. <br>\nRisk: Review details may be routed through Telegram, email, webhook, or chat approval channels. <br>\nMitigation: Use approval channels that meet the business's privacy and compliance needs, especially for medical, legal, or regulated reviews. <br>\nRisk: OAuth onboarding can expose sensitive credentials if hosted insecurely. <br>\nMitigation: Use HTTPS for remote OAuth onboarding and secure the host before granting persistent Google Business Profile access. <br>\n\n\n## Reference(s): <br>\n- [ClawHub Skill Page](https://clawhub.ai/chris-openclaw/google-review-responder) <br>\n- [OpenClaw](https://openclaw.ai) <br>\n- [Google Cloud Console](https://console.cloud.google.com) <br>\n- [Google Business Profile OAuth Scope](https://www.googleapis.com/auth/business.manage) <br>\n- [Google Business Profile API](https://mybusiness.googleapis.com/v4/) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown and plain text with inline shell commands and JSON configuration snippets] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Outputs include drafted review replies, approval messages, setup guidance, and commands for checking pending reviews or posting approved replies.] <br>\n\n## Skill Version(s): <br>\n2.0.0 (source: frontmatter, changelog, release evidence) <br>\n\n## Ethical Considerations: <br>\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. <br>\n\nFile v2.0.0:clients/_template.json\n\n{\n  \"business_name\": \"Example Business LLC\",\n  \"account_id\": \"YOUR_GBP_ACCOUNT_ID\",\n  \"location_id\": \"YOUR_GBP_LOCATION_ID\",\n  \"oauth_client_id\": \"YOUR_GOOGLE_CLOUD_CLIENT_ID.apps.googleusercontent.com\",\n  \"oauth_client_secret\": \"YOUR_GOOGLE_CLOUD_CLIENT_SECRET\",\n  \"refresh_token\": \"YOUR_OAUTH_REFRESH_TOKEN\",\n  \"notes\": \"Optional notes about this client or their preferred tone\"\n}\n\nArchive v1.0.0: 9 files, 12290 bytes\n\nFiles: clients/_template.json (383b), gbp_reviews.py (8067b), get_client_token.py (1878b), HEARTBEAT.md (1032b), oauth_server.py (4892b), README.md (2031b), SETUP.md (3850b), SKILL.md (4587b), _meta.json (142b)\n\nFile v1.0.0:SKILL.md\n\n# Skill: Google Business Review Responder\n\n## Description\nAutomatically monitors Google Business Profile reviews for clients, drafts professional responses, and sends them via Telegram for approval before posting.\n\n## Trigger\nThis skill activates during heartbeat checks and when the operator replies to a review approval message.\n\n---\n\n## Review Check Flow (Heartbeat)\n\n1. Run the review check script for each configured client:\n   ```\n   python3 ~/review-responder/gbp_reviews.py check --client <client_id>\n   ```\n2. For each new unanswered review found, draft a response following the Response Guidelines below.\n3. Send the draft to the operator via Telegram in this format:\n\n```\n📝 New Review for [Business Name]\n\n⭐ [star_rating] from [reviewer_name]\n💬 \"[review comment]\"\n\nMy draft reply:\n\"[your drafted response]\"\n\nReply OK to post, or send your edits.\n(Review ID: [review_id] | Client: [client_id])\n```\n\n4. Do NOT post the reply automatically. Wait for operator approval.\n\n---\n\n## Approval Flow (Chat)\n\nWhen the operator replies to a review draft:\n\n- **\"OK\"** or **\"post it\"** or **\"send it\"** or **\"approved\"**: Post the draft as-is using:\n  ```\n  python3 ~/review-responder/gbp_reviews.py reply --client <client_id> --review <review_id> --reply \"the approved response\"\n  ```\n  Confirm once posted: \"Done -- reply posted for [reviewer_name]'s review.\"\n\n- **Edited text**: If the operator sends replacement text (anything that isn't a simple approval), use their text as the reply instead. Confirm before posting: \"Got it -- posting your version now.\"\n\n- **\"Skip\"** or **\"ignore\"**: Do not reply to that review. Remove it from pending.\n\n---\n\n## Response Guidelines\n\n### Tone Principles\n- Warm, professional, and human -- not corporate or robotic\n- Specific to what the reviewer said (never generic \"thanks for your review!\")\n- Concise: 2-4 sentences max\n- Match the energy of the review without being over the top\n\n### By Star Rating\n\n**5 Stars:**\n- Thank them warmly and reference something specific they mentioned\n- Reinforce what they loved (\"We're glad [specific thing] made a difference\")\n- End with a light invitation to return or share with others\n- Keep it brief -- don't overdo it on a great review\n\n**4 Stars:**\n- Thank them and acknowledge specific positives\n- If they mentioned something that could improve, acknowledge it gracefully without being defensive\n- Show you're listening: \"We appreciate the feedback on [topic] and are always looking to improve\"\n\n**3 Stars:**\n- Thank them for taking the time\n- Acknowledge both the positives and the concern\n- Show genuine interest in making it right: \"We'd love the chance to do better next time\"\n- Optionally invite them to reach out directly\n\n**1-2 Stars:**\n- Lead with empathy, not defensiveness: \"We're sorry to hear this wasn't the experience you deserved\"\n- Acknowledge the specific issue without making excuses\n- Offer a path forward: invite them to contact the business directly\n- Keep it short and dignified -- do not argue or over-explain\n- Never blame the reviewer or question their experience\n\n### HIPAA Compliance (CRITICAL)\n- NEVER reference or confirm any medical conditions, diagnoses, treatments, medications, or health details -- even if the reviewer mentioned them in their review\n- NEVER confirm or deny that someone is or was a patient\n- Keep responses general: \"your experience,\" \"your visit,\" \"your care\" -- not \"your diagnosis\" or \"your treatment\"\n- If a reviewer shares health details in their review, do NOT reference those specifics in the reply. Respond to the sentiment and experience only.\n- When inviting someone to follow up, use \"please contact our office\" -- never suggest discussing their \"case\" or \"medical records\"\n- This applies to ALL star ratings, positive and negative\n\n### Things to Avoid\n- Generic filler: \"We value all our customers\" / \"Your feedback is important to us\"\n- Mentioning the star rating directly: \"Thanks for the 5 stars!\"\n- Being defensive about negative reviews\n- Making promises the business can't keep\n- Using the reviewer's full name unless they used it in their review\n- Emojis (unless the business brand is very casual and the operator approves it)\n- Referencing any health information, even if the patient shared it publicly (HIPAA)\n\n---\n\n## Checking Pending Reviews\n\nTo see what's waiting for approval:\n```\npython3 ~/review-responder/gbp_reviews.py pending\n```\n\n---\n\n## Dependencies\n- Python 3 with: google-auth, google-auth-oauthlib, requests\n- Client config files in `~/review-responder/clients/`\n- Telegram channel connected for approval messages\n\nFile v1.0.0:README.md\n\n# Google Business Review Responder\n\nAn [OpenClaw](https://openclaw.ai) skill that monitors Google Business Profile reviews, drafts professional responses, and sends them to you via Telegram for approval before posting.\n\nBuilt for consultants and agencies managing reviews across multiple client locations.\n\n## How It Works\n\n1. On each heartbeat, OpenClaw checks for new unanswered reviews across your configured clients\n2. For each new review, your agent drafts a response following tone and compliance guidelines (including HIPAA)\n3. The draft is sent to you on Telegram for approval\n4. You reply \"OK\" to post it, send edits to revise it, or \"skip\" to ignore it\n\nNo reviews are ever posted without your explicit approval.\n\n## What's Included\n\n- `SKILL.md` - Agent behavior instructions (response guidelines, approval flow, HIPAA rules)\n- `HEARTBEAT.md` - Periodic check instructions for OpenClaw's heartbeat system\n- `gbp_reviews.py` - Main script for checking reviews and posting replies\n- `get_client_token.py` - One-time OAuth helper for onboarding clients locally\n- `oauth_server.py` - Web-based OAuth flow for remote client onboarding\n- `clients/_template.json` - Config template for adding new clients\n- `SETUP.md` - Full setup and per-client onboarding guide\n\n## Quick Start\n\n1. Set up a Google Cloud project with the Business Profile API enabled (details in `SETUP.md`)\n2. Install dependencies: `pip install google-auth google-auth-oauthlib requests`\n3. Copy the `review-responder` folder into your OpenClaw workspace\n4. Register the skill in your `openclaw.json`\n5. Onboard your first client using `get_client_token.py` or `oauth_server.py`\n6. Wire up the heartbeat and you're live\n\nSee `SETUP.md` for the full walkthrough.\n\n## Requirements\n\n- Python 3 with `google-auth`, `google-auth-oauthlib`, `requests`\n- Flask (only if using the web-based OAuth onboarding server)\n- A Google Cloud project with OAuth 2.0 credentials\n- OpenClaw with a Telegram channel connected\n\n## License\n\nMIT. See [LICENSE](LICENSE) for details.\n\nFile v1.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn77r9qjvh6fy4aja2km8bzgvd83khv9\",\n  \"slug\": \"google-review-responder\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1775998396450\n}\n\nFile v1.0.0:HEARTBEAT.md\n\n# Heartbeat: Review Responder\n\n## On Every Heartbeat\n\n1. Check for new unanswered Google Business reviews for each active client.\n   Run for each client configured in `~/review-responder/clients/`:\n   ```\n   python3 ~/review-responder/gbp_reviews.py check --client <client_id>\n   ```\n\n2. If the script finds new reviews, read the output carefully. For each new review:\n   - Draft a response following the guidelines in the Review Responder skill (SKILL.md)\n   - Send the draft to the operator via Telegram for approval\n   - Use the message format specified in SKILL.md\n\n3. If no new reviews are found for any client, reply HEARTBEAT_OK.\n\n## Important\n- Do NOT auto-post replies. Every response requires operator approval via Telegram.\n- If the script errors (missing config, API failure), report the error via Telegram so the operator can investigate.\n- Check `python3 ~/review-responder/gbp_reviews.py pending` to see if there are stale pending reviews that haven't been addressed. If any are older than 48 hours, send a reminder.\n\nFile v1.0.0:SETUP.md\n\n# Review Responder: Setup Guide\n\n## One-Time Setup (Your VPS)\n\n### 1. Install Python Dependencies\n```bash\npip install google-auth google-auth-oauthlib requests\n```\n\n### 2. Create a Google Cloud Project\n1. Go to https://console.cloud.google.com\n2. Create a new project (e.g., \"Review Responder\")\n3. Enable the **Google My Business API** (also called Business Profile API)\n4. Go to **Credentials** > **Create Credentials** > **OAuth 2.0 Client ID**\n5. Application type: **Desktop app**\n6. Save the **Client ID** and **Client Secret** -- you'll use these for every client\n\n### 3. Copy Files to OpenClaw Workspace\nCopy the `review-responder` folder into your OpenClaw agent workspace:\n```bash\ncp -r review-responder ~/.openclaw/workspace/review-responder\n```\n\n### 4. Register the Skill\nAdd the skill to your OpenClaw config (openclaw.json):\n```json\n{\n  \"skills\": {\n    \"entries\": {\n      \"review-responder\": {\n        \"path\": \"~/review-responder/SKILL.md\"\n      }\n    }\n  }\n}\n```\n\n### 5. Wire Up the Heartbeat\nAppend the review check instructions to your HEARTBEAT.md, or if you want a dedicated agent for this, reference `~/review-responder/HEARTBEAT.md` in your heartbeat config.\n\n### 6. Set Heartbeat Interval\nIn openclaw.json, set the heartbeat to run every 1-2 hours:\n```json\n{\n  \"agent\": {\n    \"heartbeat\": { \"every\": \"60m\" }\n  }\n}\n```\n\n---\n\n## Per-Client Onboarding\n\n### Step 1: Get Their Authorization\nYou need the client to authorize your app to access their Google Business Profile.\n\nRun this one-time script on your machine to generate a refresh token:\n```bash\npython3 get_client_token.py\n```\nThis will:\n1. Open a browser for the client to log in with their Google account\n2. Ask them to authorize access to their Business Profile\n3. Print a refresh token you save to their config file\n\n(See `get_client_token.py` for the helper script.)\n\n### Step 2: Find Their Account and Location IDs\nAfter authorization, use the access token to look up their IDs:\n```bash\n# List accounts\ncurl -H \"Authorization: Bearer ACCESS_TOKEN\" \\\n  \"https://mybusinessaccountmanagement.googleapis.com/v1/accounts\"\n\n# List locations for an account\ncurl -H \"Authorization: Bearer ACCESS_TOKEN\" \\\n  \"https://mybusinessbusinessinformation.googleapis.com/v1/accounts/ACCOUNT_ID/locations\"\n```\n\n### Step 3: Create Their Config File\nCopy the template and fill in the values:\n```bash\ncp clients/_template.json clients/joes-pizza.json\n```\n\nEdit with their specific values:\n```json\n{\n  \"business_name\": \"Joe's Pizza\",\n  \"account_id\": \"accounts/123456789\",\n  \"location_id\": \"locations/987654321\",\n  \"oauth_client_id\": \"YOUR_PROJECT_CLIENT_ID.apps.googleusercontent.com\",\n  \"oauth_client_secret\": \"YOUR_PROJECT_CLIENT_SECRET\",\n  \"refresh_token\": \"1//TOKEN_FROM_STEP_1\",\n  \"notes\": \"Family pizza place, casual and friendly tone\"\n}\n```\n\n### Step 4: Test It\n```bash\npython3 gbp_reviews.py check --client joes-pizza\n```\n\nIf it returns reviews (or \"No new unanswered reviews\"), you're good.\n\n---\n\n## OAuth Token Helper Script\n\nThe `get_client_token.py` script handles the one-time OAuth flow. Before running it, update the `CLIENT_ID` and `CLIENT_SECRET` variables at the top of the file with your Google Cloud project credentials.\n\nFor remote/web-based onboarding, see `oauth_server.py` instead (requires Flask).\n\n---\n\n## Folder Structure\n```\nreview-responder/\n  gbp_reviews.py          # Main script (check + reply)\n  get_client_token.py      # One-time OAuth helper\n  SKILL.md                 # Agent behavior instructions\n  HEARTBEAT.md             # Periodic check instructions\n  SETUP.md                 # This file\n  review_log.json          # Auto-generated: tracks processed reviews\n  clients/\n    _template.json         # Config template\n    joes-pizza.json        # Example client config\n  pending/\n    joes-pizza_abc123.json # Auto-generated: reviews awaiting approval\n```\n\nFile v1.0.0:clients/_template.json\n\n{\n  \"business_name\": \"Example Business LLC\",\n  \"account_id\": \"YOUR_GBP_ACCOUNT_ID\",\n  \"location_id\": \"YOUR_GBP_LOCATION_ID\",\n  \"oauth_client_id\": \"YOUR_GOOGLE_CLOUD_CLIENT_ID.apps.googleusercontent.com\",\n  \"oauth_client_secret\": \"YOUR_GOOGLE_CLOUD_CLIENT_SECRET\",\n  \"refresh_token\": \"YOUR_OAUTH_REFRESH_TOKEN\",\n  \"notes\": \"Optional notes about this client or their preferred tone\"\n}","readmeExcerpt":"Skill: Review Responder Owner: chris Summary: Use this skill when an operator is actively running the Google Business Profile review-response workflow for one of their configured client accounts. Specific triggers: 'check for new reviews,' 'run the review check for [client],' 'new review came in for [client],' 'draft a reply to the [reviewer] r Tags: business-profile:1.0.0, gbp:1.0.0, google:1.0.0, hipaa:1.0.0, lates","codeSnippets":[],"executableExamples":[{"language":"json","snippet":"{\n  \"script_path\": \"~/review-responder/gbp_reviews.py\",\n  \"clients_dir\": \"~/review-responder/clients/\",\n  \"approval_channel\": \"telegram\",\n  \"telegram_chat_id\": \"\",\n  \"email_recipient\": \"\",\n  \"webhook_url\": \"\",\n  \"default_industry\": \"general\",\n  \"memory_file\": \"approval-patterns.json\"\n}"},{"language":"json","snippet":"{\n  \"client_id\": \"smithdental\",\n  \"business_name\": \"Smith Family Dental\",\n  \"industry\": \"medical\",\n  \"approval_channel\": \"email\",\n  \"email_recipient\": \"office@smithdental.com\",\n  \"tone_notes\": \"Dr. Smith is warm but understated. Avoid exclamation points.\"\n}"},{"language":"text","snippet":"python3 {script_path} check --client {client_id}"},{"language":"text","snippet":"📝 New Review for [Business Name]\n\n⭐ [star_rating] from [reviewer_name]\n💬 \"[review comment]\"\n\nMy draft reply:\n\"[your drafted response]\"\n\nReply OK to post, or send your edits.\n(Review ID: [review_id] | Client: [client_id])"},{"language":"text","snippet":"python3 {script_path} reply --client {client_id} --review {review_id} --reply \"{approved response}\""},{"language":"json","snippet":"{\n  \"client_id\": \"smithdental\",\n  \"review_id\": \"abc123\",\n  \"stars\": 5,\n  \"draft\": \"Thank you, Maria...\",\n  \"decision\": \"edited\",\n  \"final\": \"Thanks Maria...\",\n  \"length_delta_words\": -8,\n  \"timestamp\": \"2026-03-20T14:22:00Z\"\n}"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: review-responder\nversion: 2.0.1\ndescription: \"Use this skill when an operator is actively running the Google Business Profile review-response workflow for one of their configured client accounts. Specific triggers: 'check for new reviews,' 'run the review check for [client],' 'new review came in for [client],' 'draft a reply to the [reviewer] review,' 'approve the draft for [reviewer/client],' 'post the reply for [review id],' 'show pending review approvals,' 'show me the pending reviews,' or 'apply the [medical/legal/restaurant/retail/general] industry profile to this draft.' Do NOT trigger on: general questions about how to handle reviews, casual mentions of Google reviews, marketing strategy chat, requests to write a review (versus reply to one), or any workflow where no configured client exists. Covers: scheduled checks against Google Business Profile API for configured clients, star-rating-matched draft replies with industry-aware drafting constraints (medical/HIPAA-aware, legal, restaurant, retail), and an approval gate across Telegram, email, webhook, or in-chat channels. Drafts are NEVER auto-posted; operator approval is required before any reply is published. See Privacy and Data Handling for credential and posting scope.\"\nmetadata:\n  openclaw:\n    emoji: ⭐\n---\n\n# Review Responder\n\nAutomatically monitors Google Business Profile reviews across one or more client accounts, drafts professional responses tuned to star rating and industry, and routes drafts to a configurable approval channel before posting. Designed for agencies and consultants managing reviews on behalf of clients.\n\n## Trigger\n\nThis skill activates during scheduled review checks (heartbeat) and when an operator responds to a pending review approval message.\n\n---\n\n## Configuration\n\nAll paths and channels are read from a single config file: `review-responder.config.json` in the skill's data directory. If it doesn't exist, create one from this template on first run:\n\n```json\n{\n  \"script_path\": \"~/review-responder/gbp_reviews.py\",\n  \"clients_dir\": \"~/review-responder/clients/\",\n  \"approval_channel\": \"telegram\",\n  \"telegram_chat_id\": \"\",\n  \"email_recipient\": \"\",\n  \"webhook_url\": \"\",\n  \"default_industry\": \"general\",\n  \"memory_file\": \"approval-patterns.json\"\n}\n```\n\n### Configuration fields\n\n- **script_path**: Absolute path to the `gbp_reviews.py` CLI. Defaults to `~/review-responder/gbp_reviews.py` but can live anywhere.\n- **clients_dir**: Directory containing per-client config files. Each client gets its own subdirectory or JSON entry.\n- **approval_channel**: One of `telegram`, `email`, `webhook`, or `chat`. Determines where draft replies are sent for approval. See Approval Channels below.\n- **default_industry**: Industry profile applied when a client doesn't specify one. See Industry Compliance Profiles below.\n- **memory_file**: Where to log approval patterns for the learning layer.\n\n### Per-client overrides\n\nEach client in `clients_dir` can override `industry`, `approv"},{"path":"README.md","content":"# Review Responder\n\nAn [OpenClaw](https://openclaw.ai) skill that monitors Google Business Profile reviews, drafts professional responses, and routes them to a configurable approval channel before posting.\n\nBuilt for consultants and agencies managing reviews across multiple client locations and industries.\n\n**Current version: 2.0.1**\n\n## What's new in 2.0.1\n\n- Added a **Privacy and Data Handling** section to SKILL.md that honestly describes the skill's real network calls (Google Business Profile API), credential storage (operator-owned OAuth credentials per client), and the no-auto-post guardrail\n- Added a **Permissions and Privacy** section to this README so operators see scope, credential handling, and the HIPAA-aware (not HIPAA-certified) boundary before installing\n- Reworded the `medical` industry profile from \"HIPAA-safe\" to \"HIPAA-aware drafting\" to accurately describe what the skill enforces (drafting constraints) versus what it does not provide (workflow certification)\n- Narrowed the activation triggers in `description` to require an active, configured-client workflow, with a \"do NOT trigger\" guard for casual reviews chat and review-writing requests\n\n## What's new in 2.0.0\n\n- **Configurable script paths and channels** via a single `review-responder.config.json` file\n- **Channel-agnostic approval flow**: Telegram, email, webhook, or in-thread chat\n- **Industry compliance profiles**: medical (HIPAA-aware drafting), legal, restaurant, retail, and general\n- **Operator pattern learning**: logs approval decisions per client and surfaces patterns (e.g., \"you usually shorten 5-star replies for this client\")\n- **Per-client overrides** for industry, approval channel, and tone notes\n\nSee [CHANGELOG.md](CHANGELOG.md) for the full release history.\n\n## How It Works\n\n1. On each scheduled check, OpenClaw enumerates configured clients and looks for new unanswered reviews\n2. For each new review, the agent applies the client's industry profile and drafts a tone-matched response\n3. The draft is sent to the configured approval channel (Telegram, email, webhook, or chat)\n4. The operator replies \"OK\" to post it, sends edits to revise it, or \"skip\" to ignore it\n5. Decisions are logged so the agent can learn the operator's preferences over time\n\nNo reviews are ever posted without explicit operator approval.\n\n## What's Included\n\n- `SKILL.md` — Agent behavior instructions (configuration, approval flow, industry profiles, pattern learning)\n- `HEARTBEAT.md` — Periodic check instructions for OpenClaw's heartbeat system\n- `gbp_reviews.py` — Main script for checking reviews and posting replies\n- `get_client_token.py` — One-time OAuth helper for onboarding clients locally\n- `oauth_server.py` — Web-based OAuth flow for remote client onboarding\n- `clients/_template.json` — Config template for adding new clients\n- `SETUP.md` — Full setup and per-client onboarding guide\n\n## Quick Start\n\n1. Set up a Google Cloud project with the Business Profile API enabled (details in `SETUP"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn77r9qjvh6fy4aja2km8bzgvd83khv9\",\n  \"slug\": \"google-review-responder\",\n  \"version\": \"2.1.1\",\n  \"publishedAt\": 1790621086156\n}"},{"path":"CHANGELOG.md","content":"# Changelog\n\nAll notable changes to this skill will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this skill adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n## [2.0.1] — 2026-06-08\n\n### Added\n- **Privacy and Data Handling** section in SKILL.md describing the real network surface (Google Business Profile API v4, Google OAuth token endpoint, configured approval channel), credential storage (operator-owned OAuth credentials per client in `clients_dir`), and hard guardrails (no auto-posting, no PHI in public replies, no credential leakage, no bulk export)\n- **Permissions and Privacy** section in README.md so operators see the full network surface, credential storage posture, hard guardrails, and the compliance scope (HIPAA-aware drafting, NOT a HIPAA-certified workflow) before installing\n\n### Changed\n- Reworded the `medical` industry profile from \"HIPAA-safe\" to \"HIPAA-aware drafting\" to accurately describe the constraint (avoids PHI in public reply text) without implying a regulatory certification this skill cannot provide. CHANGELOG references to \"HIPAA-safe\" updated in the 2.0.0 entry's description of this profile for consistency\n- Narrowed the activation triggers in the `description` frontmatter to require an explicit configured-client workflow (named client, named reviewer, specific approval/post action), with a \"do NOT trigger\" guardrail for casual review chat, review-writing requests, and marketing-strategy questions\n- Unquoted the `version` field in frontmatter (matches updated ClawHub CLI semver requirements)\n\n## [2.0.0] — 2026-05-12\n\n### Added\n- Configuration file (`review-responder.config.json`) for centralizing script paths, clients directory, approval channel, default industry, and memory file location\n- Per-client configuration overrides for industry, approval channel, and tone notes\n- Channel-agnostic approval flow with four supported channels: Telegram, email, webhook, and in-thread chat\n- Industry compliance profiles for medical (HIPAA-safe), legal, restaurant, retail, and general business types\n- Operator pattern learning layer that logs each approval decision (approved-as-is, edited with diff summary, skipped) per client and surfaces patterns over time\n- Periodic insight surfacing to the operator (e.g., \"you usually shorten 5-star replies for this client by ~10 words\")\n\n### Changed\n- **BREAKING**: Hardcoded script paths (`~/review-responder/gbp_reviews.py`) replaced with a configurable `script_path` field\n- **BREAKING**: Telegram is no longer the assumed approval channel; `approval_channel` must be set explicitly in config\n- HIPAA section promoted from a sub-block under Response Guidelines into a top-level `Industry Compliance Profiles` section with peer profiles for other industries\n- SKILL.md now has proper YAML frontmatter (`name`, `version`, `description`, `metadata.openclaw.emoji`)\n\n### Removed\n- MIT LICENSE file (license now managed at"},{"path":"HEARTBEAT.md","content":"# Heartbeat: Review Responder\n\n## On Every Heartbeat\n\n1. Check for new unanswered Google Business reviews for each active client.\n   Run for each client configured in `~/review-responder/clients/`:\n   ```\n   python3 ~/review-responder/gbp_reviews.py check --client <client_id>\n   ```\n\n2. If the script finds new reviews, read the output carefully. For each new review:\n   - Draft a response following the guidelines in the Review Responder skill (SKILL.md)\n   - Send the draft to the operator via Telegram for approval\n   - Use the message format specified in SKILL.md\n\n3. If no new reviews are found for any client, reply HEARTBEAT_OK.\n\n## Important\n- Do NOT auto-post replies. Every response requires operator approval via Telegram.\n- If the script errors (missing config, API failure), report the error via Telegram so the operator can investigate.\n- Check `python3 ~/review-responder/gbp_reviews.py pending` to see if there are stale pending reviews that haven't been addressed. If any are older than 48 hours, send a reminder."}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":1886,"uniquenessScore":36,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-10T21:14:25.073Z","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-10T21:14:25.073Z","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-11T00:32:45.078Z","emptyReason":null},"items":[{"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-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"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":"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"}]}}}