-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.js
183 lines (160 loc) · 4.97 KB
/
app.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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// @flow
const Discord = require("discord.js");
const MongoClient = require("mongodb").MongoClient;
const _ = require("lodash");
const request = require("request");
const moment = require("moment");
const bot = new Discord.Client();
const { getItemID, calculateUniqueProbability } = require("./utils.js");
const config = require("./config.json");
const ITEM_DATA = require("./itemData.json");
const DB_URI = `mongodb+srv://${config.db_user}:${config.db_password}@${
config.db_url
}`;
const ROTATIONS_IMAGE_URL = "https://i.redd.it/hdfsf45xwzqy.png";
const OSRS_GE_BASE_URL =
"http://services.runescape.com/m=itemdb_oldschool/api/catalogue/detail.json?item=";
const HELP_MESSAGE =
"This bot supports the following commands:\n" +
"- `!help`: provides an overview of the bots functionality\n" +
"- `!rotation`: displays the different possible raid rotations\n" +
"- `!item [itemName]`: displays the drop rate and current price of the specified raids items\n" +
"- `!drop [points]`: calculates the % chance of receiving a unique drop based on the amount of points accumulated in a raid";
const COMMANDS = {
HELP: "help",
ROTATION: "rotation",
ITEM: "item",
DROP: "drop"
};
bot.login(config.token);
bot.on("ready", () => {
console.log("Bot has started successfully!");
bot.user.setPresence({
status: "Online",
game: {
name: "Old School RuneScape",
type: "LISTENING"
}
});
updateDBItems();
setInterval(() => {
updateDBItems();
}, config.update_item_interval);
});
bot.on("message", async message => {
if (message.author.bot || message.content.indexOf(config.prefix) !== 0) {
return;
}
const args = message.content
.slice(config.prefix.length)
.trim()
.split(/ +/g);
const command = args.shift().toLowerCase();
const { HELP, ROTATION, DROP, ITEM } = COMMANDS;
const commandsWithArgs = [DROP, ITEM];
if (!COMMANDS[command.toUpperCase()]) {
return;
}
if (commandsWithArgs.indexOf(command) !== -1 && _.isEmpty(args)) {
message.channel.send(
"ERROR: You must supply an arguement for this command! Use `!help` for an overview of functionality."
);
return;
}
switch (command) {
case HELP:
message.channel.send(HELP_MESSAGE);
break;
case ROTATION:
message.channel.send(ROTATIONS_IMAGE_URL);
break;
case DROP:
message.channel.send(calculateUniqueProbability(args.join(" ")));
break;
case ITEM:
const itemID = getItemID(args.join(" "));
if (!!itemID) {
const retVal = await getSingleItem(itemID);
if (!!retVal) {
message.channel.send(buildSingleItemTable(retVal));
} else {
message.channel.send("ERROR: Item not found!");
}
} else {
message.channel.send("ERROR: Item not found!");
}
break;
default:
break;
}
});
// Gets the price of an item from the RuneScape Grand Exchange website (http://services.runescape.com/m=itemdb_oldschool/)
const getExchangePrice = (itemID, callback) => {
const url = OSRS_GE_BASE_URL + itemID;
request(
{
url: url,
json: true
},
(error, response) => {
if (error || response.statusCode !== 200) {
return callback(error || { statusCode: response.statusCode });
}
callback(itemID, response);
}
);
};
// Updates a single item by id
const updateDBItem = (itemID, response) => {
const currentPrice = _.get(response, "body.item.current.price");
if (!currentPrice) {
console.log("Error retrieving response for item:", itemID);
}
MongoClient.connect(DB_URI, (err, client) => {
if (err) throw err;
const items = client.db(config.db_name).collection(config.db_collection);
const itemQuery = { id: itemID };
const updateQuery = {
$set: { value: currentPrice }
};
items.updateOne(itemQuery, updateQuery, (err, res) => {
if (err) {
console.log("Error updating item:", itemID);
console.log("Error:", err);
}
client.close();
});
});
};
// Updates all items in the DB
const updateDBItems = () => {
_.forEach(ITEM_DATA.items, item => {
getExchangePrice(item.id, updateDBItem);
});
};
// Retrieves the object for a specific item from the database
async function getSingleItem(itemID) {
const client = await MongoClient.connect(DB_URI);
const result = await client
.db(config.db_name)
.collection(config.db_collection)
.find({ id: itemID })
.toArray();
return result;
}
// Builds a Discord Rich Embedded Message with the item's information
const buildSingleItemTable = response => {
if (!response) {
console.log("null response");
return null;
}
const itemName = _.get(response[0], "itemName", "N/A");
const value = _.get(response[0], "value", "N/A");
const probability = _.get(response[0], "probability", "N/A");
let message = new Discord.RichEmbed();
message
.addField("Item", itemName, true)
.addField("Price", value, true)
.addField("Drop Rate", probability, true);
return message;
};