본문으로 건너뛰기

Webhook 자동화

Basic 이상

자동화는 Basic 이상에서 쓸 수 있어요. Basic: 1개, Pro: 3개, Ultra: 10개. Free에서는 해당 행에 자동화를 사용하려면 업그레이드하세요라고 나와요.

Webhook은 데이터를 자동으로 받는 웹 주소예요. 자동화를 쓰면 TellDone은 노트가 준비되는 대로 각 새 노트를 작업, 이벤트와 함께 그 주소로 보내고, 리포트가 준비되면 각 새 리포트도 보내요. 그래서 Zapier, Make, n8n 같은 도구가 이를 받아 처리할 수 있어요. 작업과 이벤트는 각각 별도의 전송으로 보내져요.

보낼 항목 고르기​

자동화마다 전송할 항목 아래에 자체 설정이 있어요. 하나 또는 원하는 조합으로 고르세요.

  • 노트 - 처리된 전체 노트 (제목, 받아쓰기, 요약, 유형, 태그, 우선순위, 언어, 생성 날짜)
  • 노트 + 오디오 - Ultra 플랜에서 각 노트 전송에 오디오 파일의 24시간 다운로드 링크를 추가해요. 노트는 켜 두세요. 꺼져 있으면 노트가 전송되지 않아요
  • 작업 - 추출된 작업마다 전송 하나
  • 이벤트 - 추출된 캘린더 이벤트마다 전송 하나
  • 리포트 - 생성된 일간, 주간, 월간, 연간 리포트마다 전송 하나 (플랜에 포함된 리포트 유형). 조용한 날의 자리표시 리포트와 짧은 조용한 주 리포트는 보내지 않아요

자동화 설정에서 언제든 바꿀 수 있어요. 변경은 새 전송에만 적용돼요.

보낼 시점 고르기​

데이터 선택 아래의 별도 스위치 네 개가 어떤 변경이 전송을 일으킬지 정해요. 생성, 업데이트, 완료, 삭제됨이에요. 트리거는 바로 위의 해당 데이터 스위치와 함께 켜져 있어야 작동해요. 예를 들어 완료는 작업이 켜져 있어야 완료된 작업을 보내요.

생성은 TellDone이 녹음이나 텍스트 노트로 만든 노트와, 그 안에서 찾은 작업 및 이벤트에 대해 전송돼요. 직접 또는 AI 어시스턴트로 추가한 작업과 이벤트, 그리고 음성으로 추가에서 생긴 새 항목은 생성으로 전송되지 않아요. 업데이트, 완료, 삭제됨은 앱에서 또는 음성으로 추가로 항목을 바꿀 때 전송돼요. Smart Context, AI 어시스턴트, Todoist, Notion, Microsoft To Do에서 한 변경은 전송을 일으키지 않아요.

각 전송의 event 필드에 무슨 일이 있었는지 나와요. 예를 들면 task.created, task.completed, calendar_event.updated예요.

Webhook 설정하기​

Zapier, Make, n8n용 설정 자동화

  1. 설정 > 연동 > 자동화로 이동하세요
  2. 새 자동화를 누르세요

새 자동화 Webhook 설정

  1. 이름을 입력하세요 (예: "My Zapier webhook")
  2. 자동화 서비스의 webhook URL을 붙여넣으세요
  3. 보낼 데이터(노트, Ultra에서는 노트 + 오디오, 작업, 이벤트, 리포트)와 사용할 트리거(생성, 업데이트, 완료, 삭제됨)를 고르세요
  4. 선택 사항으로 인증 헤더를 추가하세요. 보안 엔드포인트용으로 Authorization 헤더에 담겨 전송되는 토큰이에요
  5. 저장을 누르세요
  6. 서명 시크릿을 복사하세요. 자동화를 처음 만들 때나 시크릿을 재발급한 직후에만 전체가 표시돼요. 전송이 정말 TellDone에서 온 것인지 확인하는 데 필요해요 (Webhook 서명 확인하기 참고)
  7. 테스트 전송을 누르면 데이터를 하나도 바꾸지 않고 엔드포인트로 샘플 페이로드를 보내요. HTTP 코드와 응답 시간이 함께 성공으로 나오거나, 이유와 함께 오류가 나와요. 테스트 전송은 전송 기록에 나타나지 않아요

전송되는 내용​

모든 전송은 필드 세 개가 있는 JSON 객체예요. event(이벤트 유형), timestamp, data(실제 내용)예요. 테스트 전송에는 "test": true도 들어 있어요. 이벤트 유형별 모양은 이래요.

