whatsapp-web-js

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

WhatsApp Web.js

WhatsApp Web.js

Provides expert guidance for whatsapp-web.js, a library that automates WhatsApp Web by controlling a Chromium browser instance via Puppeteer.
提供针对whatsapp-web.js的专业指导,这是一个通过Puppeteer控制Chromium浏览器实例来自动化WhatsApp Web的库。

Quick Start

快速开始

Initialize client with authentication strategy and listen for events:
js
const { Client, LocalAuth } = require('whatsapp-web.js');

const client = new Client({
    authStrategy: new LocalAuth(),
    puppeteer: { headless: true }
});

client.on('qr', (qr) => console.log('Scan QR:', qr));
client.on('ready', () => console.log('Client ready'));
client.on('message', async (msg) => {
    if (msg.body === 'ping') await msg.reply('pong');
});

client.initialize();  // Non-blocking - listen for 'ready' event
Requirements: Node.js >= 18.0.0,
puppeteer
(required),
ffmpeg
(optional for stickers).
使用认证策略初始化客户端并监听事件:
js
const { Client, LocalAuth } = require('whatsapp-web.js');

const client = new Client({
    authStrategy: new LocalAuth(),
    puppeteer: { headless: true }
});

client.on('qr', (qr) => console.log('Scan QR:', qr));
client.on('ready', () => console.log('Client ready'));
client.on('message', async (msg) => {
    if (msg.body === 'ping') await msg.reply('pong');
});

client.initialize();  // Non-blocking - listen for 'ready' event
要求:Node.js >= 18.0.0,
puppeteer
(必填),
ffmpeg
(贴纸功能可选)。

ID Format Conventions

ID格式规范

Always use correct ID format for chat operations:
  • Private chats:
    <country_code><phone>@c.us
    (e.g.,
    5511999999999@c.us
    )
  • Groups:
    <id>@g.us
    (e.g.,
    120363XXX@g.us
    )
  • Channels:
    <id>@newsletter
  • Status broadcasts:
    status@broadcast
