Automatyzacje webhookami
Webhooki wymagają płatnego planu. Basic: 1 webhook, Pro: 3, Ultra: 10.
Webhooki pozwalają połączyć TellDone z dowolną usługą zewnętrzną. Gdy tworzysz notatkę głosową, TellDone ją przetwarza i automatycznie wysyła wyodrębnione dane - notatki, zadania, wydarzenia i raporty - na podany przez ciebie URL. Każde zadanie i wydarzenie wysyłane jest jako osobna dostawa, więc twoje narzędzie automatyzacji może je obsługiwać pojedynczo.
Wybór tego, co wysyłać
Każda automatyzacja ma własne przełączniki ładunku. Wybierz jeden lub dowolną kombinację:
- Notes - pełna przetworzona notatka (tytuł, transkrypt, podsumowanie, tagi, język)
- Audio - w planie Ultra dołącz 24-godzinny link do pobrania pliku audio obok ładunku notatki
- Tasks - jedna dostawa na wyodrębnione zadanie
- Events - jedna dostawa na wyodrębnione wydarzenie kalendarzowe
- Reports - jedna dostawa na wygenerowany raport dzienny, tygodniowy, miesięczny lub roczny
Przełączniki możesz zmieniać w dowolnej chwili z ustawień automatyzacji - zmiany dotyczą tylko nowych zdarzeń.
Konfiguracja webhooka

- Wejdź w Ustawienia > Integracje > Automatyzacje webhookami
- Naciśnij Nowa automatyzacja

