Coder Social home page Coder Social logo

wechaty / wechaty Goto Github PK

View Code? Open in Web Editor NEW
19.0K 383.0 2.5K 8.86 MB

Conversational RPA SDK for Chatbot Makers. Join our Discord: https://discord.gg/7q8NBZbQzt

Home Page: https://wechaty.js.org

License: Apache License 2.0

Shell 3.97% TypeScript 75.17% Dockerfile 0.77% JavaScript 20.09%
wechaty chatbot wechat whatsapp conversational-ai robotics qq framework bot

wechaty's Introduction

Wechaty Join Wechaty Discord Developer Community NPM Version NPM Docker

Wechaty

Downloads GitHub stars Docker Pulls ES Modules

TypeScript JavaScript Python Go Java .NET PHP Rust Scala

WeChat Whatsapp

Elevator Pitch

Wechaty is a conversational RPA SDK that simplifies the process of building chatbots. It's like a Swiss Army knife for chatbot development, providing a universal interface to various messaging platforms such as WhatsApp, WeChat, and more. With Wechaty, you write your bot code once, and it runs on any of the supported platforms. This means you can focus on creating engaging conversational experiences without worrying about the underlying complexities of each platform's API. It's open-source, easy to use, and backed by a vibrant community that's ready to help you bring your chatbot ideas to life.

Connecting Chatbots

Wechaty is an RPA (Robotic Process Automation) SDK for Chatbot Makers which can help you create a bot in 6 lines of JavaScript, Python, Go, and Java, with cross-platform support including Linux, Windows, MacOS, and Docker.

🕸️ https://wechaty.js.org
:octocat: https://github.com/Wechaty/wechaty
🪲 https://github.com/Wechaty/wechaty/issues
📖 https://github.com/Wechaty/wechaty-getting-started
🐳 https://hub.docker.com/r/wechaty/wechaty

Breaking News

Voice of Developers

"Wechaty is a great solution; I believe there would be much more users who recognize it." link
— @Gcaufy, Tencent Engineer, Author of WePY

"太好用,好用的想哭"
— @xinbenlv, Google Engineer, Founder of HaoShiYou.org

”好用到哭“——你们对得起这个评价! link
@bigbrother666sh, creator of《社长不见了》剧本杀 NPC DM

"最好的微信开发库" link
— @Jarvis, Baidu Engineer

"Wechaty让运营人员更多的时间思考如何进行活动策划、留存用户,商业变现" link
— @lijiarui, Founder & CEO of Juzi.BOT.

"If you know js ... try Wechaty. It's easy to use."
— @Urinx Uri Lee, Author of WeixinBot(Python)

"Wechaty is a good project; I hope it can continue! Therefore, I became a contributor in open collective."
@Simple

See more at Wiki:Voice Of Developer

Join Us on Discord

Join Wechaty Discord Developer Community Wechaty Discord

Wechaty is used in many ChatBot projects by thousands of developers. To talk with other developers, scan the QR Code below and join our Wechaty Developer Community.

Wechaty Discord Community QR Code

Scan now because other Wechaty developers want to talk with you, too!

Resource

Wechaty has already held lots of talks and got a lot of blogs in the past years; here are all of the wechaty resources:

🚀 The World's Shortest ChatBot Code: 6 lines of JavaScript

import { WechatyBuilder } from 'wechaty'

const wechaty = WechatyBuilder.build() // get a Wechaty instance
wechaty
  .on('scan', (qrcode, status) => console.log(`Scan QR Code to login: ${status}\nhttps://wechaty.js.org/qrcode/${encodeURIComponent(qrcode)}`))
  .on('login',            user => console.log(`User ${user} logged in`))
  .on('message',       message => console.log(`Message: ${message}`))
wechaty.start()

Notice: Wechaty requires Node.js version >= 16

This bot can log all messages to the console after login by the scan.

You can find Wechaty's Official Examples at examples/ding-dong-bot.ts and more from our Example Directory.

🏁 Requirements

  1. Node.js version 16+
  2. NPM version 7+
  3. TypeScript version 4.4+

Getting Started

node

We have a Wechaty starter repository for beginners with the simplest setting. It will be work out-of-the-box after you clone & npm install & npm start.

If you are new to Wechaty and want to try it the first time, we'd like to strong recommend you starting from this repository, and using it as your starter template for your project.

Otherwise, please saved the above The World's Shortest ChatBot Code: 6 lines of JavaScript example to a file named bot.js before you can use either NPM or Docker to run it.

1. Npm

NPM Version npm (tag)

Downloads install size

npm init
npm install wechaty

# create your first bot.js file, you can copy/paste from the above "The World's Shortest ChatBot Code: 6 lines of JavaScript"
# then:
node bot.js

2. Docker

Docker Pulls Docker Layers

Wechaty Docker supports both JavaScript and TypeScript. To use TypeScript just write in TypeScript and save with extension name .ts, no need to compile because we use ts-node to run it.

2.1. Run JavaScript

# for JavaScript
docker run -ti --rm --volume="$(pwd)":/bot wechaty/wechaty bot.js

2.2. Run TypeScript

# for TypeScript
docker run -ti --rm --volume="$(pwd)":/bot wechaty/wechaty bot.ts

Learn more about Wechaty Docker at Wiki:Docker.

3. Switch Protocol(Puppet)

Wechaty is very powerful that it can run over different protocols. You can specify the protocol by set the environment variable WECHATY_PUPPET to different puppet provider.

If you cannot use Web protocol, you can apply other protocal following the instruction here: https://github.com/wechaty/wechaty/wiki/Support-Developers We provide free token to support developers build a valuable WeChat chatbot.

Currently we support the following puppet providers :

Protocol Puppet Provider Environment Variable
Web PuppetPuppeteer export WECHATY_PUPPET=wechaty-puppet-puppeteer
Windows PuppetWorkPro export WECHATY_PUPPET=wechaty-puppet-service
Mock PuppetMock export WECHATY_PUPPET=wechaty-puppet-mock
Web PuppetWechat4u export WECHATY_PUPPET=wechaty-puppet-wechat4u
iPad PuppetRock export WECHATY_PUPPET=wechaty-puppet-service
iPad PuppetPadLocal export WECHATY_PUPPET=wechaty-puppet-service
Windows PuppetDonut export WECHATY_PUPPET=wechaty-puppet-service
iPad PuppetPadpro DEPRECATED export WECHATY_PUPPET=wechaty-puppet-padpro
iPad PuppetPadchat DEPRECATED export WECHATY_PUPPET=wechaty-puppet-padchat
iPad PuppetPadplus DEPRECATED export WECHATY_PUPPET=wechaty-puppet-padplus
Mac PuppetMacpro DEPRECATED export WECHATY_PUPPET=wechaty-puppet-macpro
Windows PuppetWxwork DEPRECATED export WECHATY_PUPPET=wechaty-puppet-service

Learn more about Wechaty Puppet from the Puppet Wiki:

  1. Puppet Directory: https://github.com/Wechaty/wechaty-puppet/wiki/Directory
  2. Puppet Compatibility: https://github.com/Wechaty/wechaty-puppet/wiki/Compatibility

🎸 API

Read the Full Documentation at Wechaty Official API Reference

1 Class Wechaty

Main bot class.

A Bot is a Wechaty instance that control a specific wechaty-puppet.

Wechaty API Description
event login emit after bot login full successful
event logout emit after the bot log out
event friendship emit when someone sends bot a friend request
event message emit when there's a new message
event room-join emit when anyone join any room
event room-topic emit when someone change room topic
event room-leave emit when anyone leave the room
event room-invite emit when there is a room invitation
event scan emit when the bot needs to show you a QR Code for scanning
method start(): Promise<void> start the bot
method stop(): Promise<void> stop the bot
method logonoff(): boolean bot login status
method logout(): Promise<void> logout the bot
method currentUser(): ContactSelf get the login-ed bot contact
method say(text: string): Promise<void> let bot say text to itself

2 Class Contact

All wechat contacts(friends/non-friends) will be encapsulated as a Contact.

Contact API Description
static find(query: string): Promise<null | Contact> find contact by name or alias, if the result more than one, return the first one.
static findAll(query: string): Promise<Contact[]> find contact by name or alias
static load(query: string): Contact get contact by id
property id: readonly string get contact id
method sync(): Promise<void> force reload data for contact , sync data from lowlevel API again
method say(text: string): Promise<void | Message> send text, Contact, or file to contact, return the message which the bot sent (only puppet-padplus supported).
method self(): boolean check if contact is self
method name(): string get the name from a contact
method alias(): Promise<string> get the alias for a contact
method alias(newAlias: string): Promise<void> set or delete the alias for a contact
method friend(): boolean check if contact is friend
method type(): ContactType return the type of the Contact
method province(): string get the region 'province' from a contact
method city(): string get the region 'city' from a contact
method avatar(): Promise<FileBox> get avatar picture file stream
method gender(): ContactGender get gender from a contact

2.1 Class ContactSelf

Class ContactSelf is extended from Contact.

ContactSelf API Description
method avatar(file: FileBox): Promise<void> set avatar for bot
method qrcode(): Promise<string> get qrcode for bot
method signature(text: string): Promise<void> set signature for bot

2.2 Class Friendship

Send, receive friend request, and friend confirmation events.

Friendship API Description
static add(contact: Contact, hello?: string): Promise<void> send a friend invitation to contact
method accept(): Promise<void> accept Friend Request
method hello(): string get the hello string from a friendship invitation
method contact(): Contact get the contact from friendship
method type(): FriendshipType return the Friendship Type(unknown, confirm, receive, verify)

3 Class Message

All wechat messages will be encapsulated as a Message.

Message API Description
static find(query: string): Promise<null | Message> find message in cache and return the first one
static findAll(query: string): Promise<Message[]> find messages in cache, return a message list
method from(): Contact get the sender from a message
method to(): Contact get the destination of the message
method room(): null | Room get the room from the message.(If the message is not in a room, then will return null)
method text(): string get the text content of the message
method say(text: string): Promise<void | Message> reply a Text, Media File , or contact message to the sender, return the message which the bot sent (only puppet-padplus supported).
method type(): MessageType get the type from the message
method self(): boolean check if a message is sent by self
method mention(): Contact[] get message mentioned contactList.
method mentionSelf(): boolean check if a message is mention self
method forward(to: Contact): Promise<void> Forward the received message
method age(): number the number of seconds since it has been created
method date(): Date the time it was created
method toFileBox(): Promise<FileBox> extract the Media File from the Message, and put it into the FileBox.
method toContact(): Promise<Contact> get Share Card of the Message

4 Class Room

All wechat rooms(groups) will be encapsulated as a Room.

Room API Description
static create(contactList: Contact[], topic?: string): Promise<Room> create a new room
static find(query: string): Promise<null | Room> Try to find a room by filter. If get many, return the first one.
static findAll(query: string): Promise<Room[]> Find all contacts in a room
static load(query: string): Room load room by room id
property id: readonly string
event join emit when anyone join any room
event topic emit when someone change room topic
event leave emit when anyone leave the room
event invite emit when receive a room invitation
method sync(): <Promise<void> force reload data for room, sync data from lowlevel API again.
method say(text: string): Promise<void | Message> Send text,media file, contact card, or text with mention @mention contact inside Room, return the message which the bot sent (only puppet-padplus supported).
method add(contact: Contact): Promise<void> Add contact in a room
method del(contact: Contact): Promise<void> Delete a contact from the room
method quit(): Promise<void> Bot quit the room itself
method topic(): Promise<string> GET topic from the room
method topic(newTopic: string): Promise<void> SET topic from the room
method announce(text: string): Promise<void> SET/GET announce from the room
method qrcode(): Promise<string> Get QR Code of the Room from the room, which can be used as scan and join the room.
method alias(contact: Contact): Promise<string> Return contact's roomAlias in the room
method roomAlias(contact: Contact): Promise<string | null> Same as function alias
method has(contact: Contact): Promise<boolean> Check if the room has member contact
method memberAll(query?: string): Promise<Contact[]> Find all contacts or with specific name in a room
method member(query: string): Promise<null | Contact> Find all contacts in a room, if get many, return the first one.
method memberList():Promise<Contact[]> get all room member from the room
method owner(): null | Contact Get room's owner from the room.

