├── pepes └── angry_pepe.jpg ├── config.json ├── package.json ├── README.md └── index.js /pepes/angry_pepe.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meme-lord/CryptoBot/HEAD/pepes/angry_pepe.jpg -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "polotrolls" : ["ed65l","cryptocube","manakill","Pilot"], 3 | "polofollow" : [], 4 | "trollboxChannel" : "222666730437083137", 5 | "botToken": "no one cares nerd" 6 | } 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cryptobot", 3 | "version": "1.0.0", 4 | "description": "Bot for getting live cryptocurrency market data", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "meme-lord", 10 | "license": "ISC", 11 | "dependencies": { 12 | "discord.io": "^2.1.3", 13 | "poloniex-unofficial": "^1.1.2", 14 | "request": "^2.74.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CryptoBot 2 | A cryptocurrency Discord chat bot 3 | 4 | ***This is no longer the current version of the bot, I've rewritten it*** 5 | 6 | Made for the Crypto Trader's Room: https://discordapp.com/invite/2xUpcpB 7 | 8 | These are the commands this bot supports: 9 | 10 | | Command | 2nd Parameter | Description | 11 | | :------------ | :------------ | :----------------------------------------------------------------------------- | 12 | | Ping | | Pong | 13 | | Currencies | | Returns list of currencies on Poloniex | 14 | | Price | Coin Ticker | Gets the current price of the currencies provided | 15 | | Volume | Coin Ticker | Gets the 24 hour volume of the currencies provided | 16 | | Cap/Marketcap | Coin Ticker | Gets the current marketcap and rank of the cryptocurrency | 17 | | Convert | Coin Ticker | Converts the currency amount to dollars eg: convert 100 xmr / convert xmr 100 | 18 | | Pepe | | Uploads pepe to chat for your enjoyment | 19 | | Pepe | Add | Adds image to pepe repository. eg pepe add http://site.com/lol.jpg | 20 | | Pepe | List | Lists all pepes in pepe repository | 21 | | Pepe | Remove | Removes pepe from repository | 22 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | // https://discordapp.com/oauth2/authorize?&client_id=222461168319594498&scope=bot&permissions=0 2 | var Discord = require('discord.io'); 3 | var polo = require("poloniex-unofficial"); 4 | var request = require('request'); 5 | var fs = require('fs'); 6 | var util = require('util'); 7 | 8 | var data = require("./config.json"); 9 | 10 | trollboxChannel = data.trollboxchannel; 11 | botToken = data.botToken; 12 | // Discord channel id for the trollbox channel probably shouldnt be hardcoded 13 | 14 | var poloPublic = new polo.PublicWrapper(); 15 | var poloPush = new polo.PushWrapper(); 16 | var bot = new Discord.Client({ 17 | token: botToken, 18 | autorun: true 19 | }); 20 | 21 | bot.on('ready', function() { 22 | console.log(bot.username + " - (" + bot.id + ")"); 23 | }); 24 | 25 | bot.on('disconnect', function(errMsg, code){ 26 | console.log('---Bot disconnected with code ',code,' for reason ', errMsg,'---'); 27 | bot.connect(); 28 | }); 29 | 30 | bot.on('message', function(user, userID, channelID, message, event){ 31 | command = message.toLowerCase().split(' '); 32 | // Just for debugging - prints peoples messages 33 | //if (user!='CryptoBot'){ 34 | // console.log(user + " : " + userID + " : " + channelID + " : " + message); 35 | //} 36 | if (command[0] == "help" && command.length == 1){ 37 | bot.sendMessage({ 38 | to: channelID, 39 | message: "These are the commands this bot supports:\nCommand\t\tDescription\nPing\t\tPong" 40 | +"\nCurrencies\t\tReturns list of currencies on Poloniex\nPrice\t\tGets the current price of the currencies provided" 41 | +"\nVolume\t\tGets the 24 hour volume of the currencies provided\nCap/Marketcap\t\tGets the current marketcap and rank of the cryptocurrency" 42 | +"\nConvert\t\tConverts the currency amount to dollars eg: convert 100 xmr / convert xmr 100" 43 | +"\nPepe\t\tOnly the rarest, images can be added with pepe add http://link.com/img.jpg" 44 | }); 45 | } 46 | if (command[0] == "ping" && command.length == 1){ 47 | bot.sendMessage({ 48 | to: channelID, 49 | message: "pong" 50 | }); 51 | } 52 | if(command[0]=="troll" && command[0]=="trollbox"){ 53 | if(command[1]=="list"){ 54 | var message = "Trolls: " + data.polotrolls.join(',') + "\n" + "Following: " + data.polofollow.join(','); 55 | bot.sendMessage({ 56 | to: channelID, 57 | message: message 58 | }); 59 | } 60 | if(command[1]=="follow"){ 61 | if(command[2] != null){ 62 | data.polofollow.push(command[2]); 63 | } 64 | } 65 | if(command[1]=="add"){ 66 | if(command[2] != null){ 67 | data.polotrolls.push(command[2]); 68 | } 69 | } 70 | if(command[1]=="remove" || command[1]=="delete"){ 71 | if(command[2] != null){ 72 | if(data.polotrolls.indexOf(command[2])>-1){ 73 | data.polotrolls.splice(data.polotrolls.indexOf(command[2]),1); 74 | } 75 | if(data.polofollow.indexOf(command[2])>-1){ 76 | data.polofollow.splice(data.polofollow.indexOf(command[2]),1); 77 | } 78 | } 79 | } 80 | } 81 | if (command[0] == "rip" && command[1] == "bot"){ 82 | bot.sendMessage({ 83 | to: channelID, 84 | message: "I'm right here?" 85 | }); 86 | } 87 | if (command[0] == "pepe"){ 88 | if (command[1] == "add"){ 89 | if(command[2] != null){ 90 | download(command[2],'pepes'); 91 | } 92 | } 93 | else if(command[1] == "list"){ 94 | var pepes = fs.readdirSync('pepes'); 95 | bot.sendMessage({ 96 | to: channelID, 97 | message: "Pepes: "+pepes.toString() 98 | }); 99 | } 100 | else if (command[1] == "delete" || command[1] == "remove"){ 101 | if (command[2] != null){ 102 | path = 'pepes/' + command[2].replace(/\.\.\//g,''); 103 | if (fs.existsSync(path)){ 104 | fs.unlinkSync(path); 105 | bot.sendMessage({ 106 | to: channelID, 107 | message: "Bad meme "+ path + " successfully deleted" 108 | }); 109 | } else { 110 | bot.sendMessage({ 111 | to: channelID, 112 | message: "File " + path + " does not exist? Try 'pepe list' to find the filename" 113 | }); 114 | } 115 | } 116 | } 117 | else{ 118 | var pepes = fs.readdirSync('pepes'); 119 | var pepefile = 'pepes/'+pepes[Math.floor(Math.random() * pepes.length)]; 120 | bot.uploadFile({ 121 | to: channelID, 122 | file: pepefile 123 | }); 124 | } 125 | } 126 | if (command[0] == "currencies" && command.length == 1){ 127 | poloCurrencies(channelID); 128 | } 129 | if (command[0] == "price"){ 130 | tickers = command.slice(1,command.length); 131 | poloPrice(channelID,tickers); 132 | } 133 | if (command[0] == "volume"){ 134 | tickers = command.slice(1,command.length); 135 | poloVolume(channelID,tickers); 136 | } 137 | if (command[0] == "cap" || command[0] == "marketcap" ){ 138 | tickers = command.slice(1,command.length); 139 | marketCap(channelID,tickers); 140 | } 141 | if(command[0] == "convert" && command.length == 3){ 142 | if(isNaN(command[1])){ 143 | currency = command[1]; 144 | amount = command[2]; 145 | } else { 146 | currency = command[2]; 147 | amount = command[1]; 148 | } 149 | ticker = 'BTC_' + currency.toUpperCase(); 150 | poloPublic.returnTicker((err, response) => { 151 | if (err) { 152 | console.log("An error occurred: " + err.msg); 153 | } else { 154 | btc_value = response['USDT_BTC'].last; 155 | if (currency == 'btc'){ 156 | bot.sendMessage({ 157 | to: channelID, 158 | message: amount + ' BTC is worth $' + amount*btc_value 159 | }) 160 | } 161 | if(response[ticker]){ 162 | bot.sendMessage({ 163 | to: channelID, 164 | message: amount + ' ' + currency + ' is worth $' + amount*response[ticker].last*btc_value 165 | }); 166 | } 167 | } 168 | }); 169 | } 170 | }); 171 | 172 | function updateJSON(dataobj){ 173 | fs.writeFileSync('./config.json',util.inspect(dataobj), 'utf-8'); 174 | data = require("./config.json"); 175 | } 176 | 177 | function numberWithCommas(x) { 178 | var parts = x.toString().split("."); 179 | parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); 180 | return parts.join("."); 181 | } 182 | 183 | function download(uri,folder){ 184 | filename = folder+'/'+uri.split(/[//]+/).pop(); 185 | console.log(filename); 186 | try{ 187 | var options = { 188 | uri:uri, 189 | headers:{ 190 | 'User-Agent':'Mozilla/5.0 (Linux; Android 4.1.2; GT-I9100 Build/JZO54K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Mobile Safari/537.36' 191 | } 192 | }; 193 | request.head(options, function(err, res, body){ 194 | console.log('content-type:', res.headers['content-type']); 195 | console.log('content-length:', res.headers['content-length']); 196 | request(uri).pipe(fs.createWriteStream(filename)); 197 | }); 198 | } catch(exception){ 199 | console.log(exception); 200 | } 201 | } 202 | 203 | function marketCap(channelID, tickers){ 204 | var cmc_url = 'https://api.coinmarketcap.com/v1/ticker/'; 205 | // https://api.coinmarketcap.com/v1/ticker/ 206 | request({ 207 | url: cmc_url, 208 | json: true 209 | }, function (error, response, body) { 210 | if (!error && response.statusCode === 200) { 211 | //var cmc_object = JSON.parse(body); 212 | var cmc_object = body; 213 | console.log(cmc_object[0]); 214 | message = ''; 215 | for (var key in cmc_object){ 216 | if(tickers.indexOf(cmc_object[key].symbol.toLowerCase())>-1){ 217 | var cap = numberWithCommas(cmc_object[key].market_cap_usd); 218 | message+=cmc_object[key].symbol+'\t$'+cap+'\tRank: #'+cmc_object[key].rank+'\n'; 219 | } 220 | } 221 | console.log('Message: ' + message); 222 | bot.sendMessage({ 223 | to: channelID, 224 | message: message 225 | }); 226 | } 227 | }); 228 | } 229 | 230 | function poloVolume(channelID, tickers){ 231 | var newtickers = []; 232 | for (var ticker in tickers){ 233 | if(tickers[ticker]=='btc'){ 234 | newtickers.push("USDT_BTC"); 235 | } 236 | else{ 237 | newtickers.push("BTC_" + tickers[ticker].toUpperCase()); 238 | } 239 | } 240 | tickers = newtickers; 241 | poloPublic.returnTicker((err, response) => { 242 | if (err) { 243 | console.log("An error occurred: " + err.msg); 244 | } else { 245 | //return response; 246 | //console.log(response); 247 | message = ''; 248 | for (var key in response){ 249 | if(tickers.indexOf(key)>-1){ 250 | console.log(key); 251 | message += key.replace(/^[A-Za-z]*_/,'') + '\t' + response[key].baseVolume + '\n'; 252 | } 253 | } 254 | console.log(message); 255 | bot.sendMessage({ 256 | to: channelID, 257 | message: message 258 | }); 259 | } 260 | }); 261 | } 262 | 263 | function poloPrice(channelID,tickers){ 264 | var newtickers = []; 265 | for (var ticker in tickers){ 266 | if(tickers[ticker]=='btc'){ 267 | newtickers.push("USDT_BTC"); 268 | } 269 | else{ 270 | newtickers.push("BTC_" + tickers[ticker].toUpperCase()); 271 | } 272 | } 273 | tickers = newtickers; 274 | poloPublic.returnTicker((err, response) => { 275 | if (err) { 276 | console.log("An error occurred: " + err.msg); 277 | } else { 278 | //return response; 279 | //console.log(response); 280 | console.log(tickers); 281 | message = ''; 282 | btc_value = response['USDT_BTC'].last; 283 | for (var key in response){ 284 | if(tickers.indexOf(key)>-1){ 285 | ticker_btc_value = response[key].last; 286 | if(key=='USDT_BTC'){ 287 | ticker_btc_value = 1; 288 | } 289 | message += key.replace(/^[A-Za-z]*_/,'') + '\t' + ticker_btc_value + ' (' + (response[key].percentChange*100).toFixed(2) + '%)\t$' + (ticker_btc_value*btc_value).toFixed(8) + '\n'; 290 | } 291 | } 292 | console.log(message); 293 | bot.sendMessage({ 294 | to: channelID, 295 | message: message 296 | }); 297 | } 298 | }); 299 | } 300 | 301 | function poloCurrencies(channelID){ 302 | poloPublic.returnCurrencies((err, response) => { 303 | if (err) { 304 | console.log("An error occurred: " + err.msg); 305 | } else { 306 | //return response; 307 | //console.log(response); 308 | message = ''; 309 | for (var key in response){ 310 | if(message==''){ 311 | message = "Poloniex's current currencies: "+key; 312 | } 313 | else{ 314 | message += ', ' + key; 315 | } 316 | } 317 | console.log(message); 318 | bot.sendMessage({ 319 | to: channelID, 320 | message: message 321 | }); 322 | } 323 | }); 324 | } 325 | 326 | poloPush.trollbox((err, response) => { 327 | if (err) { 328 | // Log error message 329 | console.log("An error occurred: " + err.msg); 330 | // Disconnect 331 | return true; 332 | } 333 | // Log chat message as "[rep] username: message" 334 | //console.log(" [" + response.reputation + "] " + response.username + ": " + response.message); 335 | if(trollboxFilter(response.message)){ 336 | if(data.polotrolls.indexOf(response.username.toLowerCase())>-1) { 337 | message = "```css\n" + response.username + ": " + decodeHTML(response.message) + "\n```"; 338 | } else if(data.polofollow.indexOf(response.username.toLowerCase())>-1) { 339 | message = "```xl\n" + response.username + ": " + decodeHTML(response.message) + "\n```"; 340 | } else { 341 | message = "__**" + response.username + "**__: " + decodeHTML(response.message); 342 | } 343 | bot.sendMessage({ 344 | to : trollboxChannel, 345 | message : message 346 | }, function(err,res){ 347 | if(res){ 348 | if(res.content!=null){ 349 | if(res.content.indexOf("```xl")>-1){ 350 | bot.pinMessage({ 351 | channelID: res.channel_id, 352 | messageID: res.id 353 | }); 354 | } 355 | } 356 | } 357 | }); 358 | } 359 | }); 360 | 361 | function trollboxFilter(message){ 362 | //returns true if the message is signal, false if its noise 363 | if(message.substring(0,7)=='PRO TIP:' || message.substring(0,8)=='POLO TIP:'){ 364 | //Poloniex's Tips 365 | return false; 366 | } 367 | if(message.indexOf("http") !== -1){ 368 | //Links, we want those 369 | return true; 370 | } 371 | if(message.length<10){ 372 | //Messages this short are likely to be noise 373 | return false; 374 | } 375 | return true; 376 | } 377 | 378 | function decodeHTML(message){ 379 | return message 380 | .replace(/&/,"&") 381 | .replace(/</,"<") 382 | .replace(/>/,">") 383 | .replace(/"/,"\"") 384 | .replace(/'/,"'") 385 | .replace(/(/,"(") 386 | .replace(/@/,"@") 387 | .replace(/)/,")"); 388 | } 389 | --------------------------------------------------------------------------------