常见问题

w
Last updated 3 months ago

1. 基本使用

1.1 如何用最简单的方式把wechaty 跑起来?

  1. 从github 上clone wechaty 的教学代码: https://github.com/Chatie/wechaty-getting-started

  2. 运行 `npm install`

  3. 运行 `npm start`

  4. 默认会跑起来我们的demo 例子,demo代码位置: examples/starter-bot.js

  5. 修改demo 的例子,实现你自己想要的bot 逻辑

1.2 Windows 安装wechaty-puppet-padchat 失败怎么办?

请参考这篇博客:在Windows10下安装Wechaty

1.3 我的微信号无法登陆

从2017年6月下旬开始,使用基于web版微信接入方案存在大概率的被限制登陆的可能性。 主要表现为:无法登陆Web 微信,但不影响手机等其他平台。 验证是否被限制登陆: https://wx.qq.com 上扫码查看是否能登陆。 更多内容详见:

解决方案: 我们提供了非web 版本解决方案,点击购买token , 更多技术细节查看 wechaty-puppet-padchat

1.4 如何打开调试信息

参考 最佳实践之日志说明

2. 功能相关

请查看 Puppet功能兼容性清单 查看完整功能内容

2.1 如何获取到用户的微信号

我用`Contact.id`获取到的不是用户的微信号,如何获取到用户的微信号?

对的,Contact.id 获取不到用户的微信号的,应该用 Contact.weixin() 获取用户的微信号。

能否获取到用户的微信号,取决于你使用的是哪一个Puppet。

  • 如果使用的是Web 版本的Puppet,基于网页微信的机制,大部分情况下获取不到微信号,只有一小部分用户能获取到微信号。

  • 如果使用的是iPad 版本的Puppet,即将推出获取微信号的功能,详情看 #1647

相关issue:

  • #1658 How to get the wx_id when user had wx account?

  • #1307 How to get the user's wechat account(微信号)?

2.2 如何获取好友和群的唯一id?

通过 Contact.idRoom.id 获取好友和群的唯一id。

不同的Puppet,这个唯一id是不同的。

除此之外,还有一定重要的不同:是否能够跨session 依然保持不变,换句话说,当你重新登录的时候,或者切换账号登录的时候,同一个好友或者群的id 是否唯一。

不通的Puppet 表现各不相同:

  • 基于Web 版本的Puppet 得到的id 跨session 是会变化的,所以不能被用来当做你系统的唯一标识码来使用。

  • 基于iPad 版本的Puppet 得到的id 跨session 是不会变化的,可以用来当做这个联系人的唯一标识码。

相关issue:

  • #1644 About wxid or chatroomID

  • #90 请问可以获取到群号吗?

  • #1276 最新版本Contact没有uin字段了吗?

  • #133 请问有办法取得个人和群的唯一标识吗?或者有没有办法自己构建?

  • #1307 How to get the user's wechat account(微信号)?

2.3 支持 红包、转账、朋友圈… 吗?

以下功能目前均不支持

  • 支付相关 - 红包、转账、收款 等都不支持

  • 在群聊中@他人 - 是的,Web 微信中被人@后也不会提醒

  • 朋友圈相关 - 后续会支持

  • 小程序 - 后续会支持

  • 发送视频 - 后续会支持

以下功能部分支持

  • 发送分享链接,仅padchat 支持

  • 发送名片,仅padchat 支持

  • 发送语音消息,仅padchat 支持

2.4 wechaty 是支持个人号还是公众号?

现阶段,wechaty 只支持个人号,未来会陆续开放支持公众号的功能。

相关Issue:

  • #1016 Using wechaty to start a wechatOA account

2.5 wechaty 是否可以发送卡片消息,然后跳转到网页

是否可以通过wechaty 发送分享链接?

PuppetPadchat 是支持的, 其他版本是不支持的,示例代码:

import { UrlLink } from 'wechaty'
bot.on('message', async function (m: Message) {
const link = new UrlLink({
description : '这是图文链接里面的描述',
title : '这是图文链接的标题',
url : 'https://github.com/chatie/wechaty',
thumbnailUrl: 'https://avatars0.githubusercontent.com/u/25162437?s=30&v=4',
})
m.say(link)
})

相关issue:

  • #1593 feat: add receive and send link

  • #718 Add support for send url rich media message

  • #537 [enhancement] Cant send a wechat page link to the room.

  • #331 [Feature] sending formatted links / href tags

2.6 机器人被拉到一个新的群组里的事件是否支持?

支持,可以通过`room-join` 获取到这个事件。

bot.on('room-join', (room, inviteeList, inviter) => {
const nameList = inviteeList.map(c => c.name()).join(',')
console.log(`Room ${room.topic()} got new member ${nameList}, invited by ${inviter}`)
// 如果机器人被拉到一个新的群组里, inviteeList[0] === bot.self()
})