4.1 Class RoomInvitation

Accept room invitation

RoomInvitation API Description
method accept(): Promise<void> accept Room Invitation
method inviter(): Contact get the inviter from room invitation
method roomTopic(): Promise<string> get the room topic from room invitation
method date(): Promise<Date> the time it was created
method age(): Promise<number> the number of seconds since it has been created

TEST

NPM Docker Coverage Status

Known Vulnerabilities

Wechaty is fully automatically tested by unit and integration tests, with Continious Integration & Continious Deliver(CI/CD) support powered by CI like Travis, Shippable and Appveyor.

To test Wechaty, run:

npm test

Get to know more about the tests from Wiki:Tests

CREATING WECHATY PLUGIN

Creating and publishing a Wechaty Plugin is simple. Simply expose your module as a function that takes 1 parameter: wechaty. When your plugin is imported by Wechaty, it will pass itself in as the argument, and so you are free to add any configuration that Wechaty supports.

import { WechatyPlugin } from 'wechaty'

export default const MyPlugin: WechatyPlugin = (wechaty: Wechaty) => {
  // ...
}

The config exist so the user can pass in customizations to your Plugin. In documenting your Wechaty Plugin, you would lay out your supported config for the user.

See:

  1. Wechaty Plugin Support with KickOut Example #1939
  2. Wechaty Plugins Contrib

📝 RELEASE NOTES

🎷 Views Since Feb 15, 2019

HitCount

💖 POWERED BY WECHATY

Powered by Wechaty

✨ Wechaty Badge

[![Powered by Wechaty](https://img.shields.io/badge/Powered%20By-Wechaty-brightgreen.svg)](https://wechaty.js.org)

Get more embed html/markdown code from Wiki:Badge

🌟 Projects Using Wechaty

  1. 一个用CNN深度神经网络给图片评分的wechaty项目
  2. Relay between Telegram and WeChat
  3. A chat bot managing the HaoShiYou wechat groups run by volunteers of haoshiyou.org
  4. An interactive chat bot to manage a TODO list
  5. Forward WeChat messages to telegram
  6. koa与wechaty实现的微信小助手,可定时提醒与发消息设定定时任务
  7. Wechaty Pay - 让线上没有难做的生意
  8. 开源社的微信机器人项目

Pull Request is welcome to add yours!

Learn more about Projects Using Wechaty at Wiki:Projects Using Wechaty

😇 Find a Good Server

The best practice for running Wechaty Docker/NPM is using a VPS(Virtual Private Server) outside of China, which can save you hours of time because npm install and docker pull will run smoothly without any problem.

The following VPS providers are used by the Wechaty team, and they worked perfectly in production. You can use the following link to get one in minutes. Also, doing this can support Wechaty because you are referred by us.

Location Price Ram Payment Provider
Singapore $5 512MB Paypal DigitalOcean
Japan $5 1GB Paypal Linode
Korea $10 1GB Alipay, Paypal Netdedi
Singapore $3.5 512MB Alipay, Wechat Vultr

🎶 See Also

💩 The Story

In 2017 ...

Huan's daily life/work depends on too much chat on wechat.

  • Almost 14,000 wechat friends in May 2014, before wechat restricts a total number of friends to 5,000.
  • Almost 400 wechat rooms, and most of them have more than 400 members.

Can you imagine that? He was dying...

So a tireless bot working for me 24x7 on wechat, monitoring/filtering the most important message is badly needed. For example, it highlights discussion which contains the KEYWORDS which he want to follow up(especially in a noisy room). ;-)

At last, It's built for huan's personal study purpose of Automatically Testing.

Stargazers over time

Stargazers over time

💕 Contributors

GitHub issues GitHub pull requests Open Collective Backers Open Collective Sponsors

contributor contributor contributor contributor contributor contributor contributor contributor

This project exists thanks to all the people who contribute. [Contribute].


Contribute

😎 Backers

Backers on Open Collective

Thank you to all our backers! 🙏 [Become a backer]

Open Collective Wechaty

😏 Sponsors

Sponsors on Open Collective

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]

Wechaty Sponsor

Multi-language Wechaty

