Drift
"Drift: conversational marketing, live chat, chatbots, meeting scheduling, contact management, REST API, webhooks, JavaScript SDK"
You are an expert in integrating Drift for conversational support, live chat, chatbot playbooks, and meeting routing. ## Key Points - Route conversations using Drift's Playbook targeting rules rather than building custom routing logic; Playbooks can filter by URL, contact attributes, visit count, and time on page. - Store the Drift `conversationId` and `contactId` in your own system to correlate support interactions with internal user records and enable cross-platform reporting. - Drift's API rate limits are not publicly documented in detail; implement exponential backoff on `429` responses and avoid polling conversation lists more frequently than once per minute.
skilldb get customer-support-services-skills/DriftFull skill: 242 linesDrift — Customer Support Integration
You are an expert in integrating Drift for conversational support, live chat, chatbot playbooks, and meeting routing.
Core Philosophy
Overview
Drift (now part of Salesloft) is a conversational marketing and support platform that combines live chat, AI-powered chatbots (Playbooks), meeting scheduling, and contact enrichment. It is designed to convert website visitors into leads and route support queries to the right agents. The REST API provides access to conversations, contacts, messages, and account data. The JavaScript SDK controls the on-page chat widget behavior.
Setup & Configuration
Authenticate with an OAuth2 access token:
import axios, { AxiosInstance } from "axios";
function createDriftClient(accessToken: string): AxiosInstance {
return axios.create({
baseURL: "https://driftapi.com",
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
});
}
const drift = createDriftClient(process.env.DRIFT_ACCESS_TOKEN!);
// Verify connection
async function verifyConnection(): Promise<void> {
const response = await drift.get("/users/list");
console.log(`Connected. ${response.data.data.length} agents found.`);
}
Embed the chat widget and control it via the JavaScript SDK:
<script>
!function() {
var t = window.driftt = window.drift = window.driftt || [];
if (!t.init) {
t.invoked = true;
t.methods = ["identify", "config", "track", "reset", "debug", "show",
"ping", "page", "hide", "off", "on"];
t.factory = function(e) {
return function() {
var n = Array.prototype.slice.call(arguments);
n.unshift(e);
t.push(n);
return t;
};
};
t.methods.forEach(function(e) { t[e] = t.factory(e); });
t.load = function(t) {
var e = document.createElement("script");
e.type = "text/javascript";
e.async = true;
e.src = "https://js.driftt.com/include/" + t + ".js";
var n = document.getElementsByTagName("script")[0];
n.parentNode.insertBefore(e, n);
};
}
}();
drift.SNIPPET_VERSION = '0.3.1';
drift.load('YOUR_DRIFT_EMBED_ID');
</script>
Identify logged-in users:
declare global {
interface Window {
drift: {
identify: (userId: string, attrs: Record<string, unknown>) => void;
on: (event: string, callback: (...args: any[]) => void) => void;
show: () => void;
hide: () => void;
};
}
}
function identifyUser(userId: string, email: string, attributes: Record<string, unknown> = {}): void {
window.drift.identify(userId, {
email,
...attributes,
});
}
// Example: pass plan and company info
identifyUser("user_12345", "jane@acme.com", {
company: "Acme Corp",
plan: "enterprise",
createdAt: 1640000000,
});
Core Patterns
Send a Message in a Conversation
interface DriftMessage {
conversationId: number;
body: string;
type?: "chat" | "private_prompt";
}
async function sendMessage(params: DriftMessage): Promise<any> {
const response = await drift.post(
`/conversations/${params.conversationId}/messages`,
{
type: params.type ?? "chat",
body: params.body,
}
);
return response.data.data;
}
List and Filter Conversations
async function getConversations(statusId?: number): Promise<any[]> {
const params: Record<string, unknown> = {};
if (statusId !== undefined) {
params.statusId = statusId; // 1=open, 2=closed, 3=pending
}
const response = await drift.get("/conversations/list", { params });
return response.data.data;
}
// Get conversation details with messages
async function getConversationWithMessages(conversationId: number): Promise<any> {
const [convo, messages] = await Promise.all([
drift.get(`/conversations/${conversationId}`),
drift.get(`/conversations/${conversationId}/messages`),
]);
return {
conversation: convo.data.data,
messages: messages.data.data,
};
}
Manage Contacts
interface DriftContact {
email: string;
attributes: Record<string, unknown>;
}
async function createOrUpdateContact(contact: DriftContact): Promise<any> {
// Drift auto-merges contacts by email
const response = await drift.post("/contacts", {
attributes: {
email: contact.email,
...contact.attributes,
},
});
return response.data.data;
}
// Retrieve a contact by email
async function findContactByEmail(email: string): Promise<any | null> {
const response = await drift.get("/contacts", {
params: { email },
});
const contacts = response.data.data;
return contacts.length > 0 ? contacts[0] : null;
}
Webhook Handler
import express, { Request, Response } from "express";
import crypto from "crypto";
function verifyDriftWebhook(body: string, signature: string, secret: string): boolean {
const expected = crypto.createHmac("sha256", secret).update(body).digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}
function setupDriftWebhooks(app: express.Application): void {
app.post("/webhooks/drift", express.text({ type: "*/*" }), (req: Request, res: Response) => {
const signature = req.headers["x-drift-signature"] as string;
if (!verifyDriftWebhook(req.body, signature, process.env.DRIFT_WEBHOOK_SECRET!)) {
res.sendStatus(401);
return;
}
const event = JSON.parse(req.body);
switch (event.type) {
case "new_conversation":
handleNewConversation(event.data);
break;
case "new_message":
handleNewMessage(event.data);
break;
case "conversation_status_updated":
handleStatusChange(event.data);
break;
}
res.sendStatus(200);
});
}
Best Practices
- Use
drift.identify()on every authenticated page load with up-to-date user attributes; this ensures agents see current account context in the sidebar and Playbook targeting rules evaluate correctly. - Route conversations using Drift's Playbook targeting rules rather than building custom routing logic; Playbooks can filter by URL, contact attributes, visit count, and time on page.
- Store the Drift
conversationIdandcontactIdin your own system to correlate support interactions with internal user records and enable cross-platform reporting.
Common Pitfalls
- The Drift JavaScript snippet must load before calling
drift.identify(). If you call identify too early, the call is silently dropped. Usedrift.on("ready", callback)to defer identity calls until the SDK is initialized. - Drift's API rate limits are not publicly documented in detail; implement exponential backoff on
429responses and avoid polling conversation lists more frequently than once per minute.
Anti-Patterns
Using the service without understanding its pricing model. Cloud services bill differently — per request, per GB, per seat. Deploying without modeling expected costs leads to surprise invoices.
Hardcoding configuration instead of using environment variables. API keys, endpoints, and feature flags change between environments. Hardcoded values break deployments and leak secrets.
Ignoring the service's rate limits and quotas. Every external API has throughput limits. Failing to implement backoff, queuing, or caching results in dropped requests under load.
Treating the service as always available. External services go down. Without circuit breakers, fallbacks, or graceful degradation, a third-party outage becomes your outage.
Coupling your architecture to a single provider's API. Building directly against provider-specific interfaces makes migration painful. Wrap external services in thin adapter layers.
Install this skill directly: skilldb add customer-support-services-skills
Related Skills
Crisp
"Crisp: live chat widget, chatbot scenarios, CRM contacts, campaigns, helpdesk, REST API, JavaScript SDK, webhooks"
Freshdesk
"Freshdesk: ticket management, contact CRUD, automations, canned responses, REST API v2, webhooks, satisfaction surveys"
Help Scout
"Help Scout: conversation management, mailbox API, customer profiles, Beacon widget, webhooks, Docs knowledge base, REST API v2"
Intercom
"Intercom: Messenger widget, conversations API, custom bots, product tours, help center, user/company data, events, webhooks, Node SDK"
LiveChat
"LiveChat: real-time chat, ticket system, agent management, chat archives, customer SDK, REST API v3, webhooks, rich messages"
Tawk.to
"Tawk.to: free live chat widget, JavaScript API, visitor monitoring, triggers, REST API, webhooks, customization"