- Wpisz nazwę (np. "Mój webhook Zapier")
- Wklej URL webhooka z usługi automatyzacji
- Wybierz, jakie dane wysyłać: notatki, zadania, wydarzenia, raporty (lub dowolną kombinację)
- Opcjonalnie dodaj nagłówek auth - wartość jest domyślnie wysyłana w nagłówku
Authorization. Jeśli twój endpoint używa innej nazwy nagłówka, możesz ją dostosować w polu nagłówka auth - Naciśnij Zapisz
- Skopiuj sekret podpisu - pojawia się tylko przy tworzeniu lub rotacji. Zapisz go teraz; nie możesz go zobaczyć ponownie bez rotacji
- Naciśnij "Test", by wysłać przykładowy ładunek do endpointa bez tworzenia prawdziwego zdarzenia
URL webhooka musi używać HTTPS. Adresy HTTP i adresy z sieci prywatnej nie są akceptowane.
Co jest wysyłane
Każda dostawa to obiekt JSON z trzema polami: event (typ zdarzenia), timestamp i data (faktyczna treść). Oto, jak wygląda każdy typ zdarzenia.
Notatki (note.created)
Zawiera tytuł wygenerowany przez AI, pełny transkrypt, podsumowanie, typ notatki, tagi, priorytet, język i datę utworzenia.
{
"event": "note.created",
"timestamp": "2026-02-27T14:38:00Z",
"data": {
"note_id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Meeting notes - Project Alpha",
"transcript": "Full transcript text...",
"summary": "Brief AI-generated summary...",
"type": "meeting",
"tags": ["work", "project-alpha"],
"priority": "high",
"language": "en",
"created_at": "2026-02-27T10:00:00Z"
}
}
W planie Ultra dostawy notatek mogą zawierać też link do nagrania audio (audio_url, audio_format, duration_seconds). Link wygasa po 24 godzinach. Włącz to opcją "Note + Audio" przy tworzeniu automatyzacji.
Zadania (task.created)
Jedna dostawa na zadanie. Pojedyncza notatka z 3 zadaniami wysyła 3 osobne webhooki.
{
"event": "task.created",
"timestamp": "2026-02-27T14:38:01Z",
"data": {
"note_id": "550e8400-...",
"note_title": "Meeting notes - Project Alpha",
"task_id": "660f9511-...",
"title": "Send proposal to client",
"description": "Include pricing for Q2",
"priority": "high",
"due_date": "2026-03-01",
"reminder_at": "2026-02-28T09:00:00Z",
"tags": ["work"],
"status": "todo",
"created_at": "2026-02-27T10:00:00Z"
}
}
Wydarzenia (calendar_event.created)
Jedna dostawa na wydarzenie kalendarzowe.
{
"event": "calendar_event.created",
"timestamp": "2026-02-27T14:38:02Z",
"data": {
"note_id": "550e8400-...",
"note_title": "Meeting notes",
"event_id": "770a0622-...",
"title": "Team standup",
"description": "Weekly sync",
"start": "2026-03-03T10:00:00+03:00",
"end": "2026-03-03T10:30:00+03:00",
"location": "Zoom",
"is_all_day": false,
"attendees": ["alice@example.com"],
"tags": ["work"],
"created_at": "2026-02-27T10:00:00Z"
}
}
Raporty (report.created)
Wysyłane, gdy zostaje wygenerowany raport dzienny, tygodniowy, miesięczny lub roczny.
{
"event": "report.created",
"timestamp": "2026-02-28T00:05:00Z",
"data": {
"report_id": "880b1733-...",
"report_type": "daily",
"period_start": "2026-02-27",
"period_end": "2026-02-27",
"content_md": "# Daily Report\n\n...",
"content_json": {
"productivity_score": 72,
"day_type": "productive",
"tasks_created": 5,
"tasks_completed": 3
},
"created_at": "2026-02-28T00:05:00Z"
}
}
Bezpieczeństwo
Każda dostawa jest podpisywana HMAC-SHA256 z użyciem sekretu podpisu twojej automatyzacji. Z każdą dostawą trafiają następujące nagłówki:
X-LP-Signature- podpis HMAC-SHA256 (sha256=...)X-LP-Timestamp- znacznik czasu Unix użyty do podpisaniaX-LP-Event- typ zdarzenia (note.created,task.created,calendar_event.created,report.created)X-LP-Delivery-Id- unikalne ID dostawy (przydatne do deduplikacji)User-Agent- zawszeTellDone-Webhooks/1.0
Nagłówki podpisu są wysyłane z każdą dostawą, niezależnie od innych ustawień.
Jeśli ustawisz nagłówek auth w ustawieniach automatyzacji, jest on wysyłany domyślnie jako nagłówek Authorization przy każdej dostawie. Możesz zastąpić nazwę nagłówka inną (np. X-API-Key), jeśli twój endpoint tego wymaga. Jeśli pole nagłówka auth jest puste, żaden nagłówek auth nie jest wysyłany.
Każda automatyzacja ma własny sekret podpisu, więc rotacja jednego nie wpływa na inne webhooki. Sekret jest pokazywany tylko przy tworzeniu lub rotacji. Aby go wymienić, naciśnij "Rotuj sekret" w ustawieniach automatyzacji - generuje to nowy klucz HMAC bez zmiany URL ani nagłówka auth. Stary sekret natychmiast przestaje działać.
Akceptowane są tylko URL-e HTTPS. HTTP, adresy IP i adresy sieci prywatnych są odrzucane.
Weryfikacja podpisów webhooków
Każda dostawa zawiera nagłówek podpisu w postaci X-LP-Signature: sha256=<hex>. Przykład poniżej pokazuje, jak go zweryfikować w Pythonie.
Każdy webhook jest podpisany, byś mógł potwierdzić, że faktycznie pochodzi z TellDone. Podpis liczy się jako:
HMAC-SHA256(signing_secret, timestamp + "." + raw_body)
Wynik jest kodowany w hex i poprzedzony sha256= w nagłówku podpisu.
TellDone serializuje JSON ze spacjami po separatorach (np. {"event": "note.created"}). Jeśli sparsujesz i ponownie zserializujesz ciało, podpis się nie zgodzi. Zawsze weryfikuj na surowych bajtach ciała żądania.
Python
import hmac
import hashlib
def verify_signature(raw_body: bytes, signature: str, timestamp: str, secret: str) -> bool:
payload = f"{timestamp}.".encode() + raw_body
expected = "sha256=" + hmac.new(
secret.encode(), payload, hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)
# Flask example
@app.route("/webhook/telldone", methods=["POST"])
def telldone_webhook():
raw_body = request.get_data() # raw bytes, NOT request.json
signature = request.headers.get("X-LP-Signature", "")
timestamp = request.headers.get("X-LP-Timestamp", "")
if not verify_signature(raw_body, signature, timestamp, SIGNING_SECRET):
abort(403)
data = request.json
# process webhook...
Node.js
const crypto = require("crypto");
function verifySignature(rawBody, signature, timestamp, secret) {
const payload = `${timestamp}.${rawBody}`;
const expected =
"sha256=" +
crypto.createHmac("sha256", secret).update(payload).digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// Express example (use express.raw to get the raw body)
app.post("/webhook/telldone", express.raw({ type: "application/json" }), (req, res) => {
const rawBody = req.body.toString();
const signature = req.headers["x-lp-signature"] || "";
const timestamp = req.headers["x-lp-timestamp"] || "";
if (!verifySignature(rawBody, signature, timestamp, SIGNING_SECRET)) {
return res.status(403).send("Invalid signature");
}
const data = JSON.parse(rawBody);
// process webhook...
});
Ochrona przed powtórzeniami (opcjonalnie)
Aby zapobiec atakom typu replay, sprawdź, czy znacznik czasu jest świeży:
import time
def verify_timestamp(timestamp: str, tolerance_seconds: int = 300) -> bool:
try:
return abs(time.time() - int(timestamp)) < tolerance_seconds
except (ValueError, TypeError):
return False