-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommands.ts
157 lines (149 loc) · 4.67 KB
/
commands.ts
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
156
157
import * as Discord from "discord.js";
import { default as JSONInterface, default as JSONParser } from "./json_parser";
import { duckSearch } from "./search"
import { Cat, Dog} from "./catdog"
export interface Command {
onCall: (message: Discord.Message, args: string[]) => void;
}
export interface CommandCollection {
[commandName: string]: Command;
}
export interface CustomCommand {
response: string;
}
export interface CustomCommandCollection {
[commandName: string]: CustomCommand;
}
export default class CommandManager {
botID: string;
/**
* The character that indicates the start of a command.
*/
commandToken = "!";
commands: CommandCollection = {};
customCommands: CustomCommandCollection = {};
jsonParser: JSONInterface;
cmdNameRegex = new RegExp('^[A-Za-z0-9]+$')
constructor(botID: string, commandsFilename: string) {
this.botID = botID;
// Grab all commands
// these are just test ones for now
this.commands["addcommand"] = {
onCall: this.addNewCommand.bind(this)
};
this.commands["removecommand"] = {
onCall: (message, args) => this.removeCommand(message, args)
};
this.commands["s"] = {
onCall: (message, args) => this.searchCommand(message, args)
};
this.commands["meow"] = {
onCall: (message) => this.animalCommand("cat", message)
};
this.commands["woof"] = {
onCall: (message) => this.animalCommand("dog", message)
};
this.jsonParser = new JSONParser(commandsFilename);
// Grab commands from the JSON file, if any
const commandJSON: any = this.jsonParser.ReadFromJSON();
for (const [commandName, commandData] of Object.entries(commandJSON)) {
const typedData = commandData as any;
this.customCommands[commandName] = typedData;
}
}
addNewCommand(
message: Discord.Message,
[cmdName, ...cmdResponse]: string[]
) {
if (
!cmdName ||
cmdName in this.customCommands ||
cmdName in this.commands
) {
message.channel.send(`Failed to create command ${cmdName}`);
return;
} else if (!this.cmdNameRegex.test(cmdName)) {
message.channel.send(`Command name must be alphanumeric`);
return;
}
try {
let cmdResponseString = cmdResponse.join(" ");
this.customCommands[cmdName] = {
response: cmdResponseString
};
this.jsonParser.WriteToJSON(this.customCommands);
} catch (err) {
message.channel.send(`Failed to create command ${cmdName}`);
// DEBUG
console.log(err);
return;
}
message.channel.send(`Successfully created command ${cmdName}`);
}
removeCommand(message: Discord.Message, [cmdName]: string[]) {
delete this.customCommands[cmdName];
this.jsonParser.WriteToJSON(this.customCommands);
message.channel.send(`Successfully deleted command ${cmdName}`);
}
searchCommand(message: Discord.Message, ...query) {
const queryString = query[0].join(" ")
duckSearch(queryString).then(result => {
console.log("DuckDuckGo API result: ", result)
// TODO add a formatted response that change based on the Type
let response = "No results found"
if (["D"].includes(result.Type)) {
response =
`${result.RelatedTopics[0].Text}
${result.RelatedTopics[0].FirstURL}
`;
}
if (["A", "C"].includes(result.Type)) {
response = result.AbstractURL;
}
if (result.Redirect && result.Redirect != "") {
response = result.Redirect;
}
console.log(response)
message.channel.send(response);
}).catch(err => {
console.log("Error from API call: ", err)
message.channel.send("There was an error in your search.")
});
}
animalCommand(animal: "cat" | "dog", message: Discord.Message) {
const callback = result => {
message.channel.send(result.message, { files: [ result.image_url ] } )
}
const err_func = err => {
console.log(err);
message.channel.send(`There was a problem grabbing your ${animal}!`)
};
if (animal === "cat") {
Cat.getPic(message.author.username).then(callback).catch(err_func)
} else if (animal === "dog") {
Dog.getPic(message.author.username).then(callback).catch(err_func)
}
}
/**
* Parses a message body and calls a command if one was issued.
* @param messageBody
*/
parseMessage(message: Discord.Message) {
// TODO: return if the bot is the one sending the message
if (message.author.id === this.botID) {
return;
}
if (message.content.includes(this.commandToken)) {
// Grab the command being called
const commandInfo = message.content.substring(1).split(/ +/);
const [commandName, ...commandArgs] = commandInfo;
if (commandName in this.commands) {
const command = this.commands[commandName];
command.onCall(message, commandArgs);
} else if (commandName in this.customCommands) {
const command = this.customCommands[commandName];
message.channel.send(command.response);
}
}
}
}