2.7 为什么需要扫码登陆而不是用户名密码登陆?

我发现代码是有通过用户名密码登陆的方法的,所以也许我可以很简单的写一个创建账户的功能,然后不用再扫码登陆,但是为什么现在没做呢?

对的,我们不支持账号密码登陆,以后也不会支持。

有一些Puppet 有有通过账号密码登陆的方法的,但是我们并不打算把这个API开放出来,因为以下3个原因:

  1. 有一些Puppet 是不支持这个功能的,比如使用网页API的PuppetWechat4u

  2. 当你使用扫码的方式登陆的时候,你是可以保存你手机的session的。换句话说,你可以同时让手机和机器人同时在线。如果你使用了用户名密码登陆,那么的session将会失效,只有机器人微信在线,手机微信将会自动退出。

  3. 通过用户名密码登陆的协议,是使用一个协议服务器来控制iPad 微信的。如果你使用用户名密码的方式登陆,那么你就会直接把这些敏感的账号信息发给第三方的服务器,这种方式大部分用户会觉得很不舒服。

2.8 如何不使用onMessage 来发消息?

在群内发送消息:

const room = await Room.find('room name')
room.say('hello room')

给一个好友私信发消息:

const contact = await Contact.find('contact name')
contact.say('hello room')

更多例子请参考:https://github.com/Chatie/wechaty-getting-started/blob/master/examples

相关issue:

  • #446 how to send mesage without onMessage

  • #200 [new feature] Forward Message

  • #89 Wechaty.send() error when send message to the room

  • #41 [New Feature] send message by branding new method: say()

2.9 运行出现Error: can not found bot file: xxx.js when using docker to start wechaty.

首先,请确认你有xxx.js文件,如果依然有这个问题,请检查一下Linux 的 SELinux设置。

SELinuxCentOS系统下是默认开启的,Ubuntu默认 看不到这个。

root 用户是没有权限读这个目录的,你可以运行下面的命令

setenforce 0

setenforce 0 会禁掉SELinux

2.10 通过Room.find()找到的群,要是用户名或群名字有相同的会怎么办,find找到的是哪一个?

返回找到的第一个群,排序方式是随机的。

2.11 如何发送一个链接邀请好友进群?

我是用 `room.add(contact)` 的方法邀请好友入群的,但是我发现机器人是直接拉用户进群的,而没有给用户发送的入群邀请链接。

这个是微信自带的机制,手工操作也是同样的效果:

  • 40人以下的群,是直接拉用户进群的。

  • 40人以上的群,是发送入群邀请链接的。

2.12 为什么我通过Room.findAll只拿到了一部分的群

有谁知道, Room.findAll拿不到所有的群列表吗?

首先,Room.findAll可以拿到所有的群,但是微信的群数据量很大,需要同步时间。无论是web的puppet还是iPad的puppet都需要一定时间来同步这部分消息,如果在同步的时候去调用Room.findAll,就只能拿到当前已经同步好的群。

因此,wechaty 有一个ready 的事件可以供大家来监听,当所有数据都加载完毕的时候,ready 事件会被触发,此事件在wechaty 启动后只会被触发一次。那么,在ready 事件被触发了之后去调用Room.findAll 就会拿到所有的群聊消息了。示例代码如下:

