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

add npmignore

上级 cd24b2fe
doc
example
test
circle.yml
.travis.yml
......@@ -62,7 +62,7 @@ Plan to glue with Machine Learning/Deep Learning/Neural Network/Natural Language
# Installation
# Use NPM - to Use in Production
# Install from NPM
Use NPM is recommended to install a stable version of Wechaty published on NPM.com
```shell
npm install --save wechaty
......@@ -70,8 +70,8 @@ npm install --save wechaty
Then you are set.
# Start from source - to Hack / Development
In case that you want to dive into Wechaty, then follow instructions would help you to run Wechaty bot on your machine, and easy to hack.
# Install from Github(for hack)
In case that you want to dive deeper into Wechaty, fork & clone to run Wechaty bot on your machine, and start hacking.
## 1. Install Node.js
Node.js Version 6.0 or above is required.
......@@ -294,17 +294,37 @@ Know more about TAP: [Why I use Tape Instead of Mocha & So Should You](https://m
4. ...
## v0.0.5 (2016/5/11)
1. Receive & send message
1. Receive & send text message
1. Show contacts info
1. Show groups info
1. 1st usable version
1. Start coding from May 1st 2016
# Todo List
[ ] Deal with friend request
[ ] Manage contacts(send friend request/delete contact etc.)
[ ] Create a new chat group, invite people to join
## v0.0.1 (2016/5/1)
1. Start coding
2. Publish the very first npm module `wechaty`
# Todo List
[ ] Contact
[ ] Accept a friend request
[ ] Send a friend request
[ ] Delete a contact
[ ] Chat Group
[ ] Create a new chat group
[ ] Invite people to join a existing chat group
[ ] Rename a Chat Group
[ ] Events
[ ] Use EventEmitter2 to emit message events, so we can use wildcard
1. `message`
2. `message.recv`
3. `message.sent`
4. `message.recv.image`
5. `message.sent.image`
6. `message.recv.sys`
1. `message.**.image`
1. `message.recv.*`
[ ] Message
[ ] Send/Reply image message
Everybody is welcome to issue your needs.
# Known Issues & Support
......
......@@ -1572,7 +1572,20 @@ angular.module("Controllers", []),
}(),
!function() {
"use strict";
angular.module("Controllers").controller("contextMenuController", ["$rootScope", "$scope", "$state", "contextMenuFactory", "accountFactory", "confFactory", "contactFactory", "ngDialog", "chatroomFactory", "emojiFactory", "utilFactory", "chatFactory", function(e, t, o, n, r, a, i, c, s, l, u, f) {
angular.module("Controllers").controller("contextMenuController", ["$rootScope", "$scope", "$state", "contextMenuFactory", "accountFactory", "confFactory", "contactFactory", "ngDialog", "chatroomFactory", "emojiFactory", "utilFactory", "chatFactory", function(
e // $rootScope
, t // $scope
, o // $state
, n // contextMenuFactory
, r // accountFactory
, a // confFactory
, i // contactFactory
, c // ngDialog
, s // chatroomFactory
, l // emojiFactory
, u // utilFactory
, f // chatFactory
) {
function d(e) {
function o(e) {
return e.parentNode != e.document ? (n.push(e.parentNode),
......@@ -3974,7 +3987,11 @@ angular.module("Services", []),
}(),
!function() {
"use strict";
angular.module("Services").factory("utilFactory", ["$q", "$rootScope", "confFactory", function(e, t, o) {
angular.module("Services").factory("utilFactory", ["$q", "$rootScope", "confFactory", function(
e // $q
, t // $rootScope
, o // $confFactory
) {
function n(e, t, o, n) {
var r;
(r = l[e]) ? (r.intervalSum += o,
......
var apiai = require('apiai')
var app = apiai('7217d7bce18c4bcfbe04ba7bdfaf9c08')
var request = app.textRequest('Hello')
request.on('response', function(response) {
console.log(response)
/**
*
* Wechaty bot use a ApiAi.com brain
*
* Apply your own tuling123.com API_KEY
* at: http://www.tuling123.com/html/doc/api.html
*
* Enjoy!
*
* Wechaty - https://github.com/zixia/wechaty
*
*/
const log = require('npmlog')
const co = require('co')
const ApiAi = require('apiai')
const EventEmitter2 = require('eventemitter2')
const Wechaty = require('../src/wechaty')
//log.level = 'verbose'
// log.level = 'silly'
/**
*
* Apply Your Own ApiAi Developer API_KEY at:
* http://www.api.ai
*
* `7217d7bce18c4bcfbe04ba7bdfaf9c08` for Wechaty demo
*
*/
const APIAI_API_KEY = '7217d7bce18c4bcfbe04ba7bdfaf9c08'
const brainApiAi = ApiAi(APIAI_API_KEY)
const bot = new Wechaty({head: false})
console.log(`
Welcome to Tuling Wechaty Bot.
Api.AI Doc: https://docs.api.ai/v16/docs/get-started
Notice: This bot will only active in the group which name contains 'wechaty'.
/* if (m.group() && /Wechaty/i.test(m.group().name())) { */
Loading... please wait for QrCode Image Url and then scan to login.
`)
bot
.on('scan', ({url, code}) => {
console.log(`[${code}]Scan qrcode in url to login:\n${url}`)
})
request.on('error', function(error) {
console.log(error)
.on('login' , user => log.info('Bot', `bot login: ${user}`))
.on('logout' , e => log.info('Bot', 'bot logout.'))
.on('message', m => {
co(function* () {
const msg = yield m.ready()
if (m.group() && /Wechaty/i.test(m.group().name())) {
log.info('Bot', 'talk: %s' , msg)
talk(m)
} else {
log.info('Bot', 'recv: %s' , msg)
}
})
.catch(e => log.error('Bot', 'on message rejected: %s' , e))
})
request.end()
bot.init()
.catch(e => {
log.error('Bot', 'init() fail:' + e)
bot.quit()
process.exit(-1)
})
class Talker extends EventEmitter2 {
constructor(thinker) {
log.verbose('Talker()')
super()
this.thinker = thinker
this.obj = {
text: []
, time: []
}
this.timer = null
}
save(text) {
log.verbose('Talker', 'save(%s)', text)
this.obj.text.push(text)
this.obj.time.push(Date.now())
}
load() {
const text = this.obj.text.join(', ')
log.verbose('Talker', 'load(%s)', text)
this.obj.text = []
this.obj.time = []
return text
}
updateTimer(delayTime) {
delayTime = delayTime || this.delayTime()
log.verbose('Talker', 'updateTimer(%s)', delayTime)
if (this.timer) { clearTimeout(this.timer) }
this.timer = setTimeout(this.say.bind(this), delayTime)
}
hear(text) {
log.verbose('Talker', `hear(${text})`)
this.save(text)
this.updateTimer()
}
say() {
log.verbose('Talker', 'say()')
const text = this.load()
this.thinker(text)
.then(reply => this.emit('say', reply))
this.timer = null
}
delayTime() {
const minDelayTime = 5000
const maxDelayTime = 15000
const delayTime = Math.floor(Math.random() * (maxDelayTime - minDelayTime)) + minDelayTime
return delayTime
}
}
var Talkers = []
function talk(m) {
const fromId = m.from().id
const groupId = m.group().id
const content = m.content()
const talkerName = fromId + groupId
if (!Talkers[talkerName]) {
Talkers[talkerName] = new Talker(function(text) {
return new Promise((resolve, reject) => {
brainApiAi.textRequest(text)
.on('response', function(response) {
console.log(response)
/*
{ id: 'a09381bb-8195-4139-b49c-a2d03ad5e014',
timestamp: '2016-05-27T17:22:46.597Z',
result:
{ source: 'domains',
resolvedQuery: 'hi',
action: 'smalltalk.greetings',
parameters: { simplified: 'hello' },
metadata: {},
fulfillment: { speech: 'Hi there.' },
score: 0 },
status: { code: 200, errorType: 'success' } }
*/
const reply = response.result.fulfillment.speech
if (!reply) {
log.info('ApiAi', `Talker do not want to talk for "${text}"`)
return reject()
}
log.info('ApiAi', 'Talker reply:"%s" for "%s" ', reply, text)
return resolve(reply)
})
.on('error', function(error) {
log.error('ApiAi', error)
reject(error)
})
.end()
})
})
Talkers[talkerName].on('say', reply => bot.reply(m, reply))
}
Talkers[talkerName].hear(content)
}
......@@ -41,7 +41,7 @@ Loading...
`)
bot
.on('login' , e => log.info('Bot', 'bot login.'))
.on('login' , user => log.info('Bot', `bot login: ${user}`))
.on('logout' , e => log.info('Bot', 'bot logout.'))
.on('scan', ({url, code}) => {
console.log(`[${code}]Scan qrcode in url to login:\n${url}`)
......@@ -124,20 +124,20 @@ class Talker extends EventEmitter2 {
var Talkers = []
function talk(m) {
const fromId = m.from().id
const groupId = m.group().id
const content = m.content()
const talkerName = fromId + groupId
if (!Talkers[talkerName]) {
Talkers[talkerName] = new Talker(function(text) {
return brain.ask(text, {userid: talkerName})
.then(r => {
log.info('Tuling123', 'Talker reply:"%s" for "%s" ', r.text, text)
return r.text
})
const fromId = m.from().id
const groupId = m.group().id
const content = m.content()
const talkerName = fromId + groupId
if (!Talkers[talkerName]) {
Talkers[talkerName] = new Talker(function(text) {
return brain.ask(text, {userid: talkerName})
.then(r => {
log.info('Tuling123', 'Talker reply:"%s" for "%s" ', r.text, text)
return r.text
})
Talkers[talkerName].on('say', reply => bot.reply(m, reply))
}
Talkers[talkerName].hear(content)
})
Talkers[talkerName].on('say', reply => bot.reply(m, reply))
}
Talkers[talkerName].hear(content)
}
......@@ -30,6 +30,8 @@ class Contact {
, province: rawObj.Province
, city: rawObj.City
, signature: rawObj.Signature
, stranger: rawObj.stranger // assign by injectio.js
}
}
name() { return this.obj.name }
......@@ -65,15 +67,17 @@ class Contact {
get(prop) { return this.obj[prop] }
send(message) {
}
static find() {
}
static findAll() {
send(message) {
const msg = new Contact.puppet.Message() // create a empty message
msg.set('from', this)
msg.set('content', message)
return Contact.puppet.send(message)
}
stranger() { return this.obj.stranger }
static find() { }
static findAll() { }
}
Contact.init = function() { Contact.pool = {} }
......
......@@ -39,6 +39,7 @@ class Bridge {
getUserName() { return this.proxyWechaty('getUserName') }
getContact(id) {
// TODO: use retry-promise instead of waitData
return this.waitData(r => {
return this.proxyWechaty('getContact', id)
}, 3000)
......@@ -49,6 +50,7 @@ class Bridge {
*
* @param {Function} pfunc
* @param {Number} timeout
*
* @TODO: change waitData to retry-promise
*/
waitData(pfunc, timeout) {
......@@ -66,12 +68,10 @@ class Bridge {
} else if (totalTime > timeout) {
log.silly('Bridge', `waitData(${totalTime}/${timeout}) timeout`)
return resolve()
} else {
log.silly('Bridge', `waitData(${totalTime}/${timeout}) retry`)
totalTime += waitTime
return setTimeout(retry, waitTime)
}
throw new Error('should not run to here')
log.silly('Bridge', `waitData(${totalTime}/${timeout}) retry`)
totalTime += waitTime
return setTimeout(retry, waitTime)
})
} catch (e) {
log.silly('Bridge', `waitData(${totalTime}/${timeout}) exception: %s`, e)
......@@ -148,5 +148,8 @@ ac = Wechaty.glue.contactFactory.getAllContacts();
Object.keys(ac).filter(function(k) { return /李/.test(ac[k].NickName) }).map(function(k) { var c = ac[k]; return {NickName: c.NickName, Alias: c.Alias, Uin: c.Uin, MMInChatRoom: c.MMInChatRoom} })
Object.keys(window._chatContent).filter(function (k) { return window._chatContent[k].length > 0 }).map(function (k) { return window._chatContent[k].map(function (v) {return v.MMDigestTime}) })
.web_wechat_tab_add
.web_wechat_tab_launch-chat
*
*/
\ No newline at end of file
......@@ -2,6 +2,8 @@
*
* Wechaty - Wechat for Bot, and human who talk to bot.
*
* Class PuppetWebInjectio
*
* Inject this js code to browser,
* in order to interactive with wechat web program.
*
......@@ -9,6 +11,9 @@
* https://github.com/zixia/wechaty-lib
*
*/
/*global angular*/
if (typeof Wechaty !== 'undefined') {
return 'Wechaty already injected?'
}
......@@ -188,7 +193,9 @@ return (function(port) {
}
function getContact(id) {
if (Wechaty.glue.contactFactory) {
return Wechaty.glue.contactFactory.getContact(id)
var c = Wechaty.glue.contactFactory.getContact(id)
c.stranger = !(c.isContact())
return c
}
log('contactFactory not inited')
return null
......@@ -232,8 +239,8 @@ return (function(port) {
}
if (Wechaty.vars.eventsBuf.length) {
clog('Wechaty.vars.eventsBuf has ' + Wechaty.vars.eventsBuf.length + ' unsend events')
var eventData
while (eventData = Wechaty.vars.eventsBuf.pop()) {
while (Wechaty.vars.eventsBuf.length) {
var eventData = Wechaty.vars.eventsBuf.pop()
Wechaty.vars.socket.emit(eventData[0], eventData[1])
}
clog('Wechaty.vars.eventsBuf all sent')
......@@ -257,7 +264,7 @@ return (function(port) {
return // wait to be called via script.onload()
}
// Wechaty global variable: socket
/*global io*/ // Wechaty global variable: socket
var socket = Wechaty.vars.socket = io.connect('https://127.0.0.1:' + port)
// ding -> dong. for test & live check purpose
......
/**
* Wechat for Bot. and for human who can talk with bot/robot
*
* Interface for puppet
* Web Server for puppet
*
* Class PuppetWebServer
*
* Licenst: ISC
* https://github.com/zixia/wechaty
*
......
......@@ -2,7 +2,8 @@
*
* wechaty: Wechat for Bot. and for human who talk to bot/robot
*
* Web Puppet
* Class PuppetWeb
*
* use to control wechat web.
*
* Licenst: ISC
......
......@@ -2,6 +2,8 @@
* Wechat for Bot. and for human who can talk with bot/robot
*
* Interface for puppet
*
* Class Puppet
*
* Licenst: ISC
* https://github.com/zixia/wechaty
......
......@@ -2,10 +2,13 @@
*
* wechaty: Wechat for Bot. and for human who talk to bot/robot
*
* Class Wechaty
*
* Licenst: ISC
* https://github.com/zixia/wechaty
*
*/
const log = require('npmlog')
const EventEmitter = require('events')
......@@ -87,4 +90,7 @@ Object.assign(Wechaty, {
, Group: Group
})
module.exports = Wechaty
/**
* Expose `Wechaty`.
*/
module.exports = Wechaty['default'] = Wechaty.Wechaty = Wechaty
\ No newline at end of file
'use strict'
const path = require('path')
const co = require('co')
const test = require('tap').test
......@@ -64,7 +66,7 @@ test('WebDriver process create & quit test', function(t) {
})
// XXX WTF with co module???
false && test('WebDriver smoke testing', function(t) {
test('WebDriver smoke testing', function(t) {
const wb = new PuppetWebBrowser()
t.ok(wb, 'Browser instnace')
......@@ -122,6 +124,7 @@ test('WebDriver WTF testing', function(t) {
t.ok(bridge, 'Bridge instnace')
var driver // for help function `execute`
var injectio
driverProcessNum()
.then(n => {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册