Webhooks + CRM + chat: automating the follow-up
A survey response should instantly become a lead, a task or an alert. Three working webhook scenarios you can set up without writing much code.
A survey without integrations is a spreadsheet in your inbox. A survey with integrations is a process: a lead in the CRM, a task for an operator, an alert in a team channel. Here are three scenarios that take about ten minutes each.
What a webhook looks like in Askyo
On every submitted response, Askyo sends an HTTP POST to your URL with JSON like this:
{
"surveyId": "nps-feedback-v3",
"responseId": "r_2k9a8b7c",
"submittedAt": "2026-04-22T10:30:00Z",
"answers": {
"score": 9,
"comment": "Really liked it, especially the graph editor",
"email": "user@example.com"
},
"variables": {
"userId": "user-42",
"plan": "pro"
},
"respondent": {
"userAgent": "Mozilla/5.0 ...",
"language": "en",
"country": "GB"
}
}
What happens next is up to you: push it to a CRM, a chat channel, your own database, or into n8n / Make / Zapier for further branching.
Scenario 1: NPS detractors go straight into the CRM
Goal: a customer scores 0–6 → create a lead, tag it retention-risk, and
assign a task to be handled within two hours.
Steps:
- In the Askyo survey editor, open Integrations and add a webhook.
- URL:
https://your-bridge.example.com/askyo-to-crmis your endpoint. It can be an n8n workflow, a make.com scenario, or a 30-line Lambda. - In Askyo set a filter: only send when
answers.score ≤ 6. That is one click, no code. - On the bridge side:
// Pseudocode: implement it on n8n, Lambda or whatever you already run
async function handle(req, res) {
const { answers, respondent } = req.body;
// Create the lead
const lead = await crm.leads.create({
name: `NPS ${answers.score}, churn risk`,
fields: {
nps: answers.score,
comment: answers.comment,
email: answers.email,
},
tags: ['retention-risk'],
});
// Task for the account manager: reach out within two hours
await crm.tasks.create({
entityId: lead.id,
entityType: 'leads',
text: `Contact NPS detractor (${answers.score}). Comment: ${answers.comment}`,
completeTill: Math.floor(Date.now() / 1000) + 2 * 3600,
});
res.status(200).send('ok');
}
Done. Every time a detractor submits, a lead and a task appear in the CRM, and the manager sees it in their normal queue.
Scenario 2: important responses into a team chat
Goal: every response from a paying customer (plan == 'pro') lands in the
product team’s group chat in real time.
Steps:
- Create a bot via @BotFather and get the token (the same idea applies to a Slack incoming webhook).
- Add the bot to the group chat and find the
chat_id: callhttps://api.telegram.org/bot<TOKEN>/getUpdatesafter posting any message. - In Askyo, add a webhook with the filter
variables.plan == 'pro'. - Use the built-in “Telegram via webhook” preset, you only fill in the token and chat id, and the message templates itself:
🔔 A Pro customer answered "NPS feedback"
⭐️ Score: {{ answers.score }}/10
💬 Comment: {{ answers.comment }}
👤 userId: {{ variables.userId }}
🌐 Country: {{ respondent.country }}
🔗 Open in Askyo: https://app.askyo.ru/r/{{ responseId }}
No code: the template lives in a visual editor. Five minutes.
Scenario 3: responses into Google Sheets for marketing
Old school, still effective: marketers like seeing data in a spreadsheet.
Steps:
- Create a sheet and add an Apps Script:
function doPost(e) {
const sheet = SpreadsheetApp.getActiveSheet();
const data = JSON.parse(e.postData.contents);
sheet.appendRow([
new Date(data.submittedAt),
data.responseId,
data.answers.score,
data.answers.comment,
data.answers.email,
data.variables.utmSource ?? '',
]);
return ContentService.createTextOutput('ok');
}
- Deploy → Web app → anyone can access.
- Copy the webhook URL.
- In Askyo: Integrations → Webhook → paste the URL. That is it.
Every response becomes a new row. No manual CSV exports.
Handling failed deliveries
Webhooks are unreliable: networks, timeouts, your server going down. Askyo:
- Performs three retries with exponential backoff (5s, 30s, 5 min).
- Keeps every attempt in a log with the response code and timestamp.
- On the fourth failure, emails the survey owner and marks the response
webhook_failed. - If a later attempt succeeds, the status updates itself.
For critical integrations (payments, billing) prefer polling via the API. We support that too, but that is a separate article.
A security checklist
A webhook accepts data from the open internet. Protect it:
- HMAC signature. Askyo signs every request with an
X-Askyo-Signature: sha256=...header. Verify it on the bridge. - Verify the signature, not the IP. An address allow-list looks solid but breaks on every infrastructure move, and it does not help if someone else ends up in the same subnet. The HMAC signature above covers the same ground better. If your internal rules still demand a fixed address, email support@askyo.ru and we will hand you the current one.
- Idempotency. Use
responseIdas a deduplication key, retries can deliver twice, and you do not want duplicate leads. - Rate limiting. During a response storm (thousands a minute) put a queue between the webhook and the CRM, most CRMs have their own rate limits.
When you do not need a webhook
If the integration is simple and needed once a day rather than in real time, use CSV export, Google Sheets or an API pull. A webhook earns its complexity when:
- you need a fast reaction (minutes, not hours),
- delivery is conditional on the answer (“detractors only”),
- there is a downstream service with its own processing logic.
Otherwise skip them and sleep better.
A ready n8n template is published in our public GitHub repository, fork it and adapt it to your stack.