노트 (note.created)​

AI가 만든 제목, 전체 받아쓰기, 요약, 노트 유형, 태그, 우선순위, 언어, 생성 날짜가 들어 있어요.

{
"event": "note.created",
"timestamp": "2026-02-27T14:38:00.512345+00:00",
"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:00.284117+00:00"
}
}

Ultra 플랜에서는 노트 전송에 녹음 오디오 링크(audio_url, audio_format, duration_seconds)도 넣을 수 있어요. 링크는 24시간 뒤에 만료돼요. 자동화의 노트 + 오디오 옵션으로 켜세요.

작업 (task.created)​

작업마다 전송 하나예요. 작업이 3개인 노트는 별도 전송 3개를 보내요.

{
"event": "task.created",
"timestamp": "2026-02-27T14:38:01.204718+00:00",
"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:00+00:00",
"tags": ["work"],
"status": "todo",
"cancel_reason": null,
"cancelled_at": null,
"created_at": "2026-02-27T10:00:00.284117+00:00"
}
}

이벤트 (calendar_event.created)​

캘린더 이벤트마다 전송 하나예요.

{
"event": "calendar_event.created",
"timestamp": "2026-02-27T14:38:02.093361+00:00",
"data": {
"note_id": "550e8400-...",
"note_title": "Meeting notes",
"event_id": "770a0622-...",
"title": "Team standup",
"description": "Weekly sync",
"start": "2026-03-03T07:00:00+00:00",
"end": "2026-03-03T07:30:00+00:00",
"location": "Zoom",
"is_all_day": false,
"attendees": ["alice@example.com"],
"tags": ["work"],
"created_at": "2026-02-27T10:00:00.284117+00:00",
"timezone": "Europe/Istanbul",
"start_local": "2026-03-03T10:00:00+03:00",
"end_local": "2026-03-03T10:30:00+03:00",
"start_date": "2026-03-03",
"end_date": "2026-03-03"
}
}

start와 end는 UTC예요. start_local, end_local, start_date, end_date는 내 시간대(timezone)를 써요. 종일 이벤트에서 end_date는 이벤트의 마지막 날이에요.

리포트 (report.created)​

일간, 주간, 월간, 연간 리포트가 생성되면 전송돼요.

{
"event": "report.created",
"timestamp": "2026-02-28T00:05:00.731902+00:00",
"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": "planning",
"tasks_created": 5,
"tasks_completed": 3
},
"created_at": "2026-02-28T00:05:00.418253+00:00"
}
}

보안​

모든 전송은 자동화의 서명 시크릿으로 HMAC-SHA256 서명이 붙어요. 전송마다 이런 헤더가 포함돼요.

  • X-LP-Signature - HMAC-SHA256 서명 (sha256=...)
  • X-LP-Timestamp - 서명에 쓴 Unix 타임스탬프
  • X-LP-Event - 이벤트 유형 (예: note.created, task.completed, calendar_event.updated, report.created)
  • X-LP-Delivery-Id - 고유 전송 ID (중복 제거에 유용해요)
  • User-Agent - 항상 TellDone-Webhooks/1.0

TellDone은 자동화에 인증 헤더를 추가한 경우에만 Authorization 헤더를 보내요. 형식은 두 가지예요. Header-Name: value는 이름이 지정된 헤더를 보내고, 값만 쓰면 Authorization: <value>를 보내요. 서명 시크릿은 헤더로 절대 전송되지 않아요.

자동화마다 자체 서명 시크릿이 있어서 하나를 재발급해도 다른 webhook에는 영향이 없어요. 시크릿은 자동화를 처음 만들 때나 재발급한 직후에만 전체가 표시돼요. 그 밖의 때에는 미리보기(whsec_...last4)만 보여요. 새 시크릿으로 바꾸려면 자동화 설정에서 시크릿 재발급을 누르세요. URL이나 인증 헤더는 그대로 두고 새 HMAC 키를 만들어요. 이전 시크릿은 즉시 작동을 멈춰요.

도메인 이름이 있는 HTTPS URL만 허용돼요. HTTP, IP 주소(공용이든 사설이든), 사용자 이름이나 비밀번호가 들어간 URL, 사설 네트워크 주소를 가리키는 도메인은 거부돼요. TellDone은 보낼 때마다 주소를 다시 확인해요. 예를 들어 그 순간 도메인이 확인되지 않아서 검사에 실패하면 전송은 중단되고 다시 시도하지 않아요.

Webhook 서명 확인하기​

모든 webhook에는 서명이 붙어 있어서 실제로 TellDone에서 온 것인지 확인할 수 있어요. 서명은 이렇게 계산해요.

