Integrations
Route Trump post alerts into Slack, Discord, email, spreadsheets, or your own systems with n8n, Zapier, Make, or a few lines of code.
Automations are built on webhooks: Covfefe POSTs each event to a URL, and your automation tool takes it from there. The Telegram bot only sends to you, so it can't trigger automations.
A good starting filter for most setups: event is post.enriched and enrichment.relevance is 7 or higher. That's the scored version of posts that plausibly matter.
n8n
Download the ready-made n8n workflow. It receives Covfefe webhooks, verifies the signature, keeps posts scoring 7+ that aren't videos, and posts them to a Discord channel.
Covfefe webhook → Verify signature → Scored 7+ and not a video? → Post to Discord
We tested it on n8n 2.40 with real signed events, including posts with curly quotes and emoji.
Setup
- In n8n, open Workflows → Import from file and choose the downloaded file.
- Open Verify signature and replace
whsec_PASTE_YOUR_SIGNING_SECRETwith your signing secret from Webhook settings. - Open Post to Discord and replace the URL with a Discord webhook URL (in Discord: channel settings → Integrations → Webhooks → New Webhook → Copy Webhook URL).
- Publish (activate) the workflow. Open Covfefe webhook, copy its Production URL, and save it as your endpoint in Webhook settings.
- Click Send test event in Webhook settings. The sample scores 7 and is a text post, so it should appear in your Discord channel.
Running n8n on your laptop? Expose it with a tunnel (for example tailscale funnel 5678) and use the tunnel's URL.
Self-hosting n8n? The signature check uses Node's built-in crypto module. If the node fails with a message that crypto isn't allowed, set the environment variable NODE_FUNCTION_ALLOW_BUILTIN=crypto and restart n8n.
Making it yours
- Slack instead of Discord: replace the last node with n8n's Slack node (or an HTTP Request to a Slack incoming-webhook URL, with the body field named
textinstead ofcontent). - Email, SMS, Google Sheets, Notion: connect the
truebranch of the IF node to the matching n8n node. Useful fields:{{ $json.post.url }},{{ $json.post.content }},{{ $json.enrichment.relevance }},{{ $json.enrichment.plain_english }},{{ $json.enrichment.entities.tickers }}. - Different filters: edit the IF node. Remove the
videocondition to include videos, or add{{ $json.enrichment.topics }}containstariffs. - Log everything: connect a Google Sheets Append row node directly after Verify signature to keep a record of every event.
- Want videos after all? Video posts can get a second
post.enrichedonce their preview frame is analyzed. The workflow handles that automatically: if the new score clears 7, it gets through.
The webhook node answers Covfefe immediately, so a slow Discord or Slack never causes retries.
Zapier
- Create a Zap with Webhooks by Zapier → Catch Hook as the trigger, and save the hook URL as your endpoint in Webhook settings.
- Add a Filter step:
eventexactly matchespost.enriched, andenrichment relevanceis greater than6. - Add your action: Slack, Gmail, Google Sheets, SMS, and so on.
Make
- Create a scenario that starts with Webhooks → Custom webhook, and save its address as your endpoint in Webhook settings.
- Add a filter between modules:
eventequalspost.enriched, andenrichment.relevanceis greater than or equal to7. - Add your action modules.
Protecting no-code webhook URLs
Zapier's and Make's standard webhook triggers parse the body for you, which makes signature verification impractical there. Their URLs are long and unguessable, but for an extra check you can add a secret token to the endpoint URL, like https://hooks.zapier.com/hooks/catch/123/abc/?token=pick-a-long-random-string. Then add a filter step that only continues when the token equals that value. Both tools include query-string parameters with the incoming data; check the field name in your trigger's sample. Covfefe sends to the exact URL you save, including the query string.
For full signature verification, use n8n or code.
Code: a Cloudflare Worker
A small serverless function that verifies each event and forwards the important ones to Slack. It runs on Cloudflare's free plan. Set COVFEFE_SIGNING_SECRET and SLACK_WEBHOOK_URL as Worker secrets, and use the Worker's URL as your endpoint.
export default {
async fetch(request, env) {
if (request.method !== "POST") return new Response("Method not allowed", { status: 405 });
const body = await request.text();
const header = request.headers.get("X-Covfefe-Signature") || "";
if (!(await verify(env.COVFEFE_SIGNING_SECRET, body, header))) {
return new Response("Invalid signature", { status: 401 });
}
const event = JSON.parse(body);
if (event.event === "post.enriched" && event.enrichment.relevance >= 7) {
const text = `*Trump post · relevance ${event.enrichment.relevance}/10*\n${event.enrichment.plain_english}\n${event.post.url}`;
await fetch(env.SLACK_WEBHOOK_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ text }),
});
}
return new Response("ok");
},
};
async function verify(secret, body, header, toleranceSeconds = 300) {
const parts = Object.fromEntries(header.split(",").map((p) => {
const i = p.indexOf("=");
return [p.slice(0, i), p.slice(i + 1)];
}));
const timestamp = Number(parts.t);
if (!Number.isFinite(timestamp) || Math.abs(Date.now() / 1000 - timestamp) > toleranceSeconds) return false;
const encoder = new TextEncoder();
const key = await crypto.subtle.importKey(
"raw", encoder.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]
);
const mac = await crypto.subtle.sign("HMAC", key, encoder.encode(`${timestamp}.${body}`));
const expected = [...new Uint8Array(mac)].map((b) => b.toString(16).padStart(2, "0")).join("");
return typeof parts.v1 === "string" && expected.length === parts.v1.length &&
[...expected].reduce((diff, c, i) => diff | (c.charCodeAt(0) ^ parts.v1.charCodeAt(i)), 0) === 0;
}
Reading the body as text is safe here: Covfefe's bodies are plain ASCII (non-ASCII characters are escaped), so the text is byte-for-byte what we signed.
The same pattern works on other serverless platforms such as Vercel, Netlify Functions, AWS Lambda, or Pipedream: read the raw body, verify, filter, forward.