Minara 사용하기클라이언트 및 인터페이스메시징 플랫폼
Lark / Feishu
tenant_access_token을 통한 Lark IM 메시징. 선택적 AES-256-CBC 암호화 webhook 이벤트를 지원합니다.
🟡 아웃바운드 준비 완료, 인바운드 지원, 중국 본토 Feishu(
open.feishu.cn)와 국제 Lark(open.larksuite.com) 모두 지원합니다. 인바운드 webhook은 Lark의 세 가지 보안 모드인 검증 토큰, 암호화, 서명된 HMAC를 모두 처리합니다.
제공 기능
POST /open-apis/im/v1/messages?receive_id_type=chat_id를 통한 아웃바운드 텍스트 메시징. tenant access token은 2시간 동안 캐시되며, 5분의 갱신 여유 시간이 있어 대용량 발신 시 앱별 token 속도 제한에 걸리지 않습니다./webhooks/lark에서의 인바운드 webhook 이벤트. Lark는 운영자가 세 가지 보안 모드(검증 토큰, 암호화 키, HMAC 서명)를 자유롭게 조합하여 선택할 수 있습니다. Minara는 개발자 콘솔에서 활성화된 모드를 모두 지원합니다.- 도메인 인식 라우팅.
LARK_DOMAIN으로 중국 본토 Feishu 또는 국제 Lark를 선택합니다. 두 서비스는 동일한 API 구조를 공유합니다. - 현재 텍스트만 지원. 리치 카드, 이미지, 파일은 향후 추가 예정입니다. 현재는 tenant 토큰 캐시와 서명된 webhook 기반이 제공됩니다.
- 30,000자 제한. 이를 초과하는 텍스트는 잘립니다.
설정
1. 앱 생성
- Lark 개발자 콘솔(또는 국제 Lark)에 로그인합니다.
- Custom App을 생성합니다. App ID(
cli_로 시작)와 App Secret을 기록해 둡니다. - "권한 및 범위"에서
im:message:send_as_bot을 부여하고, 인바운드의 경우 봇에 필요한 메시지 수신 범위(일반적으로im:message)를 추가합니다. - "이벤트 구독"에서 요청 URL을
https://<your-host>/webhooks/lark로 설정합니다. Verification Token과 (선택 사항) Encrypt Key를 복사합니다.
2. 기본 chat_id 찾기
대상 채팅(1:1 또는 그룹)에 메시지를 보낸 후, 개발자 콘솔에서 POST /open-apis/im/v1/messages/list를 호출하거나 tenant 토큰으로 curl을 실행하여 chat_id(oc_xxxxxxxxxxxxxxxx 형식)를 추출합니다. 이를 LARK_DEFAULT_CHAT_ID로 저장합니다.
3. Minara 설정
minara auth messaging add
# 목록에서 `lark`를 선택하고 app id, app secret, chat id,
# verification token(암호화를 활성화한 경우 encrypt key)을 입력합니다.또는 프로젝트 루트의 .env 파일에 직접 작성합니다.
LARK_APP_ID=cli_xxxxxxxxxxxxxxxx
LARK_APP_SECRET=<opaque secret>
LARK_DEFAULT_CHAT_ID=oc_xxxxxxxxxxxxxxxx
LARK_VERIFICATION_TOKEN=<verification token>
LARK_ENCRYPT_KEY=<encrypt key, optional>
LARK_DOMAIN=open.feishu.cn # or open.larksuite.com4. 테스트
minara auth messaging test lark인바운드 webhook
Lark 이벤트 구독 URL을 다음으로 설정합니다.
https://<your-host>/webhooks/lark세 가지 보안 모드가 중첩 적용됩니다.
| 모드 | 환경 변수 | 동작 |
|---|---|---|
| 검증 토큰 | LARK_VERIFICATION_TOKEN | 디코딩된 페이로드의 최상위 token 필드가 일치해야 합니다. 평문 모드 및 복호화 이후에 사용됩니다. |
| 암호화 | LARK_ENCRYPT_KEY (선택 사항) | 설정 시 본문이 {encrypt: "<base64>"} 형태로 수신되며, key = SHA256(encrypt_key), IV = 키의 첫 16바이트로 AES-256-CBC 복호화됩니다. |
| 서명 | X-Lark-Signature 헤더 (항상 선택 사항) | timestamp + nonce + encrypt_key + body에 대한 SHA-256 hex가 헤더로 전달됩니다. 추가 무결성 검사가 필요한 경우 콘솔에서 활성화합니다. |
URL 검증 핸드셰이크: Lark가 {type:"url_verification", challenge:"..."}를 전송하면, Minara는 검증 토큰 확인 후 {challenge}로 응답합니다. 토큰이 일치하지 않으면 403을 반환합니다.
제한 사항 및 주의점
- Tenant 토큰 속도 제한. Lark는 앱당 분당 약 100회의 토큰 발급 호출을 허용합니다. 2시간 캐시로 이 제한을 충분히 회피할 수 있습니다.
content는 JSON 인코딩 문자열이어야 합니다. Lark API의 특성상, 텍스트 메시지도content: JSON.stringify({text: "..."})로 전송해야 합니다. Minara가 이를 자동으로 처리합니다.- 카드 인터랙션 미지원. 인터랙티브 카드의 버튼 클릭 콜백은 별도의 webhook 이벤트 타입으로 수신되며, 현재 파싱되지 않습니다.
문제 해결
"테스트 메시지에서 code 99991663 반환"
- tenant access token 갱신에 실패한 것입니다. 개발자 콘솔에서
LARK_APP_ID와LARK_APP_SECRET을 확인합니다.
"인바운드 webhook이 401 반환"
- 콘솔에서 암호화 모드를 활성화했지만
LARK_ENCRYPT_KEY를 설정하지 않은 경우, 모든 인바운드 POST 요청에서 복호화가 실패합니다. 콘솔에서 암호화를 비활성화하거나 환경 변수를 설정합니다. - 서명 모드를 활성화한 경우, 저장한
LARK_ENCRYPT_KEY가 콘솔에 표시된 값과 일치하는지 확인합니다. 이 값은 서명 입력으로도 사용됩니다.
"content 필드 필수 (400)"
send_message를text에 빈 문자열로 호출하고 있습니다. Lark는 빈 본문을 거부합니다.
참조
- 환경 변수:
LARK_* - 아웃바운드:
apps/agent/src/messaging/lark.ts - 인바운드 스펙:
apps/agent/src/messaging/inbound/specs/lark.ts - Lark 오픈 플랫폼: open.feishu.cn
- 암호화 방법: open.feishu.cn / Encryption case