import { makeWASocket, WAProto, DisconnectReason, fetchLatestBaileysVersion, makeCacheableSignalKeyStore, makeInMemoryStore, useMultiFileAuthState, } from '@whiskeysockets/baileys' import NodeCache from 'node-cache' import P from 'pino' import fs from "fs" const logger = P({ timestamp: () => `,"time":"${new Date().toJSON()}"` }, P.destination('./wa-logs.txt')) logger.level = 'trace' // external map to store retry counts of messages when decryption/encryption fails // keep this out of the socket itself, so as to prevent a message decryption/encryption loop across socket restarts const msgRetryCounterCache = new NodeCache() // the store maintains the data of the WA connection in memory // can be written out to a file & read from it const store = makeInMemoryStore({ logger }) store?.readFromFile('./baileys_store_multi.json') // save every 10s setInterval(() => { store?.writeToFile('./baileys_store_multi.json') }, 10_000) // start a connection const startSock = async () => { const channelId = '创建时赋值,唯一标识' const phone = '手机号' const createTimestamp = '创建时间戳' const status = 'close, open, connecting' const sendTextMessage = (whatsAppNo, content) => { sock.sendMessage(whatsAppNo + '@s.whatsapp.net', { text: content }) } const sendMediaMessage = (whatsAppNo, content) => { sock.sendMessage(whatsAppNo + '@s.whatsapp.net', { video: fs.readFileSync("d:\\Workspace\\1.jpg"), caption: "hello!", gifPlayback: true }) } const { state, saveCreds } = await useMultiFileAuthState('baileys_auth_info') // fetch latest version of WA Web const { version, isLatest } = await fetchLatestBaileysVersion() console.log(`using WA v${version.join('.')}, isLatest: ${isLatest}`) const sock = makeWASocket({ version, logger, auth: { creds: state.creds, /** caching makes the store faster to send/recv messages */ keys: makeCacheableSignalKeyStore(state.keys, logger), }, msgRetryCounterCache, generateHighQualityLinkPreview: true, // ignore all broadcast messages -- to receive the same // comment the line below out // shouldIgnoreJid: jid => isJidBroadcast(jid), // implement to handle retries & poll updates getMessage, }) sock.ev.on('connection.update', (update) => { const { connection, lastDisconnect, qr } = update if(connection === 'close') { console.info('链接断了') } else if(connection === 'open') { console.info('扫码成功') } else if(connection === 'connecting') { console.info('二维码:', qr) } }) sock.ev.on('messages.upsert', (upsert) => { console.log('收到消息:', JSON.stringify(upsert, undefined, 2)) if (upsert.type === 'notify') { for (const msg of upsert.messages) { if (msg.message?.conversation || msg.message?.extendedTextMessage?.text) { const text = msg.message?.conversation || msg.message?.extendedTextMessage?.text if (text.indexOf('图片')){ sendMediaMessage('8617607730395', 'ddddd') } else if (text.indexOf('文本')){ sendMediaMessage('8617607730395', 'ddddd') sendTextMessage('8617607730395', '发送文本:' + new Date().toString()) } } } } }) // 不绑定不会影响扫码登录 // store?.bind(sock.ev) // the process function lets you process all events that just occurred // efficiently in a batch sock.ev.process( // events is a map for event name => event data async (events) => { // something about the connection changed // maybe it closed, or we received all offline message or connection opened if (events['connection.update']) { const update = events['connection.update'] const { connection, lastDisconnect, qr } = update if (connection === 'close') { console.log('链接断开:', lastDisconnect) if (lastDisconnect?.error?.output?.statusCode !== DisconnectReason.loggedOut) { startSock() } else { sock.end((error) => console.error('end.error: ', error)) sock.logout((msg) => console.error('logout.msg: ', msg)) console.log('Connection closed. You are logged out.') } } // 扫码成功,可以发送消息 if (update.connection === 'open') { await sock.sendMessage('8617607730395' + '@s.whatsapp.net', { text: 'oh ' + new Date().toDateString() }) } // WebSocket 创建成功等待扫码,如果没有扫码会更新 qr if (update.connection === 'connecting') { // qr } console.log('connection update', update) } // credentials updated -- save them if (events['creds.update']) { await saveCreds() } // history received if (events['messaging-history.set']) { const { chats, contacts, messages, isLatest, progress, syncType } = events['messaging-history.set'] if (syncType === WAProto.HistorySync.HistorySyncType.ON_DEMAND) { console.log('received on-demand history sync, messages=', messages) } console.log(`recv ${chats.length} chats, ${contacts.length} contacts, ${messages.length} msgs (is latest: ${isLatest}, progress: ${progress}%), type: ${syncType}`) } // received a new message if (events['messages.upsert']) { const upsert = events['messages.upsert'] console.log('收到消息:', JSON.stringify(upsert, undefined, 2)) if (upsert.type === 'notify') { for (const msg of upsert.messages) { if (msg.message?.conversation || msg.message?.extendedTextMessage?.text) { const text = msg.message?.conversation || msg.message?.extendedTextMessage?.text console.log('收到 notify:', text) } } } } }, ) return sock async function getMessage(key) { if (store) { const msg = await store.loadMessage(key.remoteJid, key.id) return msg?.message || undefined } // only if store is present return WAProto.Message.fromObject({}) } } startSock()