-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
143 lines (129 loc) · 4.52 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
/**
* Commands Plugin for Unibot
* @param {Object} options [description]
* db: {mongoose} the mongodb connection
* bot: {irc} the irc bot
* web: {connect} a connect + connect-rest webserver
* config: {object}
* @return {Function} init function to access shared resources
*/
module.exports = function init(options){
var mongoose = options.db;
var bot = options.bot;
var webserver = options.web;
var config = options.config;
/**
* Creating a mongoose schema for a channel command collection record (1 record per channel)
* {
* channel: '123-abc',
* commands: {
* 'help': 'Let me help you!',
* 'hello': 'Hi there'
* }
* }
*
*/
var Commands = new mongoose.Schema({
channel : {
type : String, // channel._id
index : {
unique : true,
dropDups : false
}
},
commands : {
type: mongoose.Schema.Types.Mixed,
default: {}
}
});
var model = mongoose.model('Commands', Commands);
webserver.get('/commands', function(req, res, next){
res.sendFile(__dirname + '/index.html');
});
webserver.get('/commands/:channel', function(req, res, next) {
model.findOne({ channel: req.params.channel }, function(err, commands){
res.send(err || commands);
});
});
// lowercase and escapes characters that are invalid JSON keys
function cleanCommand(input) {
var out = input;
return out.replace(/\$/g, String.fromCharCode(0xFF04)).replace(/\./g, '.').toLowerCase();
}
return function plugin(channel){
// Retrieve or create a new mongo record for this channel and store it to `commands`
var commands;
model.findOne({ channel: channel.id }, function(err, _commands_){
if (err || !_commands_) {
commands = new model({
channel: channel.id
});
commands.save();
} else {
commands = _commands_;
}
});
return {
// Execute Command
// [nick:] !command [tokens]
"(?:(\\S+)[:,] )?(?:!(\\S+))(?: (.+))?": function(from, matches) {
if (!commands) return; // mongoose hasn't retrieved channel record yet
matches[2] = cleanCommand(matches[2]);
if (!commands.commands[matches[2]]) return;
if (matches[1]) from = matches[1];
var message = commands.commands[matches[2]];
var tokens = matches[3] || '';
tokens = tokens.split(' ');
message = message.split(':tokens').join(tokens.join('+'));
var l = tokens.length;
while (l--) {
message = message.split( ':token'+ (l + 1) ).join(tokens[l]);
}
message
message = message.split(':nick').join(from);
channel.say(message);
},
// Save Command
// !remember [command] is [Hello :nick, this is the output :tokens]
"^!remember (\\S+) is (.+)": function(from, matches) {
if (!commands) return; // mongoose hasn't retrieved channel record yet
matches[1] = cleanCommand(matches[1]);
commands.commands[matches[1]] = matches[2];
commands.markModified('commands');
commands.save(function(err){
if (err) {
channel.say('Error saving "'+matches[1]+'": '+err, from);
if (config.owner)
channel.say('Please notify '+config.owner, from);
} else {
channel.say('Command "'+matches[1]+'" saved!', from);
}
});
},
// Delete Command
"^!forget (\\S+)": function(from, matches) {
if (!commands) return; // mongoose hasn't retrieved channel record yet
matches[1] = cleanCommand(matches[1]);
if (!commands.commands[matches[1]]) return channel.say('Command Not Found: '+matches[1], from);
delete commands.commands[matches[1]];
commands.markModified('commands');
commands.save(function(err){
if (err) {
channel.say('Error removing "'+matches[1]+'": '+err, from);
if (config.owner)
channel.say('Please notify '+config.owner, from);
} else {
channel.say('Command "'+matches[1]+'" forgotten!', from);
}
});
},
// Show Raw Command
"^!show (\\S+)": function(from, matches) {
if (!commands) return; // mongoose hasn't retrieved channel record yet
matches[1] = cleanCommand(matches[1]);
if (!commands.commands[matches[1]]) return channel.say('Command Not Found: '+matches[1], from);
channel.say(commands.commands[matches[1]], from);
}
};
};
};