Skip to main content

GoHighLevel Integration

Connect TrolleyShield to GoHighLevel (GHL) to analyze calls and forms directly from GHL workflows. When installed, two custom workflow actions become available: Analyze Call and Analyze Form.

Phone numbers and number pools are synced automatically from your GHL location. Conversion settings are configured per-workflow, giving you full control over which Google Ads conversions to fire and when.

Requirements

  • A paid plan with API access (any Call Shield plan, or Form Pro/Business)
  • A GoHighLevel account with workflow access

Setup

1. Install the App

  1. Go to Settings → Integrations → GoHighLevel in the TrolleyShield dashboard
  2. Click Connect GoHighLevel
  3. You'll be redirected to GoHighLevel to select a location
  4. Authorize TrolleyShield to access your GHL account
  5. You'll be redirected back to TrolleyShield with a success confirmation
  6. Phone numbers and number pools are synced automatically on connect

2. Add Workflow Actions

Once connected, two custom actions are available in GHL's workflow builder:

  1. Open a workflow in GoHighLevel (Automation → Workflows)
  2. Add a new action step
  3. Search for TrolleyShield in the action list
  4. Select Analyze Call or Analyze Form
  5. Configure the action fields (see below)
  6. Use IF/ELSE branches on the output variables to route contacts

Workflow Actions

Analyze Call

Analyze a call transcript or recording using TrolleyShield's AI. Creates a full call record in the TrolleyShield dashboard with AI analysis, and optionally fires Google Ads conversions.

Trigger: Use "Transcript Generated", not "Call Completed"

GHL's Call Completed trigger does not expose the call transcript or recording URL. You must use the Transcript Generated trigger so the transcript is available to map.

To enable transcriptions in GHL:

  1. Go to Settings → Phone Numbers → Advanced Settings
  2. Enable Call Transcriptions under Voice Calls
  3. On each number, click the three dots → Edit Configuration → enable Call Recording

Transcription is a paid GHL feature (~$0.03/minute on top of call recording).

Input Fields:

FieldTypeRequiredDescription
TranscripttextareaYes*Call transcript text. Map to {{transcript_generated.call_transcript}}
Recording URLstringYes*URL to audio recording for automatic transcription. Map to {{transcript_generated.recording_url}}
Caller NumberstringNoCaller phone number. Map to {{transcript_generated.call_from}}
Caller NamestringNoCaller ID name. Map to {{contact.name}} or {{contact.firstName}} {{contact.lastName}}
Called NumberstringNoThe number that was called. Map to {{transcript_generated.call_to}}. Used to match against synced tracking numbers
Duration (seconds)numberNoCall duration in seconds. Map to {{transcript_generated.call_duration}}
Call TimestringNoWhen the call occurred. Map to {{transcript_generated.call_start_time}}
External Call IDstringNoUnique identifier to prevent duplicate processing
Landing PagestringNoThe full landing page URL with query string. Map to {{contact.attributionSource.url}}. TrolleyShield parses gclid, gbraid, wbraid, fbclid, msclkid, and all utm_* parameters out of this URL automatically — you do not need to map them individually.
ReferrerstringNoReferrer URL. Map to {{contact.attributionSource.referrer}}
GA Client IDstringNoGoogle Analytics client ID for GA4 session stitching. Map to {{contact.attributionSource.gaClientId}}
Call ContexttextareaNoDescribe what this tracking number or campaign is for (e.g. "Google Ads campaign for bathroom remodeling leads"). Helps the AI understand what a qualified call looks like for this workflow. Your account-level business description is always included automatically.
Conversion ActiondropdownNoSelect a Google Ads conversion action from your connected account
Conversion Tagsmulti-selectNoOnly fire conversions when the AI tags the call with one of these services. Leave empty for any qualifying call. Populated from your service tags.
Conversion ValuenumberNoDollar value to report for this conversion
Min ConfidencenumberNoMinimum AI confidence score to trigger a conversion (default: 80)
Min Duration (sec)numberNoMinimum call duration to trigger a conversion (default: 60)

* Either Transcript or Recording URL is required.

Hidden Fields (configured once, not visible to workflow users):

FieldDefault Value
Location ID{{location.id}}
Contact ID{{contact.id}}

Output Variables (available in subsequent workflow steps):

