Documentation

Feishu/Lark Integration

AgentHub uses Feishu/Lark as a collaboration surface: bot messages, event subscriptions, interactive cards, and an H5/workbench entry. Product login and account binding still belong to TokenDance ID.

Identity boundary

Do not describe Feishu OAuth as AgentHub product login. Feishu user identifiers are collaboration context only. TokenDance ID remains the identity authority and owns account binding.

Integration Boundary

mermaid
flowchart LR
  Client["Feishu/Lark Client"] --> App["AgentHub Bot, Cards, H5"]
  App --> Gateway["Feishu Integration Gateway"]
  Gateway --> Hub["AgentHub Hub Server"]
  Hub --> ID["TokenDance ID"]
  ID --> Binding["Feishu Account Binding"]

The Feishu app should stay focused on collaboration entry points:

  • receive direct messages and group @mentions;
  • send bot replies and task cards;
  • process card action callbacks;
  • open AgentHub in an H5/workbench surface;
  • hand off identity and binding to TokenDance ID.

Production Ingress

Production should keep an HTTPS webhook gateway as the durable event ingress. The gateway should expose separate routes for message events and card actions:

Text
POST /integrations/feishu/events
POST /integrations/feishu/card-actions

The webhook path handles URL challenge, signature/encryption checks, event deduplication, token caching, message parsing, and fast acknowledgement. Slow AgentHub work should be queued asynchronously.

SDK long-connection receiving is useful for enterprise self-built app development and internal testing, but it should not be the only production path or the sole option for future cross-tenant event delivery.

App Setup Checklist

Use this checklist before claiming that a Feishu/Lark integration is ready for user testing. Keep real app ids, secrets, tenant ids, callback tokens, and approval screenshots out of this public repository.

StepPublic-safe requirementEvidence to keep
App modelChoose an enterprise self-built app or an explicitly approved deployment shapePrivate implementation note with owner and tenant scope
Bot entryEnable bot messages for direct messages and group @mentionsScreenshot or tenant config evidence in private ops docs
Event subscriptionsSubscribe only to im.message.receive_v1 and card.action.trigger for MVPEvent subscription list with approval owner
URL challengeWebhook returns the platform challenge body before business logicRedacted request id and success timestamp
Signature and encryptionVerify token and signature, and decrypt the payload before parsing the event bodyUnit/integration test result, no raw payload in public docs
ScopesRequest only bot/message/card/H5 scopes required by the MVPScope review note and explicit rejection of broad read scopes
IdempotencyDerive idempotency from event_id, message_id, or action idRetry test that does not create duplicate Hub tasks
Queue handoffAcknowledge quickly, then enqueue AgentHub workLatency evidence for callback ack and queue enqueue
BindingUnbound users receive a TokenDance ID binding cardRedacted card screenshot and binding-state audit record
Failure UXUnknown command, unauthorized action, queue failure, and binding failure have cardsFailure-state screenshots with synthetic ids

Required Events

The MVP event set is deliberately small:

EventPurposeHandling
im.message.receive_v1Direct messages and group @mentionsDeduplicate message events by message_id; only parse commands and required context.
card.action.triggerInteractive card actionsRespond within 3 seconds; queue slow work; do not rely on HTTP redirects.

Group chats should default to @mention-triggered behavior. Avoid requesting broad "read every group message" permissions unless the product requirement and security review are explicit.

Public-Safe Payload Examples

URL challenge should complete before business logic and return the platform-required challenge body. This example shows shape only:

JSON
{
  "type": "url_verification",
  "challenge": "challenge_string"
}
JSON
{
  "challenge": "challenge_string"
}

Message event example:

JSON
{
  "schema": "2.0",
  "header": {
    "event_id": "evt_123",
    "event_type": "im.message.receive_v1",
    "tenant_key": "tenant_123"
  },
  "event": {
    "message": {
      "message_id": "msg_123",
      "chat_id": "chat_123",
      "message_type": "text",
      "content": "{\"text\":\"@AgentHub review docs\"}"
    },
    "sender": {
      "sender_id": {
        "open_id": "ou_xxx",
        "union_id": "on_xxx"
      }
    }
  }
}

