본문으로 건너뛰기

메시징 쓰기

상담 콘솔이 대화를 운영하기 위한 쓰기 엔드포인트입니다 — 답장 전송, 읽음 처리, 담당자 배정, 채널 종료/재개. 읽기 엔드포인트와 같은 Base URL·봉투·에러 규약을 따릅니다.

쓰기 엔드포인트는 BFF(서버 사이드)에서만 호출하세요. Public API는 CORS를 허용하지 않으며, PAT는 워크스페이스 전체를 읽고 쓸 수 있는 비밀 값입니다.

답장 전송

POST /channels/{id}/messages — 채널에 메시지를 전송합니다.

  • Scope: messages:write
  • Body
필드타입설명
content_typetext | markdown본문 형식
contentstring메시지 본문 (1–2000자, 초과 시 400 INVALID_BODY)
sender_member_idstring · 선택발신 상담원 membership ID. 생략하면 토큰의 integration 신원으로 귀속됩니다 (하이브리드 귀속, 아래 참고)
client_request_idstring · 선택멱등성 키 (최대 128자). 같은 값으로 재전송하면 원본 메시지를 반환합니다
curl -X POST "https://api.talk.zeroworks.ai/api/public/v1/channels/c1d2.../messages" \
-H "Authorization: Bearer ztpat_..." \
-H "Content-Type: application/json" \
-d '{
"content_type": "text",
"content": "안녕하세요, 무엇을 도와드릴까요?",
"sender_member_id": "m1n2o3-...",
"client_request_id": "req-7f3a..."
}'

응답 — 신규 생성 시 201, 멱등 중복 시 200(deduplicated: true).

{
"success": true,
"data": {
"id": "msg-9z8y-...",
"channel_id": "c1d2e3f4-...",
"sender_id": "00000000-0000-0000-0000-...",
"sender_type": "integration",
"sender_name": "ztpat_a1b2c3",
"content_type": "text",
"content": "안녕하세요, 무엇을 도와드릴까요?",
"created_at": "2026-06-02T01:23:45Z",
"updated_at": "2026-06-02T01:23:45Z",
"client_request_id": "req-7f3a...",
"deduplicated": false
}
}

하이브리드 귀속

  • sender_member_id지정하면 해당 상담원으로 귀속됩니다. 그 상담원은 message:write 권한이 있어야 하며, 호출 측은 자신의 상담원을 ZeroTalk membership ID에 매핑해야 합니다.
  • sender_member_id생략하면 토큰의 integration 신원으로 귀속됩니다 — 메시지의 sender_typeintegration, 표시 이름(sender_name)은 토큰 프리픽스(secret 앞 12자, 예: ztpat_a1b2c3)입니다 (상담원 측 렌더링은 이벤트 문서의 sender_type 참고).

에코와 멱등성

  • 전송한 답장은 message.created 웹훅으로 되돌아옵니다. 웹훅에는 client_request_id가 없으므로, 응답의 data.id 를 웹훅의 data.message_id와 대조해 자신의 전송을 식별하세요.
  • client_request_id전송 멱등성 용도입니다 — 실패한 POST를 같은 키로 재시도하면 새 메시지를 만들지 않고 원본을 200(deduplicated: true)으로 반환합니다. 웹훅 상관(correlation) 키로는 쓰지 마세요.

읽음 처리

POST /channels/{id}/read — 채널을 특정 메시지까지 읽음 처리합니다.

  • Scope: channels:write
  • Body: { "actor_member_id": "...", "message_id": "..." }
  • 응답: 204 No Content
curl -X POST "https://api.talk.zeroworks.ai/api/public/v1/channels/c1d2.../read" \
-H "Authorization: Bearer ztpat_..." \
-H "Content-Type: application/json" \
-d '{ "actor_member_id": "m1n2o3-...", "message_id": "msg-9z8y-..." }'

종료 / 재개

POST /channels/{id}/close · POST /channels/{id}/reopen — 채널을 종료하거나 재개합니다.

  • Scope: channels:write
  • Body: { "actor_member_id": "..." }
  • 응답: 200, data는 갱신된 채널 객체(채널 조회와 동일 스키마) — 변경된 status를 별도 GET 없이 확인할 수 있습니다.
curl -X POST "https://api.talk.zeroworks.ai/api/public/v1/channels/c1d2.../close" \
-H "Authorization: Bearer ztpat_..." \
-H "Content-Type: application/json" \
-d '{ "actor_member_id": "m1n2o3-..." }'

종료·재개는 각각 channel.closed·channel.reopened 웹훅을 발생시킵니다.

담당자 배정

POST /channels/{id}/assign — 채널 담당자를 지정하거나 해제합니다.

  • Scope: channels:write (그리고 actor_member_id 상담원에게 channel:operate 권한 필요)
  • Body: { "actor_member_id": "...", "member_id": "..." }member_idnull로 보내면 배정이 해제됩니다.
  • 응답: 200, data는 갱신된 채널 객체(채널 조회와 동일 스키마) — 변경된 assigned_member_id를 별도 GET 없이 확인할 수 있습니다.
curl -X POST "https://api.talk.zeroworks.ai/api/public/v1/channels/c1d2.../assign" \
-H "Authorization: Bearer ztpat_..." \
-H "Content-Type: application/json" \
-d '{ "actor_member_id": "m1n2o3-...", "member_id": "p4q5r6-..." }'

배정 변경은 channel.assigned 웹훅을 발생시킵니다. 현재 담당자는 채널 조회의 assigned_member_id와 웹훅 envelope의 assigned_member 스냅샷에서 확인합니다.

참고