Meetily
Agent APIGuides

Post meeting summaries to Slack

When a summary finishes, verify the webhook, fetch the summary, and post it to Slack.

This sends meeting content off your device

Meetily is privacy-first and local by default. This automation reads summary text and sends it to a third party (Slack). You are the data controller for that transfer: get the participants' consent, scope the token to read only, and treat the destination as untrusted. Never hard-code a token in a script you share; read it from the environment or the loopback token file.

This recipe posts a meeting summary to Slack the moment it is ready. It uses the summary.completed webhook (a firing event), verifies the HMAC signature, fetches the summary, and posts to a Slack incoming webhook.

1. Register the webhook

Register a webhook on the summary.completed event. Webhooks cannot be delivered to localhost, so run a tunnel (ngrok or cloudflared) in front of your receiver and register the tunnel's public HTTPS URL. Use summary.completed, not meeting.updated (meeting.* events never fire). See Webhooks for registration and the HMAC recipe.

curl -s -X POST http://127.0.0.1:8420/v1/webhooks -H "Authorization: Bearer $MEETILY_PRO_TOKEN" -H "content-type: application/json" -d '{"url":"https://YOUR-TUNNEL.example/hook","events":["summary.completed"]}'

2. Receive, verify, fetch, post

import json, urllib.request
from meetily_agent import MeetilyClient, verify_signature

HMAC_SECRET = "whsec_..."      # the secret returned once at registration
SLACK_WEBHOOK = "https://hooks.slack.com/services/XXX"

def handle(headers, raw_body):
    ts = headers["X-Meetily-Timestamp"]
    sig = headers["X-Meetily-Signature"]
    if not verify_signature(HMAC_SECRET, ts, raw_body, sig):
        return  # reject unsigned or tampered deliveries

    event = json.loads(raw_body)
    if event["event"] != "summary.completed":
        return
    meeting_id = event["resource_id"]

    summary = MeetilyClient().meetings.summary(meeting_id)
    text = json.dumps(summary.get("result", summary))[:3000]

    req = urllib.request.Request(
        SLACK_WEBHOOK,
        data=json.dumps({"text": f"Summary for {meeting_id}:\n{text}"}).encode(),
        headers={"content-type": "application/json"},
    )
    urllib.request.urlopen(req)

You cannot receive webhooks on localhost

The gateway rejects any webhook URL whose host is loopback or a private IP, at registration and at delivery, and there is no flag to disable this. Put a tunnel in front of your receiver and register the tunnel's public HTTPS URL. Never disable the SSRF protection.

Inspect delivery attempts with GET /v1/webhooks/:id/deliveries if a post does not arrive.

Last updated on

On this page