HMAC-SHA256(signing_secret, timestamp + "." + raw_body)

결과는 16진수로 인코딩되어 서명 헤더에 sha256= 접두사와 함께 들어가요.

원본 요청 본문을 사용하세요

TellDone은 구분 기호 뒤에 공백을 넣어 JSON을 직렬화해요 (예: {"event": "note.created"}). 본문을 파싱했다가 다시 직렬화하면 서명이 맞지 않아요. 항상 요청 본문의 원본 바이트로 확인하세요.

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");
const a = Buffer.from(signature);
const b = Buffer.from(expected);
// timingSafeEqual throws if the lengths differ, e.g. when the header is missing
return a.length === b.length && crypto.timingSafeEqual(a, b);
}

// 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...
});

재전송 공격 방지 (선택)​

재전송 공격을 막으려면 타임스탬프가 최근인지 확인하세요.

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

흔한 실수​

실수해결 방법
파싱했다가 다시 직렬화한 본문 사용원본 요청 본문을 사용하세요
JS의 JSON.stringify() (공백 없는 압축 형태)원본 요청 본문을 사용하세요
타임스탬프 접두사 빠뜨림페이로드 형식은 timestamp + "." + body예요
문자열을 직접 비교hmac.compare_digest나 timingSafeEqual을 사용하세요

재시도 정책​

엔드포인트가 실패하면 TellDone은 각 전송을 이 일정에 따라 다시 시도해요.

시도대기 시간
1번째 재시도30초
2번째 재시도2분
3번째 재시도15분
4번째 재시도1시간
5번째 재시도4시간

5번째 재시도도 실패하면 전송은 실패로 표시되고 더 이상 재시도하지 않아요. 앱에서는 빨간 X로 나와요. 전체 전송 기록에서 직접 다시 보낼 수는 있어요. 모든 전송을 열고 (자동화에 전송이 5건보다 많아지면 링크가 나타나요) 실패한 전송에서 다시 시도를 누르세요. 짧은 최근 전송 목록에는 재시도가 없어요.

응답에 따라 TellDone은 이렇게 처리해요.

  • 2xx - 전송 성공
  • 4xx (429 제외) - 즉시 실패로 표시하고 재시도하지 않아요 (엔드포인트가 데이터를 명시적으로 거부한 거예요)
  • 429 (Too Many Requests) - Retry-After에 적힌 초 뒤에 재시도해요 (없으면 60초). 이 재시도에는 5번 제한이 없지만, 하나하나가 자동화를 끄게 되는 실패 20회에 포함돼요
  • 5xx 또는 시간 초과 - 위 일정대로 재시도해요

전송이 계속 실패할 때​

전송이 계속 실패하면 TellDone이 알려주고, 결국 자동화를 꺼요.

3번 실패하면: 받은편지함 경고​

연속 3번 실패하면 (재시도도 포함) TellDone이 받은편지함에 자동화 "이름"에 문제가 있어요라는 제목의 메시지를 보내요. 따옴표 안에는 자동화 이름이 들어가요. 그러면 설정 > 연동 > 자동화에서 열어 전송 기록을 확인하고 어떻게 할지 정할 수 있어요.

20번 실패하면: 자동 비활성화​

자동 비활성화

같은 자동화에서 연속 20번 실패하면 (재시도도 포함) TellDone은 작동하지 않는 주소로 계속 보내지 않도록 자동화를 꺼요. 자동화 도구에서 문제를 고친 다음 설정 > 연동 > 자동화에서 활성 스위치를 다시 켜세요. 다시 켜도 실패 횟수는 초기화되지 않으므로, 전송이 한 번 성공하기 전까지는 한 번만 실패해도 다시 꺼져요.

실패한 시도는 모두 횟수에 포함돼요. 그래서 재시도 5번이 모두 실패한 전송 하나는 횟수를 6만큼 늘려요. 따라서 실패하는 전송이 약 4건이면 자동화가 저절로 꺼질 수 있어요. 횟수는 다음 성공한 전송에서 0으로 돌아가요.