bot.on('ready', () => {
const allRooms = await bot.Room.findAll()
// Then do whatever you want to do
}

2.13 我的群好多,我等不了ready事件就想要操作bot的群

这个问题暂时没法完全解决,有两个临时的解决方案,首先要明确一下需求:

我需要操作的这个群是我的长期管理的群,每次启动都需要拿到这个群

对于这种情况,可以在开发阶段先拿到这个群的id 并且保存这个id,之后每次启动之后,主动加载这个room。

bot.on('login', user => {
const room = bot.Room.load(roomId)
await room.sync()
// Do whatever you want to do with the room
}

我需要对这个群的事件有些响应

对于这种情况,所有的群的事件(room-join, room-leave, room-topic)在触发了之后,都会对当前这个群做一次加载,所有监听到的事件里面,都是可以直接拿到这个群的信息的,是不需要等待的,还有当群里面有消息的时候,如果当前的群并没有被加载过,也是会手动加载这个群的,然后可以通过消息对象来获取这个群。

bot.on('message', message => {
const room = message.room()
// room might not be available if the message is not in a room
if (room) {
// Do things you like in the room
}
}

2.14 为什么我的bot疯狂的在说话

以下只是一个可能的原因,但是应该是大部分人遇到这个问题的原因

Wechaty 的消息事件是会在所有消息被发出来的时候都会触发的,包括自己发的消息。所以大部分情况如果发现机器人疯狂的在说话,那么大概是机器人在自己和自己说话了。建议在消息事件里面对自己说的话做一个过滤,只处理别人说话,这样就不会造成死循环一直自己对自己说话了

bot.on('message', message => {
if (message.self()) {
// Don't deal with message from yourself.
return
}
// Deal with message from anyone else
}

2.15 重新登陆之后是否可以读到之前的消息

这取决于你多久之后重新启动,也取决于这条消息是否在手机上被阅读过。如果是断线重连的情况,是可以读到之前的消息的。

通常情况下,机器人只能读到在线期间所有的消息

3. 最佳实践

3.1 wechaty & 队列的最佳实践

参考 最佳实践之设置合理间隔

3.2 如何能不多次扫码登陆机器人

在启动的时候可以设置wechaty 的 name(旧版本叫profile) 来存储机器人的登陆信息,登陆后会自动生成一个*.memory-card.json 的文件,这样再次运行的时候,就不需要扫码就可以直接登陆机器人了

const bot = Wechaty.instance({ name: 'your-cute-bot-name' })

3.3 我发现在根目录下有一个default.memory-card.json 的文件,这个文件是干什么的?

default.memory-card.json 会用来存储登陆信息,机器人可以通过这个文件实现自动登陆。

3.4 既然default.memory-card.json 存储了机器人的登陆信息,如果我想启动多个机器人,如何防止每次启动的时候加载不同的信息呢?

如果你想在一个机器上启动多个机器人,你可以通过设置 name(旧版本叫profile) 的值设置不同的机器人登陆信息,对应的你得到多个*.memory-card.json文件。有两种方法可以设置profile

1. wechaty 初始化的时候设置name

const bot = Wechaty.instance({ name: 'your-cute-bot-name' })
或者
const bot = new Wechaty({ name: 'your-bot-name'})

2. 通过设置WECHATY_NAME 环境变量传递profile

WECHATY_NAME="your-cute-bot-name" node bot.js

这样,你就可以在根目录下看到your-cute-bot-name.memory-card.json的文件了。

3.5 wechaty 运行的bot 如何修改文件后自动重启

参考 最佳实践之热加载

4. 其他

4.1 wechaty 和 wechat4u 项目,有什么区别?

wechaty 可以实现多个微信接入的方案,对外提供统一的接口,包括web,ipad,ios等等,其中wechat4uSPACELAN写的基于web 实现微信接入的,wechaty 可以实现用wechaty 的接口,调用wechat4u的api。

这么理解:wechat4u有的,wechaty都有,反之不一定有,对么?

这个也不是完全确定的,因为wechaty 只是基于wechaty 暴露出来的接口为wechat4u 进行了封装。

4.2 Python 版本什么时候上线?

请关注这个项目:

4.3 如何理解Wechaty 的版本号

参考 最佳实践之版本说明

如果FAQ的内容无法满足你,可以去官网发Issue 获取支持: https://github.com/chatie/wechaty/issues

Contents
1. 基本使用 1.1 如何用最简单的方式把wechaty 跑起来? 1.2 Windows 安装wechaty-puppet-padchat 失败怎么办? 1.3 我的微信号无法登陆 1.4 如何打开调试信息 2. 功能相关 2.1 如何获取到用户的微信号 2.2 如何获取好友和群的唯一id? 2.3 支持 红包、转账、朋友圈… 吗? 2.4 wechaty 是支持个人号还是公众号? 2.5 wechaty 是否可以发送卡片消息,然后跳转到网页 2.6 机器人被拉到一个新的群组里的事件是否支持? 2.7 为什么需要扫码登陆而不是用户名密码登陆? 2.8 如何不使用onMessage 来发消息? 2.9 运行出现Error: can not found bot file: xxx.js when using docker to start wechaty. 2.10 通过Room.find()找到的群,要是用户名或群名字有相同的会怎么办,find找到的是哪一个? 2.11 如何发送一个链接邀请好友进群? 2.12 为什么我通过Room.findAll只拿到了一部分的群 2.13 我的群好多,我等不了ready事件就想要操作bot的群 2.14 为什么我的bot疯狂的在说话 2.15 重新登陆之后是否可以读到之前的消息 3. 最佳实践 3.1 wechaty & 队列的最佳实践 3.2 如何能不多次扫码登陆机器人 3.3 我发现在根目录下有一个default.memory-card.json 的文件,这个文件是干什么的? 3.4 既然default.memory-card.json 存储了机器人的登陆信息,如果我想启动多个机器人,如何防止每次启动的时候加载不同的信息呢? 3.5 wechaty 运行的bot 如何修改文件后自动重启 4. 其他 4.1 wechaty 和 wechat4u 项目,有什么区别? 4.2 Python 版本什么时候上线? 4.3 如何理解Wechaty 的版本号