Skip to main content
Proactive push does not depend on the reply target of Sender. You need to specify the target IM, group, or user. For group push, pass groupCode; for private push, pass userID.

Function overview

FunctionPurposeParametersReturns
push(imType, groupCode, userID, title, content, options?, timeout?)Push text.imType: required; groupCode: group ID, pass '' for private chat; userID: user ID, pass '' for group push; title: title or fallback text; content: text; options: optional; timeout: optional milliseconds.Promise<number>, number of successfully sent targets, usually 0 or 1.
pushImage(imType, groupCode, userID, title, imageUrl, options?, timeout?)Push an image.First four parameters are the same; imageUrl: required image source; options: optional media parameters; timeout: optional milliseconds.Promise<number>
pushVoice(imType, groupCode, userID, title, voiceUrl, options?, timeout?)Push voice/audio.voiceUrl: required voice source; options: optional media parameters; timeout: optional milliseconds.Promise<number>
pushVideo(imType, groupCode, userID, title, videoUrl, options?, timeout?)Push a video.videoUrl: required video source; options: optional media parameters; timeout: optional milliseconds.Promise<number>
pushFile(imType, groupCode, userID, title, fileUrl, options?, timeout?)Push a file.fileUrl: required file source; options can pass account, filename, and MIME type; timeout: optional milliseconds.Promise<number>
pushMixed(imType, groupCode, userID, title, items, options?, timeout?)Push a mixed message.items: required mixed items; options: optional account parameters; timeout: optional milliseconds.Promise<number>

push(imType, groupCode, userID, title, content, options?, timeout?)

imType
string
required
Target IM type, such as qq, weixin, or qx, depending on enabled adapters.
groupCode
string
required
Group ID / group number. Required for group push; pass an empty string for private chat.
userID
string
required
User ID. Required for private push; group push can pass an empty string.
title
string
required
Push title or note. In text push, if content is empty, title is used as the text.
content
string
required
Text content. The runtime also supports text / message fields, but the helper always sends content.
options
object
Optional extension fields. middleware.js shallow-merges this object into the top-level request body.
options.account_id
string
Target account ID. You can also write accountID or accountId. Explicit values have the highest priority.
timeout
number
default:"5000"
Request timeout in milliseconds.
const { push } = require('./middleware.js')

const sent = await push('qq', '123456', '', 'Daily report', 'Tasks done today', {
  account_id: 'bot_qq_ops',
})

if (sent === 0) {
  console.log('Not sent: check the target, adapter status, or whether the account is online')
}

Push account selection

These rules apply to push(...), pushImage(...), pushVoice(...), pushVideo(...), pushFile(...), and pushMixed(...). Selection rules:
  1. If options contains account_id, use it.
  2. If this is a message trigger and the target IM is the same as the current chat IM, use the current chat account by default.
  3. If this is cron / fake, use the target IM default account.
  4. For cross-IM push, use the target IM default account.
  5. If the target IM has no default account, the runtime selects the first online account that can send. If there is no available sending account, it returns 0 or throws an adapter-offline error.
When you know which sending account to use, pass options.account_id explicitly. This is more stable than depending on the current chat account or target IM default account.
// 1. Explicit account wins.
await push('qq', '123456', '', 'Notice', 'Done', {
  account_id: 'bot_qq_ops',
})

// 2. The message comes from qq:bot_qq_2 and target IM is also qq: bot_qq_2 is used by default.
await push('qq', '123456', '', 'Notice', 'Done')

// 3. cron / fake: use the qq default account.
await push('qq', '123456', '', 'Scheduled notice', 'Good morning')

// 4. Cross-IM: the current message comes from qq but pushes to weixin; use the weixin default account.
await push('weixin', '', 'wxid_user', 'Notice', 'Done')

Media push

await pushImage('qq', '123456', '', 'Daily image', './daily.png', {
  account_id: 'bot_qq_ops',
})
await pushVoice('qq', '123456', '', 'Voice reminder', './notice.wav', {
  accountId: 'bot_qq_ops',
}, 15000)
await pushVideo('qq', '123456', '', 'Demo video', './demo.mp4', {
  account_id: 'bot_qq_ops',
})
await pushFile('qq', '123456', '', 'Daily file', './daily.csv', {
  account_id: 'bot_qq_ops',
  filename: 'daily.csv',
  mimeType: 'text/csv',
})
await pushMixed('qq', '123456', '', 'Result', [
  { type: 'text', text: 'Result:' },
  { type: 'image', source: './result.png' },
], {
  account_id: 'bot_qq_ops',
})
Media push helpers also support options and timeout. Use options.account_id / accountID / accountId to choose the sending account explicitly. Use filename / fileName / file_name and mimeType / mime_type to add media metadata.

Return value

Proactive push functions return a number: the count of targets that the runtime considers successfully sent.
1
0
  • 1: usually means the message was submitted to one target.
  • 0: usually means no available adapter, invalid target, or not sent.
  • Adapter request failures may throw Error.

Mixed items

pushMixed(...) items are the same as replyMixed(...): they support text, markdown, image, voice, video, and file.
await pushMixed('qq', '123456', '', 'mixed demo', [
  { type: 'text', text: 'See the image:' },
  { type: 'image', source: 'https://example.com/a.png', name: 'a.png' },
])

Next steps

Runtime context

See differences between message, cron, route, and cross-IM contexts.

Media files

See media sources, downloads, and user-uploaded file handling.
Last modified on June 3, 2026