Python Wechaty Go Wechaty Java(Kotlin) Wechaty Scala Wechaty PHP Wechaty .NET(C#) Wechatyin

History

main v1.11 (Nov 22, 2021)

Working on reduxify the Wechaty ecosystem for applying the CQRS pattern.

v1.10 (Nov 21, 2021)

Second beta release of Wechaty, with all ecosystem npm modules with version v1.10 (wechaty-puppet, wechaty-puppet-service, etc)

v1.0 (Sep 2021)

  • Release v1.0 of Wechaty is the first beta release of Wechaty.

v0.69

  1. v0.69: Supports ES Modules (with CJS dual support) (#2232)

v0.68 (Aug 27, 2021)

  1. TLS support (#2231)
  2. The latest CommonJS version

Creators

  1. Huan (LinkedIn), 🐧 Tencent TVP of Chatbot・🤖 Chatie Architect・⭐️ GitHub Star・🚀 YC W19・🌐 Microsoft RD & AI MVP・🦾 Google ML GDE ・🤠 Serial Entrepreneur・🔥 Burner
  2. Rui (李佳芮), Microsoft AI MVP & RD, Co-founder & CEO of Juzi.BOT (YC W19 Alumni)

Profile of Huan Li on StackOverflow

Cite Wechaty

To cite this project in publications:

@misc{Wechaty,
  author = {Huan Li, Rui Li},
  title = {Wechaty: Conversational SDK for Chatbot Makers},
  year = {2016},
  publisher = {GitHub},
  journal = {GitHub Repository},
  howpublished = {\url{https://github.com/wechaty/wechaty}},
}

Copyright & License

  • Code & Docs © 2016-now Huan, Rui, and Wechaty Community Contributors
  • Code released under the Apache-2.0 License
  • Docs released under Creative Commons

wechaty's People

Contributors

christianzzz avatar dchaofei avatar gcaufy avatar greenkeeper[bot] avatar greenkeeperio-bot avatar hcfw007 avatar hczhcz avatar hiwanz avatar huan avatar imerse avatar iyjian avatar jaslin avatar jzj1993 avatar kis87988 avatar leochen-g avatar lijiarui avatar linuxsuren avatar mukaiu avatar plainheart avatar satouriko avatar silentqianyi avatar snyk-bot avatar su-chang avatar suntong avatar taoxincn avatar tbht avatar windmemory avatar xinbenlv avatar xquotes avatar zhaoic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wechaty's Issues

function sendMessage error

hi,

I use function sendMessage after accept friend request,
when the new friend request and the bot not in the same network, the program stopped and has error.

while if the new friend request and the bot are in the same network, it can work well

error log as follows:

WARN PuppetWebBrowser execute() exception: unknown error: r.isBrandContact is not a function
(Session info: chrome=53.0.2785.143)
(Driver
WARN PuppetWebBridge execute() exception: unknown error: r.isBrandContact is not a function
(Session info: chrome=53.0.2785.143)
(Driver info: chromedriver=2.24.417412 (ac882d3ce7c0d99292439bf3405780058fcca0a6),platform=Mac OS X 10.11.6 x86_64)
WARN PuppetWebBridge proxyWechaty() exception: unknown error: r.isBrandContact is not a function
(Session info: chrome=53.0.2785.143)
(Driver info: chromedriver=2.24.417412 (ac882d3ce7c0d99292439bf3405780058fcca0a6),platform=Mac OS X 10.11.6 x86_64)
ERR PuppetWebBridge send() exception: unknown error: r.isBrandContact is not a function
(Session info: chrome=53.0.2785.143)
(Driver info: chromedriver=2.24.417412 (ac882d3ce7c0d99292439bf3405780058fcca0a6),platform=Mac OS X 10.11.6 x86_64)
ERR PuppetWeb send() exception: unknown error: r.isBrandContact is not a function
(Session info: chrome=53.0.2785.143)
(Driver info: chromedriver=2.24.417412 (ac882d3ce7c0d99292439bf3405780058fcca0a6),platform=Mac OS X 10.11.6 x86_64)
ERR Wechaty send() exception: unknown error: r.isBrandContact is not a function
(Session info: chrome=53.0.2785.143)
(Driver info: chromedriver=2.24.417412 (ac882d3ce7c0d99292439bf3405780058fcca0a6),platform=Mac OS X 10.11.6 x86_64)
/Users/lijiarui/git/wechaty/node_modules/selenium-webdriver/lib/promise.js:2291
throw error;
^

WebDriverError: unknown error: r.isBrandContact is not a function
(Session info: chrome=53.0.2785.143)
(Driver info: chromedriver=2.24.417412 (ac882d3ce7c0d99292439bf3405780058fcca0a6),platform=Mac OS X 10.11.6 x86_64)
at WebDriverError (/Users/lijiarui/git/wechaty/node_modules/selenium-webdriver/lib/error.js:27:5)
at Object.checkLegacyResponse (/Users/lijiarui/git/wechaty/node_modules/selenium-webdriver/lib/error.js:505:15)
at parseHttpResponse (/Users/lijiarui/git/wechaty/node_modules/selenium-webdriver/lib/http.js:398:13)
at doSend.then.response (/Users/lijiarui/git/wechaty/node_modules/selenium-webdriver/lib/http.js:330:11)
at process.tickCallback (internal/process/next_tick.js:103:7)
From: Task: WebDriver.executeScript()
at Driver.schedule (/Users/lijiarui/git/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:414:17)
at Driver.executeScript (/Users/lijiarui/git/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:563:16)
at Browser.execute (/Users/lijiarui/git/wechaty/src/puppet-web/browser.js:437:38)
at Bridge.execute (/Users/lijiarui/git/wechaty/src/puppet-web/bridge.js:346:32)
at execute.then.then (/Users/lijiarui/git/wechaty/src/puppet-web/bridge.js:332:19)
at ManagedPromise.invokeCallback
(/Users/lijiarui/git/wechaty/node_modules/selenium-webdriver/lib/promise.js:1303:14)
at TaskQueue.execute_ (/Users/lijiarui/git/wechaty/node_modules/selenium-webdriver/lib/promise.js:2731:14)
at TaskQueue.executeNext_ (/Users/lijiarui/git/wechaty/node_modules/selenium-webdriver/lib/promise.js:2714:21)
at asyncRun (/Users/lijiarui/git/wechaty/node_modules/selenium-webdriver/lib/promise.js:2584:27)

before use sendMessage, the log shows, the parameter isn't null

INFO Bot sendMessage(Class Wechaty(web), {content: hi,我是桔子蜜,最好用的微信群助手,回复1,加入测试1群,回复2,加入测试2群, to: @323bce54d6559e43a712796d14340d68, room: null})

be careful about the `unofficial client` check and report (in browser)

TL;DR

when we inject our hooking code to https://wx.qq.com , we should keep the environment as clean as possible.


there has javascript code in wx.qq.com, which will check the run environment to see if had been modified: for example, the checksum of the whole angularjs object.

when we inject some code to https://wx.qq.com , we should keep the environment as clean as possible. because if a user account is reported using an unofficial client, the system might add some extra limitation to this account, for example, this account can not "say hi" to other strangers. (as the following screen shot, I think it's purpose is to prevent spamming other users by robot)

wechat-unofficial-client-warning
wechat-moments-disabled-hooltool

TODO

  • disable API_webwxreport: "/cgi-bin/mmwebwx-bin/webwxstatreport"

See

  1. 揭秘“微信群控” - 微信安全中心

element_wrong----contact.get('name') got room name not contact name

when I use Message Event as follows:

.on('message', m => {
m.ready()
.then(msg => {
const contact = m.from()

the event happens in the chatroom

I use Class Contact function as follows:

contact.get('name')

refer your document:
https://github.com/wechaty/wechaty#class-contact

but I got the room name not the contact name.

I print contact, the log as follows:

Contact {
id: '@@c728bd50281d791a174968892264afb04abb9d845e00c1e919274ccaff6bcb41',
obj:
{ id: '@@c728bd50281d791a174968892264afb04abb9d845e00c1e919274ccaff6bcb41',
uin: 0,
weixin: '',
* name: 'test1',*

while, when i use the same function not in room, all the things works well
I print contact, the log as follows:

Contact {
id: '@3ed374e169fd41e4f809bc1784967f80',
obj:
{ id: '@3ed374e169fd41e4f809bc1784967f80',
uin: 0,
weixin: 'ruirui_0914',
name: '芮芮',

I guess the element you define in the Contact when in a room may wrong.

thanks

Wechaty account logout unexpectedly

Description

Since account login successfully, wechaty run in Ubuntu Server, but after several hours, the account logout unexpectedly.

Trace


^[[31m[2016-10-06 22:19:26.753] [ERROR] console - ^[[39mERR PuppetWebServer initEventsFromClient() client on error: TypeError: Cannot read property 'bridge' of undefined
    at new MediaMessage (/root/git/chatbot-mvp/philly-wechat/node_modules/wechaty/src/message-media.js:18:33)
    at PuppetWeb.onServerMessage (/root/git/chatbot-mvp/philly-wechat/node_modules/wechaty/src/puppet-web/event.js:365:11)
    at emitOne (events.js:96:13)
    at Server.emit (events.js:188:7)
    at Socket.client.on.data (/root/git/chatbot-mvp/philly-wechat/node_modules/wechaty/src/puppet-web/server.js:149:14)
    at emitOne (events.js:96:13)
    at Socket.emit (events.js:188:7)
    at Socket.onevent (/root/git/chatbot-mvp/philly-wechat/node_modules/socket.io/lib/socket.js:335:8)
    at Socket.onpacket (/root/git/chatbot-mvp/philly-wechat/node_modules/socket.io/lib/socket.js:295:12)
    at Client.ondecoded (/root/git/chatbot-mvp/philly-wechat/node_modules/socket.io/lib/client.js:193:14)
^[[32m[2016-10-06 22:19:26.755] [INFO] console - ^[[39mINFO Bot 小白 logouted
^[[32m[2016-10-06 22:20:12.745] [INFO] console - ^[[39mINFO Bot error: [object Object]
^[[33m[2016-10-06 22:20:12.893] [WARN] console - ^[[39mWARN PuppetWebEvent onBrowserDead() will not init browser because browser.targetState(close) !== open

image

Is it a bug? Or what is the solution to keep it steady?
One solution is auto restart when getting crash.

Session Cookies not loaded correctly?

I'm trying to develop using nodemon, so my node process is restarting frequently. I wanted to use the profile option so I don't need to scan the QR every time it restarts. I am using the sample 7 line script.

I initialize like this:

const profile = 'dax.wechaty.json';
const bot = new Wechaty({ profile });

I get the following errors upon restart:

ERR! PuppetWebBrowser loadSession() addCookies() exception: {"errorMessage":"Can only set Cookies for the current domain","request":{"headers":{"Accept":"application/json; charset=utf-8","Connection":"close","Content-Length":"99","Content-Type":"application/json;charset=UTF-8","Host":"[REDACTED]:65121"},"httpVersion":"1.1","method":"POST","post":"{\"cookie\":{\"name\":\"pgv_si\",\"value\":\"[REDACTED]\",\"path\":\"/\",\"domain\":\".wechat.com\",\"secure\":false}}","url":"/cookie","urlParsed":{"anchor":"","query":"","file":"cookie","directory":"/","path":"/cookie","relative":"/cookie","port":"","host":"","password":"","user":"","userInfo":"","authority":"","protocol":"","source":"/cookie","queryKey":{},"chunks":["cookie"]},"urlOriginal":"/session/[REDACTED]/cookie"}}

[REDACTED] contains the (seemingly) correct session info.

Am I doing something wrong?

Can't get wechaty up and running using phantomjs

I'm using the latest branch. While executing

WECHATY_HEAD=phantomjs ts-node example/ding-dong-bot.ts

it complains:

INFO Wechaty v#git[bdac338 BREAKING CHANGE: `room-join`/`room-leave`/`join`/`leave` events now only emit `contactList: Contact[]` as params. no `contact: Contact` anymore.] initializing...
WARN PuppetWebBrowser execute() exception: {"errorMessage":"Unexpected token ','","request":{"headers":{"Accept":"application/json; charset=ut
...
WARN PuppetWebBrowser driver() exception: no driver

Did I miss something?

test/fix Watchdog with browser dead & timeout conditions

  • browser be killed during init
  • browser be killed after init
  • WechatyBro injection fail
  • WechatyBro init() fail
  • WechatyBro heartbeat lost
  • Wx App died during scan/login(not fire events any more)
  • Wx App died after scan/login(not fire events any more)

etc...

room-join 事件下,无法通过contact.id 方法获取contact_id

Please run npm run doctor and paste the output here

Wechaty Doctor

  1. Wechaty version: #git[fe60b3c code clean]
  2. Darwin x64 version 15.6.0 memory 4 GB
  3. Docker: false

Expected behavior

触发room-join event 时,获取当前机器人的contact.id

代码如下:

.on('room-join', (room, invitee, inviter) => {
  const user = bot.user()
  console.log(user.id)
})

Actual behavior

运行报错:

orangiss/testfun.ts(31,15): Object is possibly 'null'. (2531)

处理办法:

检查发现,虽然console.log(user.id)会运行报错,但是console.log(user)可以正常显示user内容。
user类型为Contact,理论上Contact.id 是可以成功获取到id的,但是在room-join事件触发时不可以。

进一步将代码修改为:

console.log((user as any).id)

可以成功的运行并获取到user.id

希望可以修复此bug。

Error `Object is possibly 'null'. (2531)` with TypeScript

@#### Wechaty Doctor

Wechaty version: #git[cd7c7dd log for #55]
Darwin x64 version 15.6.0 memory 38/4096 MB
Docker: false

when I try to use the function Room.member(name: string) and Room.has(contact Contact), I can't run wechaty.

the code as follows:

.on('message', m => {
  m.ready()
  .then(msg => {
    const sender  = m.from()
    const msgRoom = m.room()
     if(msgRoom.member("芮芮")){   
       msgRoom.del(msgRoom.member("芮芮"))
     }
...

the error log as follows:

/Users/lijiarui/git/wechaty/node_modules/ts-node/src/index.ts:308
throw new TSError(diagnosticList)
^
TSError: ⨯ Unable to compile TypeScript
orangiss/juzimi.ts (293,18): Object is possibly 'null'. (2531)
orangiss/juzimi.ts (294,17): Object is possibly 'null'. (2531)
orangiss/juzimi.ts: Emit skipped
at getOutput (/Users/lijiarui/git/wechaty/node_modules/ts-node/src/index.ts:308:17)
at /Users/lijiarui/git/wechaty/node_modules/ts-node/src/index.ts:334:18
at Object.compile (/Users/lijiarui/git/wechaty/node_modules/ts-node/src/index.ts:488:17)
at Module.m._compile (/Users/lijiarui/git/wechaty/node_modules/ts-node/src/index.ts:392:44)
at Module._extensions..js (module.js:550:10)
at Object.require.extensions.(anonymous function) as .ts
at Module.load (module.js:458:32)
at tryModuleLoad (module.js:417:12)
at Function.Module._load (module.js:409:3)

npm ERR! Darwin 15.6.0
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "run" "ts-node" "orangiss/juzimi.ts"
npm ERR! node v6.2.0
npm ERR! npm v3.8.9
npm ERR! code ELIFECYCLE
npm ERR! [email protected] ts-node: ts-node "orangiss/juzimi.ts"
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] ts-node script 'ts-node "orangiss/juzimi.ts"'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the wechaty package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! ts-node "orangiss/juzimi.ts"
npm ERR! You can get information on how to open an issue for this project with:
npm ERR! npm bugs wechaty
npm ERR! Or if that isn't available, you can get their info via:
npm ERR! npm owner ls wechaty
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR! /Users/lijiarui/git/wechaty/orangiss/npm-debug.log

when I try the code as follows, it works!

.on('message', m => {
  m.ready()
  .then(msg => {
    const sender  = m.from()
    const msgRoom = m.room()
     if((msgRoom as any).member("芮芮")){   
        (msgRoom as any).del((msgRoom as any).member("芮芮"))       
     }
...

Thanks!

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

Problem

When we want to send message, we need to use Wechaty.send().

If you send a lot, you will feel it a bit complicated:

const m = new Message()
m.room(room)
m.to(contact)
m.content('@' + contact.name() + ' hello')

wechaty.send(m)

It's complicated because:

  1. we have to instanciated a Message class handly
  2. we have to construct the content string for mention someone
  3. we have to get instance of Wechaty for call send(), sometimes the only way to get it is from a global variable.

Solution

Then I decide to create a new method: say(content: string, replyTo?: Contact|Contact[]): void

say() will exist in the following instances:

  1. Room instance: room.say()
  2. Message instance: msg.say()
  3. Contact instance: contact.say()
  4. this inside some of Wechaty global events callback(which has no room/message/contact instance to call say):
    1. error event callback
    2. heartbeat event callback
    3. login event callback
    4. logout event callback
    5. scan event callback

Be aware of say(content: string) inside events callback, what they behave is:

  1. If wechaty is not login yet, the only latest content will be stored, for to be sent after login.
  2. content will be send to filehelper, just for convenience logging.

WARN PuppetWebBridge init() inject FINAL fail

I met a problem when running the demo ding-dong bot on my mac.
Here is the console log

✘ programath@wentuopudeMaxBook-Air ⮀ ~/wechaty ⮀ ⭠ master ● ⮀ node example/ding-dong-bot.js

| __ __ _ _
| \ \ / /__ | | __ | | _ _
| \ \ /\ / / _ / **| '
\ / ` | __| | | |
| \ V V / __/ (**| | | | (
| | || || |
| _// **|**|| ||__,||, |
| |___/

=============== Powered by Wechaty ===============
-------- https://github.com/zixia/wechaty --------

I'm a bot, my super power is talk in Wechat.

If you send me a 'ding', I will reply you a 'dong'!


Hope you like it, and you are very welcome to
upgrade me for more super powers!

Please wait... I'm trying to login in...

info Wechaty v0.3.9 initializing...
undefined
WARN PuppetWebBridge init() inject FINAL fail: execute proxyWechaty(init) error: 503, init() without a ready angular env
ERR! PuppetWeb initBridge() exception: execute proxyWechaty(init) error: 503, init() without a ready angular env
ERR! PuppetWeb init exception: execute proxyWechaty(init) error: 503, init() without a ready angular env
ERR! Wechaty init() exception: execute proxyWechaty(init) error: 503, init() without a ready angular env
ERR! Bot Error: execute proxyWechaty(init) error: 503, init() without a ready angular env
ERR! Bot at Bridge. (/Users/programath/wechaty/src/puppet-web/bridge.js:84:15)
ERR! Bot at next (native)
ERR! Bot at onFulfilled (/Users/programath/wechaty/node_modules/co/index.js:65:19)
ERR! Bot at ManagedPromise.invokeCallback_ (/Users/programath/wechaty/node_modules/selenium-webdriver/lib/promise.js:1315:14)
ERR! Bot at TaskQueue.execute_ (/Users/programath/wechaty/node_modules/selenium-webdriver/lib/promise.js:2736:14)
ERR! Bot at TaskQueue.executeNext_ (/Users/programath/wechaty/node_modules/selenium-webdriver/lib/promise.js:2719:21)
ERR! Bot at asyncRun (/Users/programath/wechaty/node_modules/selenium-webdriver/lib/promise.js:2595:27)
ERR! Bot at /Users/programath/wechaty/node_modules/selenium-webdriver/lib/promise.js:639:7
ERR! Bot at process.tickCallback (internal/process/next_tick.js:103:7)
ERR! Bot init() fail: %s Error: execute proxyWechaty(init) error: 503, init() without a ready angular env
ERR! Bot at Bridge. (/Users/programath/wechaty/src/puppet-web/bridge.js:84:15)
ERR! Bot at next (native)
ERR! Bot at onFulfilled (/Users/programath/wechaty/node_modules/co/index.js:65:19)
ERR! Bot at ManagedPromise.invokeCallback
(/Users/programath/wechaty/node_modules/selenium-webdriver/lib/promise.js:1315:14)
ERR! Bot at TaskQueue.execute_ (/Users/programath/wechaty/node_modules/selenium-webdriver/lib/promise.js:2736:14)
ERR! Bot at TaskQueue.executeNext_ (/Users/programath/wechaty/node_modules/selenium-webdriver/lib/promise.js:2719:21)
ERR! Bot at asyncRun (/Users/programath/wechaty/node_modules/selenium-webdriver/lib/promise.js:2595:27)
ERR! Bot at /Users/programath/wechaty/node_modules/selenium-webdriver/lib/promise.js:639:7
ERR! Bot at process._tickCallback (internal/process/next_tick.js:103:7)

The version of node is v6.4.0 and npm is 3.10.3
Can you tell me what's going wrong?

Suggest give an api to get url

hi
I want to get url in Message, I print message and find url in Message.rawOby.Url. But i can't use m.rawObj.Url to get Url

than I use (m.rawObj as any).Url to get Url

I suggest you can give an api for us to get Url if you have time.

thanks!

[New Feature] Bot.reply with audio and image

Description

Now, bot.reply can only send text message. But more rich user story can be done with audio and picture.
So, I suggest wechaty support reply with multi media messages.

How to Install & Run Wechaty in Linux Server

Steps:

1.install nvm:

curl https://raw.githubusercontent.com/creationix/nvm/v0.11.1/install.sh | bash

2.install node

nvm install 6
nvm alias default 6

3.install git and clone repo

sudo apt-get install git
git clone https://github.com/wechaty/wechaty.git

4.install google chrome for debian

sudo apt-get update
sudo apt-get install libxss1 libappindicator1 libindicator7
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo dpkg -i google-chrome*.deb
sudo apt-get install -f

5.wechaty operation:

cd wechaty
npm install
cd script
bash xvfb.sh
export DISPLAY=':99.0'

6.run wechaty:

go back wechaty directory

cd example
npm run ts-node example/ding-dong-bot.ts

then run wechaty successfuly:

image

webdriver.executeScript wait a long time(26s) before page load

It seems that webdriver always wait browser window to be stable before run executeScript.

the condition of stable is set to be like this:

window.document.readyState === 'complete'

But...

If we have a ajax call / http long pulling / etc, the readyState will be interactive for a long time.

Solution(?)

make webdrive wait only for readyState is loading

See Also

  1. How to executeScript before page load by WebDriver in selenium? https://stackoverflow.com/questions/37071807/how-to-executescript-before-page-load-by-webdriver-in-selenium
  2. A ghost driver on phantomjs quick & dirty patch https://github.com/detro/ghostdriver/issues/334#issuecomment-41361564
  3. Attempt to make selenium tests more reliable https://github.com/18F/calc/pull/267
  4. PhantomJS 1.9 has introduced resourceTimeout

PhantomJS Log

When waiting, it output lots of logs like this:

[DEBUG - 2016-08-07T10:21:57.754Z] Session [b69451a0-5c88-11e6-bed4-fb6eca6b39c0] - _execFuncAndWaitForLoadDecorator - Page Loading in Session: true

PhantomJS Code

Do not know what SIGNAL is, what SLOT is...

https://github.com/ariya/phantomjs/blob/096d0da87ee6d94f3eed84446c0eb5176566d54a/src/webpage.cpp#L396

GhostDriver Code

https://github.com/detro/ghostdriver/blob/f976007a431e634a3ca981eea743a2686ebed38e/src/session.js#L233

maybe change _isLoading() to this?

    /**
     * Is any window in this Session Loading?
     * @returns "true" if at least 1 window is loading.
     */
    _isLoading = function() {
        var wHandle;

        for (wHandle in _windows) {
//            if (_windows[wHandle].loading) {
            if (_windows[wHandle].document.readyState) === 'loading')
                return true;
            }
        }

        // If we arrived here, means that no window is loading
        return false;
    }

[New Feature] Room.{create,addMember,delMember,quit,modTopic} support

according to the original issue #14

Room Factory of WxApp

type ChatroomResponse {
  BaseResponse: {
    Ret: number
  }
  , ChatRoomName: string
}

class chatroomFactory {
  create(e: userId[]): Promise<{BaseResponse.Ret:number}>

  addMember(roomId, userList: UserName[].join(','), cb: ({BaseResponse.Ret:number}) => void )
  delMember(roomId, userList: string)
  quit(roomId) // un-implenment?
  modTopic(roomId, newTopic)
}

type ContactQuery = {
  filterContacts: UserName[]
  , noHeader: boolean
  , showFriendHeader: boolean
  , isWithoutStar: boolean
  , isWithoutBrand: boolean 
  , isSaved: boolean
}

type PickQuery = {
  all?: ContactQuery
  , friend?: ContactQuery
  , star?: ContactQuery
  , brand?: ContactQuery
}

class contactFactory {
  pictContacts(typeList: string[], query: PickQuery, clone: boolean): Contact[]
  getAllChatroomContact(query: ContactQuery)
  getAllFriendContact(query: ContactQuery)
  getContact(query: ContactQuery)
}

Room Class of Wechaty

type Query = { name: string|Regex }
Room.find(query : Query) : Room | null
Room.findAll(query : Query) : Room[]

1. static Room.find(query: Query): Promise<Room|null>

2. static Room.findAll(query: Query): Promise<Room[]>

3. static Room.create(contactList: Contact[]): Promise

4. Room.add(contact: Contact): Promise

const friend = message.get('from')
const room = Room.find({ name: 'Group Name' })
if (room) {
  room.add(friend)
}

5. Room.del(contact: Contact): void

6. Room.topic(newTopic?: string): string

7. Room.nick(contact: Contact): string

8. Room.has(contact Contact): boolean

10. Room.on('join', (invitee, inviter) => void)

Event join: Room New Member

room.on('join', (invitee, inviter) => {
  console.log(`user ${invitee} joined the room ${room}, invited by ${inviter}`)
})

11. Room.on('leave', (leaver) => void)

12. Room.refresh(): Promise

13. Room.owner(): Contact|null

14. Room.member(name: string): Contact|null

[New Feature] FriendRequest class and event

according to #14

WxApp

class contactFactory {
  verifyUser({
      UserName: string
      , Opcode: confFactory.VERIFYUSER_OPCODE_VERIFYOK
      , Scene: confFactory.ADDSCENE_PF_WEB
      , Ticket: Ticket
      , VerifyContent: string
  })
}

type RecommendInfo = {
  UserName: string
  NickName: string
  Content:     string // request message
  Ticket:         string // a pass token
  VerifyFlag:  number
}

interface Message = {
  RecommendInfo: RecommendInfo
}

Wechaty Class FriendRequest

  1. send request to other
  2. receive request from other(in friend event)
class FriendRequest {
  private info: RecommentInfo
  private hello: string
  private ticket: string

  private contact: Contact

  constructor(): FriendRequest

  send(contact: string|Contact, hello?: string): Promise<any> // 1. send friend request to other
  receive(info?: RecommendInfo): FriendRequest    // 2. receive request from other

  accept(): Promise<any>
}

Interface Wechaty {
  on('friend', (contact: Contact, request: FriendRequest) => void): void
}

Add Friend / Send Friend Request

accept friend requirest interface should be like this:

const sender : Contact = message.get('from')
const fr = new FriendRequest()
fr.send(sender, 'hello~')

Event: Friend Request

  1. Receive New Friend Request
  2. Confirmation of FriendShip

friend request is a message from SP_CONTACT_RECOMMEND_HELPER: "fmessage", with type Message.Type.VERIFYMSG

in PuppetWeb.onServerMessage():

if (message.MsgType === MSGTYPE_VERIFYMSG) {
  const request = new FriendRequest()
  request.receive(message.RecommendInfo)
  emit('friend', request.contact, request)
}

// Be Accepted: I've accepted your friend request. Now let's chat!
// Accept: You have added ${NickName} as your WeChat contact. Start chatting!
case Message.Type.SYS:
if (/^You have added (.+) as your WeChat contact. Start chatting!$/.test(m.get('content'))) {
const request = new FriendRequest()
  const contact = Contact.load(m.get('from'))
  request.confirm(contact)

  this.emit('friend', contact)
}

then we can:

wechaty.on('friend', (contact, request) => {
  if (request) { // 1. we got new request
    if (/secret/.test(request.hello)) {
      request.accept()
    }
  } else { // 2. we got new friend
    console.log('got new friend: ' + contact)
  }
})

TSError: ⨯ Unable to compile TypeScript src/puppet-web/event.ts (120,12): Type 'PuppetWeb' is not assignable to type 'void'. (2322)

0 info it worked if it ends with ok
1 verbose cli [ '/Users/liujiaan/.nvm/versions/node/v6.7.0/bin/node',
1 verbose cli '/Users/liujiaan/.nvm/versions/node/v6.7.0/bin/npm',
1 verbose cli 'run',
1 verbose cli 'demo' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'predemo', 'demo', 'postdemo' ]
5 info lifecycle [email protected]predemo: [email protected]
6 silly lifecycle [email protected]
predemo: no script for predemo, continuing
7 info lifecycle [email protected]demo: [email protected]
8 verbose lifecycle [email protected]
demo: unsafe-perm in lifecycle true
9 verbose lifecycle [email protected]demo: PATH: /Users/liujiaan/.nvm/versions/node/v6.7.0/lib/node_modules/npm/bin/node-gyp-bin:/Users/liujiaan/wechaty/node_modules/.bin:/Users/liujiaan/.nvm/versions/node/v6.7.0/bin:/Users/liujiaan/.nvm/versions/node/v6.7.0/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/aria2/bin:/Applications/Server.app/Contents/ServerRoot/usr/bin:/Applications/Server.app/Contents/ServerRoot/usr/sbin
10 verbose lifecycle [email protected]
demo: CWD: /Users/liujiaan/wechaty
11 silly lifecycle [email protected]demo: Args: [ '-c', 'ts-node example/ding-dong-bot.ts' ]
12 silly lifecycle [email protected]
demo: Returned: code: 1 signal: null
13 info lifecycle [email protected]~demo: Failed to exec demo script
14 verbose stack Error: [email protected] demo: ts-node example/ding-dong-bot.ts
14 verbose stack Exit status 1
14 verbose stack at EventEmitter. (/Users/liujiaan/.nvm/versions/node/v6.7.0/lib/node_modules/npm/lib/utils/lifecycle.js:242:16)
14 verbose stack at emitTwo (events.js:106:13)
14 verbose stack at EventEmitter.emit (events.js:191:7)
14 verbose stack at ChildProcess. (/Users/liujiaan/.nvm/versions/node/v6.7.0/lib/node_modules/npm/lib/utils/spawn.js:40:14)
14 verbose stack at emitTwo (events.js:106:13)
14 verbose stack at ChildProcess.emit (events.js:191:7)
14 verbose stack at maybeClose (internal/child_process.js:877:16)
14 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5)
15 verbose pkgid [email protected]
16 verbose cwd /Users/liujiaan/wechaty
17 error Darwin 16.0.0
18 error argv "/Users/liujiaan/.nvm/versions/node/v6.7.0/bin/node" "/Users/liujiaan/.nvm/versions/node/v6.7.0/bin/npm" "run" "demo"
19 error node v6.7.0
20 error npm v3.10.3
21 error code ELIFECYCLE
22 error [email protected] demo: ts-node example/ding-dong-bot.ts
22 error Exit status 1
23 error Failed at the [email protected] demo script 'ts-node example/ding-dong-bot.ts'.
23 error Make sure you have the latest version of node.js and npm installed.
23 error If you do, this is most likely a problem with the wechaty package,
23 error not with npm itself.
23 error Tell the author that this fails on your system:
23 error ts-node example/ding-dong-bot.ts
23 error You can get information on how to open an issue for this project with:
23 error npm bugs wechaty
23 error Or if that isn't available, you can get their info via:
23 error npm owner ls wechaty
23 error There is likely additional logging output above.
24 verbose exit [ 1, true ]

是我环境有问题吗?刚运行成功了,但是想要再运行api-ai-bot.ts的时候,不知怎么就不行了.重新clone也不行

[Upgrade to v0.5] Convert code base to Typescript from Javascript

It's in my mind for months.

  • rename .js to .ts
  • setup tsconfig.json
  • fix tsc error
  • fix tslint error
  • run examples/*-bot.ts & fix
  • hacking ava to support run typescript natively by adding a --ext ts arg
  • run tests/**/*.spec.ts & fix

Typescript will benefit us as the following:

  1. enable circular dependency between modules
  2. better async coding style: async/await (now we use co module)
  3. strong type definition/checking for data structure
  4. auto completion/static syntax check with vscode ide
  5. static variable with initializing inside class
  6. public/private setting for methods/member variables
  7. other benefits...

after converted, there will be different if you:

  1. use the master code base directly. solution: use ts-node instead of node, and write your code with typescript.
  2. study typescript and setup typescript environment.

there will be no different if you:

  • use npm module to require('wechaty'). you can use javascript as before because typescript will be compiled to javascript before publish.

The lastest javascript version is: v0.4.0

Reference

  1. The Future of Declaration Files
  2. What's new in TypeScript
  3. export default can lead to problems

[New Feature] Contact.{tag,star,remark,find,findAll}

update 2016-10-17: there's no api for star/tag in web api. we can only do remark name by api.

according to #14

Contact : {
  remark() : string
  remark(string) : string
}

type TagInfo = { any: boolean }
tag() : string[]
tag(tags: TagInfo): string[]
star() : boolean
star(boolean) : boolean
static findByTag(tags: TagInfo)
static findByStar()

Tag / Star / Remark Contact

const contact = Contact.load(message.get('from'))
contact.remark('Remark Memo Name')

contact.tag({tag1: true})
contact.tag({tag1: false})
contact.tag() : string[]
contact.star(true)
contact.star(false)
contact.star() : boolean

Find Contact

const contact = Contact.findByTag({tag1: true})
const starContacts = Contact.findByStar()

FriendRequest is not export to npm module

i'am trying v0.4.0 with npm install

how to get a FriendRequest instance while using require('wechaty') ?

const {Wechaty,Room,Contact,FriendRequest} = require('wechaty')

FriendRequest is undefined

i'am testing the following code.

const sender : Contact = message.get('from')
const fr = new FriendRequest()
fr.send(sender, 'hello~')

近期wechaty启动失败次数较多

更新后的代码,启动wechaty会出现错误

关闭代理、清除json文件后,依然启动失败,程序卡死。

多试几次后,可以成功跑通。

具体日志如下:

lijiaruideMacBook-Air:orangiss lijiarui$ WECHATY_LOG=silly npm run ts-node orangiss/testfun.ts

[email protected] ts-node /Users/lijiarui/git/wechaty
ts-node "orangiss/testfun.ts"

VERB Brolog WECHATY_LOG set level to silly
VERB Wechaty contructor()
VERB Wechaty on(login, function)
VERB Wechaty on(logout, function)
VERB Wechaty on(error, function)
VERB Wechaty on(scan, function)
VERB Wechaty on(room-join, function)
VERB Wechaty on(room-leave, function)
VERB Wechaty on(room-topic, function)
VERB Wechaty on(message, function)
INFO Wechaty v#git[6a400a2 #52 add chinese friend confirm message] initializing...
VERB Wechaty puppet: web
VERB Wechaty head: chrome
VERB Wechaty profile: TestFun.wechaty.json
VERB Wechaty uuid: 4e6c9108-4287-4b76-be10-ed6e3258abcb
VERB Puppet targetState(dead)
VERB Puppet currentState(dead)
VERB PuppetWeb init() with head:chrome, profile:TestFun.wechaty.json
VERB Puppet targetState(live)
VERB Puppet currentState(birthing)
VERB UtilLib getPort(18788)
VERB UtilLib getPort(18788) return: 19005
VERB PuppetWeb init() getPort 19005
VERB PuppetWeb initServer()
VERB PuppetWebServer init() on port 19005
VERB PuppetWebServer createHttpsServer() listen on port 19005
VERB PuppetWebServer init()-ed
VERB PuppetWeb initServer() done
VERB PuppetWeb initBrowser()
VERB PuppetWebBrowser constructor() with head(chrome) sessionFile(TestFun.wechaty.json)
VERB PuppetWebBrowser targetState(close)
VERB PuppetWebBrowser currentState(close)
VERB PuppetWebBrowser targetState(open)
VERB PuppetWebBrowser currentState(opening)
VERB PuppetWebBrowser initDriver(head: chrome)
VERB PuppetWebBrowser getChromeDriver()
VERB PuppetWebBrowser open(https://wx.qq.com/zh_CN/htmledition/v2/images/webwxgeticon.jpg)
VERB PuppetWebBrowser loadSession(TestFun.wechaty.json)
SILL PuppetWebBrowser dead() checking ...
SILL PuppetWebBrowser dead() checking ...
SILL PuppetWebBrowser dead() checking ...
SILL PuppetWebBrowser addCookies({"domain":".wx.qq.com","expiry":1476928227,"httpOnly":false,"name":"wxsid","path":"/","secure":false,"value":"Y+Tkp+m7jO0X+AIf"})
SILL PuppetWebBrowser dead() checking ...
SILL PuppetWebBrowser addCookies({"domain":".wx.qq.com","expiry":1477144227,"httpOnly":false,"name":"wxuin","path":"/","secure":false,"value":"891575575"})
SILL PuppetWebBrowser dead() checking ...
SILL PuppetWebBrowser addCookies({"domain":".wx.qq.com","expiry":1476928227,"httpOnly":false,"name":"wxloadtime","path":"/","secure":false,"value":"1476885027_expired"})
SILL PuppetWebBrowser dead() checking ...
SILL PuppetWebBrowser addCookies({"domain":".wx.qq.com","expiry":1792241469,"httpOnly":false,"name":"webwxuvid","path":"/","secure":false,"value":"389a7ed41c7b9fa88205a69eff706fa79d6108aedcaa14e11b47fb41e71ac4b4db1f040ee0bea303a02e026e595106c6"})
SILL PuppetWebBrowser dead() checking ...
SILL PuppetWebBrowser addCookies({"domain":".wx.qq.com","expiry":1476928227,"httpOnly":false,"name":"wxpluginkey","path":"/","secure":false,"value":"1476870482"})
SILL PuppetWebBrowser dead() checking ...
SILL PuppetWebBrowser addCookies({"domain":".qq.com","expiry":2147385600,"httpOnly":false,"name":"pgv_pvi","path":"/","secure":false,"value":"5948175360"})
SILL PuppetWebBrowser dead() checking ...
SILL PuppetWebBrowser addCookies({"domain":".qq.com","expiry":1476928227,"httpOnly":false,"name":"webwx_data_ticket","path":"/","secure":false,"value":"gSe51PVVyozkkWQ2Ox87ln8S"})
SILL PuppetWebBrowser dead() checking ...
SILL PuppetWebBrowser addCookies({"domain":".wx.qq.com","expiry":1476928227,"httpOnly":false,"name":"mm_lang","path":"/","secure":false,"value":"zh_CN"})
SILL PuppetWebBrowser dead() checking ...
SILL PuppetWebBrowser addCookies({"domain":".qq.com","httpOnly":false,"name":"pgv_si","path":"/","secure":false,"value":"s4124510208"})
VERB PuppetWebBrowser loaded session(9 cookies) from TestFun.wechaty.json
VERB PuppetWebBrowser open(https://wx.qq.com)
VERB PuppetWebBrowser currentState(open)
VERB PuppetWeb initBrowser() done
VERB PuppetWeb initBridge()
VERB PuppetWebBridge new Bridge({puppet: PuppetWeb, port: 19005})
VERB PuppetWebBridge init()
VERB PuppetWebBridge inject()
SILL PuppetWebBrowser Browser.execute("injectioReturnValue = /** * * Wechaty - Wechat for Bot, and human who talk to ... ")
SILL PuppetWebBrowser dead() checking ...
SILL PuppetWebBridge inject() eval(Wechaty) return code[200] message[WechatyBro Inject Succ] port[19005]
SILL PuppetWebBrowser Browser.execute("return typeof WechatyBro === "undefined"")

Run wechaty occurs chromedriver is still running and the solution

Please run npm run doctor and paste the output here

Wechaty Doctor

  1. Wechaty version: #git[93d1728 doc]
  2. Darwin x64 version 15.6.0 memory 146/4096 MB
  3. Docker: false

Expected behavior

run wechaty

Actual behavior

error log as follows:

ERR PuppetWeb initBrowser() exception: The previously configured ChromeDriver service is still running. You must shut it down before you may adjust its configuration.
ERR PuppetWebEvent onBrowserDead() exception: The previously configured ChromeDriver service is still running. You must shut it down before you may adjust its configuration.

Steps to reproduce the behavior (and fixes, if any)

execute npm install

lijiaruideAir:example lijiarui$ npm install
[email protected] /Users/lijiarui/git/wechaty
├── [email protected]
├── [email protected]
└── [email protected] extraneous

├─┬ [email protected]
│ └── [email protected]
└── [email protected] extraneous

and close some program then fix the error

Can't run wechaty with error log

Please run npm run doctor and paste the output here

Wechaty Doctor

  1. Wechaty version: #git[93d1728 doc]
  2. Darwin x64 version 15.6.0 memory 146/4096 MB
  3. Docker: false

Expected behavior

run wechaty

Actual behavior

can't run wechaty on my mac, but can run wechaty on digital ocean
the error log as follows:

VERB Wechaty contructor()
VERB Wechaty on(scan, function)
VERB Wechaty on(logout, function)
VERB Wechaty on(error, function)
VERB Wechaty on(login, function)
VERB Wechaty on(room-join, function)
VERB Wechaty on(room-leave, function)
VERB Wechaty on(room-topic, function)
VERB Wechaty on(message, function)
INFO Wechaty v#git[93d1728 doc] initializing...
VERB Wechaty puppet: web
VERB Wechaty head: chrome
VERB Wechaty profile: demo.wechaty.json
VERB Wechaty uuid: 53108ef9-2d2e-4326-ae18-e28bd9792e7e
VERB Puppet targetState(dead)
VERB Puppet currentState(dead)
VERB PuppetWeb init() with head:chrome, profile:demo.wechaty.json
VERB Puppet targetState(live)
VERB Puppet currentState(birthing)
VERB UtilLib getPort(18788)
VERB UtilLib getPort(18788) return: 18853
VERB PuppetWeb init() getPort 18853
VERB PuppetWeb initServer()
VERB PuppetWebServer init() on port 18853
VERB PuppetWebServer createHttpsServer() listen on port 18853
VERB PuppetWebServer init()-ed
VERB PuppetWeb initServer() done
VERB PuppetWeb initBrowser()
VERB PuppetWebBrowser constructor() with head(chrome) sessionFile(demo.wechaty.json)
VERB PuppetWebBrowser targetState(close)
VERB PuppetWebBrowser currentState(close)
VERB PuppetWebBrowserCookie constructor(Browser, demo.wechaty.json)
VERB PuppetWebBrowser targetState(open)
VERB PuppetWebBrowser currentState(opening)
VERB PuppetWebBrowser initDriver() for head: chrome
VERB PuppetWebBrowser getChromeDriver()
VERB PuppetWebBrowser driver(Driver)
VERB PuppetWebBrowser open(https://wx.qq.com/zh_CN/htmledition/v2/images/webwxgeticon.jpg)
VERB PuppetWebBrowserCookie loadSession() from demo.wechaty.json
SILL PuppetWebBrowserCookie addCookies({"domain":".wx.qq.com","expiry":1477418987,"httpOnly":false,"name":"wxloadtime","path":"/","secure":false,"value":"1477375787"})
SILL PuppetWebBrowserCookie addCookies({"domain":".wx.qq.com","expiry":1477418987,"httpOnly":false,"name":"wxsid","path":"/","secure":false,"value":"4FGtPc3H2t6Zjaec"})
SILL PuppetWebBrowserCookie addCookies({"domain":".wx.qq.com","expiry":1477418987,"httpOnly":false,"name":"wxuin","path":"/","secure":false,"value":"891575575"})
SILL PuppetWebBrowserCookie addCookies({"domain":".qq.com","expiry":2147385600,"httpOnly":false,"name":"pgv_pvi","path":"/","secure":false,"value":"9225103360"})
SILL PuppetWebBrowserCookie addCookies({"domain":".wx.qq.com","expiry":1792239143,"httpOnly":false,"name":"webwxuvid","path":"/","secure":false,"value":"389a7ed41c7b9fa88205a69eff706fa7c493c8e056775cee761d67f1da927bab366cceb7b7c6a060c8dde76b81c36c0f"})
SILL PuppetWebBrowserCookie addCookies({"domain":".qq.com","expiry":1477418987,"httpOnly":false,"name":"webwx_data_ticket","path":"/","secure":false,"value":"gSfhB0Zxd6tRcLz0OwotwKIP"})
SILL PuppetWebBrowserCookie addCookies({"domain":".wx.qq.com","expiry":1477418987,"httpOnly":false,"name":"mm_lang","path":"/","secure":false,"value":"zh_CN"})
SILL PuppetWebBrowserCookie addCookies({"domain":".qq.com","httpOnly":false,"name":"pgv_si","path":"/","secure":false,"value":"s3690461184"})
VERB PuppetWebBrowserCookie loaded session(8 cookies) from demo.wechaty.json
VERB PuppetWebBrowser open(https://wx.qq.com)
VERB PuppetWebBrowser currentState(open)
VERB PuppetWeb initBrowser() done
VERB PuppetWeb initBridge()
VERB PuppetWebBridge new Bridge({puppet: PuppetWeb, port: 18853})
VERB PuppetWebBridge init()
VERB PuppetWebBridge inject()
SILL PuppetWebBrowser Browser.execute("injectioReturnValue = /** * * Wechaty - Wechat for Bot, and human who talk to ... ")
SILL PuppetWebBridge inject() eval(Wechaty) return code[200] message[WechatyBro Inject Succ] port[18853]
SILL PuppetWebBrowser Browser.execute("return typeof WechatyBro === "undefined"")
SILL PuppetWebBrowser Browser.execute(" const callback = arguments[arguments.length - 1] const isAsync = (typeof ... ")
SILL PuppetWebBridge inject() Wechaty.init() return code[200] message[WechatyBro Init Succ on port: 18853] port[18853]
SILL PuppetWebBrowser Browser.execute("return typeof WechatyBro === "undefined"")
SILL PuppetWebBrowser Browser.execute(" const callback = arguments[arguments.length - 1] const isAsync = (typeof ... ")
SILL PuppetWebBridge inject() ding success
VERB PuppetWeb initBridge() done
SILL PuppetWebWatchdog onFeed: 120000, HEARTBEAT:[inited]
SILL PuppetWebWatchdog clearWatchDogTimer() nothing to clear
SILL PuppetWebWatchdog setWatchDogTimer(120000, HEARTBEAT:[inited])
SILL PuppetWebWatchdog monitorScan(HEARTBEAT)
SILL PuppetWebWatchdog autoSaveSession()
SILL PuppetWebWatchdog memoryCheck() free: 602 MB, require: 64 MB
VERB PuppetWeb init() done
VERB Puppet currentState(live)

VERB PuppetWebWatchdog watchDogReset() timeout 120000
INFO Bot error: Error: watchdog reset after 120 seconds, last feed:[HEARTBEAT:[inited]]
VERB PuppetWebEvent onBrowserDead(watchdog reset after 120 seconds, last feed:[HEARTBEAT:[inited]])
SILL PuppetWebWatchdog onFeed: 180000, HEARTBEAT:[onBrowserDead() set a timeout of 180 seconds to prevent unknown state change]
SILL PuppetWebWatchdog clearWatchDogTimer() [0] seconds left
SILL PuppetWebWatchdog setWatchDogTimer(180000, HEARTBEAT:[onBrowserDead() set a timeout of 180 seconds to prevent unknown state change])
SILL PuppetWebWatchdog monitorScan(HEARTBEAT)
SILL PuppetWebWatchdog autoSaveSession()
SILL PuppetWebWatchdog memoryCheck() free: 297 MB, require: 64 MB
VERB PuppetWebBrowser quit()
VERB PuppetWebBrowser currentState(closing)
SILL PuppetWebBrowser quit() driver.close()-ed
SILL PuppetWebBrowser quit() driver.quit()-ed
VERB PuppetWebBrowser driver(null)
SILL PuppetWebBrowser quit() this.driver = null
SILL PuppetWebBrowser clean() retryPromise: attempt 1 time for timeout 45000
SILL PuppetWebBrowser getBrowserPids()
SILL PuppetWebBrowser getBrowserPids() child: {"PPID":"38740","PID":"38745","STAT":"S+","COMM":"node"}
SILL PuppetWebBrowser getBrowserPids() child: {"PPID":"38745","PID":"38746","STAT":"S+","COMM":"/Users/lijiarui/git/wechaty/node_modules/chromedriver/lib/chromedriver/chromedriver"}
SILL PuppetWebBrowser getBrowserPids() child: {"PPID":"38740","PID":"38771","STAT":"R+","COMM":"ps"}
VERB PuppetWebBrowser clean() retryPromise() resolved
VERB PuppetWebBrowser currentState(close)
VERB PuppetWebEvent onBrowserDead() browser quit-ed

Steps to reproduce the behavior (and fixes, if any)

google-chrome fails to start in docker

google-chrome sometimes fail to start in docker, error message is:

Failed to move to new namespace: PID namespaces supported, Network namespace supported, but failed: errno = Operation not permitted

a fix is to use --no-sandbox args for chrome: elgalu/docker-selenium#58

code here: 4fbee4a

See Also

  1. BE CAREFUL WITH DOCKER UPGRADE
  2. What is Chrome Sandbox in Animation
  3. https://linuxmeerkat.wordpress.com/2014/10/17/running-a-gui-application-in-a-docker-container/
  4. https://forums.docker.com/t/docker-user-namespaces/16885?u=zixia

wx.qq.com detect phantomjs and disabled it

Update 2016-9-1

Phantomjs work well now, without any modification at wechaty side.

It seems like js code in wx upgraded again, and the accident that disable phantomjs is not the purpose (more like a compatible bug of checksum code run in phantomjs).


before fix, you can switch to chrome instead of phantomjs to use wechaty as usual.

$ WECHATY_HEAD=chrome node example/ding-dong-bot.js

detail:

https://res.wx.qq.com/zh_CN/htmledition/v2/js/webwxApp2fd632.js

    try {
        var p = angular.bootstrap.toString().replace(/\n"use strict";\n/, "")
          , h = m(p);
        "54c6b762ad3618c9ebfd4b439c8d4bda" !== h && ($.getScript("https://tajs.qq.com/stats?sId=54802481"),
        location.href = "https://wx.qq.com/?t=v2/fake")
    } catch (M) {}
    angular.bootstrap(document, ["webwxApp"])

https://wx.qq.com/?t=v2/fake

See Also

[design] new class: BrowserCookie

to separate cookie related code from Class Browser.

this.cookie = new BrowserCookie(this: Browser, profile: string)
this.cookie.clean(): Promise<void>
this.cookie.save(): Promise<void>
this.cookie.load(): Promise<void>
this.cookie.read(): Promise<Cookie[]>

Qr Auth fails after a day

Hi after 1-2 days our docker instance loses authorisation and we have to rescan a QR code. Is this normal? How long has anyone else kept an account authorised after first scanning a QR code. We were hoping to keep it long running as otherwise we miss messages? Any tips appreciated.

(PS. thanks for a great SDK)

ChromeDriver PATH problem

running the sample code from README.me section 'Install from Github' on a mac laptop, some error logs appear

Please wait... I'm trying to login in...

INFO Wechaty v0.3.17 initializing...
ERR PuppetWebBrowser init() exception: The ChromeDriver could not be found on the current PATH. Please download the latest version of the ChromeDriver from http://chromedriver.storage.googleapis.com/index.html and ensure it can be found on your PATH.
ERR PuppetWeb initBrowser() exception: The ChromeDriver could not be found on the current PATH. Please download the latest version of the ChromeDriver from http://chromedriver.storage.googleapis.com/index.html and ensure it can be found on your PATH.

this link will fix the problem
http://stackoverflow.com/questions/27733731/passing-requirechromedriver-path-directly-to-selenium-webdriver

use StateMonitor to record&check wechaty/puppet/bridge/browser state change

now, the all above modules have the same targetState() & currentState() code, should be modulized & well tested, to make sure all the state are well monitor & managed.

  • Browser Class
  • [ ] Bridge Class
  • [ ] Server Class
  • Puppet Class
  • Wechaty Class
  • Io Class
  • IoClient Class

StateMonitor Class: https://github.com/wechaty/wechaty/blob/master/src/state-monitor.ts

after this, Watchdog should work better, and we can dig deeper for how to deal with browser problems, i.e.: killed by operation system or hang with no reason.

Can not launching app - WebDriverError: un known error: cannot find Chrome binary

Description

The question is how to launch wechaty in Ubuntu Server. I have read the dockfile, which using google's source to install chrome drivers. But my server is now behind the wall.

I also tried with my machine oversea, but it fails too.

$ apt-get update -q && apt-get install -qy \
  apt-utils \
  chromium \
  google-chrome-stable \
  vim \
  xvfb

W: Failed to fetch http://dl.google.com/linux/chrome/deb/dists/stable/Release  Unable to find expected entry 'main/binary-i386/Packages' in Release file (Wron
g sources.list entry or malformed file)

E: Some index files failed to download. They have been ignored, or old ones used instead.

OS

Aliyun ECS
Ubuntu 14.04.4 LTS (GNU/Linux 3.13.0-86-generic x86_64)

Install chromedriver and phantomjs

chromedriver and phantomjs are accessable from path.

image

image

install node modules

npm install # successfully.

get Errors when running npm start.

image

Start failed: "ERR! PuppetWeb Error: Server terminated early with status 127"

=============== Powered by Wechaty ===============
-------- https://github.com/zixia/wechaty --------

I'm a bot, my super power is talk in Wechat.

If you send me a 'ding', I will reply you a 'dong'!


Hope you like it, and you are very welcome to
upgrade me for more super powers!

Please wait... I'm trying to login in...

info Wechaty init() with version: 0.0.11
verb PuppetWeb init()
verb PuppetWeb initAttach()
verb PuppetWeb initAttach done: true
verb PuppetWeb initBrowser
verb Browser init()
verb Browser initDriver()
sill Browser phantomjs binary: /data/www/default/wechaty/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs
verb Browser initDriver() done
verb Browser open()ing at https://wx.qq.com
ERR! PuppetWeb Error: Server terminated early with status 127
ERR! PuppetWeb at Error (native)
ERR! PuppetWeb at /data/www/default/wechaty/node_modules/selenium-webdriver/remote/index.js:242:20
ERR! PuppetWeb at ManagedPromise.invokeCallback_ (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/promise.js:1379:14)
ERR! PuppetWeb at TaskQueue.execute_ (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/promise.js:2913:14)
ERR! PuppetWeb at TaskQueue.executeNext_ (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/promise.js:2896:21)
ERR! PuppetWeb at asyncRun (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/promise.js:2775:27)
ERR! PuppetWeb at /data/www/default/wechaty/node_modules/selenium-webdriver/lib/promise.js:639:7
ERR! PuppetWeb at process.tickCallback (internal/process/next_tick.js:103:7)
ERR! PuppetWeb From: Task: WebDriver.createSession()
ERR! PuppetWeb at Function.createSession (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:329:24)
ERR! PuppetWeb at Driver (/data/www/default/wechaty/node_modules/selenium-webdriver/phantomjs.js:192:38)
ERR! PuppetWeb at Builder.build (/data/www/default/wechaty/node_modules/selenium-webdriver/builder.js:479:16)
ERR! PuppetWeb at Browser.getPhantomJsDriver (/data/www/default/wechaty/src/puppet-web-browser.js:79:6)
ERR! PuppetWeb at Browser.initDriver (/data/www/default/wechaty/src/puppet-web-browser.js:54:26)
ERR! PuppetWeb at Browser.init (/data/www/default/wechaty/src/puppet-web-browser.js:28:17)
ERR! PuppetWeb at PuppetWeb.initBrowser (/data/www/default/wechaty/src/puppet-web.js:83:25)
ERR! PuppetWeb at initAttach.then.r (/data/www/default/wechaty/src/puppet-web.js:50:19)
ERR! PuppetWeb at process.tickCallback (internal/process/next_tick.js:103:7)
ERR! PuppetWeb at Function.Module.runMain (module.js:577:11)
ERR! PuppetWeb From: Task: WebDriver.navigate().to(https://wx.qq.com)
ERR! PuppetWeb at Driver.schedule (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:377:17)
ERR! PuppetWeb at Navigation.to (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:1027:25)
ERR! PuppetWeb at Driver.get (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:795:28)
ERR! PuppetWeb at Browser.open (/data/www/default/wechaty/src/puppet-web-browser.js:43:24)
ERR! PuppetWeb at initDriver.then.r (/data/www/default/wechaty/src/puppet-web-browser.js:31:19)
ERR! PuppetWeb at process.tickCallback (internal/process/next_tick.js:103:7)
ERR! PuppetWeb at Function.Module.runMain (module.js:577:11)
ERR! PuppetWeb at startup (node.js:160:18)
ERR! PuppetWeb at node.js:456:3
ERR! PuppetWeb Error: Server terminated early with status 127
ERR! PuppetWeb at Error (native)
ERR! PuppetWeb at /data/www/default/wechaty/node_modules/selenium-webdriver/remote/index.js:242:20
ERR! PuppetWeb at ManagedPromise.invokeCallback
(/data/www/default/wechaty/node_modules/selenium-webdriver/lib/promise.js:1379:14)
ERR! PuppetWeb at TaskQueue.execute
(/data/www/default/wechaty/node_modules/selenium-webdriver/lib/promise.js:2913:14)
ERR! PuppetWeb at TaskQueue.executeNext
(/data/www/default/wechaty/node_modules/selenium-webdriver/lib/promise.js:2896:21)
ERR! PuppetWeb at asyncRun (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/promise.js:2775:27)
ERR! PuppetWeb at /data/www/default/wechaty/node_modules/selenium-webdriver/lib/promise.js:639:7
ERR! PuppetWeb at process.tickCallback (internal/process/next_tick.js:103:7)
ERR! PuppetWeb From: Task: WebDriver.createSession()
ERR! PuppetWeb at Function.createSession (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:329:24)
ERR! PuppetWeb at Driver (/data/www/default/wechaty/node_modules/selenium-webdriver/phantomjs.js:192:38)
ERR! PuppetWeb at Builder.build (/data/www/default/wechaty/node_modules/selenium-webdriver/builder.js:479:16)
ERR! PuppetWeb at Browser.getPhantomJsDriver (/data/www/default/wechaty/src/puppet-web-browser.js:79:6)
ERR! PuppetWeb at Browser.initDriver (/data/www/default/wechaty/src/puppet-web-browser.js:54:26)
ERR! PuppetWeb at Browser.init (/data/www/default/wechaty/src/puppet-web-browser.js:28:17)
ERR! PuppetWeb at PuppetWeb.initBrowser (/data/www/default/wechaty/src/puppet-web.js:83:25)
ERR! PuppetWeb at initAttach.then.r (/data/www/default/wechaty/src/puppet-web.js:50:19)
ERR! PuppetWeb at process.tickCallback (internal/process/next_tick.js:103:7)
ERR! PuppetWeb at Function.Module.runMain (module.js:577:11)
ERR! PuppetWeb From: Task: WebDriver.navigate().to(https://wx.qq.com)
ERR! PuppetWeb at Driver.schedule (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:377:17)
ERR! PuppetWeb at Navigation.to (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:1027:25)
ERR! PuppetWeb at Driver.get (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:795:28)
ERR! PuppetWeb at Browser.open (/data/www/default/wechaty/src/puppet-web-browser.js:43:24)
ERR! PuppetWeb at initDriver.then.r (/data/www/default/wechaty/src/puppet-web-browser.js:31:19)
ERR! PuppetWeb at process.tickCallback (internal/process/next_tick.js:103:7)
ERR! PuppetWeb at Function.Module.runMain (module.js:577:11)
ERR! PuppetWeb at startup (node.js:160:18)
ERR! PuppetWeb at node.js:456:3
ERR! Bot Error: Server terminated early with status 127
ERR! Bot at Error (native)
ERR! Bot at /data/www/default/wechaty/node_modules/selenium-webdriver/remote/index.js:242:20
ERR! Bot at ManagedPromise.invokeCallback
(/data/www/default/wechaty/node_modules/selenium-webdriver/lib/promise.js:1379:14)
ERR! Bot at TaskQueue.execute
(/data/www/default/wechaty/node_modules/selenium-webdriver/lib/promise.js:2913:14)
ERR! Bot at TaskQueue.executeNext
(/data/www/default/wechaty/node_modules/selenium-webdriver/lib/promise.js:2896:21)
ERR! Bot at asyncRun (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/promise.js:2775:27)
ERR! Bot at /data/www/default/wechaty/node_modules/selenium-webdriver/lib/promise.js:639:7
ERR! Bot at process.tickCallback (internal/process/next_tick.js:103:7)
ERR! Bot From: Task: WebDriver.createSession()
ERR! Bot at Function.createSession (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:329:24)
ERR! Bot at Driver (/data/www/default/wechaty/node_modules/selenium-webdriver/phantomjs.js:192:38)
ERR! Bot at Builder.build (/data/www/default/wechaty/node_modules/selenium-webdriver/builder.js:479:16)
ERR! Bot at Browser.getPhantomJsDriver (/data/www/default/wechaty/src/puppet-web-browser.js:79:6)
ERR! Bot at Browser.initDriver (/data/www/default/wechaty/src/puppet-web-browser.js:54:26)
ERR! Bot at Browser.init (/data/www/default/wechaty/src/puppet-web-browser.js:28:17)
ERR! Bot at PuppetWeb.initBrowser (/data/www/default/wechaty/src/puppet-web.js:83:25)
ERR! Bot at initAttach.then.r (/data/www/default/wechaty/src/puppet-web.js:50:19)
ERR! Bot at process.tickCallback (internal/process/next_tick.js:103:7)
ERR! Bot at Function.Module.runMain (module.js:577:11)
ERR! Bot From: Task: WebDriver.navigate().to(https://wx.qq.com)
ERR! Bot at Driver.schedule (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:377:17)
ERR! Bot at Navigation.to (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:1027:25)
ERR! Bot at Driver.get (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:795:28)
ERR! Bot at Browser.open (/data/www/default/wechaty/src/puppet-web-browser.js:43:24)
ERR! Bot at initDriver.then.r (/data/www/default/wechaty/src/puppet-web-browser.js:31:19)
ERR! Bot at process.tickCallback (internal/process/next_tick.js:103:7)
ERR! Bot at Function.Module.runMain (module.js:577:11)
ERR! Bot at startup (node.js:160:18)
ERR! Bot at node.js:456:3
ERR! Bot init() fail: %s Error: Server terminated early with status 127
ERR! Bot at Error (native)
ERR! Bot at /data/www/default/wechaty/node_modules/selenium-webdriver/remote/index.js:242:20
ERR! Bot at ManagedPromise.invokeCallback
(/data/www/default/wechaty/node_modules/selenium-webdriver/lib/promise.js:1379:14)
ERR! Bot at TaskQueue.execute
(/data/www/default/wechaty/node_modules/selenium-webdriver/lib/promise.js:2913:14)
ERR! Bot at TaskQueue.executeNext
(/data/www/default/wechaty/node_modules/selenium-webdriver/lib/promise.js:2896:21)
ERR! Bot at asyncRun (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/promise.js:2775:27)
ERR! Bot at /data/www/default/wechaty/node_modules/selenium-webdriver/lib/promise.js:639:7
ERR! Bot at process._tickCallback (internal/process/next_tick.js:103:7)
ERR! Bot From: Task: WebDriver.createSession()
ERR! Bot at Function.createSession (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:329:24)
ERR! Bot at Driver (/data/www/default/wechaty/node_modules/selenium-webdriver/phantomjs.js:192:38)
ERR! Bot at Builder.build (/data/www/default/wechaty/node_modules/selenium-webdriver/builder.js:479:16)
ERR! Bot at Browser.getPhantomJsDriver (/data/www/default/wechaty/src/puppet-web-browser.js:79:6)
ERR! Bot at Browser.initDriver (/data/www/default/wechaty/src/puppet-web-browser.js:54:26)
ERR! Bot at Browser.init (/data/www/default/wechaty/src/puppet-web-browser.js:28:17)
ERR! Bot at PuppetWeb.initBrowser (/data/www/default/wechaty/src/puppet-web.js:83:25)
ERR! Bot at initAttach.then.r (/data/www/default/wechaty/src/puppet-web.js:50:19)
ERR! Bot at process._tickCallback (internal/process/next_tick.js:103:7)
ERR! Bot at Function.Module.runMain (module.js:577:11)
ERR! Bot From: Task: WebDriver.navigate().to(https://wx.qq.com)
ERR! Bot at Driver.schedule (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:377:17)
ERR! Bot at Navigation.to (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:1027:25)
ERR! Bot at Driver.get (/data/www/default/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:795:28)
ERR! Bot at Browser.open (/data/www/default/wechaty/src/puppet-web-browser.js:43:24)
ERR! Bot at initDriver.then.r (/data/www/default/wechaty/src/puppet-web-browser.js:31:19)
ERR! Bot at process._tickCallback (internal/process/next_tick.js:103:7)
ERR! Bot at Function.Module.runMain (module.js:577:11)
ERR! Bot at startup (node.js:160:18)
ERR! Bot at node.js:456:3
verb PuppetWeb quit()
WARN PuppetWeb quit() without bridge
WARN PuppetWeb quit() without server

demo 无法运行

按照文档进行了如下操作:
git clone https://github.com/wechaty/wechaty.git
cd wechaty
npm install
npm run demo

报了如下错误

INFO Wechaty v#git[5cb8afd bug fix] initializing...
ERR PuppetWebBrowser open() exception: unknown error: Chrome version must be >= 52.0.2743.0
  (Driver info: chromedriver=2.24.417412 (ac882d3ce7c0d99292439bf3405780058fcca0a6),platform=Mac OS X 10.12.0 x86_64)
WARN PuppetWebBrowser dead() because unknown error: Chrome version must be >= 52.0.2743.0
  (Driver info: chromedriver=2.24.417412 (ac882d3ce7c0d99292439bf3405780058fcca0a6),platform=Mac OS X 10.12.0 x86_64)
ERR PuppetWebBrowser init() exception: unknown error: Chrome version must be >= 52.0.2743.0
  (Driver info: chromedriver=2.24.417412 (ac882d3ce7c0d99292439bf3405780058fcca0a6),platform=Mac OS X 10.12.0 x86_64)
ERR PuppetWeb initBrowser() exception: unknown error: Chrome version must be >= 52.0.2743.0
  (Driver info: chromedriver=2.24.417412 (ac882d3ce7c0d99292439bf3405780058fcca0a6),platform=Mac OS X 10.12.0 x86_64)
ERR PuppetWeb init() exception: WebDriverError: unknown error: Chrome version must be >= 52.0.2743.0
  (Driver info: chromedriver=2.24.417412 (ac882d3ce7c0d99292439bf3405780058fcca0a6),platform=Mac OS X 10.12.0 x86_64)
    at WebDriverError (/Users/Maopy/www/repo/wechaty/node_modules/selenium-webdriver/lib/error.js:27:5)
    at Object.checkLegacyResponse (/Users/Maopy/www/repo/wechaty/node_modules/selenium-webdriver/lib/error.js:505:15)
    at parseHttpResponse (/Users/Maopy/www/repo/wechaty/node_modules/selenium-webdriver/lib/http.js:398:13)
    at doSend.then.response (/Users/Maopy/www/repo/wechaty/node_modules/selenium-webdriver/lib/http.js:330:11)
    at process._tickDomainCallback (internal/process/next_tick.js:129:7)
From: Task: WebDriver.createSession()
    at Function.createSession (/Users/Maopy/www/repo/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:366:24)
    at Driver (/Users/Maopy/www/repo/wechaty/node_modules/selenium-webdriver/chrome.js:716:38)
    at Builder.build (/Users/Maopy/www/repo/wechaty/node_modules/selenium-webdriver/index.js:554:16)
    at Browser.getChromeDriver (/Users/Maopy/www/repo/wechaty/src/puppet-web/browser.ts:197:18)
    at Browser.initDriver (/Users/Maopy/www/repo/wechaty/src/puppet-web/browser.ts:151:28)
    at Browser.<anonymous> (/Users/Maopy/www/repo/wechaty/src/puppet-web/browser.ts:77:18)
    at next (native)
    at /Users/Maopy/www/repo/wechaty/src/puppet-web/browser.ts:7:65
    at __awaiter (/Users/Maopy/www/repo/wechaty/src/puppet-web/browser.ts:3:12)
    at Browser.init (/Users/Maopy/www/repo/wechaty/src/puppet-web/browser.ts:53:16)
From: Task: WebDriver.navigate().to(https://wx.qq.com/zh_CN/htmledition/v2/images/webwxgeticon.jpg)
    at Driver.schedule (/Users/Maopy/www/repo/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:414:17)
    at Navigation.to (/Users/Maopy/www/repo/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:1042:25)
    at Driver.get (/Users/Maopy/www/repo/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:832:28)
    at Promise (/Users/Maopy/www/repo/wechaty/src/puppet-web/browser.ts:121:19)
    at Browser.open (/Users/Maopy/www/repo/wechaty/src/puppet-web/browser.ts:118:12)
    at Browser.<anonymous> (/Users/Maopy/www/repo/wechaty/src/puppet-web/browser.ts:80:18)
    at next (native)
    at fulfilled (/Users/Maopy/www/repo/wechaty/src/puppet-web/browser.ts:4:58)
    at process._tickDomainCallback (internal/process/next_tick.js:129:7)
    at Function.Module.runMain (module.js:606:11)
From: Task: WebDriver.manage().timeouts().setScriptTimeout(10000)
    at Driver.schedule (/Users/Maopy/www/repo/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:414:17)
    at Timeouts._scheduleCommand (/Users/Maopy/www/repo/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:1402:25)
    at Timeouts.setScriptTimeout (/Users/Maopy/www/repo/wechaty/node_modules/selenium-webdriver/lib/webdriver.js:1385:17)
    at Browser.initDriver (/Users/Maopy/www/repo/wechaty/src/puppet-web/browser.ts:160:12)
    at Browser.<anonymous> (/Users/Maopy/www/repo/wechaty/src/puppet-web/browser.ts:77:18)
    at next (native)
    at /Users/Maopy/www/repo/wechaty/src/puppet-web/browser.ts:7:65
    at __awaiter (/Users/Maopy/www/repo/wechaty/src/puppet-web/browser.ts:3:12)
    at Browser.init (/Users/Maopy/www/repo/wechaty/src/puppet-web/browser.ts:53:16)
    at PuppetWeb.<anonymous> (/Users/Maopy/www/repo/wechaty/src/puppet-web/puppet-web.ts:197:21)
WARN PuppetWeb quit() without a bridge
WARN PuppetWebBrowser quit() exception: There was an uncaught error in the control flow: WebDriverError: unknown error: Chrome version must be >= 52.0.2743.0
  (Driver info: chromedriver=2.24.417412 (ac882d3ce7c0d99292439bf3405780058fcca0a6),platform=Mac OS X 10.12.0 x86_64)
WARN PuppetWebBrowser driver.quit() exception: There was an uncaught error in the control flow: WebDriverError: unknown error: Chrome version must be >= 52.0.2743.0
  (Driver info: chromedriver=2.24.417412 (ac882d3ce7c0d99292439bf3405780058fcca0a6),platform=Mac OS X 10.12.0 x86_64)
WARN PuppetWebBrowser quit() exception: unknown error: Chrome version must be >= 52.0.2743.0
  (Driver info: chromedriver=2.24.417412 (ac882d3ce7c0d99292439bf3405780058fcca0a6),platform=Mac OS X 10.12.0 x86_64)
WARN PuppetWebBrowser driver.quit() exception: unknown error: Chrome version must be >= 52.0.2743.0
  (Driver info: chromedriver=2.24.417412 (ac882d3ce7c0d99292439bf3405780058fcca0a6),platform=Mac OS X 10.12.0 x86_64)
ERR Wechaty init() exception: unknown error: Chrome version must be >= 52.0.2743.0
  (Driver info: chromedriver=2.24.417412 (ac882d3ce7c0d99292439bf3405780058fcca0a6),platform=Mac OS X 10.12.0 x86_64)
ERR Bot init() fail: WebDriverError: unknown error: Chrome version must be >= 52.0.2743.0
  (Driver info: chromedriver=2.24.417412 (ac882d3ce7c0d99292439bf3405780058fcca0a6),platform=Mac OS X 10.12.0 x86_64)
WARN PuppetWeb quit() without a bridge
WARN PuppetWeb quit() without a browser

而我的chrome 版本是 53.0.2785.116 (64-bit) Mac版本

webdriver fail in docker when use ava (parallel tests mode)

ava tests run ok on windows & linux, but not ok inside docker.

according to elgalu/docker-selenium#20 (comment) , this is due to /dev/shm memory size too small.

$ df -h
shm              64M  3.2M   61M   5% /dev/shm

it's only 64M

Solution

  1. increase shm size with --shm-size param with build & run moby/moby#16168 (comment)
  2. use --privileged when run docker, then mount /dev/shm -o remount,size=1g moby/moby#2606 (comment)
  3. use -v /dev/shm:/dev/shm when run docker. SeleniumHQ/docker-selenium#79 (comment)

Wechat帐号界面语言设为中文环境下:wechaty的room-join room-leave room-topic 事件无法触发

room-join
room-leave
room-topic
以上三个event,无法成功触发

代码如下:

import {
  Wechaty
  , log
} from '../'

const bot = Wechaty.instance({ profile: 'TestFun' })

bot
.on('login'   , user => log.info('Bot', `${user.name()} logined`))
.on('logout'  , user => log.info('Bot', `${user.name()} logouted`))
.on('error'   , e => log.info('Bot', 'error: %s', e))
.on('scan', (url, code) => {
  if (!/201|200/.test(String(code))){
    let loginUrl = url.replace(/\/qrcode\//, '/l/')
    require('qrcode-terminal').generate(loginUrl)
  }
  console.log(`${url}\n[${code}] Scan QR Code in above url to login: `)
})

.on('room-join', (room, invitee, inviter) => {
  console.log("room-join@@@@@@@@@@@@@")
})

.on('room-leave', (room, leaver) => {
  console.log("room-leave!!!!!!!!")
})

.on('room-topic', (room, topic, oldTopic, changer) => {
  try {
    console.log('room-topic##############')
  } catch (e) {
    log.error('Bot', 'room-topic event exception: %s', e.stack)
  }
})

.on('message', m => {
  m.ready()
  .then(msg => {

  const room    = msg.room()
  const sender  = msg.from()

  console.log((room ? '[' + room.topic() + ']' : '')
              + '<' + sender.name() + '>'
              + ':' + msg.toStringDigest()
  )

  })
  .catch(e => log.error('Bot', 'ready: %s' , e))
})

bot.init()
.catch(e => {
  log.error('Bot', 'init() fail: %s', e)
  bot.quit()
  process.exit(-1)
})

当群中拉入成员、删除成员、修改群名,理应打印出:

room-join@@@@@@@@@@@@@
room-leave!!!!!!!!
room-topic##############

实际上并没有打印出以上内容,仅仅作为消息形式,日志输出如下:(加入好友的情况)

SILL Message ready()
SILL Contact constructor(@@dfd07c3e0246851cc2084e1ffc9983d2d5d833331b6b2e1c64c41b206035b176)
SILL Room constructor(@@dfd07c3e0246851cc2084e1ffc9983d2d5d833331b6b2e1c64c41b206035b176)
SILL Contact ready()
SILL Contact get contact via PuppetWeb
SILL PuppetWebBridge getContact() retryPromise: attampt 1/35 time for timeout 306250
SILL PuppetWebBrowser Browser.execute("return typeof WechatyBro === "undefined"")
SILL PuppetWebBrowser dead()
SILL PuppetWebBrowser Browser.execute(" const callback = arguments[arguments.length - 1] const isAsync = (typeof ... ")
SILL PuppetWebBrowser dead()
SILL Contact contactGetter(@@dfd07c3e0246851cc2084e1ffc9983d2d5d833331b6b2e1c64c41b206035b176) resolved
SILL Contact ready()
SILL Room ready()
SILL PuppetWebBridge getContact() retryPromise: attampt 1/35 time for timeout 306250
SILL PuppetWebBrowser Browser.execute("return typeof WechatyBro === "undefined"")
SILL PuppetWebBrowser dead()
SILL PuppetWebBrowser Browser.execute(" const callback = arguments[arguments.length - 1] const isAsync = (typeof ... ")
SILL PuppetWebBrowser dead()
SILL Room contactGetter(@@dfd07c3e0246851cc2084e1ffc9983d2d5d833331b6b2e1c64c41b206035b176) resolved
SILL Contact constructor(@7e50d293942e6e283a3143c3dd42fb05afc9647b2c2d4ce68dab17a3fe13810d)
SILL Contact ready()
SILL Contact ready()
SILL Contact get contact via PuppetWeb
SILL PuppetWebBridge getContact() retryPromise: attampt 1/35 time for timeout 306250
SILL PuppetWebBrowser Browser.execute("return typeof WechatyBro === "undefined"")
SILL PuppetWebBrowser dead()
SILL PuppetWebBrowser Browser.execute(" const callback = arguments[arguments.length - 1] const isAsync = (typeof ... ")
SILL PuppetWebBrowser dead()
SILL Contact contactGetter(@7e50d293942e6e283a3143c3dd42fb05afc9647b2c2d4ce68dab17a3fe13810d) resolved
VERB PuppetWebFirer fireRoomJoin(你邀请"李佳芮"加入了群聊)
VERB PuppetWebFirer checkRoomJoin()
VERB PuppetWebFirer fireRoomLeave(你邀请"李佳芮"加入了群聊)
SILL Message ready()
SILL Contact ready()
SILL Contact ready()
SILL Room ready()
SILL Message ready()
SILL Contact ready()
SILL Contact ready()
SILL Room ready()
[ding哦哦]<ding哦哦>:{SYS}你邀请"李佳芮"加入了群聊
SILL Message ready()
SILL Contact ready()
SILL Contact ready()
SILL Room ready()
SILL Message ready()
SILL Contact ready()
SILL Contact ready()
SILL Room ready()
SILL Message ready()
SILL Contact ready()
SILL Contact ready()
SILL Room ready()
[ding哦哦]<wuli舞哩>:{TEXT}wuli舞哩:欢迎 @李佳芮 入群

在移除好友时:

SILL Message ready()
SILL Contact ready()
SILL Contact ready()
SILL Room ready()
VERB PuppetWebFirer fireRoomJoin(你将"李佳芮"移出了群聊)
VERB PuppetWebFirer checkRoomJoin()
VERB PuppetWebFirer fireRoomLeave(你将"李佳芮"移出了群聊)
SILL Message ready()
SILL Contact ready()
SILL Contact ready()
SILL Room ready()
SILL Message ready()
SILL Contact ready()
SILL Contact ready()
SILL Room ready()
[ding哦哦]<ding哦哦>:{SYS}你将"李佳芮"移出了群聊

在修改群名称时:

SILL Message ready()
SILL Contact ready()
SILL Contact ready()
SILL Room ready()
VERB PuppetWebFirer fireRoomJoin("李佳芮"修改群名为“ding”)
VERB PuppetWebFirer checkRoomJoin()
VERB PuppetWebFirer fireRoomLeave("李佳芮"修改群名为“ding”)
SILL Message ready()
SILL Contact ready()
SILL Contact ready()
SILL Room ready()
SILL Message ready()
SILL Contact ready()
SILL Contact ready()
SILL Room ready()
[ding哦哦]<ding哦哦>:{SYS}"李佳芮"修改群名为“ding”

为什么会没有触发到
.on('room-join', (room, invitee, inviter)
.on('room-leave', (room, leaver)
.on('room-topic', (room, topic, oldTopic, changer)
里面的内容呢?

谢谢!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.