DingTalk (钉钉)
HMAC-SHA256 서명 URL을 사용하는 DingTalk 사용자 정의 그룹 로봇. Stream Mode (WebSocket)는 향후 추가될 예정입니다.
🟡 사용자 정의 그룹 로봇으로 아웃바운드, outgoing webhook으로 인바운드를 지원합니다. 가장 간단한 설정 방법은 서명 URL을 사용하는 DingTalk "사용자 정의 그룹 로봇"입니다. 엔터프라이즈 자체 구축 앱과 Stream Mode (신규 빌드에 DingTalk이 권장하는 WebSocket 전송 방식)는 향후 지원될 예정입니다.
제공 기능
- HMAC-SHA256 URL 서명 (timestamp + secret) 방식으로
POST https://oapi.dingtalk.com/robot/send를 통한 아웃바운드 텍스트 전송. - 사용자 정의 그룹 로봇 멘션 플로우를 위한
/webhooks/dingtalk인바운드 outgoing webhook. DingTalk이 사용자 메시지를 새로운timestamp+sign쌍과 함께 POST하면, Minara는 아웃바운드 서명 방식과 동일하게 검증합니다. - 텍스트 전용. Markdown, actionCard, feedCard 메시지 유형은 추후 지원 예정입니다.
- 텍스트 메시지당 5,000자 제한.
설정
1. 사용자 정의 그룹 로봇 생성
- 데스크톱 또는 모바일에서 대상 DingTalk 그룹을 엽니다.
- 그룹 설정 → "그룹 도우미" → "로봇 추가" → "사용자 정의" 순으로 선택합니다.
- 이름과 아바타를 설정하고, "보안 설정"에서 "서명" ("사용자 정의 키워드" 또는 "IP 화이트리스트"가 아닌 서명 URL 옵션)을 선택합니다.
- 저장 후 다음 두 가지 정보를 복사합니다.
- Webhook URL (
https://oapi.dingtalk.com/robot/send?access_token=...형식의 URL) - 서명 secret (
SEC로 시작)
- Webhook URL (
2. Minara 설정
minara auth messaging add
# `dingtalk`을 선택하고, webhook URL과 SECxxxx secret을 붙여 넣습니다.또는 환경 변수를 직접 설정합니다.
DINGTALK_WEBHOOK_URL=https://oapi.dingtalk.com/robot/send?access_token=<token>
DINGTALK_WEBHOOK_SECRET=SECxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx3. 테스트
minara auth messaging test dingtalk1~2초 내에 대상 그룹에 "✅ Minara gateway test ping" 메시지가 수신됩니다.
아웃바운드 서명 동작 방식
DingTalk은 모든 POST 요청에 밀리초 단위 timestamp와 secret의 HMAC 값을 URL 인코딩하여 요청 URL에 포함하도록 요구합니다.
sign = base64( HmacSHA256( "<timestamp>\n<secret>", secret ) )
url = <webhook URL>?timestamp=<ts>&sign=<urlencoded sig>DingTalk은 서버 시계 기준 1시간을 초과한 timestamp를 거부합니다. 따라서 호스트 시간이 동기화되지 않은 경우 "签名错误" / "sign error" 응답이 반환됩니다.
인바운드 webhook (outgoing-message 모드)
사용자 정의 그룹 로봇의 outgoing-message 플로우에서, DingTalk은 다음 주소로 POST 요청을 전송합니다.
https://<your-host>/webhooks/dingtalk요청 본문에는 사용자 메시지와 함께 새로운 timestamp 및 sign 쌍이 헤더에 포함됩니다. Minara는 동일한 DINGTALK_WEBHOOK_SECRET을 사용해 서명을 재계산하며, 불일치 시 401을 반환합니다.
인바운드 페이로드 형식:
{
"msgtype": "text",
"text": { "content": "@bot hello world" },
"senderId": "user-staff-id",
"senderNick": "Alice",
"conversationId": "cidxxxx",
"msgId": "<unique>",
"createAt": 1700000000000
}msgtype === "text" 이벤트만 전달됩니다. 그 외 유형(image, audio, markdown, actionCard)은 무시됩니다.
제한 사항 및 주의 사항
- 시계 동기화가 중요합니다. DingTalk은 아웃바운드
timestamp에 1시간 윈도우를 적용합니다. 호스트 시계가 어긋나면 서명이 실패합니다. - outgoing webhook은 @멘션 시에만 실행됩니다. 그룹 로봇은 모든 메시지를 수신하는 것이 아니라, 자신을 멘션한 메시지만 수신합니다. 이는 Minara 필터가 아닌 DingTalk의 설계 방식입니다.
- Stream Mode가 향후 권장 방식입니다. DingTalk은 신규 애플리케이션에 Stream Mode (WebSocket)를 공식 권장합니다. Minara는 우선 레거시 사용자 정의 그룹 로봇 방식을 제공하며, Stream Mode는 이후 릴리스에서 추가될 예정입니다.
문제 해결
아웃바운드 "签名错误" (서명 오류)
- 서버 시계 오차가 원인일 수 있습니다.
chronyc tracking또는timedatectl status를 실행하여 오프셋이 1초 미만인지 확인합니다. DINGTALK_WEBHOOK_SECRET에 오타가 있을 수 있습니다. SECxxxx 문자열은SEC접두사를 포함한 전체 secret입니다.
"인바운드 webhook에서 401 반환"
- 수신 서명이 일치하지 않습니다. 가장 흔한 원인은 그룹의 "보안 설정"이 "서명"으로 설정되어 있으나, secret이 교체된 후 새 값이
~/.minara/credentials.json에 반영되지 않은 경우입니다.
"그룹에서 멘션해도 봇이 응답하지 않음"
- 로봇 상세 페이지에서 "Outgoing webhook"이 활성화되어 있는지 확인합니다 (인바운드 URL과는 별도의 토글). 이 설정이 없으면 로봇은 푸시 전용으로만 동작합니다.
참조
- 환경 변수:
DINGTALK_WEBHOOK_URL,DINGTALK_WEBHOOK_SECRET - 아웃바운드:
apps/agent/src/messaging/dingtalk.ts - 인바운드 명세:
apps/agent/src/messaging/inbound/specs/dingtalk.ts - DingTalk 오픈 플랫폼: open.dingtalk.com
- Stream Mode (향후 지원): 프로토콜 설명