Webhook 관리하기​

  • 활성 - 이 스위치를 끄면 자동화를 삭제하지 않고 멈출 수 있고, 언제든 다시 켤 수 있어요. 꺼져 있는 동안에는 아무것도 전송되지 않아요. 그 사이의 노트와 리포트는 나중에도 전송되지 않고, 재시도를 기다리던 전송은 버려져요
  • 전송 - 최근 전송에는 상태, HTTP 코드, 응답 시간과 함께 마지막 5건이 나와요. 그보다 많아지면 모든 전송에서 지난 30일의 기록을 열 수 있어요. 여기서 전체, 전송됨, 오류로 거르고, 실패한 전송은 다음 예약 재시도를 기다리지 않고 다시 시도를 눌러 다시 보낼 수 있어요
  • 테스트 전송 - 선택한 데이터 유형과 상관없이 샘플 노트(note.created, 본문에 "test": true 포함)를 보내며 데이터는 하나도 바꾸지 않아요. 자동화를 저장한 뒤부터 쓸 수 있어요. 테스트 전송은 월 한도에 포함되지 않아요
  • 시크릿 재발급 - URL이나 인증 헤더는 그대로 두고 새 HMAC 서명 시크릿을 만들어요
  • 편집 - URL, 인증 헤더, 데이터 선택(노트 / 노트 + 오디오 / 작업 / 이벤트 / 리포트), 트리거(생성 / 업데이트 / 완료 / 삭제됨)를 바꿔요. 변경은 즉시 적용돼요
  • 자동화 삭제 - 자동화와 모든 전송 기록을 영구적으로 삭제해요

각 전송의 상태는 아이콘으로 나타나요.

아이콘의미
초록 체크전송됨
노란 시계대기 중이거나 전송 중
빨간 삼각형실패, TellDone이 재시도할 거예요
빨간 X실패, 더 이상 자동 재시도 없음

전체 기록에서 빨간 삼각형이나 빨간 X가 있는 전송에는 다시 시도를 누를 수 있어요.

전송 한도​

한도는 두 가지예요. 플랜에 따른 월 한도와, 갑작스러운 폭주를 막기 위해 모든 유료 플랜에 적용되는 시간당 100건 한도예요.

플랜자동화월 전송시간당 한도
Free00-
Basic1300100
Pro33,000100
Ultra1015,000100

한도가 작동하는 방식

  • 월 한도에 도달하면 - 전송이 대기해요. 실패로 표시되고 ("Monthly webhook limit exceeded") TellDone이 5분마다 다시 시도해요. 한도는 매월 1일 00:00 UTC에 초기화되고 그 뒤에 전송돼요. 단, 그때 30일이 넘은 전송은 제외예요. 초기화 이후에 보낸 전송은 새 달에 포함돼요.
  • 시간당 한도에 도달하면 - 전송이 보류되었다가 약 5분 뒤에 다시 시도돼요. 짧은 폭주에도 데이터가 사라지지 않아요.

월 한도에는 성공한 전송만 포함돼요. 시간당 한도에는 재시도를 포함한 모든 시도가 포함돼요. 테스트 전송은 두 한도 모두에 포함되지 않아요.

플랜을 바꿔도 자동화와 설정은 그대로 유지돼요. Free에서는 전송이 멈추고 업그레이드할 때까지 열 수 없어요. Basic에서는 이미 있던 자동화가 월 300건 안에서 계속 전송되지만, 하나보다 많이 추가하거나 켤 수는 없어요.

테스트 이벤트 거르기​

테스트 전송을 누르면 페이로드 최상위에 "test": true가 들어가요. 자동화 도구에서 이 필드를 확인해 있으면 처리를 건너뛸 수 있어요.

플랫폼 가이드​

자동화 도구별 단계별 설정 방법은 여기에 있어요.

  • Zapier - Zap으로 TellDone을 수천 개의 앱에 연결해요
  • Make - 시각적인 자동화 시나리오를 만들어요 (이전 이름 Integromat)
  • n8n - 직접 호스팅하거나 클라우드 워크플로에서 TellDone webhook을 써요
  • 사용자 지정 엔드포인트 - HTTPS POST 요청을 받는 서비스라면 TellDone webhook과 함께 쓸 수 있어요

활용 아이디어​

  • Zapier로 작업을 Google Sheet에 보내기
  • Make로 노트에서 Slack 메시지 만들기
  • n8n으로 이벤트를 사용자 지정 CRM에 기록하기
  • 모든 노트를 클라우드 저장소에 백업하기
  • 리포트를 팀 대시보드로 전달하기

함께 보기​

  • 받은편지함과 지원 - webhook이 계속 실패하면 받은편지함에 메시지가 와요
  • Zapier - 단계별 Zapier 설정
  • Make - 단계별 Make 설정
  • n8n - 단계별 n8n 설정
  • Todoist - 전용 양방향 작업 동기화 (webhook 필요 없음)
  • Notion - 전용 Notion 연동
  • 이메일 전달 - 이메일로 노트 데이터 받기