Phone numbers exclude
+
and leading zeros. Example: US +1 (234) 567-8901 becomes
12345678901@c.us
.
在聊天操作中请始终使用正确的ID格式:
  • 私人聊天
    <country_code><phone>@c.us
    (例如:
    5511999999999@c.us
  • 群组
    <id>@g.us
    (例如:
    120363XXX@g.us
  • 频道
    <id>@newsletter
  • 状态广播
    status@broadcast
电话号码需去除
+
号和前导零。示例:美国号码+1 (234) 567-8901需转换为
12345678901@c.us

Authentication Strategies

认证策略

Choose based on deployment model:
js
// No persistence - QR scan every restart
new NoAuth()

// Local filesystem - recommended for single-instance bots
new LocalAuth({ clientId: 'bot1' })

// Remote store - for cloud/multi-instance deployments
new RemoteAuth({ store: myStore, clientId: 'bot1', backupSyncIntervalMs: 60000 })
根据部署模式选择合适的策略:
js
// 无持久化 - 每次重启都需要扫描QR码
new NoAuth()

// 本地文件系统 - 推荐用于单实例机器人
new LocalAuth({ clientId: 'bot1' })

// 远程存储 - 适用于云端/多实例部署
new RemoteAuth({ store: myStore, clientId: 'bot1', backupSyncIntervalMs: 60000 })

Pairing Code Authentication

配对码认证

Skip QR scanning by using phone number pairing:
js
const client = new Client({
    authStrategy: new LocalAuth(),
    pairWithPhoneNumber: {
        phoneNumber: '5511999999999',  // country code + number, no symbols
        showNotification: true,
        intervalMs: 180000
    }
});
client.on('code', (code) => console.log('Pairing code:', code));
通过手机号码配对跳过QR码扫描:
js
const client = new Client({
    authStrategy: new LocalAuth(),
    pairWithPhoneNumber: {
        phoneNumber: '5511999999999',  // 国家代码+号码,无特殊符号
        showNotification: true,
        intervalMs: 180000
    }
});
client.on('code', (code) => console.log('Pairing code:', code));

Essential Patterns

核心模式

Sending Messages

发送消息

js
// Text message
await client.sendMessage('5511999999999@c.us', 'Hello!');

// Reply to received message
await msg.reply('Got it!');

// With mentions
await client.sendMessage(chatId, 'Hi @5511999999999', {
    mentions: ['5511999999999@c.us']
});

// Quote specific message
await client.sendMessage(chatId, 'Replying to this', {
    quotedMessageId: msg.id._serialized
});
js
// 文本消息
await client.sendMessage('5511999999999@c.us', 'Hello!');

// 回复收到的消息
await msg.reply('Got it!');

// 提及用户
await client.sendMessage(chatId, 'Hi @5511999999999', {
    mentions: ['5511999999999@c.us']
});

// 引用特定消息
await client.sendMessage(chatId, 'Replying to this', {
    quotedMessageId: msg.id._serialized
});

Media Handling

媒体处理

js
const { MessageMedia } = require('whatsapp-web.js');

// From file
const media = MessageMedia.fromFilePath('/path/to/image.png');
await client.sendMessage(chatId, media, { caption: 'Check this out' });

// From URL
const media = await MessageMedia.fromUrl('https://example.com/image.png');
await client.sendMessage(chatId, media);

// Download received media
if (msg.hasMedia) {
    const media = await msg.downloadMedia();
    // Access: media.mimetype, media.data (base64), media.filename
}
js
const { MessageMedia } = require('whatsapp-web.js');

// 从文件加载
const media = MessageMedia.fromFilePath('/path/to/image.png');
await client.sendMessage(chatId, media, { caption: 'Check this out' });

// 从URL加载
const media = await MessageMedia.fromUrl('https://example.com/image.png');
await client.sendMessage(chatId, media);

// 下载收到的媒体
if (msg.hasMedia) {
    const media = await msg.downloadMedia();
    // 可访问:media.mimetype, media.data (base64), media.filename
}

Media Send Variants

媒体发送变体

Control how media is sent with specific options:
js
// As sticker (requires ffmpeg)
await client.sendMessage(chatId, media, { sendMediaAsSticker: true });

// As voice note
await client.sendMessage(chatId, audio, { sendAudioAsVoice: true });

// As HD quality
await client.sendMessage(chatId, media, { sendMediaAsHd: true });

// As view-once
await client.sendMessage(chatId, media, { isViewOnce: true });

// As document
await client.sendMessage(chatId, media, { sendMediaAsDocument: true });
通过特定选项控制媒体的发送方式:
js
// 作为贴纸发送(需要ffmpeg)
await client.sendMessage(chatId, media, { sendMediaAsSticker: true });

// 作为语音笔记发送
await client.sendMessage(chatId, audio, { sendAudioAsVoice: true });

// 以高清质量发送
await client.sendMessage(chatId, media, { sendMediaAsHd: true });

// 作为一次性查看内容发送
await client.sendMessage(chatId, media, { isViewOnce: true });

// 作为文档发送
await client.sendMessage(chatId, media, { sendMediaAsDocument: true });

Polls, Reactions, Location

投票、消息反应、位置

js
const { Poll, Location } = require('whatsapp-web.js');

// Poll (single choice)
await client.sendMessage(chatId, new Poll('Question?', ['A', 'B']));

// Poll (multiple choice)
await client.sendMessage(chatId, new Poll('Pick', ['A', 'B', 'C'], 
    { allowMultipleAnswers: true }));

// React to message
await msg.react('👍');   // add reaction
await msg.react('');      // remove reaction

// Send location
await client.sendMessage(chatId, 
    new Location(37.422, -122.084, { name: 'Googleplex' }));
js
const { Poll, Location } = require('whatsapp-web.js');

// 投票(单选)
await client.sendMessage(chatId, new Poll('Question?', ['A', 'B']));

// 投票(多选)
await client.sendMessage(chatId, new Poll('Pick', ['A', 'B', 'C'], 
    { allowMultipleAnswers: true }));

// 对消息添加反应
await msg.react('👍');   // 添加反应
await msg.react('');      // 移除反应

// 发送位置
await client.sendMessage(chatId, 
    new Location(37.422, -122.084, { name: 'Googleplex' }));

Message Operations

消息操作

js
// Edit sent message
const sent = await client.sendMessage(chatId, 'Original');
await sent.edit('Edited text');

// Delete message
await sent.delete(true);  // true = delete for everyone

// Pin message
await msg.pin(86400);     // Pin for 24h (86400|604800|2592000 seconds)
await msg.unpin();
js
// 编辑已发送的消息
const sent = await client.sendMessage(chatId, 'Original');
await sent.edit('Edited text');

// 删除消息
await sent.delete(true);  // true = 为所有人删除

// 固定消息
await msg.pin(86400);     // 固定24小时(可选时长:86400|604800|2592000秒)
await msg.unpin();

Critical Gotchas

关键注意事项

  • client.initialize()
    is non-blocking
    — Always listen for
    ready
    event before using client
  • message
    event fires only for incoming
    — Use
    message_create
    to capture outgoing messages too
  • Message IDs require
    ._serialized
    — Use
    msg.id._serialized
    for string representation
  • Group admin operations — Bot must be admin to setSubject, removeParticipants, etc.
  • Rate limiting — Add delays between bulk sends to avoid temporary blocks
  • fetchMessages()
    loads from cache
    — Call
    chat.syncHistory()
    for full history sync
  • Sticker conversion requires ffmpeg — Install on system PATH for sticker support
  • Memory considerations — Runs real Chromium instance; plan for multi-client setups
  • Status messages — Send to
    status@broadcast
    as chatId
  • client.initialize()
    是非阻塞的
    — 务必在使用客户端前监听
    ready
    事件
  • message
    事件仅针对 incoming 消息触发
    — 如需捕获自己发送的消息,请使用
    message_create
    事件
  • 消息ID需要使用
    ._serialized
    — 使用
    msg.id._serialized
    获取字符串格式的ID
  • 群组管理员操作 — 机器人必须是管理员才能执行设置主题、移除成员等操作
  • 速率限制 — 批量发送消息时请添加延迟,避免临时被限制
  • fetchMessages()
    从缓存加载消息
    — 如需完整历史同步,请调用
    chat.syncHistory()
  • 贴纸转换需要ffmpeg — 需在系统PATH中安装ffmpeg以支持贴纸功能
  • 内存考虑 — 运行真实的Chromium实例;多客户端部署时需做好规划
  • 状态消息 — 发送到
    status@broadcast
    作为聊天ID

Key Events

核心事件

Essential events for bot logic:
EventUse Case
ready
Client ready to use
message
Incoming message only
message_create
All messages (including own)
message_ack
Track delivery status (0=pending, 1=server, 2=device, 3=read, 4=played)
qr
QR code for authentication
authenticated
Auth successful
disconnected
Handle reconnection logic
用于机器人逻辑的关键事件:
事件使用场景
ready
客户端已准备就绪可使用
message
仅针对 incoming 消息
message_create
所有消息(包括自己发送的)
message_ack
跟踪消息送达状态(0=待处理,1=已到服务器,2=已到设备,3=已读,4=已播放)
qr
用于认证的QR码
authenticated
认证成功
disconnected
处理重连逻辑

References

参考资料

Consult these detailed references when implementing specific features:
  • detailed-guide.md — Read when implementing any WhatsApp Web.js feature. Contains comprehensive API reference organized by category: messaging, media, chats, groups, channels, contacts, events. Includes all method signatures, options, return types, and code examples. Start here for unfamiliar operations or when debugging unexpected behavior.
实现特定功能时可参考以下详细资料:
  • detailed-guide.md — 实现任何WhatsApp Web.js功能时均可查阅。包含按类别组织的完整API参考:消息发送、媒体处理、聊天、群组、频道、联系人、事件。涵盖所有方法签名、选项、返回类型及代码示例。遇到不熟悉的操作或调试异常行为时,可从此处开始。