middleware.js. Before you write business logic, first confirm whether your plugin runs in a message, HTTP route, or cron / fake context.
Runtime context
Each plugin run has asenderID. For message triggers, senderID contains the IM, account, chat, and user. Cron triggers use a fake runtime context. Route triggers use a route context.
| Scenario | getImtype() | Reply target | Proactive push account selection |
|---|---|---|---|
| Message trigger | Current message IM, such as qq or weixin | Current chat and current receiving account | If the target IM equals the current IM, the current chat account is used by default. |
| cron / fake | fake | reply* does not send real IM messages by default | Uses the target IM default account. |
| HTTP route | Route context | reply(...) / replyMarkdown(...) writes route response data | Uses the target IM default account unless you pass account_id explicitly. |
| Cross-IM push | Current context IM differs from target IM | Not applicable | Uses the target IM default account. |
Runtime response wrapper
Plugin calls receive thedata field. You do not need to handle the HTTP wrapper. The underlying runtime response shape is:
middleware.js converts the runtime error to an Error and throws it.
SendReceipt
Text, media, mixed-message, and recall methods usually return a send receipt.
Whether sending succeeded. If the adapter does not return it explicitly, the runtime fills it with
true.Standard message ID. Pass it to
recallMessage(...) when recalling a message.Message ID field kept for legacy plugins. It is usually the same as
message_id.Used for multi-part messages or when an adapter returns multiple IDs. A single message usually contains one ID.
Adapter raw receipt. Read it only when troubleshooting platform issues.
Failure reason that an adapter may return. On failure, check
receipt.ok === false and receipt.error first.FileDownloadResult
fileDownload(...) returns FileDownloadResult. downloadAdapterFile(...) returns the same fields and also includes ok, url, and action.
Always returned by
downloadAdapterFile(...). It means the file was saved.When the SDK needs an adapter to resolve a platform file ID into a download URL first, this is usually
resolveFileURL. It may be empty for direct URL downloads.Actual download URL. It may be the original URL or a temporary URL resolved by the adapter.
Saved local path. Prefer passing this field to media methods such as
replyImage(...) and replyFile(...).Same as
path. Kept as a more explicit field name.Saved filename.
Detected or provided MIME type, such as
image/png or text/csv.File size in bytes.
MediaItem
sender.getMediaItems() returns normalized media items. It first returns media captured by the latest listen(...) / input(...); otherwise it returns media_items / mediaItems from the current event.
Media type. The current normalization flow mainly keeps media items that have both
type and source.Media source. It may be a URL, local path, temporary resource ID, platform file ID, or adapter raw file identifier.
Filename or display name. The runtime normalizes
name, filename, and file_name to name.MIME type. The runtime normalizes it from
mime_type or mimeType.Platform raw file information, such as
file_id, path, or url. When downloading user-uploaded files, pass the whole MediaItem to downloadAdapterFile(...).Next steps
Read and reply to messages
See
Sender message context, reply, and recall methods.Proactive push account rules
See
push(...) account_id priority and cross-IM behavior.