MINARA
Minara 사용하기클라이언트 및 인터페이스메시징 플랫폼

WeCom (기업 위챗)

SHA1 정렬 + AES-256-CBC 콜백 봉투를 사용하는 WeCom 자체 구축 앱 메시징. 중국 엔터프라이즈 배포의 표준 채널입니다.

🟡 아웃바운드 준비 완료, 인바운드 지원, 자체 구축 애플리케이션 경로(가장 일반적인 배포 형태)를 기반으로 구축되었습니다. WeChat OA에서 사용하는 것과 동일한 레거시 SHA1 + AES 봉투를 통해 라우팅되므로, 공유 wxcrypt 헬퍼가 두 공급자를 모두 지원합니다.

제공 기능

  • 아웃바운드 텍스트 메시징: POST /cgi-bin/message/send를 통해 하나 이상의 touser 수신자(또는 전체 Agent 대상의 @all)에게 메시지를 전송합니다.
  • 인바운드 콜백 이벤트: /webhooks/wecom 엔드포인트로 수신합니다. WeCom은 모든 콜백에 msg_signature(사전순으로 정렬된 [token, timestamp, nonce, encrypt]에 대한 SHA1)로 서명합니다. 본문은 43자 EncodingAESKey를 사용하는 AES-256-CBC로 암호화됩니다.
  • 앱별 access_token 캐시: 2시간 동안 캐시되며 자동 갱신됩니다.
  • 현재 텍스트만 지원합니다. 이미지 및 파일 업로드("미디어 업로드" 엔드포인트 경유)는 향후 추가될 예정입니다.
  • 텍스트 2048자 제한 (마크다운은 4096자이나 아직 미연동).

설정

1. 자체 구축 애플리케이션 생성

  1. WeCom 관리자 콘솔에 로그인합니다.
  2. "애플리케이션 및 미니 프로그램" → "자체 구축" → "만들기"로 이동합니다.
  3. 애플리케이션 메타데이터를 입력하고, 상세 페이지에서 AgentIDSecret을 확인합니다.
  4. 회사 수준의 CorpID는 "내 회사" → "회사 정보"에서 확인할 수 있습니다.

2. 콜백 활성화 (인바운드용, 선택 사항)

  1. 애플리케이션 상세 페이지 → "API 수신" → "API 수신 설정"을 엽니다.
  2. URL을 https://<your-host>/webhooks/wecom으로 설정합니다.
  3. Token(임의의 불투명 문자열)을 입력하고, EncodingAESKey(43자 base64여야 함)는 "랜덤" 버튼을 클릭하여 생성합니다.
  4. "저장"을 클릭합니다. WeCom이 GET 핸드셰이크로 해당 URL을 호출하면, Minara가 echostr을 복호화하여 그대로 응답함으로써 바인딩이 완료됩니다.

3. Minara 설정

minara auth messaging add
# `wecom`을 선택하고 corp id, agent id, secret, default touser,
# callback token, EncodingAESKey를 입력합니다.

또는 환경 변수를 직접 설정합니다.

WECOM_CORP_ID=ww<...>
WECOM_AGENT_ID=1000002
WECOM_SECRET=<application secret>
WECOM_DEFAULT_TOUSER=user1|user2     # 또는 @all
WECOM_CALLBACK_TOKEN=<callback token>
WECOM_CALLBACK_AES_KEY=<43-char EncodingAESKey>

WECOM_DEFAULT_TOUSER는 WeCom 규약인 파이프(|)로 구분된 사용자 ID 또는 Agent 전체 대상의 @all을 허용합니다.

4. 테스트

minara auth messaging test wecom

기본 목록의 각 touser에게 "✅ Minara gateway test ping" 메시지가 전송됩니다.

인바운드 웹훅

WeCom은 메시지 서명을 헤더가 아닌 URL 쿼리로 전달합니다. Minara는 본문을 복호화하기 전에 msg_signatureSHA1(sort([token, timestamp, nonce, encrypt]).join("")) (Tencent의 레거시 IM 방식)으로 검증합니다.

GET URL 검증 핸드셰이크: WeCom이 ?msg_signature=…&timestamp=…&nonce=…&echostr=<base64> 형식으로 요청을 전송합니다. Minara는 서명을 확인한 후 AES 키(IV = 키의 처음 16바이트)로 echostr를 복호화하여 평문을 응답합니다. Token 또는 AES 키가 잘못된 경우 401 또는 500이 반환됩니다.

복호화 후 내부 XML 페이로드:

<xml>
  <ToUserName>...</ToUserName>
  <FromUserName>...</FromUserName>
  <CreateTime>...</CreateTime>
  <MsgType>text</MsgType>
  <Content>...</Content>
  <MsgId>...</MsgId>
</xml>

현재는 MsgType=text 메시지만 Agent로 전달됩니다. 이미지, 음성, 이벤트 유형은 자동으로 무시됩니다.

제한 사항 및 주의 사항

  • access_token과 콜백 token은 서로 다릅니다. 전자는 WeCom의 앱별 OAuth 토큰이고, 후자는 콜백용 공유 서명 시크릿입니다. 환경 변수 파일에서 혼동하지 않도록 주의하십시오.
  • @all은 자주 발생하는 함정입니다. Agent 범위 내 모든 사용자에게 알림을 일괄 전송합니다. 프로덕션 환경에서는 WECOM_DEFAULT_TOUSER를 특정 사용자 ID로 고정하십시오.
  • AES 키 길이는 필수 조건입니다. WeCom은 정확히 32바이트(패딩 전 43자 base64)로 디코딩되지 않는 키를 거부합니다.

문제 해결

"Get access token failed (errcode 40013)"

  • WECOM_CORP_ID가 해당 시크릿이 속한 회사와 일치하지 않습니다.

"인바운드 웹훅이 401을 반환함"

  • msg_signature가 일치하지 않습니다. 가장 흔한 원인은 WECOM_CALLBACK_TOKEN의 오타입니다. 드문 경우로, 리버스 프록시가 서명 쿼리를 제거하는 경우도 있습니다.

"signCallbackParams length mismatch"

  • WECOM_CALLBACK_AES_KEY가 43자가 아닙니다. WeCom 콘솔에서 재생성하십시오.

참조

목차