
Implementation Guide: Transcribe showing feedback calls and aggregate buyer sentiment across properties
Step-by-step implementation guide for deploying AI to transcribe showing feedback calls and aggregate buyer sentiment across properties for Real Estate clients.
Hardware Procurement
PLAUD NotePin Wearable AI Voice Recorder
$135–$155/unit MSP cost (volume estimate) / $179–$199 suggested resale per unit
Primary ambient capture device for in-person post-showing feedback conversations. Agents clip to lapel or lanyard during property showings and debriefs. Magnetic wearable form factor with one-tap recording, long-range microphones, and Bluetooth sync to mobile app. Each agent receives one device.
PLAUD NotePin S Wearable AI Voice Recorder
$150–$165/unit MSP cost / $199–$219 suggested resale per unit
High-capacity variant for team leads or high-volume listing agents who conduct 10+ showings per day. Up to 20 hours continuous recording with enhanced long-range microphones. Order 2 as spares or for power users.
Jabra Speak2 55 Speakerphone
$100–$115/unit distributor cost / $149–$169 suggested resale per unit
Office/desk speakerphone for recording feedback calls made from the brokerage office. 4 beamforming noise-cancelling microphones, Bluetooth + USB-C, Zoom/Teams certified. Deploy one per shared office or conference room used for agent phone calls. Audio routed to Fireflies.ai for transcription.
Anker PowerConf Bluetooth Speakerphone
$45–$55/unit distributor cost / $79–$89 suggested resale per unit
Portable budget speakerphone alternative for agents who take feedback calls from home offices or satellite locations. 6-microphone array with 360° pickup, 24-hour battery, Bluetooth 5.3. Lower cost option where Jabra is not justified.
Software Procurement
Fireflies.ai Business
$19/user/month billed annually ($228/user/year). For 20 agents: $380/month or $4,560/year. Resell at $29–$39/user/month for $10–$20/user/month margin.
Primary transcription and meeting intelligence platform. Auto-joins phone calls and Zoom/Teams meetings, provides speaker diarization, topic tracking, sentiment labels, and searchable transcript library. Native CRM integrations with Salesforce and HubSpot; Zapier integration for Follow Up Boss. Replaces need for custom transcription API for most use cases.
PLAUD AI Unlimited Subscription
$19.99/device/month or $239.99/device/year. For 22 devices: $439.78/month or $5,279.78/year. Resell at $29.99–$39.99/device/month.
Transcription service for PLAUD NotePin recorded audio. Unlimited transcription minutes (up to 100 hours/day), AI summaries, and export capabilities. Required for converting PLAUD field recordings into text for the sentiment pipeline. Audio files can also be exported and sent to Fireflies or the custom GPT pipeline.
OpenAI API (GPT-5.4 Mini)
$0.15 per 1M input tokens, $0.60 per 1M output tokens. Estimated ~$0.01–$0.03 per transcript sentiment analysis. For 400 transcripts/month: $4–$12/month.
Custom sentiment analysis and structured data extraction from transcripts. Takes raw transcript text and returns structured JSON with property sentiment scores, key themes, buyer objections, positive highlights, and purchase likelihood indicators. Much more real-estate-specific than generic sentiment APIs.
Zapier (Teams Plan)
$69.50/month (2,000 tasks/month) or $828/year. Resell bundled into managed service fee.
Workflow automation connecting Fireflies.ai transcription output → OpenAI sentiment analysis → Follow Up Boss CRM → Google Sheets aggregation database. Handles event-driven triggers when new transcripts are ready, orchestrates the multi-step data pipeline without custom server infrastructure.
Follow Up Boss CRM (client's existing)
$0 additional MSP cost — client's existing subscription. API access included on all plans.
Target CRM where transcript summaries, sentiment scores, and showing feedback are pushed as notes on lead/contact records and linked to property addresses. Follow Up Boss REST API and webhooks used for data sync.
Google Looker Studio
$0/month. Dashboard connects to Google Sheets data source.
Sentiment aggregation dashboard showing buyer sentiment trends by property (MLS#), sentiment over time, most common objections/praises, and agent activity metrics. Shared with brokerage management via link.
Google Sheets
$0/month if client has Google Workspace; included in most brokerage setups.
Intermediate data store for structured sentiment records. Each row represents one showing feedback interaction with columns for MLS#, property address, date, agent, overall sentiment score, key themes, objections, and highlights. Serves as the data source for Looker Studio dashboard.
Prerequisites
Installation Steps
...
Step 1: Compliance & Consent Framework Setup
Before any technology is deployed, establish the legal consent framework for call recording. Determine which states the brokerage operates in and whether they are one-party or two-party consent states. Prepare consent scripts, IVR greetings, and showing agreement addenda.
Do NOT proceed to device deployment until consent language is approved by client's legal counsel. For two-party states, the recorded consent acknowledgment must be the first segment of every audio file. Budget 2–4 hours of legal review time. Provide the client with the consent script templates from the Custom AI Components section of this guide. For phone calls, configure an auto-attendant greeting or train agents to read the disclosure verbatim before each call. For in-person conversations, add a recording disclosure clause to the showing feedback form or buyer consultation agreement.
Step 2: Create Accounts & API Keys
Provision all cloud service accounts and generate API credentials needed for the integration pipeline. Create accounts for: (1) Fireflies.ai Business — one admin account plus per-agent seats, (2) PLAUD AI — one account per device/agent, (3) OpenAI Platform — one MSP-managed account with billing, (4) Zapier Teams — one MSP-managed account, (5) Google account for Sheets and Looker Studio if client doesn't have Google Workspace.
Store all API keys in the MSP's secrets manager (e.g., Keeper, 1Password Business). Never store keys in plaintext in automation tools — use Zapier's built-in credential storage. Create a shared credentials document (encrypted) for the client's IT admin with read-only access.
Step 3: Configure PLAUD NotePin Devices
Unbox and configure each PLAUD NotePin device. Pair via Bluetooth to the agent's smartphone, install the PLAUD app, create or log into PLAUD AI accounts, and activate the Unlimited subscription on each device. Set recording quality to highest fidelity. Configure auto-sync to upload recordings over Wi-Fi when the agent returns to the office (to save cellular data). Enable cloud backup.
Batch configure devices in the MSP office before deploying to agents. Charge all devices fully (USB-C, ~1.5 hours). PLAUD NotePin has ~20 hours recording capacity before needing sync/upload. Instruct agents to sync nightly. If agents are in two-party consent states, configure the PLAUD app's recording start announcement feature if available, or train agents to verbally announce recording at the start of every conversation.
Step 4: Configure Fireflies.ai for Phone Call Recording
Set up Fireflies.ai Business accounts for each agent who conducts feedback calls by phone. Configure calendar integration (Google Calendar or Outlook) so Fireflies auto-joins scheduled calls. For ad-hoc calls, agents will use the Fireflies mobile app or browser extension. Configure the Fireflies webhook to send completed transcripts to Zapier for downstream processing.
Fireflies.ai on the Business plan includes CRM integrations (Salesforce, HubSpot) natively. For Follow Up Boss, we use Zapier as the bridge since there's no native integration. Agents should be trained to use the Fireflies mobile app 'Record' button for ad-hoc phone calls that aren't on the calendar. The Chrome extension captures audio from browser-based calling tools.
Step 5: Deploy Jabra Speak2 55 Speakerphones in Office
Install Jabra Speak2 55 units in the brokerage's shared offices and conference rooms where agents conduct feedback calls. Connect via USB-C to the office computer or via Bluetooth to agent's phone. Configure as the default audio input/output device for Zoom, Teams, and the Fireflies.ai desktop app. This ensures high-quality audio capture with noise cancellation for office-based calls.
Place speakerphones in consistent locations with a small placard reminding agents: 'This room records calls for ShowingInsight. Announce recording disclosure at call start.' Update Jabra Direct firmware quarterly. For Bluetooth mode, only one device can be paired at a time — USB-C is preferred for shared office use to avoid pairing conflicts.
Step 6: Create Google Sheets Sentiment Database
Create the structured Google Sheet that will serve as the central data store for all processed sentiment records. This sheet is the data source for the Looker Studio dashboard and the historical archive for compliance. Set up the schema with proper column headers, data validation, and sharing permissions.
Use Google Sheets API v4 for programmatic access. The free tier supports 300 requests per minute per project which is more than sufficient. For brokerages with 500+ feedback records per month, consider migrating to a PostgreSQL database on Railway or Supabase ($0–$25/month) with Looker Studio connecting via BigQuery. Keep the Sheet under 50,000 rows for performance — archive annually.
Step 7: Configure OpenAI API for Sentiment Analysis
Set up the OpenAI API account, configure billing limits, and test the sentiment analysis prompt with sample transcripts. The GPT-5.4 Mini model provides the best cost-to-quality ratio for structured sentiment extraction from real estate feedback transcripts. Set a monthly spending cap to prevent runaway costs.
curl -X POST https://api.openai.com/v1/chat/completions \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer sk-YOUR_API_KEY' \
-d '{
"model": "gpt-5.4-mini",
"response_format": { "type": "json_object" },
"messages": [
{
"role": "system",
"content": "You are a real estate showing feedback analyst. Analyze the following transcript of a post-showing feedback conversation and return a JSON object with these fields: overall_sentiment_score (float -1.0 to 1.0), sentiment_label (string: Very Negative/Negative/Neutral/Positive/Very Positive), purchase_likelihood (int 1-5), positive_themes (array of strings), negative_themes (array of strings), specific_objections (array of strings), price_feedback (string or null), condition_feedback (string or null), location_feedback (string or null), summary (string, 2-3 sentences)."
},
{
"role": "user",
"content": "Listing Agent: Hi Sarah, thanks for showing 123 Oak Street today. How did your buyers like it?\nBuyer Agent: They really loved the open floor plan and the updated kitchen. The natural light in the living room was a big hit. Their main concern was the backyard is smaller than they expected, and they mentioned the price feels a bit high compared to the comp on Maple Drive that sold last month. Overall though, they are interested and want to come back for a second showing."
}
]
}'Expected monthly cost: $4–$12 for 400 transcripts/month. GPT-5.4 Mini is ~10x cheaper than GPT-5.4 with comparable structured extraction quality for this use case. Monitor usage weekly for the first month. If costs exceed expectations, batch transcripts for processing during off-peak hours or switch to a smaller model. The response_format json_object parameter ensures valid JSON output every time.
Step 8: Build Zapier Automation Workflow
Create the master Zapier workflow (Zap) that orchestrates the entire pipeline: Fireflies.ai transcript ready → extract transcript text → send to OpenAI for sentiment analysis → parse structured response → write to Google Sheets → push summary to Follow Up Boss CRM. This is the central nervous system of the solution.
Zap 1: 'Fireflies to Sentiment Pipeline'
// Code by Zapier: Extract transcript text and meeting metadata from webhook
// payload
const data = JSON.parse(inputData.body);
return {
transcript: data.transcript || data.sentences.map(s => s.text).join(' '),
meeting_title: data.title || 'Unknown',
date: data.date || new Date().toISOString(),
duration: data.duration || 0,
participants: (data.participants || []).join(', ')
};// Code by Zapier: Parse OpenAI JSON response and extract fields
const result = JSON.parse(inputData.openai_response);
return {
sentiment_score: result.overall_sentiment_score,
sentiment_label: result.sentiment_label,
purchase_likelihood: result.purchase_likelihood,
positive_themes: (result.positive_themes || []).join('; '),
negative_themes: (result.negative_themes || []).join('; '),
objections: (result.specific_objections || []).join('; '),
price_feedback: result.price_feedback || '',
condition_feedback: result.condition_feedback || '',
location_feedback: result.location_feedback || '',
summary: result.summary,
mls_number: result.mls_number || 'NEEDS_MANUAL_ENTRY'
};# Webhooks by Zapier: POST request body to Follow Up Boss API
# (https://api.followupboss.com/v1/notes) with Authorization: Basic
# {{base64(api_key:)}}
{
"personId": "(lookup or skip)",
"subject": "Showing Feedback: {{Step5.mls_number}}",
"body": "Sentiment: {{Step5.sentiment_label}} ({{Step5.sentiment_score}})\n\nSummary: {{Step5.summary}}\n\nPositives: {{Step5.positive_themes}}\n\nConcerns: {{Step5.negative_themes}}\n\nObjections: {{Step5.objections}}\n\nPrice Feedback: {{Step5.price_feedback}}\n\nPurchase Likelihood: {{Step5.purchase_likelihood}}/5"
}Zap 2: 'PLAUD Recording to Pipeline'
For PLAUD NotePin recordings synced to PLAUD Cloud.
Zapier Teams plan allows 2,000 tasks/month. Each feedback call uses approximately 5–7 tasks (trigger + code + filter + OpenAI + parse + Sheets + FUB). This supports approximately 285–400 calls/month. If volume exceeds this, upgrade to Zapier Company plan or switch to n8n self-hosted. Test the Zap thoroughly with 5 sample transcripts before going live. The MLS number extraction from transcripts is imperfect — agents should mention the property address or MLS# at the start of each feedback call for best results. Implement a weekly manual review of 'NEEDS_MANUAL_ENTRY' records.
Step 9: Build Google Looker Studio Sentiment Dashboard
Create the executive dashboard in Google Looker Studio that connects to the Google Sheets sentiment database and provides visual aggregation of buyer sentiment across all properties. The dashboard has three pages: Property Overview, Trend Analysis, and Agent Activity.
Page 1: Property Overview
- Add Scorecard: Average Sentiment Score (all properties)
- Add Scorecard: Total Feedback Count
- Add Scorecard: Average Purchase Likelihood
- Add Bar Chart: Average Sentiment Score by MLS Number (sorted desc)
- Add Table: MLS Number | Property Address | Avg Sentiment | Feedback Count | Top Objection
- Add Dropdown filter: Listing Agent
- Add Date Range filter: default Last 30 Days
Page 2: Trend Analysis
- Add Time Series: Average Sentiment Score over Date (line chart)
- Add Time Series: Feedback Volume over Date (bar chart)
- Add Pie Chart: Sentiment Label distribution
- Add Word Cloud (using calculated field): Most common terms in Key Negative Themes
- Add Filter: MLS Number (to drill into single property trends)
Page 3: Agent Activity
- Add Table: Listing Agent | Properties Listed | Total Feedbacks | Avg Sentiment | Avg Purchase Likelihood
- Add Bar Chart: Feedback count by Listing Agent
- Add Scorecard: Agents with no feedback in last 7 days (alert metric)
Looker Studio is free and connects directly to Google Sheets with auto-refresh. Data refreshes every 15 minutes by default. For real-time needs, reduce to 1-minute refresh in data source settings (may hit API quotas on very large sheets). The dashboard URL should be bookmarked on the brokerage's shared browser toolbar and added to any internal portal or intranet. Consider creating a simplified mobile-friendly version for agents to check on their phones.
Step 10: PLAUD-to-Pipeline Integration for Field Recordings
Configure the workflow for in-person feedback captured on PLAUD NotePin devices to flow into the same sentiment analysis pipeline as phone calls. PLAUD recordings sync to the PLAUD Cloud via the mobile app, where they are transcribed by PLAUD AI. The transcripts are then exported and fed into the OpenAI sentiment pipeline via a separate Zapier workflow or manual export process.
Option A: Manual Export Workflow — Agent Steps
Google Form Fields
- Agent Name (dropdown)
- MLS Number (short text, required)
- Property Address (short text)
- Date of Showing (date picker)
- Feedback Transcript (long text, paste from PLAUD)
- Consent Confirmed (checkbox, required: 'I confirm all parties were informed of recording')
Option B: Automated Export — Status Note
- Monitor PLAUD developer documentation for API access
- When available: Zapier webhook triggered by PLAUD cloud event
- Currently PLAUD does not offer a public API for transcript retrieval
Create the PLAUD Intake Zap
Option A requires agent compliance in pasting transcripts. During training, emphasize this takes <60 seconds per feedback session. The Google Form serves as both the data intake mechanism and a compliance checkpoint (consent confirmation). If agents are not consistently pasting transcripts, escalate to the brokerage manager. Option B (automated) depends on PLAUD releasing a public API — check quarterly. Alternative: agents can email transcripts from the PLAUD app to a dedicated email address, and Zapier can trigger on new emails to that address (use Gmail + Zapier trigger).
Step 11: Configure Follow Up Boss CRM Integration
Set up the Follow Up Boss API integration to push showing feedback summaries as notes on the appropriate contact or lead records. Configure the API authentication, test with sample data, and establish the note format that listing agents will see in their CRM.
curl -X GET https://api.followupboss.com/v1/people \
-H 'Authorization: Basic BASE64_ENCODED_API_KEY' \
-H 'Content-Type: application/json'# FUB API uses HTTP Basic Auth where username = API key and password is blank
# Base64 encode:
echo -n 'YOUR_API_KEY:' | base64curl -X POST https://api.followupboss.com/v1/notes \
-H 'Authorization: Basic BASE64_ENCODED_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"personId": 12345,
"subject": "Showing Feedback: MLS# 12345678 - 123 Oak St",
"body": "**Sentiment: Positive (0.72)**\n\n**Summary:** Buyers loved the open floor plan and updated kitchen. Concerned about backyard size and pricing relative to recent comps.\n\n**Positives:** Open floor plan, updated kitchen, natural light\n**Concerns:** Small backyard, price seems high\n**Purchase Likelihood:** 4/5\n\n_Recorded: 2025-01-15 | Duration: 8 min | Source: Phone (Fireflies)_"
}'curl -X GET 'https://api.followupboss.com/v1/people?q=Sarah+Johnson' \
-H 'Authorization: Basic BASE64_ENCODED_API_KEY'Follow Up Boss API rate limit is 200 requests per minute — more than sufficient. The API does not have a native 'property' object, so feedback is attached to the buyer agent's contact record with the MLS# in the note subject for searchability. Listing agents can then search notes by MLS# to see all feedback for a property. If the brokerage uses kvCORE instead of Follow Up Boss, use kvCORE's webhook receiver to accept POST requests with the same payload structure. For Salesforce, use the native Fireflies.ai integration instead of this custom Zapier step.
Step 12: Agent Training & Consent Workflow Rollout
Conduct a 90-minute training session with all agents covering: (1) how to use PLAUD NotePin for in-person recordings, (2) how to use Fireflies.ai for phone call recordings, (3) the mandatory consent disclosure process, (4) how to submit PLAUD transcripts via Google Form, and (5) how to find feedback data in Follow Up Boss and the dashboard. Provide printed quick-reference cards.
Training Session Agenda (90 Minutes)
Quick Reference Card — Front: Consent Scripts
Phone Call Consent Script
'Hi [name], before we discuss the showing, I want to let you know
this call is being recorded to help us capture your feedback accurately.
The recording will be transcribed and used internally by our brokerage.
Is that okay with you?'In-Person Consent Script
'I'd like to record our conversation about the showing so I can
capture your feedback accurately. The recording is used internally
by our team. Do I have your permission to record?'Quick Reference Card — Back: Device Quick Steps
PLAUD NotePin Quick Steps
Fireflies Quick Steps
Schedule training during a regular office meeting to maximize attendance. Record the training session itself (with consent!) and upload to a shared Google Drive folder for agents who miss it. Follow up with a 15-minute individual check-in with each agent during their first week of use. The consent workflow is the most critical part of training — role-play scenarios where a buyer says 'no' to recording (agent must gracefully proceed without recording). Create a Slack/Teams channel called #showinginsight-support for agent questions.
Step 13: Post-Deployment Monitoring & Optimization
After going live, monitor the system for 2 weeks to verify data flow, accuracy, and agent adoption. Check Zapier task logs daily, review sentiment analysis quality, verify CRM notes are appearing correctly, and track agent usage rates. Fix any issues identified during the monitoring period.
Daily Monitoring Checklist (First 2 Weeks)
Weekly Optimization
- Review any transcripts where sentiment seems miscategorized
- Adjust OpenAI prompt if patterns of misclassification emerge
- Update MLS property list in Google Sheets Properties tab
The first 2 weeks are critical for catching integration issues and establishing agent habits. The most common failure point is agent adoption — if agents aren't recording or submitting transcripts, the entire system fails. Work with the brokerage manager to make feedback submission a performance expectation. After the 2-week monitoring period, transition to the monthly maintenance cadence described in the Maintenance section.
Custom AI Components
ShowingFeedbackAnalyzer
Type: prompt The core GPT-5.4 Mini system prompt that analyzes a raw transcript of a post-showing feedback conversation and extracts structured sentiment data, buyer themes, objections, and purchase likelihood. This prompt is used in the Zapier workflow's OpenAI step and can also be called directly via the API for testing or batch processing.
Implementation
You are an expert real estate showing feedback analyst working for a residential real estate brokerage. Your job is to analyze transcripts of conversations between listing agents and buyer's agents (or buyers directly) that occur after a property showing.
Analyze the provided transcript and return a JSON object with EXACTLY these fields:
{
"mls_number": "string - Extract MLS number if mentioned, otherwise 'NEEDS_MANUAL_ENTRY'",
"property_address": "string - Extract property address if mentioned, otherwise 'Unknown'",
"overall_sentiment_score": "float between -1.0 (extremely negative) and 1.0 (extremely positive). 0.0 is neutral.",
"sentiment_label": "string - exactly one of: 'Very Negative' | 'Negative' | 'Neutral' | 'Positive' | 'Very Positive'",
"purchase_likelihood": "integer 1-5 where 1=No interest, 2=Unlikely, 3=Maybe, 4=Interested, 5=Very likely to make offer",
"positive_themes": ["array of specific positive aspects mentioned, e.g. 'Updated kitchen', 'Natural light', 'Quiet street'"],
"negative_themes": ["array of specific negative aspects mentioned, e.g. 'Small backyard', 'Outdated bathrooms', 'Street noise'"],
"specific_objections": ["array of deal-breaker or significant concerns, e.g. 'Price too high vs. comps', 'Needs new roof', 'School district concern'"],
"price_feedback": "string summarizing any comments about listing price, or null if not discussed",
"condition_feedback": "string summarizing comments about property condition/repairs, or null if not discussed",
"location_feedback": "string summarizing comments about location/neighborhood, or null if not discussed",
"buyer_next_steps": "string - what the buyer indicated they want to do next (e.g. 'Second showing requested', 'Will submit offer', 'Not interested', 'Thinking about it')",
"summary": "string - 2-3 sentence executive summary of the feedback suitable for a listing agent to read quickly"
}
Rules:
1. Base your analysis ONLY on what is explicitly stated in the transcript. Do not infer or fabricate information.
2. If the transcript is too short or unclear to determine a field, use null for optional fields or 'Unknown' for strings.
3. Sentiment scoring guide: casual positive comments = 0.3-0.5, enthusiastic praise = 0.6-0.9, mild concerns = -0.1 to -0.3, strong objections = -0.4 to -0.7, deal-killer negativity = -0.8 to -1.0. Most feedback calls land between -0.3 and 0.7.
4. Purchase likelihood guide: If buyer says they want to make an offer = 5. If they want a second showing = 4. If they say 'we'll think about it' = 3. If they have major concerns but didn't say no = 2. If they explicitly passed = 1.
5. For positive_themes and negative_themes, be specific — use the actual features mentioned, not generic categories.
6. NEVER include personally identifiable information about the buyers (names, financial details, family composition) in the themes or summary. Focus on property feedback only.
7. Return ONLY the JSON object, no additional text.MLS Property Matcher
Type: workflow
A Zapier Code step that attempts to match a transcript's property reference to the brokerage's active listing database. It searches for MLS numbers, street addresses, or property nicknames in the transcript text and returns the matched MLS number and property details. This reduces the need for manual MLS# entry by agents.
Implementation
transcript from Fireflies/PLAUD transcript text, and map properties_json from a Zapier Storage or Lookup Table containing the brokerage's active listings as JSON.// MLS Property Matcher
// Attempts to find which property the feedback is about by searching the transcript
const transcript = (inputData.transcript || '').toLowerCase();
let properties = [];
try {
properties = JSON.parse(inputData.properties_json || '[]');
} catch(e) {
// If properties JSON fails to parse, return unknown
return { mls_number: 'NEEDS_MANUAL_ENTRY', property_address: 'Unknown', confidence: 'none' };
}
let bestMatch = null;
let bestScore = 0;
for (const prop of properties) {
let score = 0;
// Check for MLS number match (highest confidence)
if (prop.mls_number && transcript.includes(prop.mls_number.toLowerCase())) {
score += 100;
}
// Check for street number + street name match
if (prop.address) {
const addressParts = prop.address.toLowerCase().split(/[\s,]+/);
const streetNumber = addressParts[0];
const streetName = addressParts.slice(1, 3).join(' ');
if (streetNumber && transcript.includes(streetNumber)) {
score += 20;
}
if (streetName && streetName.length > 3 && transcript.includes(streetName)) {
score += 40;
}
// Full address match
if (transcript.includes(prop.address.toLowerCase())) {
score += 80;
}
}
// Check for subdivision/community name
if (prop.subdivision && prop.subdivision.length > 3 && transcript.includes(prop.subdivision.toLowerCase())) {
score += 15;
}
if (score > bestScore) {
bestScore = score;
bestMatch = prop;
}
}
if (bestMatch && bestScore >= 40) {
return {
mls_number: bestMatch.mls_number,
property_address: bestMatch.address,
list_price: bestMatch.list_price || '',
listing_agent: bestMatch.listing_agent || '',
confidence: bestScore >= 80 ? 'high' : 'medium'
};
} else {
return {
mls_number: 'NEEDS_MANUAL_ENTRY',
property_address: 'Unknown',
list_price: '',
listing_agent: '',
confidence: 'none'
};
}To populate properties_json, create a Zapier Storage entry or Lookup Table that is updated weekly from the client's MLS export. Use the following format: [{"mls_number":"12345678","address":"123 Oak Street","list_price":"$450,000","listing_agent":"John Smith","subdivision":"Oak Hills"}]
WeeklySentimentDigest
Type: prompt A GPT-5.4 Mini prompt that generates a weekly email digest summarizing showing feedback across all properties. It takes the week's aggregated data from Google Sheets and produces a human-readable report for the brokerage's Broker of Record and listing agents, highlighting properties with the most positive/negative sentiment, trending objections, and recommended actions.
Implementation
You are a real estate market intelligence analyst. Generate a concise weekly showing feedback digest email for a real estate brokerage's management team.
You will receive a JSON array of this week's showing feedback records. Each record contains: mls_number, property_address, list_price, listing_agent, overall_sentiment_score, sentiment_label, purchase_likelihood, positive_themes, negative_themes, specific_objections, price_feedback, buyer_next_steps.
Generate an email body (plain text with markdown formatting) with these sections:
## 📊 Weekly ShowingInsight Digest — [date range]
### Summary
- Total feedback sessions this week: [count]
- Average sentiment: [score] ([label])
- Average purchase likelihood: [X]/5
- Properties with feedback: [count]
### 🏆 Top Performing Properties (highest avg sentiment)
List top 3 properties by average sentiment with their address, sentiment score, and what buyers loved.
### ⚠️ Properties Needing Attention (lowest avg sentiment)
List bottom 3 properties by average sentiment with their address, sentiment score, and common objections.
### 💰 Price Feedback Alerts
List any properties where buyers specifically commented on price being too high, with the exact feedback.
### 📋 Most Common Objections This Week
Ranked list of the top 5 most frequently mentioned objections across all properties.
### 🎯 Recommended Actions
Based on the data, suggest 2-3 specific actions (e.g., 'Consider price reduction on [address]', 'Schedule maintenance for [issue] at [address]').
### 📈 Offer Pipeline
List any feedback sessions where purchase_likelihood was 4 or 5, with the property and buyer's next steps.
Keep the tone professional but conversational. Use actual data from the records provided. If fewer than 3 properties in a category, list whatever is available.Schedule a Zapier Zap to run every Monday at 7am:
Alternatively, use Google Apps Script to fetch rows, call OpenAI API, and send via Gmail on a weekly timer.
ConsentVerificationGuard
Type: workflow A validation step inserted at the beginning of every processing pipeline that checks whether recording consent was confirmed before allowing the transcript to proceed through sentiment analysis and CRM storage. This is a critical compliance safeguard ensuring no unconsented recordings are processed or stored.
Implementation
Zapier Filter + Code step inserted as Step 2 in every Zap that processes transcripts.
For Fireflies.ai Transcripts
Fireflies automatically records calls where the bot joins. The consent check is procedural:
const transcript = (inputData.transcript || '').toLowerCase();
const first500 = transcript.substring(0, 500);
const consentPhrases = [
'recorded', 'recording', 'is that okay', 'permission to record',
'do you consent', 'being recorded', 'record this call',
'okay with you', 'mind if i record', 'agree to be recorded'
];
let consentDetected = false;
let matchedPhrase = '';
for (const phrase of consentPhrases) {
if (first500.includes(phrase)) {
consentDetected = true;
matchedPhrase = phrase;
break;
}
}
return {
consent_detected: consentDetected,
consent_phrase_matched: matchedPhrase,
requires_manual_review: !consentDetected
};For PLAUD Google Form Transcripts
The Google Form includes a required checkbox: 'I confirm all parties were informed of and consented to recording.'
- Zapier Filter: Only continue if 'Consent Confirmed' field = TRUE
- If FALSE or empty → do not process; alert MSP admin
Quarantine Workflow
Transcripts failing consent verification are never sent to OpenAI for analysis and are never pushed to the CRM. They must be reviewed manually within 48 hours.
PropertySentimentAggregator
Type: integration A Google Apps Script that runs on a timed trigger to aggregate individual feedback records into per-property summary statistics. It updates the Properties tab in the Google Sheet with running averages, counts, and trend indicators that feed the Looker Studio dashboard.
Implementation
// aggregatePropertySentiment() and createDailyTrigger()
function aggregatePropertySentiment() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const feedbackSheet = ss.getSheetByName('Feedback Records');
const propertiesSheet = ss.getSheetByName('Properties');
if (!feedbackSheet || !propertiesSheet) {
Logger.log('Error: Required sheets not found');
return;
}
// Get all feedback data (skip header row)
const feedbackData = feedbackSheet.getDataRange().getValues();
const headers = feedbackData[0];
// Find column indices
const mlsCol = headers.indexOf('MLS Number');
const addressCol = headers.indexOf('Property Address');
const priceCol = headers.indexOf('List Price');
const agentCol = headers.indexOf('Listing Agent');
const sentimentCol = headers.indexOf('Overall Sentiment Score');
const likelihoodCol = headers.indexOf('Purchase Likelihood');
const dateCol = headers.indexOf('Date');
const negThemesCol = headers.indexOf('Key Negative Themes');
if (mlsCol === -1 || sentimentCol === -1) {
Logger.log('Error: Required columns not found');
return;
}
// Aggregate by MLS number
const propertyMap = {};
for (let i = 1; i < feedbackData.length; i++) {
const row = feedbackData[i];
const mls = String(row[mlsCol]).trim();
if (!mls || mls === '' || mls === 'NEEDS_MANUAL_ENTRY') continue;
if (!propertyMap[mls]) {
propertyMap[mls] = {
address: row[addressCol] || '',
listPrice: row[priceCol] || '',
listingAgent: row[agentCol] || '',
sentimentScores: [],
likelihoodScores: [],
dates: [],
objections: []
};
}
const sentiment = parseFloat(row[sentimentCol]);
if (!isNaN(sentiment)) {
propertyMap[mls].sentimentScores.push(sentiment);
}
const likelihood = parseInt(row[likelihoodCol]);
if (!isNaN(likelihood)) {
propertyMap[mls].likelihoodScores.push(likelihood);
}
if (row[dateCol]) {
propertyMap[mls].dates.push(new Date(row[dateCol]));
}
if (row[negThemesCol]) {
propertyMap[mls].objections.push(String(row[negThemesCol]));
}
}
// Calculate aggregates and write to Properties sheet
// Clear existing data (keep header)
const lastRow = propertiesSheet.getLastRow();
if (lastRow > 1) {
propertiesSheet.getRange(2, 1, lastRow - 1, 10).clearContent();
}
const outputRows = [];
for (const [mls, data] of Object.entries(propertyMap)) {
const avgSentiment = data.sentimentScores.length > 0
? (data.sentimentScores.reduce((a, b) => a + b, 0) / data.sentimentScores.length).toFixed(3)
: 'N/A';
const avgLikelihood = data.likelihoodScores.length > 0
? (data.likelihoodScores.reduce((a, b) => a + b, 0) / data.likelihoodScores.length).toFixed(1)
: 'N/A';
// Calculate trend (last 3 vs previous 3)
let trend = 'Stable';
if (data.sentimentScores.length >= 6) {
const recent3 = data.sentimentScores.slice(-3).reduce((a, b) => a + b, 0) / 3;
const prev3 = data.sentimentScores.slice(-6, -3).reduce((a, b) => a + b, 0) / 3;
if (recent3 > prev3 + 0.1) trend = '📈 Improving';
else if (recent3 < prev3 - 0.1) trend = '📉 Declining';
}
// Most recent feedback date
const lastFeedback = data.dates.length > 0
? new Date(Math.max(...data.dates.map(d => d.getTime())))
: '';
// Top objection (most frequent)
const objectionCounts = {};
data.objections.forEach(obj => {
obj.split(';').forEach(o => {
const trimmed = o.trim().toLowerCase();
if (trimmed) objectionCounts[trimmed] = (objectionCounts[trimmed] || 0) + 1;
});
});
const topObjection = Object.entries(objectionCounts)
.sort((a, b) => b[1] - a[1])[0];
outputRows.push([
mls,
data.address,
data.listPrice,
data.listingAgent,
data.sentimentScores.length, // Total feedback count
avgSentiment,
avgLikelihood,
trend,
topObjection ? topObjection[0] : '',
lastFeedback ? Utilities.formatDate(lastFeedback, Session.getScriptTimeZone(), 'yyyy-MM-dd') : ''
]);
}
if (outputRows.length > 0) {
propertiesSheet.getRange(2, 1, outputRows.length, 10).setValues(outputRows);
}
Logger.log('Aggregation complete. ' + outputRows.length + ' properties updated.');
}
// Set up daily trigger
function createDailyTrigger() {
// Delete existing triggers to avoid duplicates
const triggers = ScriptApp.getProjectTriggers();
triggers.forEach(trigger => {
if (trigger.getHandlerFunction() === 'aggregatePropertySentiment') {
ScriptApp.deleteTrigger(trigger);
}
});
// Create new daily trigger at 6 AM
ScriptApp.newTrigger('aggregatePropertySentiment')
.timeBased()
.everyDays(1)
.atHour(6)
.create();
Logger.log('Daily trigger created for 6 AM.');
}The Properties tab headers should be: MLS Number | Property Address | List Price | Listing Agent | Total Feedback Count | Avg Sentiment Score | Avg Purchase Likelihood | Trend | Top Objection | Last Feedback Date
Testing & Validation
Client Handoff
Conduct a 2-hour handoff meeting with the Broker of Record and designated office administrator covering these topics:
Documentation to Leave Behind
- Printed quick-reference cards for all agents (consent scripts + device instructions)
- Architecture diagram (one-page, laminated)
- Troubleshooting runbook (5-page PDF in shared Google Drive folder)
- API key inventory document (encrypted, shared with office admin)
- Compliance checklist (consent requirements by state, data retention policy, CCPA procedures)
- Contact information for MSP support with escalation tiers
- Google Drive folder with: training recording, all documentation, consent script templates, showing agreement addendum template
Maintenance
Monthly Maintenance Tasks (2-4 hours/month)
Quarterly Tasks
- Review and update the GPT-5.4 Mini prompt based on accumulated misclassification patterns
- Review Zapier plan usage and adjust tier if task volume has changed
- Conduct a 15-minute check-in call with the Broker of Record to review system performance and discuss any desired changes
- Update consent scripts if the brokerage expands to new states
- Review PLAUD NotePin device health (battery degradation, physical condition)
Annual Tasks
- Renegotiate software subscription pricing (Fireflies, PLAUD AI)
- Archive previous year's Google Sheet data to a separate workbook
- Full compliance audit of all stored recordings and transcripts
- Technology refresh assessment — evaluate new transcription models, new hardware options
SLA Considerations
- Target system uptime: 99% (cloud-dependent; primary risk is Zapier or API outages)
- Maximum acceptable processing delay: 30 minutes from recording to CRM note
- Response time for system-down issues: 4 business hours
- Response time for agent support questions: 1 business day
- Escalation path: Agent → Brokerage Office Admin → MSP Tier 1 (email/ticket) → MSP Tier 2 (API/integration issues) → Vendor support (Fireflies, PLAUD, OpenAI)
Alternatives
...
Dialpad AI-Native UCaaS Replacement
Replace the brokerage's existing phone system entirely with Dialpad, which includes built-in call recording, real-time transcription, AI-powered sentiment analysis, and call analytics in a single platform. This eliminates the need for Fireflies.ai, reduces the Zapier workflow complexity, and provides a unified communications platform. Dialpad's built-in AI Voice Intelligence (Vi) detects sentiment, keywords, and action items natively.
Self-Hosted Whisper + Open Source Stack
Replace all paid transcription APIs with self-hosted OpenAI Whisper (open source) running on a local GPU workstation or cloud GPU instance. Pair with open-source sentiment analysis (e.g., Hugging Face transformers with a fine-tuned model). Use n8n (self-hosted, free) instead of Zapier for workflow automation. This approach minimizes recurring SaaS costs and keeps all data on infrastructure the MSP controls.
Recommended when: the brokerage processes 1,000+ calls/month (cost savings justify complexity), or when data sovereignty requirements prohibit sending audio to third-party cloud services. Not recommended for: brokerages under 30 agents where the operational complexity isn't justified.
Otter.ai + Google Sheets Manual Workflow
Use Otter.ai Business ($20/user/month) as a simpler turnkey transcription platform. Agents review transcripts in Otter, manually tag them with MLS numbers and a 1-5 sentiment rating, then the MSP sets up a basic Zapier workflow to push tagged transcripts to a Google Sheet. No OpenAI API, no custom sentiment analysis — agents provide their own sentiment assessment. Dashboard still built in Looker Studio.
Viirtue White-Label UCaaS with Native Sentiment
For MSPs who want to maximize recurring revenue and brand control, deploy Viirtue's white-label UCaaS platform with native sentiment analysis built in. The MSP becomes the brokerage's branded phone and communications provider, with AI sentiment analysis as a built-in feature rather than a bolt-on. Requires the MSP to become a Viirtue reseller partner.
AssemblyAI All-in-One API Approach
Replace both Fireflies.ai and OpenAI with AssemblyAI's Universal API, which provides transcription, speaker diarization, sentiment analysis, entity detection, topic detection, and summarization in a single API call. This reduces the number of vendors and simplifies the pipeline to: audio → AssemblyAI → structured data → CRM.
Want early access to the full toolkit?