VariableTypeDescription
intentstringqualified_lead, general_inquiry, existing_customer, spam, wrong_number, job_seeker, vendor, or incomplete
confidencenumberAI confidence score (0-100)
reasoningstringExplanation of the classification
actionstringRecommended action: convert, nurture, ignore, or block
tagsarrayMatched service tags (e.g. ["roofing", "gutters"]). Empty if no tags configured.
transcript_statusstringcompleted, failed, or pending
contact_idstringGHL contact ID (passed through)

Analyze Form

Analyze a form submission or contact data for spam, bots, and lead quality.

Input Fields:

FieldTypeRequiredDescription
Form DatatextareaNoFull form submission as JSON. Or map individual fields below
NamestringNoSubmitter's name. Map to {{contact.name}}
EmailstringNoSubmitter's email. Map to {{contact.email}}
PhonestringNoSubmitter's phone. Map to {{contact.phone}}
MessagetextareaNoForm message or inquiry text
Form NamestringNoIdentifies which form triggered the submission (shown in TrolleyShield dashboard)
Site URLstringNoWebsite where the form was submitted
IP AddressstringNoSubmitter's IP for spam detection
Landing PagestringNoThe full landing page URL with query string. Map to {{contact.attributionSource.url}}. TrolleyShield parses gclid, gbraid, wbraid, fbclid, msclkid, and all utm_* parameters out of this URL automatically — you do not need to map them individually.
ReferrerstringNoReferrer URL. Map to {{contact.attributionSource.referrer}}
GA Client IDstringNoGoogle Analytics client ID for GA4 session stitching. Map to {{contact.attributionSource.gaClientId}}
Form ContexttextareaNoDescribe what this form is for (e.g. "Roofing quote request form on the commercial services page"). Helps the AI distinguish real leads from spam for this form type. Your account-level business description is always included automatically.
Conversion ActiondropdownNoSelect a Google Ads conversion action
Conversion ValuenumberNoDollar value for this conversion
Min ConfidencenumberNoMinimum confidence to trigger a conversion (default: 80)
tip

You can map GHL contact fields directly instead of using the Form Data JSON field. TrolleyShield will automatically build the form data from all mapped fields. System fields (locationId, contactId) are filtered out automatically.

Hidden Fields:

FieldDefault Value
Location ID{{location.id}}
Contact ID{{contact.id}}

Output Variables (available in subsequent workflow steps):

VariableTypeDescription
intentstringlegitimate, spam, bot, phishing, irrelevant, or suspicious
confidencenumberAI confidence score (0-100)
reasoningstringExplanation of the classification
actionstringRecommended action: allow, flag, or block
tagsarrayMatched service tags (e.g. ["bathroom", "interior"]). Empty if no tags configured.
contact_idstringGHL contact ID (passed through)

Phone Number Sync

TrolleyShield automatically syncs phone numbers and number pools from your connected GHL location:

  • On connect: All numbers and pools are imported automatically
  • Manual sync: Click "Sync Numbers" in Settings → Integrations → GoHighLevel
  • Auto-sync on unknown number: When a call comes in on a number not yet in TrolleyShield, a re-sync is triggered automatically
  • Auto-create: If a number still isn't found after re-sync, it's created as a new GHL tracking number

Number pools are stored as a single tracking number with all pool numbers tracked in metadata. When any pool number receives a call, it matches to the correct pool.

Synced numbers appear in the Numbers page with GHL or GHL Pool badges. These numbers are read-only in TrolleyShield — they're managed by the GHL sync.

Conversion Tracking

Conversion settings are configured per-workflow in GHL, not in TrolleyShield:

  1. Select a Conversion Action from the dropdown (loaded from your connected Google Ads account)
  2. Set a Conversion Value (e.g. $50 for a contact form, $200 for a quote request)
  3. Set Min Confidence and Min Duration thresholds

Priority order (first non-empty value wins):

  1. Workflow action fields
  2. Tracking number settings (if configured in TrolleyShield)
  3. Account defaults

Conversions are queued when:

  • AI classifies the call/form as qualifying (e.g. intent = qualified_lead for calls, intent = legitimate for forms)
  • Confidence meets the minimum threshold
  • Duration meets the minimum (calls only)
  • A GCLID, GBRAID, or WBRAID is present for attribution

Example Workflows

Call Analysis with Conversion Tracking

