-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
155 lines (133 loc) · 3.6 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
var util = require('util');
var EventEmitter = require('events').EventEmitter;
var request = require('request');
var io = require('socket.io-client');
var crypto = require('crypto');
var cheerio = require('cheerio');
var clockDrift = 30000;
var defaultMeats = "https://chat.meatspac.es";
var defaultMessage = "My author gave me nothing to say";
function Bot() {
EventEmitter.call(this);
if (!this.name) throw new Error("missing name");
if (!this.fingerprint) throw new Error("missing fingerprint");
this.jar = request.jar();
}
util.inherits(Bot, EventEmitter);
Bot.prototype.connect = function(host) {
this.host = host || defaultMeats;
this.socket = io.connect(this.host);
this.socket.on("connect", this.emit.bind(this, "connect"));
this.socket.on("disconnect", this.emit.bind(this, "disconnect"));
this._setup(function(err) {
if (err) return cb(err);
this.socket.on("message", this._handleMessage.bind(this));
}.bind(this));
return this;
};
Bot.prototype.getAvatar = function(cb) {
if (typeof this.avatar === 'string') {
return cb(null, this.avatar);
}
if (Array.isArray(this.avatar)) {
return cb(null, this.avatar[Math.floor(Math.random()*this.avatar.length)]);
}
};
Bot.prototype.getResponse = function(msg, cb) {
cb(null, defaultMessage);
};
Bot.prototype.sendMessage = function(pic, msgTxt, cb) {
var userId = this.fingerprint + this.ip;
userId = crypto.createHash('md5')
.update(userId)
.digest('hex');
var url = this.host + "/add/chat";
var body = {
picture: pic,
message: msgTxt,
fingerprint: this.fingerprint,
userid: userId,
_csrf: this.csrf
};
var ropt = {
method: 'POST',
url: url,
json: body,
jar: this.jar
};
request(ropt, function(err, res, body) {
if (err) return cb(err);
if (res.statusCode !== 200) {
return cb(new Error("failed to send message " + res.statusCode));
}
this.emit('response', pic, msgTxt);
cb();
}.bind(this));
return this;
};
Bot.prototype.respond = function(msg, cb) {
this.getAvatar(function(err, pic) {
if (err) return cb(err);
this.getResponse(msg, function(err, msgTxt) {
if (err) return cb(err);
this.sendMessage(pic, msgTxt, cb);
}.bind(this));
}.bind(this));
return this;
};
/* internal garb */
Bot.prototype._handleMessage = function(d) {
var msg = d.chat.value;
msg.message = String(msg.message).trim();
// dont show old msgs
msg.drift = Date.now() - msg.created;
if (msg.drift > clockDrift) return;
this.emit("message", msg);
if (msg.message.indexOf(this.name) !== -1) {
this.respond(msg, function(err) {
if (err) this.emit('error', err);
}.bind(this));
}
return this;
};
Bot.prototype._setup = function(cb) {
this._setIp(function(err, ip) {
if (err) return cb(err);
this.emit('ip', ip);
this.ip = ip;
this._setCsrf(function(err, csrf) {
if (err) return cb(err);
this.emit('csrf', csrf);
this.csrf = csrf;
return cb(null, ip, csrf);
}.bind(this));
}.bind(this));
return this;
};
Bot.prototype._setCsrf = function(cb) {
var ropt = {
url: this.host,
jar: this.jar
};
request(ropt, function(err, res, body) {
if (err) return cb(err);
var $ = cheerio.load(body);
var csrf = $("input[name='_csrf']").val();
cb(null, csrf);
});
return this;
};
Bot.prototype._setIp = function(cb) {
var ropt = {
url: this.host + "/ip",
json: true,
jar: this.jar
};
return request(ropt, function(err, res, body) {
if (err) return cb(err);
var ip = body.ip;
return cb(null, ip);
});
return this;
};
module.exports = Bot;