review-rover
v0.1.3
Published
CLI for Review Rover — automate Google review management
Downloads
404
Readme
review-rover CLI
A command-line interface for Review Rover — automate Google review management from your terminal, scripts, or AI agents.
Works with any AI that can run shell commands (Claude, Cursor, GPT, Copilot, etc.).
Table of contents
Prerequisites
- Node.js 18+ — nodejs.org
- A Review Rover account — admin.reviewrover.co
- A Google Business Profile connected to your account (Settings → Integrations — requires a browser the first time)
- An API token generated at Settings → API Tokens
Installation
Option A — npx (no install needed)
npx review-rover <command>Option B — global install
npm install -g review-rover
review-rover <command>Authentication
Run the auth command once to save your API token:
review-rover auth
# Paste your API token: ••••••••••••••••
# Authenticated successfully. Token saved to ~/.review-rover/config.jsonThe token is saved to ~/.review-rover/config.json (mode 0600, readable only by you).
To generate a token: log in to admin.reviewrover.co → Settings → API Tokens → New Token.
Configuration
Config is stored in ~/.review-rover/config.json:
{
"token": "rr_live_xxxxxxxxxxxxxxxxxxxx",
"accountId": "acct_AbCdEfGhIj",
"apiBase": "https://api.reviewrover.co/api/v1"
}| Field | Description |
|---|---|
| token | API token (set by review-rover auth) |
| accountId | Default account (set by review-rover accounts use <id>) |
| apiBase | Override API base URL (optional, for self-hosted or staging) |
Commands
All read commands accept a --json flag for machine-readable output:
review-rover reviews list --unreplied --jsonreview-rover auth
Save your API token to the local config file.
review-rover authPrompts for a token, verifies it against the API, and writes it to ~/.review-rover/config.json.
review-rover accounts
accounts list
List all accounts accessible with your token.
review-rover accounts list [--json]accounts use <id>
Set a default account for subsequent commands.
review-rover accounts use acct_AbCdEfGhIjOnce set, you won't need to pass --account to other commands.
review-rover contacts
contacts list
review-rover contacts list [--email <email>] [--limit <n>] [--json]| Option | Description | Default |
|---|---|---|
| --email | Filter by exact email address | — |
| --limit | Number of results (max 100) | 10 |
| --json | Output as JSON | — |
# Find a specific contact
review-rover contacts list --email="[email protected]" --jsoncontacts upsert
Create a contact, or return the existing one if the email is already registered.
review-rover contacts upsert \
--email="[email protected]" \
--name="Jane Smith" \
--phone="555-0100" \
[--company="Acme Corp"] \
[--json]| Option | Required | Description |
|---|---|---|
| --email | Yes | Contact's email address |
| --name | No | Full name (split on first space → first/last) |
| --phone | No | Phone number for SMS campaigns |
| --company | No | Company name |
review-rover campaigns
campaigns list
review-rover campaigns list [--json]Lists all campaigns with their IDs, names, and active status. Use the id field when enrolling a contact.
review-rover enroll
Enroll a contact into a campaign, triggering the review-request message sequence.
review-rover enroll \
--contact=cont_KYdl3lftgZXGRbxqoj \
--campaign=camp_AbCdEfGhIjKlMn \
[--json]| Option | Required | Description |
|---|---|---|
| --contact | Yes | Contact ID (cont_xxx) |
| --campaign | Yes | Campaign ID (camp_xxx) |
The enrollment is automatically marked completed once the contact submits a Google review.
review-rover reviews
reviews list
review-rover reviews list [--unreplied] [--json]| Option | Description |
|---|---|
| --unreplied | Only show reviews without a reply (uses the /metrics/unreplied_reviews endpoint) |
| --json | Output as JSON |
# Check the reply queue
review-rover reviews list --unreplied --json--unreplied output includes a count, a reviews array (id, rating, author, snippet, received_at), and a per-location locations breakdown.
reviews draft
Generate an AI draft reply without posting it.
review-rover reviews draft \
--id=rev_Aa1Bb2Cc3Dd4Ee \
[--tone=professional]| Option | Description | Default |
|---|---|---|
| --id | Review ID (rev_xxx) | — |
| --tone | Tone hint passed to the AI (professional, friendly, brief) | professional |
Prints the suggested reply text to stdout. Nothing is saved or posted.
reviews reply
Post a reply to a review.
review-rover reviews reply \
--id=rev_Aa1Bb2Cc3Dd4Ee \
--message="Thank you for the kind words!" \
[--json]| Option | Required | Description |
|---|---|---|
| --id | Yes | Review ID (rev_xxx) |
| --message | Yes | Reply text |
review-rover webhooks
Register HTTPS endpoints to receive real-time events instead of polling.
Supported events:
review.created— a new review arrivedenrollment.completed— a contact submitted a review, completing their enrollment
All webhook POST bodies are signed with X-ReviewRover-Signature: sha256=<hmac>. See Verifying signatures.
webhooks list
review-rover webhooks list [--json]webhooks create
review-rover webhooks create \
--url="https://myagent.example.com/hooks/review-rover" \
--events=review.created \
[--json]| Option | Required | Description |
|---|---|---|
| --url | Yes | HTTPS endpoint URL |
| --events | Yes | Comma-separated event types |
# Subscribe to multiple events
review-rover webhooks create \
--url="https://myagent.example.com/hook" \
--events="review.created,enrollment.completed"webhooks delete
review-rover webhooks delete --id=<webhook-subscription-id>Verifying webhook signatures
Each webhook delivery includes a X-ReviewRover-Signature: sha256=<hmac> header. Verify it in your endpoint:
// Node.js / Express
const crypto = require('crypto')
app.post('/hooks/review-rover', (req, res) => {
const sig = req.headers['x-reviewrover-signature']
const expected = 'sha256=' + crypto
.createHmac('sha256', process.env.WEBHOOK_SECRET)
.update(req.rawBody) // raw Buffer, not parsed JSON
.digest('hex')
if (sig !== expected) return res.status(401).send('Invalid signature')
const { type, payload } = req.body
// type: 'review.created' | 'enrollment.completed'
console.log('Event:', type, payload)
res.sendStatus(200)
})# Python / Flask
import hmac, hashlib, os
from flask import request, abort
@app.route('/hooks/review-rover', methods=['POST'])
def webhook():
sig = request.headers.get('X-ReviewRover-Signature', '')
expected = 'sha256=' + hmac.new(
os.environ['WEBHOOK_SECRET'].encode(),
request.data,
hashlib.sha256
).hexdigest()
if not hmac.compare_digest(sig, expected):
abort(401)
event = request.json
print('Event:', event['type'], event['payload'])
return '', 200The webhook secret is returned when you create the subscription via the API (POST /api/v1/webhook_subscriptions). Store it securely (environment variable, secrets manager). It is not surfaced again after creation.
Agent usage
A typical AI agent workflow after initial human setup:
# 1. Save the token the human handed over
review-rover auth
# 2. Find or create a contact
review-rover contacts upsert \
--email="[email protected]" \
--name="Customer Name" \
--phone="555-0100"
# 3. Pick a campaign
review-rover campaigns list --json
# 4. Enroll the contact
review-rover enroll \
--contact=cont_xxx \
--campaign=camp_xxx
# 5. Check the reply queue
review-rover reviews list --unreplied --json
# 6. Draft a reply
review-rover reviews draft --id=rev_xxx --tone=professional
# 7. Post the reply
review-rover reviews reply \
--id=rev_xxx \
--message="Thanks for the great review!"
# 8. Register a webhook so future reviews push rather than poll
review-rover webhooks create \
--url="https://myagent.example.com/hook" \
--events=review.createdFor a full narrative guide including raw HTTP equivalents, see docs.reviewrover.co/agent-workflow.
Development
# Clone
git clone https://github.com/Review-Growth/cli.git
cd cli
# Install dependencies
npm install
# Run in dev mode (no build step)
npm run dev -- auth
npm run dev -- reviews list --unreplied --json
# Build to dist/
npm run build
# Link for local testing
npm link
review-rover --versionProject structure
cli/
├── src/
│ ├── index.ts # Entry point, command registration
│ ├── client.ts # Typed fetch wrapper around /api/v1/*
│ ├── config.ts # ~/.review-rover/config.json read/write
│ ├── output.ts # printJson / printTable helpers
│ └── commands/
│ ├── auth.ts
│ ├── accounts.ts
│ ├── contacts.ts
│ ├── campaigns.ts
│ ├── enroll.ts
│ ├── reviews.ts
│ └── webhooks.ts
├── package.json
└── tsconfig.jsonEnvironment variables
You can override the API base URL without editing the config file:
REVIEW_ROVER_API_BASE=http://localhost:3000/api/v1 npm run dev -- reviews listThis requires adding env-variable support to
config.tsif needed during development.
Publishing to npm
npm run build
npm publish --access publicRequires npm publish rights to the review-rover package.
