@adiwajshing/baileys

中文文档
5.0.0发布于 2023/01/01MITTypeScriptCommonJS近 30 天下载 3512

何为App API

此软件包已被标记为弃用

Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.

中文使用文档
文档目录27 节
  1. 示例
  2. 安装
  3. 单位测试
  4. 连接中
  5. 配置连接
  6. 模拟桌面应用程序而不是网络
  7. 保存恢复会话( R)
  8. 正在收听连接更新
  9. 处理事件
  10. 实施数据存储
  11. 发送信件
  12. 非媒体信件
  13. 发送带有链接预览的信件
  14. 媒体消息
  15. 页:1
  16. 转发信件
  17. 读取信件
  18. 更新存在
  19. 下载媒体信件
  20. 删除信件
  21. 修改聊天
  22. 丢弃信件
  23. 杂项
  24. 组
  25. 广播列表和故事
  26. 写入自定义功能
  27. 说明

贝利斯- Typescript/ Javascript WhatsApp 网络 API

贝利斯并不要求Selenium或任何其他浏览器与WhatsApp Web接口,而是直接使用一个 网络安全套。不运行 硒或Chrimimum 保存你喜欢 半场 公羊数量:/

Baileys支持与WhatsApp的多设备版本和网络版本交互.

谢谢 @pokearaujo (英语) 他写了自己对WhatsApp多Device工作的意见 还有,谢谢你 @ 西加罗 撰写他关于WhatsApp Web工作的意见,并感谢 @ 诗人 联 合 国 离开 执行.

贝利斯型号安全,可扩展并简单使用. 如果你需要比提供功能更多的功能,那么写扩展是超容易的. 更多关于这个 这里。 。 。 .

如果你有兴趣建造一个WhatsApp机器人, 你可能会想检查出来 什么样的AppInfoBot 程序 和用它造出来的宝物, 马斯喀特。 。 。 .

读取文件 这里 加入 Discord 时 这里

示例

请检查是否运行( R) 实例.ts 以查看图书馆的示例. 剧本涵盖了最常见的使用案例. 要运行示例脚本,下载或克隆回波,然后在终端中输入以下内容:

  1. cd path/to/Baileys
  2. yarn
  3. yarn example

安装

使用稳定版本 :

yarn add @adiwajshing/baileys

使用边缘版本( 不保证稳定性, 但最新的修正 + 特性)

yarn add github:adiwajshing/baileys

然后使用 :

import makeWASocket from '@adiwajshing/baileys'

单位测试

开始

连接中

import makeWASocket, { DisconnectReason } from '@adiwajshing/baileys'
import { Boom } from '@hapi/boom'

