· 4 min · TextMeFlow Team

Sending WhatsApp Notifications from Pipedrive Deal and Activity Webhooks

Pipedrive can fire a webhook the instant a deal moves stage, a new deal is created, or an activity is marked done. Most sales teams route that into a Slack channel nobody checks between meetings. Sending the same event to WhatsApp puts it in front of the rep who needs to act on it — a "deal won, send the contract" or "demo call in 30 minutes" message that actually gets read within minutes.

This is a webhook-to-API pattern: Pipedrive's built-in webhooks, a small receiver you host, and TextMeFlow's messages API. No marketplace app, no OAuth flow to maintain.

Step 1: Create the webhook in Pipedrive

Pipedrive webhooks are configured under Settings → Tools and apps → Webhooks (on some plans this lives under a Marketplace "Webhooks" app instead). Create a new webhook with:

  • Event: pick the object and action you want — deal.updated, deal.added, or activity.updated are the common ones for notification use cases
  • Endpoint URL: your receiver (see below)
  • HTTP Auth: set a username/password if you want Pipedrive to authenticate to your receiver — do this, since the endpoint will otherwise accept unauthenticated POSTs from anyone who finds the URL

Pipedrive sends the full object plus a previous snapshot of the object before the change, which is what makes stage-change detection possible without a second API call.

Step 2: Build a receiver that checks what actually changed

A deal.updated webhook fires on any field edit, not just stage changes — a note added, a value tweak, an owner reassignment all trigger the same event. Compare current.stage_id to previous.stage_id before deciding to send anything:

import express from 'express';
const app = express();
app.use(express.json());

app.post('/pipedrive-deal-hook', async (req, res) => {
  const { current, previous } = req.body;

  if (current.stage_id === previous?.stage_id) {
    return res.sendStatus(200); // not a stage change, ignore
  }

  const ownerPhone = current.owner_id?.phone;
  if (!ownerPhone) return res.sendStatus(200);

  await fetch('https://api.textmeflow.eu/v1/messages', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.TEXTMEFLOW_TOKEN}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      to: ownerPhone,
      text: `Deal "${current.title}" moved to stage ${current.stage_id}. Value: ${current.currency} ${current.value}.`,
    }),
  });

  res.sendStatus(200);
});

The same logic works in PHP or Python — TextMeFlow ships SDKs for both, or call the REST endpoint directly with any HTTP client.

Step 3: Resolve stage IDs and phone numbers properly

Pipedrive's webhook payload gives you stage_id, not the stage name — fetch the pipeline's stage list once (GET /v1/stages in the Pipedrive API) and cache the id-to-name mapping instead of hardcoding it, since stage names and order change as the sales process evolves. For phone numbers, Pipedrive stores a person's or owner's phone as free text; normalize to E.164 before sending, and skip the send (don't guess) when the field doesn't parse:

function toE164(raw, defaultCountry = '32') {
  const digits = raw.replace(/[^\d]/g, '');
  if (raw.startsWith('+')) return '+' + digits;
  if (digits.startsWith('00')) return '+' + digits.slice(2);
  if (digits.startsWith('0')) return `+${defaultCountry}${digits.slice(1)}`;
  return `+${digits}`;
}

Step 4: Use activity webhooks for reminders, not just deal webhooks

For "call the client in 30 minutes" style nudges, subscribe to activity.added or activity.updated instead of deal events, and check due_date / due_time against the current time in your receiver before sending — Pipedrive fires the webhook when the activity record changes, not when it's actually due. A simple approach: on activity.added, schedule a delayed job (a queue, a cron check, or a scheduled_at field read by a periodic worker) that fires the WhatsApp message at due_date/due_time minus your lead window, and cancel it if the activity gets marked done or deleted before then.

Keep the receiver idempotent

Pipedrive can redeliver a webhook after a timeout or a 5xx from your endpoint. Dedupe on the object id plus the field you're reacting to (deal id + new stage id, or activity id + due timestamp) so a retry doesn't send the same WhatsApp message twice to the same rep.

What this is good for

Good fits: notifying a rep the moment their deal hits "Contract Sent" or "Won," reminding a rep about a call due soon, pinging a manager when a high-value deal stalls in one stage too long. Poor fit: sending WhatsApp messages to the contacts or leads themselves through this pattern without their prior opt-in — that's customer messaging, not an internal sales alert, and needs proper consent handling. Keep this pattern for internal, one-to-one notifications to your own team, which also keeps volume low and clear of anti-spam risk scoring.

Start free on TextMeFlow — 50 messages a month, no time limit, enough to wire up and test a Pipedrive webhook before deciding on a paid plan.

Zelf WhatsApp-berichten versturen via API?

Gratis voor altijd tot 50 berichten/maand. QR scannen en binnen 5 minuten verstuur je je eerste bericht.

Gratis voor altijd