Feishu IM messaging operations: send messages, images, files to users and groups via Bot API. Activate when user mentions: 飞书发图、发送图片、飞书消息、im:resource、image_k...
--- name: feishu-im description: | Feishu IM messaging operations: send messages, images, files to users and groups via Bot API. Activate when user mentions: 飞书发图、发送图片、飞书消息、im:resource、image_key、飞书附件、飞书机器人发消息。 --- # Feishu IM Tool Use the `message` tool with `channel=feishu` for all IM operations. ## Send Text Message ``` message(action=send, channel=feishu, target=<user_id or chat_id>, message="text") ``` ## Send Image (CORRECT method) **Always use `filePath` or `media`, never paste a raw path in message text.** ``` message(action=send, channel=feishu, target=<chat_id>, filePath="/absolute/path/to/image.jpg") ``` Or with caption: ``` message(action=send, channel=feishu, target=<chat_id>, media="/path/to/image.jpg", message="caption text") ``` The tool handles the two-step upload internally: 1. POST /im/v1/images → get image_key 2. POST /im/v1/messages with image_key ## Common Failure Modes — Images Show as Path/Link See `references/image-sending-pitfalls.md` for full diagnosis. **TL;DR root causes:** - Assistant wrote raw file path in message text instead of calling `message` tool → plain text, no upload - Used `MEDIA:/absolute/path` → security filter strips it - `image_type` wrong during upload (must be `message`, not `avatar`) - `tenant_access_token` expired (TTL ~2h) → upload silently fails, key is empty - Webhook custom bot used instead of Bot App → no access_token, can't upload images ## Permissions Required | Scope | Purpose | |-------|---------| | `im:resource` | Upload image/file to IM, get file_key / image_key | | `im:message` | Send messages with media | | `im:message:send_as_bot` | Send as bot identity | All three are currently granted on this installation. ## Bot Type Comparison | Feature | Webhook Custom Bot | Bot App (自建应用) | |---------|-------------------|-------------------| | Send text | ✅ | ✅ | | Send image | ⚠️ base64 only (不推荐) | ✅ via image_key | | access_token | ❌ 无 | ✅ tenant_access_token | | Upload API | ❌ 不支持 | ✅ /im/v1/images | **OpenClaw uses Bot App — always use the `message` tool, not raw Webhook POST.** ## Token Refresh `tenant_access_token` expires in ~2 hours. If uploads silently fail: - Error code `99991663` = image_key invalid - Error code `99991400` = token expired OpenClaw refreshes tokens automatically on each API call. If you see these errors, check Gateway logs. ## References - `references/image-sending-pitfalls.md` — detailed failure mode diagnosis - Feishu API docs: https://open.feishu.cn/document/server-docs/im-v1/image/create
don't have the plugin yet? install it then click "run inline in claude" again.
restructured raw api docs into implexa format, made decision logic explicit (token expiry, bot type, upload vs text-only), added detailed failure modes and edge cases (timeout, missing file, empty results), documented all inputs with env var names and scopes, and clarified upload-then-send procedure with specific http endpoints and form fields.
send text messages, images, and files to feishu users and chat groups using the bot api. use this skill when a user needs to push content into feishu im via automated workflows, whether that's a single image to a group chat, a captioned file to a user, or bulk notifications. activate on triggers like 飞书发图, 发送图片, 飞书消息, im:resource, image_key, 飞书附件, 飞书机器人发消息.
feishu bot credentials and permissions
tenant_access_token: bot app token (not webhook custom bot). expires every ~2 hours. openClaw auto-refreshes on each call.bot_app_id and bot_app_secret: required to obtain tenant_access_token if manual refresh needed.FEISHU_TENANT_ACCESS_TOKEN (preferred) or passed inline.required oauth scopes (all currently granted on openClaw installation)
im:resource: upload images and files to im, receive file_key and image_key in response.im:message: send messages containing media attachments.im:message:send_as_bot: identify the sender as the bot, not a user.target identifiers (exactly one required per message)
user_id: feishu user id (e.g., ou_abc123). sends dm to that user.chat_id: feishu group chat id (e.g., oc_abc123). sends to the group.email: user email address. feishu will resolve to user_id internally.content payload (at least one required)
message: plain text string. required for text-only sends; optional for image/file sends (acts as caption).filePath: absolute local file path to image or file. e.g., /tmp/report.jpg. mutually exclusive with media (use one or the other).media: alternative to filePath, same behavior. e.g., /var/uploads/chart.png.file_type: mime type if sending file (e.g., image/jpeg, application/pdf). defaults to inferred from extension.external connection
https://open.feishu.cn/open-apis/. used for image upload and message send. requires network access and valid tenant_access_token.validate inputs. check that target (user_id or chat_id or email) is present and non-empty. check that message or filePath is present. if either missing, raise error with required fields listed. if both filePath and media supplied, raise error (mutually exclusive).
obtain token. retrieve tenant_access_token from environment variable FEISHU_TENANT_ACCESS_TOKEN or accept it as parameter. if token missing, attempt auto-refresh using bot_app_id and bot_app_secret (if provided). if no token and no refresh credentials, fail with message "no feishu credentials found".
text-only send (if no image/file). if message supplied and filePath/media absent, call message(action=send, channel=feishu, target=<user_id_or_chat_id>, message="<text>"). openClaw tool handles the rest. log success or propagate error from feishu api.
prepare image/file upload (if filePath or media provided). resolve the file path to an absolute path on disk. verify file exists and is readable. determine mime type from file extension or accept as parameter. if file does not exist, raise error with path shown.
upload to feishu. post file to https://open.feishu.cn/open-apis/im/v1/images (for images) or /im/v1/files (for generic files). include headers: Authorization: Bearer <tenant_access_token>, Content-Type: multipart/form-data. include form fields: image_type=message (critical, not avatar), and file binary in field image. send request and capture response.
parse upload response. extract image_key from response json. if response contains error code, check error code against decision table. if image_key is null or empty string, treat as silent failure (token likely expired). log full response for debugging.
send message with media. call message(action=send, channel=feishu, target=<chat_id>, filePath="<path>", message="<optional_caption>") or use image_key directly in raw api call if tool does not expose it. if caption provided, include as message field in the feishu message payload. log success with target and image_key.
confirm delivery. feishu api returns message_id on success (http 200). confirm that message_id is non-empty string. if http error or missing message_id, treat as failure and log error details. do not retry silently (let caller decide).
if text only (no image or file)
message tool with action=send, channel=feishu. no upload step needed.if image or file to be sent
/im/v1/images or /im/v1/files. capture image_key or file_key. then send message with that key. never paste raw file path into message text.if token expired or missing
tenant_access_token is absent and no bot_app_id/secret provided, fail immediately with "credentials required" error.if error code 99991663 (invalid image_key)
if webhook custom bot detected instead of bot app
if file not found at provided path
if network timeout on upload (>30s)
if empty result set (user_id does not exist in feishu)
success case
/im/v1/messages endpoint.message_id field (e.g., "message_id": "om_abc123def456").image_key or file_key in previous upload response.failure case
code and msg fields (e.g., "code": 99991400, "msg": "token expired").file location