Skip to content

Feishu runbook for agents ​

Read this when you are handling Feishu work and the normal anima command help is not enough: what the Feishu identifiers mean, which settings humans must configure, the direct API calls for what anima does not cover yet, and how to avoid blind retries.

The mental model ​

Your Feishu identity is a Feishu app with a bot account. Anima delivers Feishu messages to you and sends your replies back through that app. For ordinary visible output, use audited Anima commands: anima message send, anima message read, anima message update, anima file fetch, and anima message react.

Some Feishu actions do not have first-class Anima commands yet, such as creating a group or adding members to a group. For those, you may call Feishu OpenAPI directly with FEISHU_TENANT_ACCESS_TOKEN. Do not print or log that token. Anything a human should see still goes through anima message, so the action is visible in Anima's audit trail.

Do not start with web search. First inspect the delivery envelope and this runbook.

Feishu identifiers ​

  • chat_id starts with oc_. It names a Feishu conversation. It can be a DM, a group, or a topic container. Use it with anima message send --chat-id <chat_id>.
  • message_id usually starts with om_. It names a message. For a topic reply, pass the topic thread_id when present, otherwise the root message_id, as --thread-ts.
  • open_id usually starts with ou_. It is the stable user identifier you normally want for mentions and human invites.
  • user_id is the tenant user identifier. Use it only when the envelope or user gave it explicitly.
  • app_id starts with cli_. It identifies a Feishu app. Use an Anima-created agent's Feishu App ID when inviting another bot into a chat.

Display names are not identifiers. If you only have a name, ask the user to mention that person in Feishu and send the request again. The mention metadata gives Anima stable IDs.

Permissions are not visibility ​

Feishu has two separate gates:

  • API permissions, also called scopes. These let the app perform actions like send messages, read group messages from users and bots, add group members, look up users by email or phone, or work with Feishu Drive and cloud documents. Users authorize these in Anima's Feishu setup flow and publish a new app version.
  • App visibility or availability range. This controls which users can see or use the app. It is configured in the Feishu developer console or admin console. The app cannot grant itself wider visibility through OpenAPI.

If an API call says a scope is missing, ask the user to add the recommended permission and publish a new app version. If a member invite fails with 232024 and says users do not have app visibility, ask the user to add the target person, department, or all members to the app's visibility or availability range, save or publish that change, then retry.

Replying, reading, and editing ​

Use the envelope. In a Feishu chat:

anima message send --chat-id <chat_id> <<'ANIMA_MESSAGE'
<reply>
ANIMA_MESSAGE

For a topic, include the topic id:

anima message send --chat-id <chat_id> --thread-ts <thread_id_or_root_message_id> <<'ANIMA_MESSAGE'
<reply>
ANIMA_MESSAGE

Use anima message read --chat-id <chat_id> when you need recent chat history. Add --thread-ts when you need a topic's thread history. Use anima message update --chat-id <chat_id> --message-ts <message_id> only for messages you sent.

Mentioning people ​

When you know a user's open_id, mention them in message text like this:

<mention open_id="ou_...">Name</mention>

Anima sends that as a Feishu rich-text mention. Do not write raw @Name when the user needs a real mention. Do not invent an open_id from a name.

Creating a group ​

There is no first-class anima command for Feishu group creation yet.

  1. Get at least one user open_id from the envelope, usually the person who asked you. Do not guess people from display names.

  2. Call the chat-create API once:

    curl -sS -X POST \
      "https://open.feishu.cn/open-apis/im/v1/chats?user_id_type=open_id" \
      -H "Authorization: Bearer $FEISHU_TENANT_ACCESS_TOKEN" \
      -H "Content-Type: application/json" \
      --data '{"name":"<chat_name>","description":"<description>","user_id_list":["<owner_open_id>"],"chat_mode":"group","chat_type":"private"}'
  3. Read the JSON response. If it contains chat_id, the group exists.

  4. Send the visible confirmation or first message with anima message send --chat-id <chat_id>.

Do not create another group just because you are unsure whether the first call worked. Check the response first.

Inviting people or bots ​

There is no first-class anima command for invites yet. The current agent must already be in the chat, and you need the chat's oc_... id from the envelope.

A human teammate is invited by open_id:

  • If the teammate appears in the envelope or readable history, use their open_id.
  • If the user gives an email address or phone number, resolve it to an open_id first.
  • If you only have a tenant user_id, invite with member_id_type=user_id and pass that id.
  • If you only have a display name, ask the user to mention the teammate in Feishu and send the request again, or to give an email, phone number, open_id, or user_id.

Resolve an email or phone number, passing only the fields you have:

curl -sS -X POST \
  "https://open.feishu.cn/open-apis/contact/v3/users/batch_get_id?user_id_type=open_id" \
  -H "Authorization: Bearer $FEISHU_TENANT_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{"emails":["<email>"],"mobiles":["<phone>"],"include_resigned":false}'

If Feishu returns no matching user, ask the user to mention the teammate in Feishu and send the request again, or for another deterministic identifier. Then invite:

curl -sS -X POST \
  "https://open.feishu.cn/open-apis/im/v1/chats/<chat_id>/members?member_id_type=open_id" \
  -H "Authorization: Bearer $FEISHU_TENANT_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{"id_list":["<target_open_id>"]}'

Another Anima-created Feishu bot is invited by that agent's Feishu App ID (cli_...), not by its bot open_id: the same members call with member_id_type=app_id and the App ID in id_list. If you cannot see the App ID, ask the user to copy it from the target agent's Profile page. Do not guess it from the bot name.

When invite calls fail:

  • 232024 or "visibility of the app" means app visibility is missing for the target user. Ask the user to add the target person to the app's availability range, save or publish that change, then retry. An external collaborator may also need external collaboration permission.
  • A permission error means the current app probably lacks the group-member or user-lookup scope, or the new app version has not been published.
  • A group management error means this bot may not be allowed to manage members in that specific group.

Report the specific error and the next human action. Do not keep trying the same identifiers after the platform has returned a configuration error.

Safe direct API use ​

Use FEISHU_TENANT_ACCESS_TOKEN only as an HTTP bearer token. Do not echo it, write it into a file, paste it into chat, or include it in command output. It is acceptable to check whether it exists without printing the value.

Keep visible communication separate from direct API work. A curl call may create a group or invite a member, but the human-facing explanation should still be sent with anima message send.