Send Conversation Transcript Workflow (Assistable → GoHighLevel)

🔹 Workflow Summary

This workflow:

1. Triggers when Appointment Status changes to Booked
2. Calls Assistable API to fetch conversation messages
3. Custom Code formats the transcript into:
→ 📄 Converts raw AI data into clean text 
4. Email / staff notification sends transcript to relevant parties


🔹 Component Overview

Step Action Purpose
1 Trigger: Appointment Status Booked Begin workflow only when a booking is set
2 Custom Webhook (Assistable API) Fetch conversation message logs
3 Custom Code Format raw message JSON into readable transcript
4 Email or Internal Notification Deliver transcript to recipient

🧠 Step-by-Step Setup Instructions

 Step 1 — Trigger

  • Trigger: Appointment Status Changed

  • Status: Booked

No further config required


 Step 2 — Custom Webhook (API Request)

Field Value
Event GET
URL https://api.assistable.ai/v2/get-conversation
Header Authorization → Bearer {{Your_v2_api_key}}
Query Param #1 contact_id → {{contact.id}}
Query Param #2 location_id → {{location.id}} (or static if preferred)
Save Response ✅ ENABLED

Should show: Request success status: 200


 Step 3 — Custom Code Formatting

Property Mapped:

message = {{custom_webhook.1.response.messages}}

Paste EXACT code below:

const raw = inputData.message;

// ---------- Parse safely ----------
let parsed = raw;
if (typeof raw === "string") {
  try { parsed = JSON.parse(raw); } catch { parsed = raw; }
}

// ---------- Find messages ----------
function findMessages(obj) {
  if (!obj) return null;
  if (Array.isArray(obj)) return obj;
  if (obj.messages) return obj.messages;
  if (obj.response && obj.response.messages) return obj.response.messages;
  if (obj.data && obj.data.messages) return obj.data.messages;
  return null;
}

const messages = findMessages(parsed);

if (!messages || !Array.isArray(messages)) {
  return {
    transcript: "No valid messages found.",
    transcript_html: "<p><em>No valid messages found.</em></p>",
    debug: parsed
  };
}

// ---------- Build proper line-by-line transcript ----------
const lines = messages
  .filter(m => ["assistant", "user"].includes(m.role))
  .map(m => {
    const sender = m.role === "assistant" ? "🤖 AI" : "🧍 Lead";
    const txt =
      typeof m.content === "string"
        ? m.content.trim()
        : JSON.stringify(m.content);
    return `<p style="margin:8px 0;"><strong>${sender}:</strong> ${txt}</p>`;
  });

// ---------- Plain text ----------
const transcript = lines
  .map(l => l.replace(/<[^>]+>/g, ""))
  .join("\n\n");

// ---------- Proper HTML ----------
const transcript_html = `
<div style="
  font-family:Arial, sans-serif;
  font-size:15px;
  line-height:1.6;
  color:#222;
  background:#f9fafb;
  border:1px solid #e5e7eb;
  border-radius:8px;
  padding:14px;">
  <p><strong>🗒️ Transcript Details:</strong></p>
  ${lines.join("\n")}
</div>
`;

return {
  transcript: transcript,
  transcript_html: transcript_html
};

 Output Variables Created:

  • {{custom_code.2.output.transcript}}


 Step 4 — Email or Internal Notification

Insert into the email body:

 For pure text fallback:

{{custom_code.2.output.transcript}}

TEST EMAIL

IMPORTANT — Required After Import

(Include this in your internal note!)

Users MUST:

 Open the Custom Code step
 Click Save Code (no edits needed)
 Publish workflow

Because GHL disables imported scripts until manually confirmed.


 Verification Checklist

Task Status
Webhook returns 200 OK ☐
Transcript output appears in internal notification ☐
Email displays formatted transcript correctly ☐
Code step re-saved post-import ☐
Workflow Published ☐

📎 Deliverables Included

✅ Assistable API integration
✅ Transcript formatting engine
✅ Workflow messaging delivery
✅ Custom code with HTML styling


 Result

Fully automated transcript delivery from Assistable → GoHighLevel → Inbox ✅


Was this article helpful?