Card action example:

JSON
{
  "schema": "2.0",
  "header": {
    "event_id": "evt_card_123",
    "event_type": "card.action.trigger"
  },
  "event": {
    "operator": {
      "open_id": "ou_xxx"
    },
    "action": {
      "value": {
        "action": "approve_run",
        "taskId": "task_123",
        "approvalId": "approval_123"
      }
    }
  }
}

Fast acknowledgement should be small; slow work goes to a queue:

JSON
{
  "ok": true,
  "queued": true,
  "requestId": "req_123"
}

If the user is not bound to TokenDance ID, return a binding card instead of creating a Hub task:

JSON
{
  "card": {
    "title": "Bind TokenDance ID",
    "actions": [
      {
        "type": "button",
        "label": "Continue",
        "url": "https://id.example.invalid/bind/feishu?state=opaque_state"
      }
    ]
  }
}

These examples do not replace real platform signature, encryption, challenge, or card-schema validation. Implementations should follow the Feishu/Lark official docs and the owning AgentHub repository schemas.

MVP Acceptance Criteria

A Feishu/Lark MVP is not ready just because the bot can receive a message. It should meet all of the following criteria:

AreaAcceptance criteria
App typeAn enterprise self-built app or approved deployment shape is documented in the private implementation plan
ScopesOnly required bot/message/card/H5 scopes are requested; broad read scopes have explicit security review
Event subscriptionim.message.receive_v1 and card.action.trigger are enabled and verified
Challenge responseURL verification responds with the expected challenge body before business logic
Signature/encryptiontoken, signature, and encrypted payload checks run before event parsing
Dedupemessage events dedupe by message_id; card actions dedupe by event or action id
Queue handoffslow AgentHub work is queued asynchronously after fast acknowledgement
Retry policyretries are idempotent and do not create duplicate Hub tasks
Binding failure UXunbound users receive a TokenDance ID binding card, not a generic failure
AuditHub records actor, binding state, task id, action, result, request id, and redacted failure reason

Cards And Actions

Cards are the primary Feishu-native interaction surface for AgentHub:

  • task status cards;
  • approval, retry, cancel, and view-detail actions;
  • TokenDance ID binding cards for unbound users;
  • run-state cards for running, completed, failed, or needs-input tasks.

Card actions should carry only a short action id and business object id. Do not place secrets, bearer tokens, full prompts, or sensitive workspace context in card payloads.

H5 And Workbench

The Feishu H5/workbench entry can open AgentHub inside the Feishu client, but it is not a second login system.

If the user is not bound, show a TokenDance ID binding path. Feishu JSAPI can improve the in-client experience, but the final product identity and authorization must resolve through TokenDance ID and AgentHub Hub Server permissions.

Binding Loop

The recommended user mapping is:

  1. Feishu event arrives with tenant and user context.
  2. Integration Gateway maps the Feishu user to a TokenDance ID binding.
  3. If no binding exists, the bot returns a binding card.
  4. The user completes TokenDance ID login and Feishu account binding.
  5. AgentHub receives a TokenDance ID sub and applies Hub Server permissions.

AgentHub should not store Feishu access tokens in Desktop or Web clients, and Feishu open_id, user_id, or union_id must not become the product user primary key.

Security Checklist

  • Keep the verification token, encrypt key, app secret, and tenant tokens in server-side secret storage.
  • Verify signatures and decrypt encrypted events before business handling.
  • Acknowledge events and card callbacks within 3 seconds.
  • Deduplicate im.message.receive_v1 with message_id; deduplicate other events with the event id when available.
  • Log event type, message id, event id, tenant, hashed chat id, action id, latency, result, and Feishu error code; avoid logging full message content by default.
  • Keep Feishu OAuth, refresh tokens, and account binding inside TokenDance ID.

Next Steps

  • Use the architecture guide to place the Integration Gateway beside the AgentHub Hub Server.
  • Treat Feishu bot setup as in-development until the AgentHub runtime endpoints, card schemas, and binding callback evidence are published.
  • Track production scopes and review material in the AgentHub implementation backlog.