提交 79ea4a5b 编写于 作者: Huan (李卓桓)'s avatar Huan (李卓桓)

merge

......@@ -6,8 +6,9 @@
Wechaty is a Bot Framework for Wechat **Personal** Account which can help you create a bot in 6 lines of javascript by easy to use API, with cross-platform support include [Linux](https://travis-ci.org/chatie/wechaty), [Windows](https://ci.appveyor.com/project/chatie/wechaty), [Darwin(OSX/Mac)](https://travis-ci.org/chatie/wechaty) and [Docker](https://circleci.com/gh/chatie/wechaty).
[![Join the chat at https://gitter.im/zixia/wechaty](https://badges.gitter.im/zixia/wechaty.svg)](https://gitter.im/zixia/wechaty?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![node](https://img.shields.io/node/v/wechaty.svg?maxAge=604800)](https://nodejs.org/) [![Repo Size](https://reposs.herokuapp.com/?path=Chatie/wechaty)](https://github.com/chatie/wechaty)
[![Issue Stats](http://issuestats.com/github/chatie/wechaty/badge/pr)](http://issuestats.com/github/chatie/wechaty) [![Issue Stats](http://issuestats.com/github/chatie/wechaty/badge/issue)](http://issuestats.com/github/chatie/wechaty)
[![node](https://img.shields.io/node/v/wechaty.svg?maxAge=604800)](https://nodejs.org/)
[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://github.com/ellerbrock/typescript-badges/)
[![Repo Size](https://reposs.herokuapp.com/?path=Chatie/wechaty)](https://github.com/chatie/wechaty)
:octocat: <https://github.com/chatie/wechaty>
:beetle: <https://github.com/chatie/wechaty/issues>
......@@ -100,7 +101,9 @@ Get to know more about Wechaty Docker at [Wiki:Docker](https://github.com/chatie
### NPM
[![NPM Version](https://badge.fury.io/js/wechaty.svg)](https://badge.fury.io/js/wechaty) [![Downloads][downloads-image]][downloads-url] [![Greenkeeper badge](https://badges.greenkeeper.io/Chatie/wechaty.svg)](https://greenkeeper.io/)
[![NPM Version](https://badge.fury.io/js/wechaty.svg)](https://badge.fury.io/js/wechaty)
[![Downloads][downloads-image]][downloads-url]
[![Greenkeeper badge](https://badges.greenkeeper.io/Chatie/wechaty.svg)](https://greenkeeper.io/)
```shell
$ npm install wechaty
......@@ -116,18 +119,23 @@ $ node mybot.js
Get to know more about NPM at [Wiki:NPM](https://github.com/chatie/wechaty/wiki/NPM)
### Find a Good Server
# Test
The best practice for runing 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.
[![Linux/Mac Build Status](https://img.shields.io/travis/Chatie/wechaty.svg?label=Linux/Mac)](https://travis-ci.org/Chatie/wechaty)
[![Windows Build status](https://img.shields.io/appveyor/ci/chatie/wechaty/master.svg?label=Windows)](https://ci.appveyor.com/project/chatie/wechaty)
[![Docker CircleCI](https://img.shields.io/circleci/project/github/Chatie/wechaty/master.svg?label=Docker)](https://circleci.com/gh/Chatie/wechaty)
The following VPS providers is used by ourselves, they worked perfectly in production. You can use the following link to get one in minutes, and also do this can support Wechaty because you are refered by us.
[![Coverage Status](https://coveralls.io/repos/github/Chatie/wechaty/badge.svg?branch=master)](https://coveralls.io/github/Chatie/wechaty?branch=master)
[![Known Vulnerabilities](https://snyk.io/test/github/chatie/wechaty/badge.svg)](https://snyk.io/test/github/chatie/wechaty)
| Location | Price | Ram | Payment | Provider |
| --- | --- | --- | --- | --- |
| Singapore | $5 | 512MB | Paypal | [DigitalOcean](https://m.do.co/c/01a54778df5c) |
| Japan | $5 | 1GB | Paypal | [Linode](https://www.linode.com/?r=5fd2b713d711746bb5451111df0f2b6d863e9f63) |
| Korea | $10 | 1GB | Alipay, Paypal | [Netdedi](https://www.netdedi.com/?affid=35) |
Wechaty use [AVA](https://github.com/avajs/ava) for unit testing
To test Wechaty, run:
```shell
npm test
```
Get to know more about test from [Wiki:Test](https://github.com/chatie/wechaty/wiki/Test)
# API Reference
......@@ -189,19 +197,6 @@ The following VPS providers is used by ourselves, they worked perfectly in produ
2. [accept():Promise](https://github.com/chatie/wechaty/wiki/API#friendrequestaccept-void) accept the friendrequest
3. [send(contact:Contact,hello:string):Promise](https://github.com/chatie/wechaty/wiki/API#friendrequestsendcontact-contact-hello-string-void) send a new friend request
# Test
[![Linux/Mac Build Status](https://img.shields.io/travis/Chatie/wechaty.svg?label=Linux/Mac)](https://travis-ci.org/Chatie/wechaty) [![Windows Build status](https://img.shields.io/appveyor/ci/chatie/wechaty/master.svg?label=Windows)](https://ci.appveyor.com/project/chatie/wechaty) [![Docker CircleCI](https://img.shields.io/circleci/project/github/Chatie/wechaty/master.svg?label=Docker)](https://circleci.com/gh/Chatie/wechaty) [![Coverage Status](https://coveralls.io/repos/github/Chatie/wechaty/badge.svg?branch=master)](https://coveralls.io/github/Chatie/wechaty?branch=master) [![Known Vulnerabilities](https://snyk.io/test/github/chatie/wechaty/badge.svg)](https://snyk.io/test/github/chatie/wechaty)
Wechaty use [AVA](https://github.com/avajs/ava) for unit testing
To test Wechaty, run:
```shell
npm test
```
Get to know more about test from [Wiki:Test](https://github.com/chatie/wechaty/wiki/Test)
# Release Notes
* [Latest Release](https://github.com/chatie/wechaty/releases/latest)(All releases [here](https://github.com/chatie/wechaty/releases))
......@@ -217,12 +212,31 @@ Get embed html/markdown code from [Wiki:PoweredByWechaty](https://github.com/cha
## Projects Use Wechaty
1. [chatie.io](https://www.chatie.io) ChatBot Portal Manager for Wechaty
1. [Relay between Telegram and WeChat](https://github.com/Firaenix/TeleChatRelay)
1. [A chat bot managing the HaoShiYou wechat groups run by volunteers of haoshiyou.org](https://github.com/xinbenlv/haoshiyou-bot)
1. [A chat interactive bot to manage TODO list](https://github.com/coderbunker/candobot)
1. [Forward WeChat messages to telegram](https://github.com/luosheng/Wegram)
Know more about Projects Use Wechaty at [Wiki:PoweredByWechaty](https://github.com/chatie/wechaty/wiki/PoweredByWechaty)
## Find a Good Server
The best practice for runing 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 is used by ourselves, they worked perfectly in production. You can use the following link to get one in minutes, and also do this can support Wechaty because you are refered by us.
| Location | Price | Ram | Payment | Provider |
| --- | --- | --- | --- | --- |
| Singapore | $5 | 512MB | Paypal | [DigitalOcean](https://m.do.co/c/01a54778df5c) |
| Japan | $5 | 1GB | Paypal | [Linode](https://www.linode.com/?r=5fd2b713d711746bb5451111df0f2b6d863e9f63) |
| Korea | $10 | 1GB | Alipay, Paypal | [Netdedi](https://www.netdedi.com/?affid=35) |
# Contributing
[![Issue Stats](http://issuestats.com/github/chatie/wechaty/badge/pr)](http://issuestats.com/github/chatie/wechaty)
[![Issue Stats](http://issuestats.com/github/chatie/wechaty/badge/issue)](http://issuestats.com/github/chatie/wechaty)
[![Join the chat at https://gitter.im/zixia/wechaty](https://badges.gitter.im/zixia/wechaty.svg)](https://gitter.im/zixia/wechaty?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
Howto [contribute](https://github.com/chatie/wechaty/blob/master/CONTRIBUTING.md)
Contributions in any form are highly encouraged and welcome! Be it new or improved presets, optimized streaming code or just some cleanup. So start forking!
......@@ -298,7 +312,7 @@ Huan LI <zixia@zixia.net> (http://linkedin.com/in/zixia)
Copyright & License
-------------------
* Code & Docs 2016-2017© zixia
* Code & Docs © 2016-2017 zixia
* Code released under the ISC license
* Docs released under Creative Commons
......
......@@ -61,7 +61,7 @@ bot
}
console.log(`${url}\n[${code}] Scan QR Code in above url to login: `)
})
.on('message', m => {
.on('message', async m => {
try {
const room = m.room()
console.log((room ? '[' + room.topic() + ']' : '')
......@@ -73,15 +73,13 @@ bot
m.say('dong')
log.info('Bot', 'REPLY: dong')
m.say(`Join Wechaty Developers' Community
Wechaty is used in many ChatBot projects by hundreds of developers.
If you want to talk with other developers, just scan the following QR Code in WeChat with secret code: wechaty,
you can join our Wechaty Developers' Home at once.
`.replace(/ /, ' '),
)
m.say(new MediaMessage(__dirname + '/../image/BotQrcode.png'))
m.say('Scan now, because other Wechaty developers want to talk with you too! (secret code: wechaty)')
const joinWechaty = `Join Wechaty Developers' Community\n\n` +
`Wechaty is used in many ChatBot projects by hundreds of developers.\n\n` +
`If you want to talk with other developers, just scan the following QR Code in WeChat with secret code: wechaty,\n\n` +
`you can join our Wechaty Developers' Home at once`
await m.say(joinWechaty)
await m.say(new MediaMessage(__dirname + '/../image/BotQrcode.png'))
await m.say('Scan now, because other Wechaty developers want to talk with you too!\n\n(secret code: wechaty)')
log.info('Bot', 'REPLY: Image')
}
} catch (e) {
......
{
"name": "wechaty",
"version": "0.8.36",
"version": "0.8.54",
"description": "Wechat for Bot(Personal Account)",
"main": "dist/index.js",
"types": "dist/index.d.ts",
......@@ -24,8 +24,8 @@
"doctor": "npm run check-node-version && ts-node bin/doctor",
"clean": "shx rm -fr dist/*",
"check-node-version": "check-node-version --node \">= 6.9\"",
"lint": "npm run check-node-version && npm run eslint && npm run tslint",
"nycava": "WECHATY_HEAD=chrome nyc ava --serial --fail-fast --verbose --timeout=3m \"dist/{src,test}/**/*.spec.js\"",
"lint": "npm run clean && npm run check-node-version && npm run eslint && npm run tslint",
"nycava": "WECHATY_HEAD=chrome nyc ava --serial --fail-fast --verbose --timeout=5m \"dist/{src,test}/**/*.spec.js\"",
"eslint": "eslint \"{bin,example,src,test}/**/*.js\" --ignore-pattern=\"test/fixture/**\"",
"tslint": "tslint --project tsconfig.json --type-check \"{bin,example,src,test}/**/*.ts\" --exclude=\"test/fixture/**\" --exclude=\"dist/\" && npm run clean && tsc --noEmit",
"shlint": "bash -n bin/*.sh",
......@@ -33,10 +33,10 @@
"sloc": "sloc bin example src test index.ts --details --format cli-table --keys total,source,comment && sloc bin example src test index.ts",
"test": "npm run test:chrome",
"posttest": "npm run clean && npm run sloc",
"test:phantomjs": "cross-env LC_ALL=C WECHATY_HEAD=phantomjs ava --verbose --fail-fast --serial --timeout=3m \"dist/{src,test}/**/*.spec.js\"",
"test:chrome": "cross-env LC_ALL=C WECHATY_HEAD=chrome ava --serial --fail-fast --verbose --timeout=3m \"dist/{src,test}/**/*.spec.js\"",
"test:bug": "cross-env LC_ALL=C WECHATY_HEAD=chrome WECHATY_LOG=silly ava --serial --fail-fast --verbose --timeout=3m \"dist/src/message.spec.js\"",
"test:chrome:fast": "cross-env LC_ALL=C WECHATY_HEAD=chrome ava --fail-fast --timeout=3m \"dist/{src,test}/**/*.spec.js\"",
"test:phantomjs": "cross-env LC_ALL=C WECHATY_HEAD=phantomjs ava --verbose --fail-fast --serial --timeout=5m \"dist/{src,test}/**/*.spec.js\"",
"test:chrome": "cross-env LC_ALL=C WECHATY_HEAD=chrome ava --serial --fail-fast --verbose --timeout=5m \"dist/{src,test}/**/*.spec.js\"",
"test:bug": "cross-env LC_ALL=C WECHATY_HEAD=chrome WECHATY_LOG=silly ava --serial --fail-fast --verbose --timeout=5m \"dist/src/message.spec.js\"",
"test:chrome:fast": "cross-env LC_ALL=C WECHATY_HEAD=chrome ava --fail-fast --timeout=5m \"dist/{src,test}/**/*.spec.js\"",
"testdev": "cross-env LC_ALL=C WECHATY_LOG=silly ava --ext ts --serial --verbose --fail-fast --timeout=2m",
"testdist": "cross-env WECHATY_LOG=SILLY WECHATY_HEAD=chrome ava --ext ts --verbose --fail-fast --timeout=2m",
"io-client": "ts-node bin/io-client",
......@@ -67,7 +67,7 @@
"微信控"
],
"author": {
"name": "Zhuohuan LI",
"name": "Huan LI",
"email": "zixia@zixia.net",
"url": "www.zixia.net"
},
......@@ -104,13 +104,13 @@
"node": ">= 6.9.0"
},
"dependencies": {
"@types/selenium-webdriver": "3.0.3",
"@types/selenium-webdriver": "3.0.4",
"@types/socket.io": "1.4.29",
"bl": "1.2.1",
"body-parser": "1.17.1",
"brolog": "1.1.18",
"chromedriver": "2.29.0",
"express": "5.0.0-alpha.5",
"express": "4.15.2",
"is-ci": "1.0.10",
"is-docker": "1.1.0",
"moment": "2.18.1",
......@@ -119,7 +119,7 @@
"selenium-webdriver": "3.4.0",
"socket.io": "1.7.4",
"state-switch": "0.1.13",
"ws": "2.3.1"
"ws": "3.0.0"
},
"devDependencies": {
"@types/body-parser": "1.16.3",
......@@ -128,7 +128,7 @@
"@types/mime": "0.0.29",
"@types/node": "7.0.18",
"@types/request": "0.0.43",
"@types/sinon": "2.2.1",
"@types/sinon": "2.2.2",
"@types/ws": "0.0.41",
"apiai": "4.0.2",
"ava": "0.18.2",
......@@ -164,12 +164,8 @@
"LICENSE",
"README.md",
"package.json",
"*.js",
"*.js.map",
"*.d.ts",
"bin/",
"dist/",
"src/"
"dist/"
],
"publishConfig": {
"tagBak": "next",
......
......@@ -152,8 +152,8 @@ export class Contact implements Sayable {
const wxId = this.obj && this.obj.weixin || null
if (!wxId) {
log.info('Contact', `weixin() is not able to always work, it's limited by Tencent API`)
log.silly('Contact', 'weixin() If you want to track a contact between sessions, see FAQ at')
log.silly('Contact', 'https://github.com/Chatie/wechaty/wiki/FAQ#1-how-to-get-the-permanent-id-for-a-contact')
log.info('Contact', 'weixin() If you want to track a contact between sessions, see FAQ at')
log.info('Contact', 'https://github.com/Chatie/wechaty/wiki/FAQ#1-how-to-get-the-permanent-id-for-a-contact')
}
return wxId
}
......
......@@ -474,8 +474,8 @@ export class Message implements Sayable {
log.verbose('Message', 'mentioned(%s),get mentionList: %s', this.content(), JSON.stringify(mentionList))
contactList = [].concat.apply([],
mentionList.map(member => {
room.memberAll(member)
mentionList.map(nameStr => {
room.memberAll(nameStr)
})
.filter(contact => !!contact),
)
......
......@@ -123,13 +123,49 @@ export class Browser extends EventEmitter {
throw new Error('hostname unknown')
}
// Issue #175
// TODO: set a timer to guard driver.get timeout, then retry 3 times 201607
try {
await this.driver.get(url)
} catch (e) {
log.error('PuppetWebBrowser', 'open() exception: %s', e.message)
throw e
const TIMEOUT = 60 * 1000
let TTL = 0
while (TTL++ < 3) {
log.silly('PuppetWebBrowser', 'open() begin for ttl:%d', TTL)
try {
await new Promise((resolve, reject) => {
const id = setTimeout(() => {
try {
this.driver.close()
} catch (e) {
log.warn('PuppetWebBrowser', 'open() timeout, close driver exception: %s',
e.message,
)
}
const e = new Error('timeout after '
+ Math.round(TIMEOUT / 1000) + ' seconds'
+ 'at ttl:' + TTL,
)
reject(e)
}, TIMEOUT)
this.driver.get(url)
.then(() => {
clearTimeout(id)
resolve()
})
.catch(reject)
})
// open successful!
log.silly('PuppetWebBrowser', 'open() end for ttl:%d', TTL)
return
} catch (e) {
log.error('PuppetWebBrowser', 'open() exception: %s', e.message)
}
}
throw new Error('open fail because ttl(' + TTL + ') exceed')
}
public async refresh(): Promise<void> {
......
......@@ -397,6 +397,7 @@ export class Room extends EventEmitter implements Sayable {
return Contact.load(this.rawObj.ChatRoomOwner)
}
log.info('Room', 'owner() is limited by Tencent API, sometimes work sometimes not')
return null
}
......@@ -437,7 +438,7 @@ export class Room extends EventEmitter implements Sayable {
/**
* We got filter parameter
*/
log.silly('Room', 'member({ %s })',
log.silly('Room', 'memberAll({ %s })',
Object.keys(queryArg)
.map(k => `${k}: ${queryArg[k]}`)
.join(', '),
......@@ -451,7 +452,7 @@ export class Room extends EventEmitter implements Sayable {
log.warn('Room', 'member() not ready')
return []
}
let filterKey = Object.keys(queryArg)[0]
const filterKey = Object.keys(queryArg)[0]
/**
* ISSUE #64 emoji need to be striped
*/
......@@ -464,20 +465,20 @@ export class Room extends EventEmitter implements Sayable {
roomAlias: 'roomAliasMap',
}
filterKey = keyMap[filterKey]
if (!filterKey) {
throw new Error('unsupport filter key')
const filterMapName = keyMap[filterKey]
if (!filterMapName) {
throw new Error('unsupport filter key: ' + filterKey)
}
if (!filterValue) {
throw new Error('filterValue not found')
}
const filterMap = this.obj[filterKey]
const filterMap = this.obj[filterMapName]
const idList = Object.keys(filterMap)
.filter(k => filterMap[k] === filterValue)
.filter(id => filterMap[id] === filterValue)
log.silly('Room', 'member() check %s from %s: %s', filterValue, filterKey, JSON.stringify(filterMap))
log.silly('Room', 'memberAll() check %s from %s: %s', filterValue, filterKey, JSON.stringify(filterMap))
if (idList.length) {
return idList.map(id => Contact.load(id))
......@@ -498,7 +499,7 @@ export class Room extends EventEmitter implements Sayable {
}
if (memberList.length > 1) {
log.warn('Room', 'function member(%s) get %d contacts, use the first one by default', JSON.stringify(queryArg), memberList.length)
log.warn('Room', 'member(%s) get %d contacts, use the first one by default', JSON.stringify(queryArg), memberList.length)
}
return memberList[0]
}
......
......@@ -108,15 +108,15 @@ test('Room smoking test', async t => {
t.is(r.topic() , EXPECTED.topic, 'should set topic/NickName')
const contact1 = new Contact(EXPECTED.memberId1)
const nick1 = r.nick(contact1)
t.is(nick1, EXPECTED.memberNick1, 'should get roomAlias')
const alias1 = r.alias(contact1)
t.is(alias1, EXPECTED.memberNick1, 'should get roomAlias')
const name1 = r.alias(contact1)
t.is(name1, EXPECTED.memberNick1, 'should get roomAlias')
const contact2 = new Contact(EXPECTED.memberId2)
const nick2 = r.nick(contact2)
t.is(nick2, null, 'should return null if not set roomAlias')
const alias2 = r.alias(contact2)
t.is(alias2, null, 'should return null if not set roomAlias')
const name2 = r.alias(contact2)
t.is(name2, null, 'should return null if not set roomAlias')
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册