Archived document. This file has been superseded or completed and is kept for historical reference.
Zapier Review Request System Setup
Overview
This document describes the Zapier-centric review request system that handles:
- Generating signed feedback links
- Drafting and scheduling review request emails
- Tracking when reviews are received
- Sending follow-up reminders
Architecture
LAWMATICS FORM
↓
ZAPIER: "Lawmatics → Generate Review Link → Lawmatics"
- Generate signed URL (with Matter ID)
- Write URL back to Lawmatics
- Draft email in Gmail (10-min delay before send)
- Log to Google Sheet
- Schedule 5-day follow-up
↓
GMAIL: Sends email after 10 min (or manually if edited)
↓
CLIENT: Clicks link, submits feedback
↓
ZAPIER: "process-requests-for-reviews"
- Receives feedback (positive or private)
- Updates Lawmatics _review-received = true
- Logs to Google Sheet
- Sends SMS for negative feedback
Zap 1: “Lawmatics → Generate Review Link → Lawmatics”
Trigger
- App: Lawmatics
- Event: Filled Out a Form
- Form: form-generate-a-request-for-a-review
Step 2: Code by Zapier - Generate Signed URL
Input Data:
- firstName: {{First Name}}
- lastName: {{Last Name}}
- email: {{Email}}
- phone: {{Phone}}
- matterId: {{Matter ID}}
- requestType: {{Request Type}}
Secret:
- FEEDBACK_SECRET: (your secret)
Code:
const crypto = require('crypto');
const https = require('https');
const FEEDBACK_SECRET = process.env.FEEDBACK_SECRET;
const BASE_URL = 'https://sempers.com/feedback/feedback.html';
const name = `${inputData.firstName} ${inputData.lastName}`.trim();
const email = inputData.email;
const phone = inputData.phone;
const matterId = inputData.matterId || '';
const requestType = inputData.requestType || '';
const expiryDays = 7;
const expiration = Date.now() + (expiryDays * 24 * 60 * 60 * 1000);
const randomHex = crypto.randomBytes(8).toString('hex');
const payload = {
n: name,
e: email,
p: phone,
m: matterId,
x: expiration,
r: randomHex
};
const payloadStr = JSON.stringify(payload);
const payloadB64 = Buffer.from(payloadStr)
.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
const hmac = crypto.createHmac('sha256', FEEDBACK_SECRET);
hmac.update(payloadB64);
const signature = hmac.digest('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '')
.substring(0, 16);
const token = `${payloadB64}.${signature}`;
const fullUrl = `${BASE_URL}?t=${token}`;
const shortenUrl = (url) => {
return new Promise((resolve) => {
const apiUrl = `https://is.gd/create.php?format=simple&url=${encodeURIComponent(url)}`;
https.get(apiUrl, (res) => {
let data = '';
res.on('data', chunk => data += chunk);
res.on('end', () => resolve(data.trim()));
}).on('error', () => resolve(url));
});
};
const shortUrl = await shortenUrl(fullUrl);
output = {
feedbackUrl: shortUrl,
fullUrl: fullUrl,
clientName: name,
clientEmail: email,
clientPhone: phone,
matterId: matterId,
requestType: requestType,
expiresAt: new Date(expiration).toLocaleDateString('en-US', {
year: 'numeric', month: 'long', day: 'numeric'
}),
firstName: inputData.firstName
};
Step 3: Lawmatics - Update Matter
- Action: Update Matter
- Matter ID: {{matterId}} from Code step
- Feedback Link field: {{feedbackUrl}}
Step 4: Paths - Branch by Request Type
Path A: Quick feedback from recent contact
- Condition: requestType = “A) Quick feedback from recent contact”
Path B: Other
- Condition: requestType = “B) Other”
Step 5A/5B: Gmail - Create Draft
To: {{clientEmail}} Subject: Quick feedback request Body:
Hi {{firstName}},
Thank you for contacting my firm. I'd really appreciate hearing about your experience:
{{feedbackUrl}}
It only takes about 30 seconds.
Best regards,
Zachary Sempers, Esq.
Sempers Law Firm
888-762-0297
Step 6: Delay by Zapier
- Delay for: 10 minutes
Step 7: Gmail - Send Draft
- Sends the draft created in Step 5
Step 8: Google Sheets - Create Row
- Spreadsheet: Feedback Links Log
- Columns:
- timestamp: {{zap_meta_human_now}}
- name: {{clientName}}
- email: {{clientEmail}}
- phone: {{clientPhone}}
- matterId: {{matterId}}
- requestType: {{requestType}}
- expiry: {{expiresAt}}
- feedbackUrl: {{feedbackUrl}}
- fullUrl: {{fullUrl}}
- initialEmailSent: {{zap_meta_human_now}}
- followUpSent: (blank)
- reviewReceived: (blank)
Step 9: Delay by Zapier
- Delay for: 5 days
Step 10: Lawmatics - Find Matter
- Matter ID: {{matterId}}
- Get current value of _review-received field
Step 11: Filter by Zapier
- Condition: _review-received does NOT equal true
- (Only continue if review has NOT been received)
Step 12: Gmail - Send Email (Follow-up)
To: {{clientEmail}} Subject: Following up Body:
Hi {{firstName}},
Just following up on my note from last week. If you have 30 seconds, I'd appreciate your feedback:
{{feedbackUrl}}
No worries if you can't.
Best,
Zachary Sempers, Esq.
Sempers Law Firm
888-762-0297
Step 13: Google Sheets - Update Row
- Find row by matterId
- Update followUpSent: {{zap_meta_human_now}}
Zap 2: “process-requests-for-reviews” (Update Existing)
Current Function
- Receives feedback submissions
- Logs to Google Sheet
- Sends SMS for negative feedback
New Step to Add: Lawmatics - Update Matter
After receiving feedback (positive or private), add:
Action: Lawmatics - Update Matter Matter ID: {{matterId}} from webhook payload Fields:
- _review-received: true
Updated Trigger Payload Structure
The webhook now receives:
{
"type": "positive_review" | "private_feedback",
"token": "...",
"rating": 1-5,
"name": "...",
"email": "...",
"phone": "...",
"matterId": "...",
"reviewSite": "Google" | "Avvo", // for positive only
"message": "...", // for private only
"source_page": "/feedback/feedback.html",
"submitted_at": "..."
}
Testing Plan
Test Matter Setup
- Create a test Matter in Lawmatics with:
- First Name: Test
- Last Name: User
- Email: (your email)
- Phone: 555-TEST-001
Test 1: Link Generation
- Fill out form-generate-a-request-for-a-review with test data
- Verify Zapier generates URL
- Verify URL written back to Lawmatics Matter
- Verify Gmail draft created
- Wait 10 min OR manually send draft
- Verify email received
Test 2: Positive Review Flow
- Click feedback link in email
- Select 5 stars
- Click Continue
- Verify redirect to Google/Avvo
- Check Zapier - verify “positive_review” received
- Check Lawmatics - verify _review-received = true
Test 3: Negative Feedback Flow
- Click feedback link
- Select 2 stars
- Submit private feedback
- Verify Zapier receives “private_feedback”
- Verify SMS sent (if configured)
- Verify Lawmatics _review-received = true
Test 4: Follow-up Flow
- Generate link, let email send
- Do NOT submit feedback
- Wait 5 days (or manually trigger)
- Verify follow-up email sent
- Verify Google Sheet updated
Copilot Instructions
For Zap 1 Updates
Paste this into Copilot in Zapier:
I need to update my Zap "Lawmatics → Generate Review Link → Lawmatics" with these changes:
1. In the Code step, add "matterId" to Input Data, mapped from the Lawmatics form
2. After the "Update Matter" step, add a "Paths" step:
- Path A: requestType equals "A) Quick feedback from recent contact"
- Path B: requestType equals "B) Other" (or catch-all)
3. In each path, add:
a. Gmail "Create Draft" with:
- To: clientEmail
- Subject: "Quick feedback request"
- Body: (I'll provide the template)
b. "Delay by Zapier" for 10 minutes
c. Gmail "Send Draft" (sends the draft from step a)
4. After paths merge, add:
a. "Delay by Zapier" for 5 days
b. Lawmatics "Find Matter" using matterId
c. "Filter" - only continue if _review-received is NOT true
d. Gmail "Send Email" (follow-up template)
e. Google Sheets "Update Row" - mark followUpSent timestamp
Walk me through adding each step.
For Zap 2 Updates
Paste this into Copilot in Zapier:
I need to update my Zap "process-requests-for-reviews" to update Lawmatics when a review is received.
The webhook payload now includes a "matterId" field.
Add a new step after receiving the webhook:
1. Lawmatics "Update Matter"
- Matter ID: Use {{matterId}} from the webhook
- Set field "_review-received" to true
This should happen for both "positive_review" and "private_feedback" submission types.
Walk me through adding this step.
Fields Reference
Lawmatics Fields
Feedback Link- URL field, stores the generated feedback URL_review-received- Checkbox, true when client submits any feedbackRequest Type- Dropdown: “A) Quick feedback from recent contact”, “B) Other”
Google Sheet Columns
- timestamp
- name
- phone
- matterId
- requestType
- expiry
- feedbackUrl
- fullUrl
- initialEmailSent
- followUpSent
- reviewReceived