Send handoffs to Slack
When a visitor asks to talk to a person, post it to a Slack channel within seconds, with the page they were on and a link to the conversation. You need: a Slack incoming webhook URL for the channel, and somewhere to run a small HTTPS function (a serverless function, a container or an existing server).server.mjs
1
Deploy the function
Deploy it so it is reachable at an HTTPS address, for example
https://hooks.example.com/darwin. Set SLACK_WEBHOOK_URL now; you’ll get DARWIN_WEBHOOK_SECRET in the next step.2
Add the endpoint in Darwin
In Settings → API → Webhooks, select Add endpoint, paste the address, choose only
handoff.requested, and select Add endpoint. Copy the signing secret into DARWIN_WEBHOOK_SECRET and redeploy.3
Test it
Select Send test event in the endpoint’s menu. Darwin should report a
200. The test event’s type is webhook.test, so nothing is posted to Slack.It worked if, after someone asks the chat on your live site to talk to a person, a message appears in the channel within a few seconds.meeting.booked to a sales channel or lead.captured to an SDR queue: subscribe to the type and read data.object. See Webhooks for every payload.
Sync leads to a CRM
Copy every contact Darwin captures into your CRM every 15 minutes, and record Darwin’s contact id back so later runs update the same record. You need: a key withcontacts:read (and contacts:write if you write the CRM’s id back), and a place to keep one timestamp between runs.
sync-contacts.mjs
lastRun, copies every contact.
- Writing
external_idchanges the contact, so it comes back once in the next run. Theif (!contact.external_id)check makes that second pass a no-op. - Each contact can have one
external_id, unique in the workspace. Two contacts with the same id return409conflict. - For the conversation behind a lead, list
GET /v1/conversations?has_lead=true&updated_since=…and match oncontact. - If you’d rather not poll, subscribe a webhook to
lead.capturedand upsert the contact indata.object. Keep this job as a nightly safety net for any webhook you miss.
GET /v1/contacts?email=… shows the CRM’s id as external_id.
Export conversations to your warehouse nightly
Load every conversation, with its transcript and Darwin’s grading, into BigQuery, Snowflake, Redshift or plain files each night. You need: a key withconversations:read. Leave out contacts:read if the warehouse should not hold names and emails: lead and booker fields then come back null (transcripts still hold whatever visitors typed).
export-conversations.mjs
id, merging over yesterday’s rows. Useful columns:
Add
GET /v1/meetings?updated_since=… and GET /v1/analytics?range=7d to the same job for meetings and daily funnel numbers.
It worked if the morning’s file has one line per conversation from the last three days and yesterday’s graded conversations have a non-null evaluation.