Trigger: Transcript Generated
→ TrolleyShield: Analyze Call
transcript: {{transcript_generated.call_transcript}}
caller_number: {{transcript_generated.call_from}}
called_number: {{transcript_generated.call_to}}
duration: {{transcript_generated.call_duration}}
click_id: {{contact.attributionSource.gclid}}
conversion_action: [Select from dropdown]
conversion_value: 100
min_confidence: 85
min_duration: 60
→ IF/ELSE: intent = "qualified_lead"
→ Yes: Create Opportunity, Send SMS to sales team
→ No: Add tag "low-priority", Send nurture email

Form Spam Filtering

Trigger: Form Submitted
→ TrolleyShield: Analyze Form
name: {{contact.name}}
email: {{contact.email}}
phone: {{contact.phone}}
message: {{contact.message}}
form_name: "Quote Request Form"
click_id: {{contact.attributionSource.gclid}}
conversion_action: [Select from dropdown]
conversion_value: 50
→ IF/ELSE: action = "block"
→ Yes: Add tag "spam", Stop workflow
→ No: Continue to lead routing

Routing by Service Tags

If you have service tags configured, the tags output variable returns an array of matched services. You can use GHL's Array Functions (Premium) to work with this data in your workflows.

Using Array Functions with tags:

  • Find — check if a specific tag exists (e.g. find "roofing" in tags)
  • Filter — get only tags matching a condition
  • Find by Index — get the first or Nth tag

Example: Route calls by service type

Trigger: Transcript Generated
→ TrolleyShield: Analyze Call
transcript: {{transcript_generated.call_transcript}}
caller_number: {{transcript_generated.call_from}}
called_number: {{transcript_generated.call_to}}
duration: {{transcript_generated.call_duration}}
→ IF/ELSE: intent = "qualified_lead"
→ Yes:
→ Array Functions: Find "roofing" in {{tags}}
→ Found: Add to "Roofing Leads" pipeline, Notify roofing team
→ Not Found:
→ Array Functions: Find "bathroom" in {{tags}}
→ Found: Add to "Remodel Leads" pipeline
→ Not Found: Add to "General Leads" pipeline
→ No: Send nurture email

Tags are also available in Custom Code and Custom Webhooks as a standard JSON array.

tip

You don't need Array Functions for simple workflows. You can also use tags in Custom Code actions with basic JavaScript: if (tags.includes("roofing")) { ... }

Usage & Billing

  • Each call analysis counts toward your plan's call analyses limit
  • Each form analysis counts toward your plan's form analyses limit
  • Paid plans allow overages (billed automatically)
  • Trial accounts are hard-blocked at their limits
  • Synced phone numbers do not count toward your tracking number limit

Disconnecting

To disconnect GoHighLevel:

  1. Go to Settings → Integrations → GoHighLevel in TrolleyShield
  2. Click Disconnect
  3. GHL tracking numbers are deactivated (existing call/form data is retained)
  4. Optionally uninstall the app from GHL Marketplace settings

Troubleshooting

"No GHL connection found" Error

  • Ensure you completed the OAuth flow from Settings → Integrations → GoHighLevel
  • Check that you selected the correct GHL location during setup
  • The connection may have been uninstalled from the GHL side — reconnect from TrolleyShield

"API access requires a paid plan" Error

  • GHL integration requires a paid plan with API access
  • Upgrade to any Call Shield plan, or Form Pro/Business

Conversion Action Dropdown Shows "TrolleyShield not connected"

  • Ensure TrolleyShield is connected to the GHL location where you're building the workflow
  • Check that Google Ads is connected in TrolleyShield settings

"Either transcript or recording_url is required" Error (400)

The Analyze Call action needs either a transcript or a recording URL to run. This error usually means one of the following:

  • Testing the workflow without a real call — GHL only generates a transcript when an actual call is recorded and transcribed. Test runs from the workflow builder won't have a transcript value. Paste a sample transcript directly into the Transcript field temporarily, then switch back to the {{transcript_generated.call_transcript}} variable before going live.
  • Call transcription isn't enabled on the number that was called. Go to Settings → Phone Numbers → Advanced Settings and enable Call Transcriptions, then enable Call Recording on each individual number.
  • Wrong trigger — the Call Completed trigger doesn't expose a transcript. Use Transcript Generated instead.
  • Recording URL won't work as a fallback — GHL does not expose recording URLs to workflows, so only the transcript path is available for GHL calls.

Phone Numbers Not Syncing

  • Click "Sync Numbers" in Settings → Integrations → GoHighLevel
  • Ensure the GHL OAuth token hasn't expired (disconnect and reconnect if needed)
  • New numbers added in GHL are auto-synced when a call comes in on them