Feishu And Lark

This guide shows how to use AgentInbox with a Feishu/Lark bot through UXC.

Prerequisites

Register the current runtime first:

agentinbox agent register

Follow Bot Mentions

For most agent bot workflows, use the global mention template:

agentinbox follow feishu mentions \
  --agent-id <agentId> \
  --config-json '{"uxcAuth":"feishu-default"}'

By default, AgentInbox resolves the configured app bot's open_id from the Feishu/Lark credential and follows messages that mention that bot across chats visible to the app event stream. It does not mean every chat in the tenant. The app must be allowed to receive those events, and the bot normally needs to be in the chat.

To follow mentions for another user or bot explicitly, pass openId:

agentinbox follow feishu mentions \
  --agent-id <agentId> \
  --arg openId=<openId> \
  --config-json '{"uxcAuth":"feishu-default"}'

Follow One Chat

Feishu/Lark chat_id values are API identifiers. Users normally see group names in the app UI, not oc_xxx ids. If the source is already configured, use chat discovery operations to resolve a group name before creating a chat-scoped follow:

agentinbox source invoke <sourceId> \
  --operation search_chats \
  --input-json '{"query":"bottest","limit":10}'

Use list_chats to browse visible chats and get_chat to inspect a known chatId. Results only include chats visible to the configured UXC Feishu/Lark credential. search_chats filters the visible chat page by name or identifier; pass the returned pageToken to continue searching later pages when necessary.

If the workflow is intentionally limited to one group, use the chat-scoped templates:

agentinbox follow feishu chat \
  --agent-id <agentId> \
  --arg chatId=<chatId> \
  --config-json '{"uxcAuth":"feishu-default"}'
agentinbox follow feishu mention \
  --agent-id <agentId> \
  --arg chatId=<chatId> \
  --arg openId=<botOpenId> \
  --config-json '{"uxcAuth":"feishu-default"}'

If you do not need a chat-scoped workflow, prefer feishu.mentions; it follows bot mentions across chats visible to the app event stream without requiring a specific chatId.

Read, Add Context, And Reply

Read the agent inbox:

agentinbox inbox read --agent-id <agentId>

Feishu/Lark inbox items include:

Fetch surrounding message context when needed:

agentinbox source invoke <sourceId> \
  --operation get_message_context \
  --input-json '{"messageId":"<messageId>","chatId":"<chatId>","windowBefore":5,"windowAfter":5}'

get_message_context is anchored to a specific inbox message. Keep passing the triggering messageId when an agent is adding context for a notification; this avoids racing against newer messages in the same group.

For unanchored browsing, list the latest messages in a chat instead:

agentinbox source invoke <sourceId> \
  --operation list_recent_messages \
  --input-json '{"chatId":"<chatId>","limit":20}'

Read Attachments And Documents

When a Feishu/Lark message contains files, images, or cloud document links, list the message attachments first:

agentinbox source invoke <sourceId> \
  --operation list_message_attachments \
  --input-json '{"messageId":"<messageId>"}'

The response includes each attachment with attachmentId, kind, and source-specific fields such as fileKey for message resources or token for cloud documents:

{
  "messageId": "om_xxx",
  "attachments": [
    {
      "attachmentId": "att_xxx",
      "kind": "file",
      "fileKey": "file_xxx",
      "name": "report.pdf"
    },
    {
      "attachmentId": "att_yyy",
      "kind": "doc",
      "token": "doccn_xxx",
      "url": "https://internal-api.feishu.cn/open-apis/drive/v1/documents/doccn_xxx"
    }
  ]
}

Save An Attachment

Use the returned attachmentId to save one attachment. AgentInbox writes into the path you provide; your runtime sandbox controls whether that path is accessible.

By messageId + attachmentId (recommended for most callers):

agentinbox source invoke <sourceId> \
  --operation save_attachment \
  --input-json '{"messageId":"<messageId>","attachmentId":"<attachmentId>","outputDir":"/tmp/agentinbox-feishu"}'

By attachment object (when the caller already has the full attachment):

agentinbox source invoke <sourceId> \
  --operation save_attachment \
  --input-json '{"attachment":{...},"outputDir":"/tmp/agentinbox-feishu"}'

Attachment Types And Output Formats

Attachment kindDefault outputformat optionNotes
imageoriginal image"original" onlyDownloads the message image resource; requires fileKey
fileoriginal file"original" onlyDownloads the message file resource; requires fileKey
doc / docx / wiki.md (Markdown)N/AExported via Feishu API as Markdown
sheet.xlsx"csv"CSV export requires subId for the sheet tab
bitable / base.base"csv"CSV export requires subId for the table
drive_fileoriginal file"original" onlyDownloads cloud drive file via Lark CLI

Optional Parameters

ParameterTypeDescription
outputPathstringFull absolute file path (alternative to outputDir)
outputDirstringDirectory path; filename is auto-generated from attachment name
fileNamestringOverride the auto-generated filename
formatstringOutput format ("original", "csv", "markdown")
subIdstringTab or table identifier for sheet/bitable CSV export
identity"user" | "bot"Caller identity for access control; defaults to the configured credential
overwritebooleanAllow overwriting an existing file; defaults to false

Save Response

On success, save_attachment returns:

{
  "attachmentId": "att_xxx",
  "kind": "file",
  "path": "/tmp/agentinbox-feishu/report.pdf",
  "format": "original"
}

Reply with text:

agentinbox deliver invoke \
  --handle-json '<deliveryHandle-json>' \
  --operation send_text \
  --input-json '{"text":"Acknowledged","uxcAuth":"feishu-default"}'

Rich text and files are available through delivery operations such as send_post, send_file, and send_file_from_path.

Send a new message to a chat by using the chat_message surface and the chat ID as the target:

agentinbox deliver invoke \
  --provider feishu \
  --surface chat_message \
  --target '<chatId>' \
  --operation send_text \
  --input-json '{"text":"Daily report","uxcAuth":"feishu-default"}'

Use deliver actions to inspect available operations and input schemas:

agentinbox deliver actions \
  --provider feishu \
  --surface chat_message \
  --target '<chatId>'

The Feishu adapter currently supports message_reply and chat_message surfaces.