-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparsemessage.js
102 lines (88 loc) · 2.42 KB
/
parsemessage.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
var S = require('string');
var codes = require('./codes');
/**
* The prefix of a message sits between the : and the first space.
*/
var getPrefix = function(s) {
if (s.startsWith(':')) {
return s.between(':', ' ');
}
return null;
};
/**
* Returns the nick, user, and host in the message (format: nick!user@host).
*/
var getNickUserHost = function(s) {
var nick = s.between( '', '!');
var user = s.between('!', '@');
var host = s.between('@');
if (nick && user && host) {
return {
nick: nick,
user: user,
host: host
};
}
return null;
};
/**
* Create an object representing the given IRC message.
*/
var parseMessage = function(msg) {
// The return value
var message = {};
// Create a string.js object to use for string operations
var s = S(msg);
// Check for prefix
var prefix = getPrefix(s);
if (prefix) {
message.prefix = prefix.s;
// Then check for nick!user@host or server.host.name
var match = getNickUserHost(prefix);
if (match) {
message.nick = match.nick.s;
message.user = match.user.s;
message.host = match.host.s;
} else {
message.server = message.prefix;
}
// Because the prefix has been processed, trim it off
s = s.between(' ');
}
// Grab the command (potentially just a number, i.e. no spaces)
var command = s.between('', ' ');
if (command.s == '') {
command = s;
}
// Fetch the command name, if possible
message.cmd = codes.replies[command.s] ||
codes.errors[command.s] ||
command.s;
/*
* Time to parse parameters.
*
* We start by trimming off the command itself, and then continue to trim
* off the space following it and the colon following that. The space and
* the colon are both optional, but chomping is safe (no-op if no match).
*/
s = s.chompLeft(command).chompLeft(' ').chompLeft(':').trimRight();
message.s = s;
message.args = s.s;
/*
* Special cases are handled explicitly here for convenience.
*
* PRIVMSG
* This is either a channel message or a private message. We parse the
* channel (or undefined), and the raw text.
*/
switch (message.cmd) {
case 'PRIVMSG':
message.channel = s.startsWith('#') ? s.between('', ' ').s : undefined;
message.s = s.between(':');
message.args = message.s.s;
break;
}
// Finally, return the message object
return message;
};
module.exports = parseMessage;