async function connectToWhatsApp () {
    const sock = makeWASocket({
        // can provide additional config here
        printQRInTerminal: true
    })
    sock.ev.on('connection.update', (update) => {
        const { connection, lastDisconnect } = update
        if(connection === 'close') {
            const shouldReconnect = (lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut
            console.log('connection closed due to ', lastDisconnect.error, ', reconnecting ', shouldReconnect)
            // reconnect if not logged out
            if(shouldReconnect) {
                connectToWhatsApp()
            }
        } else if(connection === 'open') {
            console.log('opened connection')
        }
    })
    sock.ev.on('messages.upsert', m => {
        console.log(JSON.stringify(m, undefined, 2))

        console.log('replying to', m.messages[0].key.remoteJid)
        await sock.sendMessage(m.messages[0].key.remoteJid!, { text: 'Hello there!' })
    })
}
// run in main file
connectToWhatsApp()

如果连接成功, 您将会看到一个 QR 代码打印在您的终端屏幕上, 扫描它与WhatsApp 在您的手机上, 您将被登录 !

说明: 安装 qrcode-terminal 使用 yarn add qrcode-terminal 自动打印QR到终端.

说明: 支持WA Web的后传版本的代码(多维前作)在v5中被删除. 现在只支持标准多设备连接. 这样做是因为WA似乎完全放弃了对遗留版本的支持.

配置连接

您可以通过传递来配置连接 SocketConfig 对象.

整个 SocketConfig 此处提及带有默认值的结构 :

type SocketConfig = {
    /** the WS url to connect to WA */
    waWebSocketUrl: string | URL
    /** Fails the connection if the socket times out in this interval */
    connectTimeoutMs: number
    /** Default timeout for queries, undefined for no timeout */
    defaultQueryTimeoutMs: number | undefined
    /** ping-pong interval for WS connection */
    keepAliveIntervalMs: number
    /** proxy agent */
    agent?: Agent
    /** pino logger */
    logger: Logger
    /** version to connect with */
    version: WAVersion
    /** override browser config */
    browser: WABrowserDescription
    /** agent used for fetch requests -- uploading/downloading media */
    fetchAgent?: Agent
    /** should the QR be printed in the terminal */
    printQRInTerminal: boolean
    /** should events be emitted for actions done by this socket connection */
    emitOwnEvents: boolean
    /** provide a cache to store media, so does not have to be re-uploaded */
    mediaCache?: NodeCache
    /** custom upload hosts to upload media to */
    customUploadHosts: MediaConnInfo['hosts']
    /** time to wait between sending new retry requests */
    retryRequestDelayMs: number
    /** time to wait for the generation of the next QR in ms */
    qrTimeout?: number;
    /** provide an auth state object to maintain the auth state */
    auth: AuthenticationState
    /** manage history processing with this control; by default will sync up everything */
    shouldSyncHistoryMessage: (msg: proto.Message.IHistorySyncNotification) => boolean
    /** transaction capability options for SignalKeyStore */
    transactionOpts: TransactionCapabilityOptions
    /** provide a cache to store a user's device list */
    userDevicesCache?: NodeCache
    /** marks the client as online whenever the socket successfully connects */
    markOnlineOnConnect: boolean
    /**
     * map to store the retry counts for failed messages;
     * used to determine whether to retry a message or not */
    msgRetryCounterMap?: MessageRetryMap
    /** width for link preview images */
    linkPreviewImageThumbnailWidth: number
    /** Should Baileys ask the phone for full history, will be received async */
    syncFullHistory: boolean
    /** Should baileys fire init queries automatically, default true */
    fireInitQueries: boolean
    /**
     * generate a high quality link preview,
     * entails uploading the jpegThumbnail to WA
     * */
    generateHighQualityLinkPreview: boolean

    /** options for axios */
    options: AxiosRequestConfig<any>
    /**
     * fetch a message from your store
     * implement this so that messages failed to send (solves the "this message can take a while" issue) can be retried
     * */
    getMessage: (key: proto.IMessageKey) => Promise<proto.IMessage | undefined>
}

模拟桌面应用程序而不是网络

  1. 默认情况下, Bairis 仿照一个铬网络会话
  2. 如果您想要模拟桌面连接( 并接收更多消息历史), 请将此添加到您的 Socket 配置中 :
    const conn = makeWASocket({
        ...otherOpts,
        // can use Windows, Ubuntu here too
        browser: Browsers.macOS('Desktop'),
        syncFullHistory: true
    })
    

保存恢复会话( R)

你显然不希望每次想要连接时都继续扫描QR代码.

因此,你可以加载证书以登录回:

import makeWASocket, { BufferJSON, useMultiFileAuthState } from '@adiwajshing/baileys'
import * as fs from 'fs'

// utility function to help save the auth state in a single folder
// this function serves as a good guide to help write auth & key states for SQL/no-SQL databases, which I would recommend in any production grade system
const { state, saveCreds } = await useMultiFileAuthState('auth_info_baileys')
// will use the given state to connect
// so if valid credentials are available -- it'll connect without QR
const conn = makeWASocket({ auth: state }) 
// this will be called as soon as the credentials are updated
conn.ev.on ('creds.update', saveCreds)

说明: 收到/发文时,由于信号会话需要更新,认证密钥(authState.keys)将更新。 无论何时,都必须保存更新的密钥(authState.keys.set() 称为). 不这样做会妨碍您的消息到达收件人并造成其他出乎意料的后果( D) 。 这个 useMultiFileAuthState 功能会自动照顾到这一点,但对于任何其他认真的执行,你需要非常小心地对待关键的国家管理.

正在收听连接更新

贝利斯现在开火 connection.update 事件让您知道相关内容。 这些数据的结构如下:

type ConnectionState = {
    /** connection is now open, connecting or closed */
    connection: WAConnectionState
    /** the error that caused the connection to close */
    lastDisconnect?: {
        error: Error
        date: Date
    }
    /** is this a new login */
    isNewLogin?: boolean
    /** the current QR code */
    qr?: string
    /** has the device received all pending notifications while it was offline */
    receivedPendingNotifications?: boolean 
}

说明: 此选项还可提供对 QR 的任何更新

处理事件

贝利斯对事件使用事件Emmitter语法. 他们都打得很好,所以你不应该有任何问题 与Intellisense编辑像VS代码.

活动如下:


export type BaileysEventMap = {
    /** connection state has been updated -- WS closed, opened, connecting etc. */
    'connection.update': Partial<ConnectionState>
    /** credentials updated -- some metadata, keys or something */
    'creds.update': Partial<AuthenticationCreds>
    /** history sync, everything is reverse chronologically sorted */
    'messaging-history.set': {
        chats: Chat[]
        contacts: Contact[]
        messages: WAMessage[]
        isLatest: boolean
    }
    /** upsert chats */
    'chats.upsert': Chat[]
    /** update the given chats */
    'chats.update': Partial<Chat>[]
    /** delete chats with given ID */
    'chats.delete': string[]
    /** presence of contact in a chat updated */
    'presence.update': { id: string, presences: { [participant: string]: PresenceData } }

    'contacts.upsert': Contact[]
    'contacts.update': Partial<Contact>[]

    'messages.delete': { keys: WAMessageKey[] } | { jid: string, all: true }
    'messages.update': WAMessageUpdate[]
    'messages.media-update': { key: WAMessageKey, media?: { ciphertext: Uint8Array, iv: Uint8Array }, error?: Boom }[]
    /**
     * add/update the given messages. If they were received while the connection was online,
     * the update will have type: "notify"
     *  */
    'messages.upsert': { messages: WAMessage[], type: MessageUpsertType }
    /** message was reacted to. If reaction was removed -- then "reaction.text" will be falsey */
    'messages.reaction': { key: WAMessageKey, reaction: proto.IReaction }[]

    'message-receipt.update': MessageUserReceiptUpdate[]

    'groups.upsert': GroupMetadata[]
    'groups.update': Partial<GroupMetadata>[]
    /** apply an action to participants in a group */
    'group-participants.update': { id: string, participants: string[], action: ParticipantAction }

    'blocklist.set': { blocklist: string[] }
    'blocklist.update': { blocklist: string[], type: 'add' | 'remove' }
    /** Receive an update on a call, including when the call was received, rejected, accepted */
    'call': WACallEvent[]
}

你可以听到这样的事件:


const sock = makeWASocket()
sock.ev.on('messages.upsert', ({ messages }) => {
    console.log('got messages', messages)
})

实施数据存储

贝利斯不会带一个可以聊天,联系人,或留言的事实上的存储器. 然而,已经提供了简单的内部执行。 店内收听聊天更新,新消息,消息更新等,始终有最新版本的数据.

其用途如下:

import makeWASocket, { makeInMemoryStore } from '@adiwajshing/baileys'
// the store maintains the data of the WA connection in memory
// can be written out to a file & read from it
const store = makeInMemoryStore({ })
// can be read from a file
store.readFromFile('./baileys_store.json')
// saves the state to a file every 10s
setInterval(() => {
    store.writeToFile('./baileys_store.json')
}, 10_000)

const sock = makeWASocket({ })
// will listen from this socket
// the store can listen from a new socket once the current socket outlives its lifetime
store.bind(sock.ev)

sock.ev.on('chats.set', () => {
    // can use "store.chats" however you want, even after the socket dies out
    // "chats" => a KeyedDB instance
    console.log('got chats', store.chats.all())
})

sock.ev.on('contacts.set', () => {
    console.log('got contacts', Object.values(store.contacts))
})

该商店还提供一些简单的功能,例如 loadMessages 利用商店加快数据检索.

说明: 我强烈建议你建立自己的数据库, 特别是MD连接, 因为存储某人的整个聊天历史 在记忆中是一个可怕的浪费RAM.

发送信件

以单一函数发送所有类型信件 :

非媒体信件

import { MessageType, MessageOptions, Mimetype } from '@adiwajshing/baileys'

const id = '[email protected]' // the WhatsApp ID 
// send a simple text!
const sentMsg  = await sock.sendMessage(id, { text: 'oh hello there' })
// send a reply messagge
const sentMsg  = await sock.sendMessage(id, { text: 'oh hello there' }, { quoted: message })
// send a mentions message
const sentMsg  = await sock.sendMessage(id, { text: '@12345678901', mentions: ['[email protected]'] })
// send a location!
const sentMsg  = await sock.sendMessage(
    id, 
    { location: { degreesLatitude: 24.121231, degreesLongitude: 55.1121221 } }
)
// send a contact!
const vcard = 'BEGIN:VCARD\n' // metadata of the contact card
            + 'VERSION:3.0\n' 
            + 'FN:Jeff Singh\n' // full name
            + 'ORG:Ashoka Uni;\n' // the organization of the contact
            + 'TEL;type=CELL;type=VOICE;waid=911234567890:+91 12345 67890\n' // WhatsApp ID + phone number
            + 'END:VCARD'
const sentMsg  = await sock.sendMessage(
    id,
    { 
        contacts: { 
            displayName: 'Jeff', 
            contacts: [{ vcard }] 
        }
    }
)

// send a buttons message!
const buttons = [
  {buttonId: 'id1', buttonText: {displayText: 'Button 1'}, type: 1},
  {buttonId: 'id2', buttonText: {displayText: 'Button 2'}, type: 1},
  {buttonId: 'id3', buttonText: {displayText: 'Button 3'}, type: 1}
]

const buttonMessage = {
    text: "Hi it's button message",
    footer: 'Hello World',
    buttons: buttons,
    headerType: 1
}

const sendMsg = await sock.sendMessage(id, buttonMessage)

//send a template message!
const templateButtons = [
    {index: 1, urlButton: {displayText: '⭐ Star Baileys on GitHub!', url: 'https://github.com/adiwajshing/Baileys'}},
    {index: 2, callButton: {displayText: 'Call me!', phoneNumber: '+1 (234) 5678-901'}},
    {index: 3, quickReplyButton: {displayText: 'This is a reply, just like normal buttons!', id: 'id-like-buttons-message'}},
]

const templateMessage = {
    text: "Hi it's a template message",
    footer: 'Hello World',
    templateButtons: templateButtons
}

const sendMsg = await sock.sendMessage(id, templateMessage)

// send a list message!
const sections = [
    {
    title: "Section 1",
    rows: [
        {title: "Option 1", rowId: "option1"},
        {title: "Option 2", rowId: "option2", description: "This is a description"}
    ]
    },
   {
    title: "Section 2",
    rows: [
        {title: "Option 3", rowId: "option3"},
        {title: "Option 4", rowId: "option4", description: "This is a description V2"}
    ]
    },
]

const listMessage = {
  text: "This is a list",
  footer: "nice footer, link: https://google.com",
  title: "Amazing boldfaced list title",
  buttonText: "Required, text on the button to view the list",
  sections
}

const sendMsg = await sock.sendMessage(id, listMessage)

const reactionMessage = {
    react: {
        text: "💖", // use an empty string to remove the reaction
        key: message.key
    }
}

const sendMsg = await sock.sendMessage(id, reactionMessage)
  1. 默认情况下, WA MD 在从网络发送时没有链接生成
  2. Baileys有生成这些链接预览内容的功能
  3. 要启用此函数的用法, 请添加 link-preview-js 作为您的项目的依赖性 yarn add link-preview-js
  4. 发送链接 :
// send a link
const sentMsg  = await sock.sendMessage(id, { text: 'Hi, this was sent using https://github.com/adiwajshing/baileys' })

媒体消息

发送媒体(视频,贴纸,图像)比以往更加容易和高效.

  • 您可以指定缓冲器,本地url甚至远程url.
  • 在指定一个媒体url时,贝利斯从未将整个缓冲器加载入内存;它甚至将媒体加密为可读流.
import { MessageType, MessageOptions, Mimetype } from '@adiwajshing/baileys'
// Sending gifs
await sock.sendMessage(
    id, 
    { 
        video: fs.readFileSync("Media/ma_gif.mp4"), 
        caption: "hello!",
        gifPlayback: true
    }
)

await sock.sendMessage(
    id, 
    { 
        video: "./Media/ma_gif.mp4", 
        caption: "hello!",
        gifPlayback: true
    }
)

// send an audio file
await sock.sendMessage(
    id, 
    { audio: { url: "./Media/audio.mp3" }, mimetype: 'audio/mp4' }
    { url: "Media/audio.mp3" }, // can send mp3, mp4, & ogg
)

// send a buttons message with image header!
const buttons = [
  {buttonId: 'id1', buttonText: {displayText: 'Button 1'}, type: 1},
  {buttonId: 'id2', buttonText: {displayText: 'Button 2'}, type: 1},
  {buttonId: 'id3', buttonText: {displayText: 'Button 3'}, type: 1}
]

const buttonMessage = {
    image: {url: 'https://example.com/image.jpeg'},
    caption: "Hi it's button message",
    footer: 'Hello World',
    buttons: buttons,
    headerType: 4
}

const sendMsg = await sock.sendMessage(id, buttonMessage)

//send a template message with an image **attached**!
const templateButtons = [
  {index: 1, urlButton: {displayText: '⭐ Star Baileys on GitHub!', url: 'https://github.com/adiwajshing/Baileys'}},
  {index: 2, callButton: {displayText: 'Call me!', phoneNumber: '+1 (234) 5678-901'}},
  {index: 3, quickReplyButton: {displayText: 'This is a reply, just like normal buttons!', id: 'id-like-buttons-message'}},
]

const buttonMessage = {
    text: "Hi it's a template message",
    footer: 'Hello World',
    templateButtons: templateButtons,
    image: {url: 'https://example.com/image.jpeg'}
}

const sendMsg = await sock.sendMessage(id, templateMessage)

页:1

  • id 是您发送消息的个人或团体的WhatsApp ID .
    • 一定在形式上 [country code][phone number]@s.whatsapp.net
    • 对于广播名单,它是 [timestamp of creation]@broadcast。 。 。 .
    • 对于故事,ID是 status@broadcast。 。 。 .
  • 对于媒体消息,可以自动生成图像标签的缩略图,前提是您添加 jimp 或者说 sharp 在您的项目中使用 yarn add jimp 或者说 yarn add sharp。视频的缩略图也可以自动生成,但您需要 ffmpeg 安装在您的系统上.
  • 杂项选项:一些关于消息的额外信息. 它可以有以下几个 选项 值 :
    const info: MessageOptions = {
        quoted: quotedMessage, // the message you want to quote
        contextInfo: { forwardingScore: 2, isForwarded: true }, // some random context info (can show a forwarded message with this too)
        timestamp: Date(), // optional, if you want to manually set the timestamp of the message
        caption: "hello there!", // (for media messages) the caption to send with the media (cannot be sent with stickers though)
        jpegThumbnail: "23GD#4/==", /*  (for location & media messages) has to be a base 64 encoded JPEG if you want to send a custom thumb, 
                                    or set to null if you don't want to send a thumbnail.
                                    Do not enter this field if you want to automatically generate a thumb
                                */
        mimetype: Mimetype.pdf, /* (for media messages) specify the type of media (optional for all media types except documents),
                                    import {Mimetype} from '@adiwajshing/baileys'
                                */
        fileName: 'somefile.pdf', // (for media messages) file name for the media
        /* will send audio messages as voice notes, if set to true */
        ptt: true,
        /** Should it send as a disappearing messages. 
         * By default 'chat' -- which follows the setting of the chat */
        ephemeralExpiration: WA_DEFAULT_EPHEMERAL
    }
    

转发信件

const msg = getMessageFromStore('[email protected]', 'HSJHJWH7323HSJSJ') // implement this on your end
await sock.sendMessage('[email protected]', { forward: msg }) // WA forward the message!

读取信件

现在必须明确读取一组消息密钥 . 在多设备中,你无法在读取的"聊天"中标出一个完整的"聊天",就像它与贝利斯Web一样. 这意味着你必须追踪未读信件.

const key = {
    remoteJid: '[email protected]',
    id: 'AHASHH123123AHGA', // id of the message you want to read
    participant: '[email protected]' // the ID of the user that sent the  message (undefined for individual chats)
}
// pass to readMessages function
// can pass multiple keys to read multiple messages as well
await sock.readMessages([key])

信件 ID 是您正在标记为已读信件的独有标识符 . 在一个 WAMessage,则 messageID 可用 messageID = message.key.id。 。 。 .

更新存在

await sock.sendPresenceUpdate('available', id) 

这让个人/团体与 id 知道你是否在线、离线、打字等等.

presence 可以是下列情况之一:

type WAPresence = 'unavailable' | 'available' | 'composing' | 'recording' | 'paused'

存在时间在10秒后结束.

说明: 在多设备版本"WhatsApp"中——如果桌面客户端活动,WA不会向设备发送推取通知. 如果您想要收到上述通知, 请使用 sock.sendPresenceUpdate('unavailable')

下载媒体信件

如果你想保存你收到的媒体

import { writeFile } from 'fs/promises'
import { downloadMediaMessage } from '@adiwajshing/baileys'

sock.ev.on('messages.upsert', async ({ messages }) => {
    const m = messages[0]

    if (!m.message) return // if there is no text or media message
    const messageType = Object.keys (m.message)[0]// get what type of message it is -- text, image, video
    // if the message is an image
    if (messageType === 'imageMessage') {
        // download the message
        const buffer = await downloadMediaMessage(
            m,
            'buffer',
            { },
            { 
                logger,
                // pass this so that baileys can request a reupload of media
                // that has been deleted
                reuploadRequest: sock.updateMediaMessage
            }
        )
        // save to file
        await writeFile('./my-download.jpeg', buffer)
    }
}

说明: WhatsApp自动从服务器上去除旧媒体. 设备要访问上述介质——另一设备需要重新装入。 可通过下列方法做到这一点:

const updatedMediaMsg = await sock.updateMediaMessage(msg)

删除信件

const jid = '[email protected]' // can also be a group
const response = await sock.sendMessage(jid, { text: 'hello!' }) // send a message
// sends a message to delete the given message
// this deletes the message for everyone
await sock.sendMessage(jid, { delete: response.key })

说明: 支持通过 chatModify (下节)

修改聊天

WA使用加密通信形式发送聊天/应用更新. 这已大部分实施,您可以发送以下更新:

  • 存档聊天

    const lastMsgInChat = await getLastMessageInChat('[email protected]') // implement this on your end
    await sock.chatModify({ archive: true, lastMessages: [lastMsgInChat] }, '[email protected]')
    
  • 静音/ 取消聊天

    // mute for 8 hours
    await sock.chatModify({ mute: 8*60*60*1000 }, '[email protected]', [])
    // unmute
    await sock.chatModify({ mute: null }, '[email protected]', [])
    
  • 标记聊天读取/ 未读

    const lastMsgInChat = await getLastMessageInChat('[email protected]') // implement this on your end
    // mark it unread
    await sock.chatModify({ markRead: false, lastMessages: [lastMsgInChat] }, '[email protected]')
    
  • 帮我删除一条消息

    await sock.chatModify(
      { clear: { messages: [{ id: 'ATWYHDNNWU81732J', fromMe: true, timestamp: "1654823909" }] } }, 
      '[email protected]', 
      []
      )
    
    
  • 删除聊天

    const lastMsgInChat = await getLastMessageInChat('[email protected]') // implement this on your end
    await sock.chatModify({
      delete: true,
      lastMessages: [{ key: lastMsgInChat.key, messageTimestamp: lastMsgInChat.messageTimestamp }]
    },
    '[email protected]')
    
  • Pin/ 取消聊天

    await sock.chatModify({
      pin: true // or `false` to unpin
    },
    '[email protected]')
    

说明: 如果你搞砸一个更新,WA可以将你从所有设备中登录出来,你必须再次登录.

丢弃信件

const jid = '[email protected]' // can also be a group
// turn on disappearing messages
await sock.sendMessage(
    jid, 
    // this is 1 week in seconds -- how long you want messages to appear for
    { disappearingMessagesInChat: WA_DEFAULT_EPHEMERAL }
)
// will send as a disappearing message
await sock.sendMessage(jid, { text: 'hello' }, { ephemeralExpiration: WA_DEFAULT_EPHEMERAL })
// turn off disappearing messages
await sock.sendMessage(
    jid, 
    { disappearingMessagesInChat: false }
)

杂项

  • 检查给定的ID是否在WhatsApp上
    const id = '123456'
    const [result] = await sock.onWhatsApp(id)
    if (result.exists) console.log (`${id} exists on WhatsApp, as jid: ${result.jid}`)
    
  • 查询一个组或某人的聊天历史 如果可能的话, TODO
  • 获得某人的地位
    const status = await sock.fetchStatus("[email protected]")
    console.log("status: " + status)
    
  • 要改变您的配置状态
    const status = 'Hello World!'
    await sock.updateProfileStatus(status)
    
  • 要更改您的配置文件名称
    const name = 'My name'
    await sock.updateProfileName(name)
    
  • 要获取某些个人/组的显示图片
    // for low res picture
    const ppUrl = await sock.profilePictureUrl("[email protected]")
    console.log("download profile picture from: " + ppUrl)
    // for high res picture
    const ppUrl = await sock.profilePictureUrl("[email protected]", 'image')
    
  • 更改您的显示图片或组合
    const jid = '[email protected]' // can be your own too
    await sock.updateProfilePicture(jid, { url: './new-profile-picture.jpeg' })
    
  • 让某人出现(如果他们打入或在线)
    // the presence update is fetched and called here
    sock.ev.on('presence-update', json => console.log(json))
    // request updates for a chat
    await sock.presenceSubscribe("[email protected]") 
    
  • 要屏蔽或解除屏蔽用户
    await sock.updateBlockStatus("[email protected]", "block") // Block user
    await sock.updateBlockStatus("[email protected]", "unblock") // Unblock user
    
  • 获取商务概况,例如描述或类别
    const profile = await sock.getBusinessProfile("[email protected]")
    console.log("business description: " + profile.description + ", category: " + profile.category)
    

当然,替换 xyz 有真实身份证明.

组

  • 创建组合
    // title & participants
    const group = await sock.groupCreate("My Fab Group", ["[email protected]", "[email protected]"])
    console.log ("created group with id: " + group.gid)
    sock.sendMessage(group.id, { text: 'hello there' }) // say hello to everyone on the group
    
  • 增/调人员到一个团体或降级/促进人员
    // id & people to add to the group (will throw error if it fails)
    const response = await sock.groupParticipantsUpdate(
        "[email protected]", 
        ["[email protected]", "[email protected]"],
        "add" // replace this parameter with "remove", "demote" or "promote"
    )
    
  • 换个话题
    await sock.groupUpdateSubject("[email protected]", "New Subject!")
    
  • 要改变小组的描述
    await sock.groupUpdateDescription("[email protected]", "New Description!")
    
  • 更改组设置
    // only allow admins to send messages
    await sock.groupSettingUpdate("[email protected]", 'announcement')
    // allow everyone to send messages
    await sock.groupSettingUpdate("[email protected]", 'not_announcement')
    // allow everyone to modify the group's settings -- like display picture etc.
    await sock.groupSettingUpdate("[email protected]", 'unlocked')
    // only allow admins to modify the group's settings
    await sock.groupSettingUpdate("[email protected]", 'locked')
    
  • 离开一个团体
    await sock.groupLeave("[email protected]") // (will throw error if it fails)
    
  • 获取组的邀请码
    const code = await sock.groupInviteCode("[email protected]")
    console.log("group code: " + code)
    
  • 在组合中取消邀请代码
    const code = await sock.groupRevokeInvite("[email protected]")
    console.log("New group code: " + code)
    
  • 查询一个组的元数据
    const metadata = await sock.groupMetadata("[email protected]") 
    console.log(metadata.id + ", title: " + metadata.subject + ", description: " + metadata.desc)
    
  • 使用邀请码加入组
    const response = await sock.groupAcceptInvite("xxx")
    console.log("joined to: " + response)
    
    当然,替换 xxx 带邀请密码.
  • 通过邀请代码获取组信息
    const response = await sock.groupGetInviteInfo("xxx")
    console.log("group information: " + response)
    
  • 使用组 InviteMessage 加入组
    const response = await sock.groupAcceptInviteV4("[email protected]", groupInviteMessage)
    console.log("joined to: " + response)
    
    当然,替换 xxx 带邀请密码.

广播列表和故事

说明: 目前无法从 MD 版本发送信件到广播列表 .

  • 您可以发送消息到广播列表中, 与您向组和个人聊天发送消息的方式相同 .
  • 现在,WA Web不支持创建广播列表,但还是可以删除.
  • 广播标识为格式 12345678@broadcast
  • 要查询广播列表的收件人名( N) :
    const bList = await sock.getBroadcastListInfo("1234@broadcast")
    console.log (`list name: ${bList.name}, recps: ${bList.recipients}`)
    

写入自定义功能

贝利斯在写作时会牢记定制的功能. 与其伪造工程并重写内部,不如简单地写出自己的扩展.

首先,通过设置来记录来自WhatsApp的未处理信件:

const sock = makeWASocket({
    logger: P({ level: 'debug' }),
})

这将使您能够看到控制台中的各种信息.

一些例子:

  1. 跟踪手机电池百分比的功能性. 你启用了记录,你会看到一个消息 关于你的电池弹出在控制台: {"level":10,"fromMe":false,"frame":{"tag":"ib","attrs":{"from":"@s.whatsapp.net"},"content":[{"tag":"edge_routing","attrs":{},"content":[{"tag":"routing_info","attrs":{},"content":{"type":"Buffer","data":[8,2,8,5]}}]}]},"msg":"communication"}

    “框架”是收到的信息,它有三个组成部分:

    • tag - 这个框架是关于什么的(例如消息会有"消息")
    • attrs - 带有一些元数据的字符串密钥值对( 通常包含信件的ID)
    • content -- 实际数据( 如消息节点将包含实际消息内容)
    • 阅读此格式的更多信息 这里

    您可以使用下列方式为事件注册回调 :

    // for any message with tag 'edge_routing'
    sock.ws.on(`CB:edge_routing`, (node: BinaryNode) => { })
    // for any message with tag 'edge_routing' and id attribute = abcd
    sock.ws.on(`CB:edge_routing,id:abcd`, (node: BinaryNode) => { })
    // for any message with tag 'edge_routing', id attribute = abcd & first content node routing_info
    sock.ws.on(`CB:edge_routing,id:abcd,routing_info`, (node: BinaryNode) => { })
    

说明

这个图书馆原来是用来 Ashoka大学的CS-2362 绝不是属于什么的。 自行取用. 不要用这个垃圾邮件.

而且,这种回购现在根据GPL 3获得许可,因为它使用 节点

版本与发布记录

@adiwajshing/baileys 共发布 27 个版本,首次发布于 2020/07/01;过去 12 个月发布了 0 个版本。

版本发布日期距今
5.0.0latest2023/01/013 年前
4.4.02022/08/194 年前
4.3.02022/07/204 年前
4.2.02022/06/154 年前
4.1.02022/04/064 年前
4.0.12022/02/244 年前

关于 @adiwajshing/baileys 的常见问题

@adiwajshing/baileys 是什么?

何为App API注意:该包已被作者标记为弃用——Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.

如何安装 @adiwajshing/baileys?

在项目目录运行 npm install @adiwajshing/baileys,或使用 pnpm add / yarn add / bun add。

@adiwajshing/baileys 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@adiwajshing/baileys 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@adiwajshing/baileys 可以商用吗?

@adiwajshing/baileys 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@adiwajshing/baileys 的下载量有多少?

根据 npm 官方下载统计,@adiwajshing/baileys 在 2026/10/05 – 2026/11/03 这 30 天内被下载 3,512 次,日均约 117 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@adiwajshing/baileys 还在维护吗?

最新版本 5.0.0 发布于 2023/01/01(3 年前);至今共发布 27 个版本,其中过去 12 个月发布了 0 个;首次发布于 2020/07/01。作者已将其标记为弃用,新项目建议寻找替代方案。