From a78695bf48754854986c1bf337dbef8ff8ff53ab Mon Sep 17 00:00:00 2001 From: LuChao Date: Wed, 29 May 2024 17:24:46 +0800 Subject: [PATCH] 0.12.1 --- README.md | 685 +----------------- ...ipe-wechaty.ts => ripe-wechaty-3090223.ts} | 0 ... => ripe-wechaty-atorber-fused-3090825.ts} | 0 ...s => ripe-wechaty-jwping-wxbot-3090825.ts} | 0 .../ripe-wechaty-ttttupup-wxhelper-3090223.ts | 222 ++++++ ...ripe-wechaty-ttttupup-wxhelper-3090581.ts} | 0 package.json | 12 +- ...puppet-bridge-ttttupup-wxhelper-3090223.ts | 4 +- 8 files changed, 237 insertions(+), 686 deletions(-) rename examples/{ripe-wechaty.ts => ripe-wechaty-3090223.ts} (100%) rename examples/{ripe-wechaty-atorber-fused.ts => ripe-wechaty-atorber-fused-3090825.ts} (100%) rename examples/{ripe-wechaty-jwping-wxbot.ts => ripe-wechaty-jwping-wxbot-3090825.ts} (100%) create mode 100644 examples/ripe-wechaty-ttttupup-wxhelper-3090223.ts rename examples/{ripe-wechaty-ttttupup-wxhelper.ts => ripe-wechaty-ttttupup-wxhelper-3090581.ts} (100%) diff --git a/README.md b/README.md index 9077283..e536ecb 100644 --- a/README.md +++ b/README.md @@ -96,690 +96,19 @@ puppet-bridge 已经在NPM上发布了安装包,Wechaty用户可以直接安 npm i wechaty-puppet-bridge ``` -示例代码: - -- 运行在[cixingguangming55555/wechat-bot](https://github.com/cixingguangming55555/wechat-bot)上的v3.9.2.23 - -```typescript -import { - WechatyBuilder, - log, - } from 'wechaty' - import { FileBox } from 'file-box' - import {PuppetBridgeCixingguangming55555WechatBotV3090223 as PuppetBridge } from 'wechaty-puppet-bridge' - - async function onLogin (user) { - log.info('onLogin', '%s login', user) - const roomList = await bot.Room.findAll() - console.info('room count:', roomList.length) - const contactList = await bot.Contact.findAll() - console.info('contact count:', contactList.length) - } - - async function onMessage (message) { - log.info('onMessage', JSON.stringify(message)) - - // 1. send Image - if (/^ding$/i.test(message.text())) { - const fileBox = FileBox.fromUrl('https://wechaty.github.io/wechaty/images/bot-qr-code.png') - await message.say(fileBox) - } - - // 2. send Text - - if (/^dong$/i.test(message.text())) { - await message.say('dingdingding') - } - - } - - const puppet = new PuppetBridge({ - token: '大师' // 当前登录账号的昵称作为token - }) - - const bot = WechatyBuilder.build({ - name: 'ding-dong-bot', - puppet, - }) - - bot.on('login', onLogin) - bot.on('message', onMessage) - - bot.start() - .then(() => { - return log.info('StarterBot', 'Starter Bot Started.') - }) - .catch(console.error) -``` +## 更多示例代码 -- 运行在[jwping/wxbot](https://github.com/jwping/wxbot)上的v3.9.8.25 - -```typescript -import { - WechatyBuilder, - log, - } from 'wechaty' - import { FileBox } from 'file-box' - import { PuppetBridgeJwpingWxbotV3090825 as PuppetBridge } from 'wechaty-puppet-bridge' - - async function onLogin (user) { - log.info('onLogin', '%s login', user) - const roomList = await bot.Room.findAll() - console.info('room count:', roomList.length) - const contactList = await bot.Contact.findAll() - console.info('contact count:', contactList.length) - } - - async function onMessage (message) { - log.info('onMessage', JSON.stringify(message)) - - // 1. send Image - if (/^ding$/i.test(message.text())) { - const fileBox = FileBox.fromUrl('https://wechaty.github.io/wechaty/images/bot-qr-code.png') - await message.say(fileBox) - } - - // 2. send Text - - if (/^dong$/i.test(message.text())) { - await message.say('dingdingding') - } - - } - - const puppet = new PuppetBridge() - - const bot = WechatyBuilder.build({ - name: 'ding-dong-bot', - puppet, - }) - - bot.on('login', onLogin) - bot.on('message', onMessage) - - bot.start() - .then(() => { - return log.info('StarterBot', 'Starter Bot Started.') - }) - .catch(console.error) -``` +- 运行在[cixingguangming55555/wechat-bot](https://github.com/cixingguangming55555/wechat-bot)上的v3.9.2.23 [示例代码](./examples/ripe-wechaty-3090223.ts) -- 运行在[ttttupup/wxhelper](https://github.com/ttttupup/wxhelper/tree/dev-3.9.8.25)上的v3.9.8.25 - -> 需要【以管理员身份运行】WeChat客户端 - -```typescript -import { - WechatyBuilder, - log, - } from 'wechaty' - import { FileBox } from 'file-box' - import { PuppetBridgeAtorberFusedV3090825 as PuppetBridge } from 'wechaty-puppet-bridge' - - async function onLogin (user) { - log.info('onLogin', '%s login', user) - const roomList = await bot.Room.findAll() - console.info('room count:', roomList.length) - const contactList = await bot.Contact.findAll() - console.info('contact count:', contactList.length) - } - - async function onMessage (message) { - log.info('onMessage', JSON.stringify(message)) - - // 1. send Image - if (/^ding$/i.test(message.text())) { - const fileBox = FileBox.fromUrl('https://wechaty.github.io/wechaty/images/bot-qr-code.png') - await message.say(fileBox) - } - - // 2. send Text - - if (/^dong$/i.test(message.text())) { - await message.say('dingdingding') - } - - } - - const puppet = new PuppetBridge() - - const bot = WechatyBuilder.build({ - name: 'ding-dong-bot', - puppet, - }) - - bot.on('login', onLogin) - bot.on('message', onMessage) - - bot.start() - .then(() => { - return log.info('StarterBot', 'Starter Bot Started.') - }) - .catch(console.error) -``` +- 运行在[jwping/wxbot](https://github.com/jwping/wxbot)上的v3.9.8.25 [示例代码](./examples/ripe-wechaty-jwping-wxbot-3090825.ts) -- 运行在[ttttupup/wxhelper](https://github.com/ttttupup/wxhelper/tree/dev-3.9.5.81)上的v3.9.5.81 - -> 需要【以管理员身份运行】WeChat客户端 - -```typescript -import { - WechatyBuilder, - log, - } from 'wechaty' - import { FileBox } from 'file-box' - import { PuppetBridgeTtttupupWxhelperV3090581 as PuppetBridge } from 'wechaty-puppet-bridge' - - async function onLogin (user) { - log.info('onLogin', '%s login', user) - const roomList = await bot.Room.findAll() - console.info('room count:', roomList.length) - const contactList = await bot.Contact.findAll() - console.info('contact count:', contactList.length) - } - - async function onMessage (message) { - log.info('onMessage', JSON.stringify(message)) - - // 1. send Image - if (/^ding$/i.test(message.text())) { - const fileBox = FileBox.fromUrl('https://wechaty.github.io/wechaty/images/bot-qr-code.png') - await message.say(fileBox) - } - - // 2. send Text - - if (/^dong$/i.test(message.text())) { - await message.say('dingdingding') - } - - } - - const puppet = new PuppetBridge() - - const bot = WechatyBuilder.build({ - name: 'ding-dong-bot', - puppet, - }) - - bot.on('login', onLogin) - bot.on('message', onMessage) - - bot.start() - .then(() => { - return log.info('StarterBot', 'Starter Bot Started.') - }) - .catch(console.error) -``` +- 运行在[ttttupup/wxhelper](https://github.com/ttttupup/wxhelper/tree/dev-3.9.2.23)上的v3.9.2.23 [示例代码](./examples/ripe-wechaty-ttttupup-wxhelper-3090223.ts) (需要【以管理员身份运行】WeChat客户端) -- 运行在[ttttupup/wxhelper](https://github.com/ttttupup/wxhelper/tree/dev-3.9.10.19)上的v3.9.10.19 - -> 需要【以管理员身份运行】WeChat客户端 - -```typescript -import { - Contact, - Message, - ScanStatus, - WechatyBuilder, - log, - types, -} from 'wechaty' -import { FileBox } from 'file-box' - -import { PuppetBridgeTtttupupWxhelperV3091019 as PuppetBridge } from 'wechaty-puppet-bridge' -import qrcodeTerminal from 'qrcode-terminal' -import * as fs from 'fs' - -// 初始化检查当前文件加下是否存在日志文件info.log,如果不存在则创建 -const logPath = 'info.log' -if (!fs.existsSync(logPath)) { - fs.writeFileSync(logPath, '') -} - -// 定义写日志的方法 -export function writeLog (info: string) { - fs.appendFileSync(logPath, info + '\n') -} - -function onScan (qrcode: string, status: ScanStatus) { - if (qrcode) { - const qrcodeImageUrl = [ - 'https://wechaty.js.org/qrcode/', - encodeURIComponent(qrcode), - ].join('') - log.info('onScan', '%s(%s) - %s', status, qrcodeImageUrl) - - qrcodeTerminal.generate(qrcode, { small: true }) // show qrcode on console - log.info(`[${status}] ${qrcode}\nScan QR Code above to log in: `) - } else { - log.info(`[${status}]`) - } -} - -async function onLogin (user: Contact) { - log.info('ripe onLogin event:', JSON.stringify(user)) -} - -function onLogout (user: Contact) { - log.info('onLogout', '%s logout', user) -} - -async function onMessage (msg: Message) { - // log.info('onMessage', msg.toString()) - log.info('onMessage接收到消息:', JSON.stringify(msg, null, 2)) - const contact = msg.talker() - log.info('当前联系人信息:', JSON.stringify(contact)) - const room = msg.room() - let sendRes:any = '' - if (room) { - log.info('当前群名称:', await room.topic()) - log.info('当前群ID:', room.id) - const owner = await room.owner() - log.info('当前群群主:', JSON.stringify(owner) || 'undefined') - log.info('当前群群主昵称:', owner && owner.name()) - } - - if (msg.text() === 'ding') { - sendRes = await msg.say(new Date().toLocaleString() + ' dong') - log.info('发送消息结果:', sendRes || 'undefined') - } - - const basepath = 'examples/media/' - /** - * 发送文件 - */ - if (msg.text() === 'txt') { - const newpath = basepath + 'test.txt' - const fileBox = FileBox.fromFile(newpath) - sendRes = await msg.say(fileBox) - log.info('发送消息结果:', sendRes) - } - - /** - * 发送图片 - */ - if (msg.text() === 'jpg') { - const newpath = 'https://bce.bdstatic.com/doc/IOTSTACK/IoTPlatform/0-0-1_abfce11.png' - const fileBox = FileBox.fromUrl(newpath) - sendRes = await msg.say(fileBox) - log.info('发送消息结果:', sendRes) - } - - /** - * 发送本地图片 - */ - if (msg.text() === 'jpg_local') { - const newpath = basepath + 'logo.jpg' - const fileBox = FileBox.fromFile(newpath) - sendRes = await msg.say(fileBox) - log.info('发送消息结果:', sendRes) - } - - /** - * 发送表情 - */ - if (msg.text() === 'gif') { - const newpath = basepath + 'test.gif' - const fileBox = FileBox.fromFile(newpath) - sendRes = await msg.say(fileBox) - log.info('发送消息结果:', sendRes) - } - - /** - * 发送视频 - */ - if (msg.text() === 'mp4') { - const newpath = basepath + 'test.mp4' - const fileBox = FileBox.fromFile(newpath) - sendRes = await msg.say(fileBox) - log.info('发送消息结果:', sendRes) - } - - let filePath = 'file/' - // 检查文件夹是否存在,不存在则创建 - if (!fs.existsSync(filePath)) { - fs.mkdirSync(filePath) - } - - try { - if (msg.type() === types.Message.Image || msg.type() === types.Message.Attachment || msg.type() === types.Message.Video || msg.type() === types.Message.Audio || msg.type() === types.Message.Emoticon) { - - let file - - if (msg.type() === types.Message.Image) { - file = await msg.toImage().thumbnail() // Save the media message as a FileBox - } else { - file = await msg.toFileBox() // Save the media message as a FileBox - } - filePath = filePath + file.name - try { - await file.toFile(filePath, true) - log.info(`Saved file: ${filePath}`) - } catch (e) { - log.error('保存文件错误:', e) - } - } else { - // Log other non-text messages - const logData = { - date: new Date(), - listener: msg.listener(), - room:await msg.room(), - talker: msg.talker(), - text: msg.text(), - type: msg.type(), - } - - const logPath = filePath + 'message.log' - fs.appendFileSync(logPath, JSON.stringify(logData, null, 2) + '\n') - - log.info(`日志查看路径: ${logPath}`) - } - } catch (e) { - log.error(`Error handling message: ${e}`) - } - -} - -const onReady = async () => { - log.info('bot已经准备好了') - // const roomList = await bot.Room.findAll() - // writeLog('群信息:' + JSON.stringify(roomList)) - // log.info('群数量:', roomList.length) - // const contactList = await bot.Contact.findAll() - // writeLog('联系人信息:' + JSON.stringify(contactList)) - // log.info('联系人数量:', contactList.length) - // const friends = contactList.filter(c => c.friend()) - // log.info('好友数量:', friends.length) - // 发送@好友消息 - const room = await bot.Room.find({ topic:'大师是群主' }) - log.info('room:', room) - - const contact = await bot.Contact.find({ name:'luyuchao' }) - log.info('contact', contact) - - // if (room && contact) { - // const contacts:Contact[] = [ contact ] - // const msg = `${new Date().toLocaleString()}${bot.currentUser.name()}上线了!` - // await contact.say(msg) - // await room.say(msg, ...contacts) - // } - -} - -const puppet = new PuppetBridge() -const bot = WechatyBuilder.build({ - name: 'ding-dong-bot', - puppet, -}) - -bot.on('scan', onScan) -bot.on('login', onLogin) -bot.on('ready', onReady) -bot.on('logout', onLogout) -bot.on('message', onMessage) -bot.on('room-join', async (room, inviteeList, inviter) => { - const nameList = inviteeList.map(c => c.name()).join(',') - log.info(`Room ${await room.topic()} got new member ${nameList}, invited by ${inviter}`) -}) -bot.on('room-leave', async (room, leaverList, remover) => { - const nameList = leaverList.map(c => c.name()).join(',') - log.info(`Room ${await room.topic()} lost member ${nameList}, the remover is: ${remover}`) -}) -bot.on('room-topic', async (room, topic, oldTopic, changer) => { - log.info(`Room ${await room.topic()} topic changed from ${oldTopic} to ${topic} by ${changer.name()}`) -}) -bot.on('room-invite', async roomInvitation => { - log.info(JSON.stringify(roomInvitation)) - try { - log.info('received room-invite event.') - await roomInvitation.accept() - } catch (e) { - log.error('处理进群申请信息错误:', e) - } -}) - -bot.start() - .then(() => { - return log.info('ripe', 'Bot Started.') - }) - .catch(log.error) -``` +- 运行在[ttttupup/wxhelper](https://github.com/ttttupup/wxhelper/tree/dev-3.9.8.25)上的v3.9.8.25 [示例代码](./examples/ripe-wechaty-atorber-fused-3090825.ts) (需要【以管理员身份运行】WeChat客户端) -- 运行在[ttttupup/wxhelper](https://github.com/ttttupup/wxhelper/tree/dev-3.9.8.25)上的v3.9.8.25 - -> 需要【以管理员身份运行】WeChat客户端 - -```typescript -import { - Contact, - Message, - ScanStatus, - WechatyBuilder, - log, - types, -} from 'wechaty' -import { FileBox } from 'file-box' - -import { PuppetBridgeAtorberFusedV3090825 as PuppetBridge } from 'wechaty-puppet-bridge' -import qrcodeTerminal from 'qrcode-terminal' -import * as fs from 'fs' - -// 初始化检查当前文件加下是否存在日志文件info.log,如果不存在则创建 -const logPath = 'info.log' -if (!fs.existsSync(logPath)) { - fs.writeFileSync(logPath, '') -} - -// 定义写日志的方法 -export function writeLog (info: string) { - fs.appendFileSync(logPath, info + '\n') -} - -function onScan (qrcode: string, status: ScanStatus) { - if (qrcode) { - const qrcodeImageUrl = [ - 'https://wechaty.js.org/qrcode/', - encodeURIComponent(qrcode), - ].join('') - log.info('onScan', '%s(%s) - %s', status, qrcodeImageUrl) - - qrcodeTerminal.generate(qrcode, { small: true }) // show qrcode on console - log.info(`[${status}] ${qrcode}\nScan QR Code above to log in: `) - } else { - log.info(`[${status}]`) - } -} - -async function onLogin (user: Contact) { - log.info('ripe onLogin event:', JSON.stringify(user)) -} - -function onLogout (user: Contact) { - log.info('onLogout', '%s logout', user) -} - -async function onMessage (msg: Message) { - // log.info('onMessage', msg.toString()) - log.info('onMessage接收到消息:', JSON.stringify(msg, null, 2)) - const contact = msg.talker() - log.info('当前联系人信息:', JSON.stringify(contact)) - const room = msg.room() - let sendRes:any = '' - if (room) { - log.info('当前群名称:', await room.topic()) - log.info('当前群ID:', room.id) - const owner = await room.owner() - log.info('当前群群主:', JSON.stringify(owner) || 'undefined') - log.info('当前群群主昵称:', owner && owner.name()) - } - - if (msg.text() === 'ding') { - sendRes = await msg.say(new Date().toLocaleString() + ' dong') - log.info('发送消息结果:', sendRes || 'undefined') - } - - const basepath = 'examples/media/' - /** - * 发送文件 - */ - if (msg.text() === 'txt') { - const newpath = basepath + 'test.txt' - const fileBox = FileBox.fromFile(newpath) - sendRes = await msg.say(fileBox) - log.info('发送消息结果:', sendRes) - } - - /** - * 发送图片 - */ - if (msg.text() === 'jpg') { - const newpath = 'https://bce.bdstatic.com/doc/IOTSTACK/IoTPlatform/0-0-1_abfce11.png' - const fileBox = FileBox.fromUrl(newpath) - sendRes = await msg.say(fileBox) - log.info('发送消息结果:', sendRes) - } - - /** - * 发送本地图片 - */ - if (msg.text() === 'jpg_local') { - const newpath = basepath + 'logo.jpg' - const fileBox = FileBox.fromFile(newpath) - sendRes = await msg.say(fileBox) - log.info('发送消息结果:', sendRes) - } - - /** - * 发送表情 - */ - if (msg.text() === 'gif') { - const newpath = basepath + 'test.gif' - const fileBox = FileBox.fromFile(newpath) - sendRes = await msg.say(fileBox) - log.info('发送消息结果:', sendRes) - } - - /** - * 发送视频 - */ - if (msg.text() === 'mp4') { - const newpath = basepath + 'test.mp4' - const fileBox = FileBox.fromFile(newpath) - sendRes = await msg.say(fileBox) - log.info('发送消息结果:', sendRes) - } - - let filePath = 'file/' - // 检查文件夹是否存在,不存在则创建 - if (!fs.existsSync(filePath)) { - fs.mkdirSync(filePath) - } - - try { - if (msg.type() === types.Message.Image || msg.type() === types.Message.Attachment || msg.type() === types.Message.Video || msg.type() === types.Message.Audio || msg.type() === types.Message.Emoticon) { - - let file - - if (msg.type() === types.Message.Image) { - file = await msg.toImage().thumbnail() // Save the media message as a FileBox - } else { - file = await msg.toFileBox() // Save the media message as a FileBox - } - filePath = filePath + file.name - try { - await file.toFile(filePath, true) - log.info(`Saved file: ${filePath}`) - } catch (e) { - log.error('保存文件错误:', e) - } - } else { - // Log other non-text messages - const logData = { - date: new Date(), - listener: msg.listener(), - room:await msg.room(), - talker: msg.talker(), - text: msg.text(), - type: msg.type(), - } - - const logPath = filePath + 'message.log' - fs.appendFileSync(logPath, JSON.stringify(logData, null, 2) + '\n') - - log.info(`日志查看路径: ${logPath}`) - } - } catch (e) { - log.error(`Error handling message: ${e}`) - } - -} - -const onReady = async () => { - log.info('bot已经准备好了') - // const roomList = await bot.Room.findAll() - // writeLog('群信息:' + JSON.stringify(roomList)) - // log.info('群数量:', roomList.length) - // const contactList = await bot.Contact.findAll() - // writeLog('联系人信息:' + JSON.stringify(contactList)) - // log.info('联系人数量:', contactList.length) - // const friends = contactList.filter(c => c.friend()) - // log.info('好友数量:', friends.length) - // 发送@好友消息 - const room = await bot.Room.find({ topic:'大师是群主' }) - log.info('room:', room) - - const contact = await bot.Contact.find({ name:'luyuchao' }) - log.info('contact', contact) - - // if (room && contact) { - // const contacts:Contact[] = [ contact ] - // const msg = `${new Date().toLocaleString()}${bot.currentUser.name()}上线了!` - // await contact.say(msg) - // await room.say(msg, ...contacts) - // } - -} - -const puppet = new PuppetBridge() -const bot = WechatyBuilder.build({ - name: 'ding-dong-bot', - puppet, -}) - -bot.on('scan', onScan) -bot.on('login', onLogin) -bot.on('ready', onReady) -bot.on('logout', onLogout) -bot.on('message', onMessage) -bot.on('room-join', async (room, inviteeList, inviter) => { - const nameList = inviteeList.map(c => c.name()).join(',') - log.info(`Room ${await room.topic()} got new member ${nameList}, invited by ${inviter}`) -}) -bot.on('room-leave', async (room, leaverList, remover) => { - const nameList = leaverList.map(c => c.name()).join(',') - log.info(`Room ${await room.topic()} lost member ${nameList}, the remover is: ${remover}`) -}) -bot.on('room-topic', async (room, topic, oldTopic, changer) => { - log.info(`Room ${await room.topic()} topic changed from ${oldTopic} to ${topic} by ${changer.name()}`) -}) -bot.on('room-invite', async roomInvitation => { - log.info(JSON.stringify(roomInvitation)) - try { - log.info('received room-invite event.') - await roomInvitation.accept() - } catch (e) { - log.error('处理进群申请信息错误:', e) - } -}) - -bot.start() - .then(() => { - return log.info('ripe', 'Bot Started.') - }) - .catch(log.error) +- 运行在[ttttupup/wxhelper](https://github.com/ttttupup/wxhelper/tree/dev-3.9.5.81)上的v3.9.5.81 [示例代码](./examples/ripe-wechaty-ttttupup-wxhelper-3090581.ts) (需要【以管理员身份运行】WeChat客户端) -``` +- 运行在[ttttupup/wxhelper](https://github.com/ttttupup/wxhelper/tree/dev-3.9.10.19)上的v3.9.10.19 [示例代码](./examples/ripe-bridge-ttttupup-wxhelper-3091019.ts) (需要【以管理员身份运行】WeChat客户端) ## 更新日志 diff --git a/examples/ripe-wechaty.ts b/examples/ripe-wechaty-3090223.ts similarity index 100% rename from examples/ripe-wechaty.ts rename to examples/ripe-wechaty-3090223.ts diff --git a/examples/ripe-wechaty-atorber-fused.ts b/examples/ripe-wechaty-atorber-fused-3090825.ts similarity index 100% rename from examples/ripe-wechaty-atorber-fused.ts rename to examples/ripe-wechaty-atorber-fused-3090825.ts diff --git a/examples/ripe-wechaty-jwping-wxbot.ts b/examples/ripe-wechaty-jwping-wxbot-3090825.ts similarity index 100% rename from examples/ripe-wechaty-jwping-wxbot.ts rename to examples/ripe-wechaty-jwping-wxbot-3090825.ts diff --git a/examples/ripe-wechaty-ttttupup-wxhelper-3090223.ts b/examples/ripe-wechaty-ttttupup-wxhelper-3090223.ts new file mode 100644 index 0000000..b0d3bcb --- /dev/null +++ b/examples/ripe-wechaty-ttttupup-wxhelper-3090223.ts @@ -0,0 +1,222 @@ +import { + Contact, + Message, + ScanStatus, + WechatyBuilder, + log, + types, +} from 'wechaty' +import { FileBox } from 'file-box' + +import { PuppetBridgeTtttupupWxhelperV3090223 as PuppetBridge } from '../src/mod.js' +import qrcodeTerminal from 'qrcode-terminal' +import * as fs from 'fs' + +// 初始化检查当前文件加下是否存在日志文件info.log,如果不存在则创建 +const logPath = 'info.log' +if (!fs.existsSync(logPath)) { + fs.writeFileSync(logPath, '') +} + +// 定义写日志的方法 +export function writeLog (info: string) { + fs.appendFileSync(logPath, info + '\n') +} + +function onScan (qrcode: string, status: ScanStatus) { + if (qrcode) { + const qrcodeImageUrl = [ + 'https://wechaty.js.org/qrcode/', + encodeURIComponent(qrcode), + ].join('') + log.info('onScan', '%s(%s) - %s', status, qrcodeImageUrl) + + qrcodeTerminal.generate(qrcode, { small: true }) // show qrcode on console + log.info(`[${status}] ${qrcode}\nScan QR Code above to log in: `) + } else { + log.info(`[${status}]`) + } +} + +async function onLogin (user: Contact) { + log.info('onLogin', JSON.stringify(user, null, 2)) +} + +function onLogout (user: Contact) { + log.info('onLogout', '%s logout', user) +} + +async function onMessage (msg: Message) { + // log.info('onMessage', msg.toString()) + log.info('onMessage接收到消息:', JSON.stringify(msg, null, 2)) + const contact = msg.talker() + log.info('当前联系人信息:', JSON.stringify(contact)) + const room = msg.room() + let sendRes:any = '' + if (room) { + log.info('当前群名称:', await room.topic()) + log.info('当前群ID:', room.id) + const owner = await room.owner() + log.info('当前群群主:', JSON.stringify(owner) || 'undefined') + log.info('当前群群主昵称:', owner && owner.name()) + } + + if (msg.text() === 'ding') { + sendRes = await msg.say(new Date().toLocaleString() + ' dong') + log.info('发送消息结果:', sendRes || 'undefined') + } + + const basepath = 'examples/media/' + /** + * 发送文件 + */ + if (msg.text() === 'txt') { + const newpath = basepath + 'test.txt' + const fileBox = FileBox.fromFile(newpath) + sendRes = await msg.say(fileBox) + log.info('发送消息结果:', sendRes) + } + + /** + * 发送图片 + */ + if (msg.text() === 'jpg') { + const newpath = 'https://bce.bdstatic.com/doc/IOTSTACK/IoTPlatform/0-0-1_abfce11.png' + const fileBox = FileBox.fromUrl(newpath) + sendRes = await msg.say(fileBox) + log.info('发送消息结果:', sendRes) + } + + /** + * 发送本地图片 + */ + if (msg.text() === 'jpg_local') { + const newpath = basepath + 'logo.jpg' + const fileBox = FileBox.fromFile(newpath) + sendRes = await msg.say(fileBox) + log.info('发送消息结果:', sendRes) + } + + /** + * 发送表情 + */ + if (msg.text() === 'gif') { + const newpath = basepath + 'test.gif' + const fileBox = FileBox.fromFile(newpath) + sendRes = await msg.say(fileBox) + log.info('发送消息结果:', sendRes) + } + + /** + * 发送视频 + */ + if (msg.text() === 'mp4') { + const newpath = basepath + 'test.mp4' + const fileBox = FileBox.fromFile(newpath) + sendRes = await msg.say(fileBox) + log.info('发送消息结果:', sendRes) + } + + let filePath = 'file/' + // 检查文件夹是否存在,不存在则创建 + if (!fs.existsSync(filePath)) { + fs.mkdirSync(filePath) + } + + try { + if (msg.type() === types.Message.Image || msg.type() === types.Message.Attachment || msg.type() === types.Message.Video || msg.type() === types.Message.Audio || msg.type() === types.Message.Emoticon) { + + let file + + if (msg.type() === types.Message.Image) { + file = await msg.toImage().thumbnail() // Save the media message as a FileBox + } else { + file = await msg.toFileBox() // Save the media message as a FileBox + } + filePath = filePath + file.name + try { + await file.toFile(filePath, true) + log.info(`Saved file: ${filePath}`) + } catch (e) { + log.error('保存文件错误:', e) + } + } else { + // Log other non-text messages + const logData = { + date: new Date(), + listener: msg.listener(), + room:await msg.room(), + talker: msg.talker(), + text: msg.text(), + type: msg.type(), + } + + const logPath = filePath + 'message.log' + fs.appendFileSync(logPath, JSON.stringify(logData, null, 2) + '\n') + + log.info(`日志查看路径: ${logPath}`) + } + } catch (e) { + log.error(`Error handling message: ${e}`) + } + +} + +const puppet = new PuppetBridge() +const bot = WechatyBuilder.build({ + name: 'ding-dong-bot', + puppet, +}) + +bot.on('scan', onScan) +bot.on('login', onLogin) +bot.on('ready', async () => { + log.info('bot已经准备好了') + // const roomList = await bot.Room.findAll() + // writeLog('群信息:' + JSON.stringify(roomList)) + // log.info('群数量:', roomList.length) + // const contactList = await bot.Contact.findAll() + // writeLog('联系人信息:' + JSON.stringify(contactList)) + // log.info('联系人数量:', contactList.length) + // const friends = contactList.filter(c => c.friend()) + // log.info('好友数量:', friends.length) + // 发送@好友消息 + const room = await bot.Room.find({ topic:'大师是群主' }) + log.info('room:', room) + + const contact = await bot.Contact.find({ name:'luyuchao' }) + log.info('contact', contact) + + if (room && contact) { + const contacts:Contact[] = [ contact ] + await room.say(new Date().toLocaleString() + ':瓦力上线了!', ...contacts) + } +}) +bot.on('logout', onLogout) +bot.on('message', onMessage) +bot.on('room-join', async (room, inviteeList, inviter) => { + const nameList = inviteeList.map(c => c.name()).join(',') + log.info(`Room ${await room.topic()} got new member ${nameList}, invited by ${inviter}`) +}) +bot.on('room-leave', async (room, leaverList, remover) => { + const nameList = leaverList.map(c => c.name()).join(',') + log.info(`Room ${await room.topic()} lost member ${nameList}, the remover is: ${remover}`) +}) +bot.on('room-topic', async (room, topic, oldTopic, changer) => { + log.info(`Room ${await room.topic()} topic changed from ${oldTopic} to ${topic} by ${changer.name()}`) +}) +bot.on('room-invite', async roomInvitation => { + log.info(JSON.stringify(roomInvitation)) + try { + log.info('received room-invite event.') + await roomInvitation.accept() + } catch (e) { + log.error('处理进群申请信息错误:', e) + } +}) + +bot.start() + .then(() => { + return log.info('ripe', 'Bot Started.') + }) + .catch(log.error) diff --git a/examples/ripe-wechaty-ttttupup-wxhelper.ts b/examples/ripe-wechaty-ttttupup-wxhelper-3090581.ts similarity index 100% rename from examples/ripe-wechaty-ttttupup-wxhelper.ts rename to examples/ripe-wechaty-ttttupup-wxhelper-3090581.ts diff --git a/package.json b/package.json index 3f5cb99..1d05c96 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wechaty-puppet-bridge", - "version": "0.12.0", + "version": "0.12.1", "description": "Puppet Bridge for Wechaty", "type": "module", "exports": { @@ -28,15 +28,15 @@ "start:raw": "cross-env BROLOG_LEVEL=silly NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node examples/raw-bridge.ts", "start:raw:nobuild": "cross-env BROLOG_LEVEL=info NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node examples/raw-bridge.ts", "start:raw:info": "cross-env BROLOG_LEVEL=info NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node examples/raw-bridge.ts", - "start:ripe": "cross-env WECHATY_LOG=verbose NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node examples/ripe-wechaty.ts", - "start:ripe:info": "cross-env WECHATY_LOG=info NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node examples/ripe-wechaty.ts", + "start:ripe": "cross-env WECHATY_LOG=verbose NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node examples/ripe-wechaty-3090223.ts", + "start:ripe:info": "cross-env WECHATY_LOG=info NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node examples/ripe-wechaty-3090223.ts", "start:ripe:demo": "cross-env WECHATY_LOG=info NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node examples/demo.ts", "start:raw-bridge-jwping-wxbot:info": "cross-env BROLOG_LEVEL=info NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node examples/raw-bridge-jwping-wxbot.ts", - "start:ripe-bridge-jwping-wxbot:info": "cross-env WECHATY_LOG=info NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node examples/ripe-wechaty-jwping-wxbot.ts", + "start:ripe-bridge-jwping-wxbot:info": "cross-env WECHATY_LOG=info NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node examples/ripe-wechaty-jwping-wxbot-3090825.ts", "start:raw-bridge-ttttupup-wxhelper:info": "cross-env BROLOG_LEVEL=info NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node examples/raw-bridge-ttttupup-wxhelper.ts", - "start:ripe-bridge-ttttupup-wxhelper:info": "cross-env WECHATY_LOG=info NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node examples/ripe-wechaty-ttttupup-wxhelper.ts", + "start:ripe-bridge-ttttupup-wxhelper:info": "cross-env WECHATY_LOG=info NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node examples/ripe-wechaty-ttttupup-wxhelper-3090581.ts", "start:raw-bridge-atorber-fused:info": "cross-env BROLOG_LEVEL=info NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node examples/raw-bridge-atorber-fused.ts", - "start:ripe-wechaty-atorber-fused:info": "cross-env WECHATY_LOG=info NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node examples/ripe-wechaty-atorber-fused.ts", + "start:ripe-wechaty-atorber-fused:info": "cross-env WECHATY_LOG=info NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node examples/ripe-wechaty-atorber-fused-3090825.ts", "start:raw-bridge-ttttupup-wxhelper-3091019:info": "cross-env BROLOG_LEVEL=info NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node examples/raw-bridge-ttttupup-wxhelper-3091019.ts", "start:ripe-bridge-ttttupup-wxhelper-3091019:info": "cross-env WECHATY_LOG=info NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node examples/ripe-bridge-ttttupup-wxhelper-3091019.ts", "test:wxhelper": "cross-env WECHATY_LOG=info NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node examples/wxhelper.ts", diff --git a/src/puppet-bridge-ttttupup-wxhelper-3090223.ts b/src/puppet-bridge-ttttupup-wxhelper-3090223.ts index 919ca06..b4394be 100644 --- a/src/puppet-bridge-ttttupup-wxhelper-3090223.ts +++ b/src/puppet-bridge-ttttupup-wxhelper-3090223.ts @@ -29,9 +29,9 @@ import { import { Bridge, -} from './agents/ttttupup-wxhelper.js' +} from './agents/ttttupup-wxhelper-3090223.js' -import type * as wxhelper from './agents/ttttupup-wxhelper-api.js' +import type * as wxhelper from './agents/ttttupup-wxhelper-3090223-api.js' import { ImageDecrypt } from './pure-functions/image-decrypt.js' import { XmlDecrypt } from './pure-functions/xml-msgpayload.js'