Build a Meeting Summarizer in Under 100 Lines of Code
A complete, production-ready meeting summarizer using Gregnote webhooks and Claude or GPT-4. Receive a webhook, summarise the transcript, send to email or Slack.
Gregnote Team
26 July 2026
The complete implementation
Here's a meeting summarizer that receives a Gregnote webhook, summarises the transcript with an LLM, and emails the summary to all participants. Under 100 lines.
import express from "express"; import crypto from "crypto"; import Anthropic from "@anthropic-ai/sdk"; import nodemailer from "nodemailer";
const app = express(); const claude = new Anthropic();
const mailer = nodemailer.createTransport({ host: process.env.SMTP_HOST, port: 587, auth: { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS }, });
function verify(req) { const [tPart, vPart] = (req.headers["x-gregnote-signature"] || "").split(","); const ts = tPart?.split("=")[1]; const sig = vPart?.split("=")[1]; const expected = crypto .createHmac("sha256", process.env.GREGNOTE_SECRET) .update(ts + "." + req.body) .digest("hex"); return sig === expected; }
app.post("/webhook", express.raw({ type: "*/*" }), async (req, res) => { if (!verify(req)) return res.sendStatus(401);
const { event, transcript } = JSON.parse(req.body.toString()); if (event !== "meeting.completed") return res.sendStatus(200);
const text = transcript.segments
.filter(s => !s.is_bot)
.map(s => ${s.speaker}: ${s.text})
.join("\n");
const { content } = await claude.messages.create({
model: "claude-3-5-haiku-20241022",
max_tokens: 512,
messages: [{
role: "user",
content: Summarise this meeting in 3–5 bullet points covering key decisions and action items:\n\n${text},
}],
});
const summary = content[0].text; const participants = transcript.speakers .filter(s => !s.is_bot) .map(s => s.display_name);
await mailer.sendMail({
from: "[email protected]",
to: participants.join(", "),
subject: Meeting summary — ${new Date().toLocaleDateString()},
text: summary,
});
res.sendStatus(200); });
app.listen(3000); ```
What each part does
- `verify()` — checks the HMAC signature. Never skip this.
- `text` — concatenates only human segments, filtering out the bot's own audio.
- Claude summarise — produces 3–5 bullets covering decisions and actions.
- `mailer.sendMail` — sends the summary to every meeting participant by name.
Deploy it
Wrap in a Dockerfile, deploy to any VPS, set four environment variables. Done. Every meeting your team takes now emails itself a summary automatically.
Try it yourself
API key in 30 seconds. Free credit on sign-up. No card required.