Fixed formating and added prettier to pre-commit.

Fixed the formatting, added prettier to auto run on pre-commit.
This commit is contained in:
Fillerino 2017-11-07 18:25:05 +01:00
parent 1836a2eaa4
commit 6ce8aade5b
19 changed files with 2634 additions and 1616 deletions

View file

@ -1,42 +1,55 @@
# Bot for [LBRY's Discord](https://discord.gg/tgnNHf5)
(This README will be updated along with bot updates)
## Features:
- Tipbot for LBC. Responds to `!tip`.
- Price bot displays price of lbc for currency given. Responds to `!price <cur> <amount>`
- Stats bot display current market stats of lbc. Responds to `!stats`
- Hash bot displays current hashrate of network. Responds to `!hash`
- Github Release Notes bot displays release notes for current lbry-app release.
* Tipbot for LBC. Responds to `!tip`.
* Price bot displays price of lbc for currency given. Responds to `!price <cur>
<amount>`
* Stats bot display current market stats of lbc. Responds to `!stats`
* Hash bot displays current hashrate of network. Responds to `!hash`
* Github Release Notes bot displays release notes for current lbry-app release.
Responds to `!releasenotes`
Responds to `!releasenotes` User with Defined Perms `!releasenotes post` to
send to specified channel
User with Defined Perms `!releasenotes post` to send to specified channel
- Purge Bot (moderator only) deletes X amount of messages. User with Defined Perms Responds to `!purge <X>`
- Speech bot displays top claim from provided image name(coming soon posting to speech).
Responds to `!speech <imagename>`
- Welcome bot sends Direct Message when new users join, User with Defined Perms can send using `!welcome <@username>`
- Spam Detection Bot to Prevent Discord Raids and Spammers
- Dynamic plugin loading with permission support.
* Purge Bot (moderator only) deletes X amount of messages. User with Defined
Perms Responds to `!purge <X>`
* Speech bot displays top claim from provided image name(coming soon posting to
speech).
Responds to `!speech <imagename>`
* Welcome bot sends Direct Message when new users join, User with Defined Perms
can send using `!welcome <@username>`
* Spam Detection Bot to Prevent Discord Raids and Spammers
* Dynamic plugin loading with permission support.
## Requirements
- node > 8.0.0
- npm > 0.12.x
* node > 8.0.0
* npm > 0.12.x
* yarn ( install with npm install -g yarn if not installed )
## Installation
Create a bot and get the bot's API Token: https://discordapp.com/developers/applications/me
Create a bot and get the bot's API Token:
https://discordapp.com/developers/applications/me
Edit and rename default.json.example in /config, then cd to wunderbot directory and run:
Edit and rename default.json.example in /config, then cd to wunderbot directory
and run:
```
npm install
yarn install
node bot/bot.js
```
## Development
Be sure to run the command below before working on any code, this ensures
prettier goes to work and keeps code to our standard.
```
yarn install --production=false
```

View file

@ -1,10 +1,10 @@
'use strict';
"use strict";
// Load up libraries
const Discord = require("discord.js");
// Load config!
let config = require('config');
config = config.get('bot');
let config = require("config");
config = config.get("bot");
var aliases;
try {
@ -12,12 +12,12 @@ try {
} catch (e) {
//No aliases defined
aliases = {
"test": {
process: function(bot,msg){
msg.channel.send('test');
test: {
process: function(bot, msg) {
msg.channel.send("test");
}
}
}
};
}
var commands = {
ping: {
@ -43,9 +43,7 @@ bot.on("ready", function() {
);
require("./plugins.js").init();
console.log("type " + config.prefix + "help in Discord for a commands list.");
bot.user.setGame(
config.prefix + "help | Tipping not available"
);
bot.user.setGame(config.prefix + "help | Tipping not available");
});
bot.on("disconnected", function() {
@ -57,7 +55,13 @@ function checkMessageForCommand(msg, isEdit) {
//check if message is a command
if (msg.author.id != bot.user.id && msg.content.startsWith(config.prefix)) {
console.log(
"treating " + msg.content + " from UserID:" + msg.author + " || UserName: " + msg.author.username + " as command"
"treating " +
msg.content +
" from UserID:" +
msg.author +
" || UserName: " +
msg.author.username +
" as command"
);
var cmdTxt = msg.content.split(" ")[0].substring(config.prefix.length);
var suffix = msg.content.substring(
@ -77,9 +81,9 @@ function checkMessageForCommand(msg, isEdit) {
}
let alias = aliases[cmdTxt];
if (alias) {
var cmd = alias;
var cmd = alias;
} else {
var cmd = commands[cmdTxt];
var cmd = commands[cmdTxt];
}
if (cmdTxt === "help") {
//help is special since it iterates over the other commands
@ -185,7 +189,7 @@ exports.addCustomFunc = function(customFunc) {
} catch (err) {
console.log(err);
}
}
};
exports.commandCount = function() {
return Object.keys(commands).length;
};

View file

@ -1,80 +1,79 @@
let config = require('config');
let permRanks = config.get('moderation');
let speechBotChannels = config.get('speechbot');
let priceBotChannels = config.get('pricebot');
let ExcludedSpam = config.get('spamdetection');
let hashBotChannels = config.get('hashbot');
let statsBotChannels = config.get('statsbot');
let config = require("config");
let permRanks = config.get("moderation");
let speechBotChannels = config.get("speechbot");
let priceBotChannels = config.get("pricebot");
let ExcludedSpam = config.get("spamdetection");
let hashBotChannels = config.get("hashbot");
let statsBotChannels = config.get("statsbot");
// Checks if user is allowed to use a command only for mods/team members
exports.hasPerms = function(msg){
if(msg.member.roles.some(r=>permRanks.perms.includes(r.name)) ) {
return true;
} else {
return false;
}
}
// Check if command was sent in dm
exports.inPrivate = function(msg){
if(msg.channel.type == 'dm'){
exports.hasPerms = function(msg) {
if (msg.member.roles.some(r => permRanks.perms.includes(r.name))) {
return true;
}else{
} else {
return false;
}
}
};
// Check if command was sent in dm
exports.inPrivate = function(msg) {
if (msg.channel.type == "dm") {
return true;
} else {
return false;
}
};
// Checks if Message was sent from a channel in speechBot Channels list
exports.hasSpeechBotChannels = function(msg){
if(speechBotChannels.channels.includes(msg.channel.id) ) {
return true;
} else {
return false;
}
}
exports.hasSpeechBotChannels = function(msg) {
if (speechBotChannels.channels.includes(msg.channel.id)) {
return true;
} else {
return false;
}
};
// Checks if Message was sent from a channel in priceBot Channels list
exports.hasPriceBotChannels = function(msg){
if(priceBotChannels.channels.includes(msg.channel.id) ) {
return true;
} else {
return false;
}
}
exports.hasPriceBotChannels = function(msg) {
if (priceBotChannels.channels.includes(msg.channel.id)) {
return true;
} else {
return false;
}
};
// Checks if Message was sent from a Excluded channel
exports.hasExcludedSpamChannels = function(msg){
if(ExcludedSpam.channels.includes(msg.channel.id) ) {
return true;
} else {
return false;
}
}
exports.hasExcludedSpamChannels = function(msg) {
if (ExcludedSpam.channels.includes(msg.channel.id)) {
return true;
} else {
return false;
}
};
// Checks if Message was sent from a Excluded user
exports.hasExcludedSpamUsers = function(msg){
if(ExcludedSpam.users.includes(msg.author.id) ) {
return true;
} else {
return false;
}
}
exports.hasExcludedSpamUsers = function(msg) {
if (ExcludedSpam.users.includes(msg.author.id)) {
return true;
} else {
return false;
}
};
// Checks if Message was sent from a channel in hashBot Channels list
exports.hasHashBotChannels = function(msg){
if(hashBotChannels.channels.includes(msg.channel.id) ) {
return true;
} else {
return false;
}
}
exports.hasHashBotChannels = function(msg) {
if (hashBotChannels.channels.includes(msg.channel.id)) {
return true;
} else {
return false;
}
};
// Checks if Message was sent from a channel in statsBot Channels list
exports.hasStatsBotChannels = function(msg){
if(statsBotChannels.channels.includes(msg.channel.id) ) {
return true;
} else {
return false;
}
}
exports.hasStatsBotChannels = function(msg) {
if (statsBotChannels.channels.includes(msg.channel.id)) {
return true;
} else {
return false;
}
};

File diff suppressed because it is too large Load diff

View file

@ -1,90 +1,121 @@
let needle = require('needle');
let config = require('config');
let hasHashBotChannels = require('../helpers.js').hasHashBotChannels;
let inPrivate = require('../helpers.js').inPrivate;
let ChannelID = config.get('hashbot').mainchannel;
let needle = require("needle");
let config = require("config");
let hasHashBotChannels = require("../helpers.js").hasHashBotChannels;
let inPrivate = require("../helpers.js").inPrivate;
let ChannelID = config.get("hashbot").mainchannel;
exports.commands = [
"hash" // command that is in this file, every command needs it own export as shown below
]
"hash" // command that is in this file, every command needs it own export as shown below
];
exports.custom = [
"timedhash"
]
exports.custom = ["timedhash"];
exports.timedhash = function(bot) {
setInterval(function() {
sendMiningInfo(bot);
}, 6 * 60 * 60 * 1000);
setInterval(function() {
sendMiningInfo(bot);
}, 6 * 60 * 60 * 1000);
function sendMiningInfo(bot) {
needle.get('https://explorer.lbry.io/api/v1/status', function(error, response) {
if (error || response.statusCode !== 200) {
bot.channels.get(ChannelID).send('Explorer API is not available');
} else {
var data, hashrate = "", difficulty = "", height = "";
function sendMiningInfo(bot) {
needle.get("https://explorer.lbry.io/api/v1/status", function(
error,
response
) {
if (error || response.statusCode !== 200) {
bot.channels.get(ChannelID).send("Explorer API is not available");
} else {
var data,
hashrate = "",
difficulty = "",
height = "";
data = response.body;
height += data.status.height;
hashrate += data.status.hashrate;
difficulty += data.status.difficulty;
description = "Hashrate: "+hashrate+"\n"+"Difficulty: "+difficulty+"\n"+"Current block: "+height+"\n"+"Source: https://explorer.lbry.io";
const embed = {
"description": description,
"color": 7976557,
"author": {
"name": "LBRY Explorer Stats",
"url": "https://explorer.lbry.io",
"icon_url": "https://i.imgur.com/yWf5USu.png"
}
};
bot.channels.get(ChannelID).send({ embed });
}
});
}
}
description =
"Hashrate: " +
hashrate +
"\n" +
"Difficulty: " +
difficulty +
"\n" +
"Current block: " +
height +
"\n" +
"Source: https://explorer.lbry.io";
const embed = {
description: description,
color: 7976557,
author: {
name: "LBRY Explorer Stats",
url: "https://explorer.lbry.io",
icon_url: "https://i.imgur.com/yWf5USu.png"
}
};
bot.channels.get(ChannelID).send({
embed
});
}
});
}
};
exports.hash = {
usage: "",
description: 'Displays current Hashrate of Network',
process: function(bot,msg){
var command = '!hash';
sendMiningInfo(bot, msg);
usage: "",
description: "Displays current Hashrate of Network",
process: function(bot, msg) {
var command = "!hash";
sendMiningInfo(bot, msg);
function sendMiningInfo(bot, msg) {
if (!inPrivate(msg) && !hasHashBotChannels(msg)) {
msg.channel.send(
"Please use <#" + ChannelID + "> or DMs to talk to hash bot."
);
return;
}
needle.get("https://explorer.lbry.io/api/v1/status", function(
error,
response
) {
if (error || response.statusCode !== 200) {
msg.channel.send("Explorer API is not available");
} else {
var data,
hashrate = "",
difficulty = "",
height = "";
data = response.body;
height += data.status.height;
hashrate += data.status.hashrate;
difficulty += data.status.difficulty;
description =
"Hashrate: " +
hashrate +
"\n" +
"Difficulty: " +
difficulty +
"\n" +
"Current block: " +
height +
"\n" +
"Source: https://explorer.lbry.io";
const embed = {
description: description,
color: 7976557,
author: {
name: "LBRY Explorer Stats",
url: "https://explorer.lbry.io",
icon_url: "https://i.imgur.com/yWf5USu.png"
}
};
msg.channel.send({
embed
});
}
});
}
function sendMiningInfo(bot, msg) {
if(!inPrivate(msg) && !hasHashBotChannels(msg)){
msg.channel.send('Please use <#' + ChannelID + '> or DMs to talk to hash bot.');
return;
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
}
needle.get('https://explorer.lbry.io/api/v1/status', function(error, response) {
if (error || response.statusCode !== 200) {
msg.channel.send('Explorer API is not available');
}
else {
var data, hashrate = "", difficulty = "", height = "";
data = response.body;
height += data.status.height;
hashrate += data.status.hashrate;
difficulty += data.status.difficulty;
description = "Hashrate: "+hashrate+"\n"+"Difficulty: "+difficulty+"\n"+"Current block: "+height+"\n"+"Source: https://explorer.lbry.io";
const embed = {
"description": description,
"color": 7976557,
"author": {
"name": "LBRY Explorer Stats",
"url": "https://explorer.lbry.io",
"icon_url": "https://i.imgur.com/yWf5USu.png"
}
};
msg.channel.send({ embed });
}
});
}
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
}
}
};

View file

@ -1,196 +1,409 @@
'use strict';
let jp = require('jsonpath');
let moment = require('moment');
let numeral = require('numeral');
let request = require('request');
let config = require('config');
let hasPriceBotChannels = require('../helpers.js').hasPriceBotChannels;
let inPrivate = require('../helpers.js').inPrivate;
let ChannelID = config.get('pricebot').mainchannel;
"use strict";
let jp = require("jsonpath");
let moment = require("moment");
let numeral = require("numeral");
let request = require("request");
let config = require("config");
let hasPriceBotChannels = require("../helpers.js").hasPriceBotChannels;
let inPrivate = require("../helpers.js").inPrivate;
let ChannelID = config.get("pricebot").mainchannel;
exports.commands = [
"price"
]
exports.commands = ["price"];
exports.price = {
usage: "<currency> <amount>",
description: 'displays price of lbc',
process: function(bot,msg,suffix){
usage: "<currency> <amount>",
description: "displays price of lbc",
process: function(bot, msg, suffix) {
var options = {
defaultCurrency: "BTC",
var options = {
defaultCurrency: 'BTC',
// supported currencies and api steps to arrive at the final value
currencies: {
USD: { steps: ['LBCBTC', 'BTCUSD'], format: '$0,0.00', sign: 'USD ' },
GBP: { steps: ['LBCBTC', 'BTCGBP'], format: '£0,0.00', sign: '£' },
AUD: { steps: ['LBCBTC', 'BTCAUD'], format: '$0,0.00', sign: 'AUD ' },
BRL: { steps: ['LBCBTC', 'BTCBRL'], format: 'R$0,0.00', sign: 'R$' },
CAD: { steps: ['LBCBTC', 'BTCCAD'], format: '$0,0.00', sign: 'CAD ' },
CHF: { steps: ['LBCBTC', 'BTCCHF'], format: 'CHF 0,0.00', sign: 'CHF' },
CLP: { steps: ['LBCBTC', 'BTCCLP'], format: '$0,0.00', sign: 'CLP ' },
CNY: { steps: ['LBCBTC', 'BTCCNY'], format: '¥0,0.00', sign: '¥' },
DKK: { steps: ['LBCBTC', 'BTCDKK'], format: 'kr 0,0.00', sign: 'kr' },
EUR: { steps: ['LBCBTC', 'BTCEUR'], format: '€0,0.00', sign: '€' },
HKD: { steps: ['LBCBTC', 'BTCHKD'], format: '$0,0.00', sign: 'HKD ' },
INR: { steps: ['LBCBTC', 'BTCINR'], format: '₹0,0.00', sign: '₹' },
ISK: { steps: ['LBCBTC', 'BTCISK'], format: 'kr 0,0.00', sign: 'kr' },
JPY: { steps: ['LBCBTC', 'BTCJPY'], format: '¥0,0.00', sign: '¥' },
KRW: { steps: ['LBCBTC', 'BTCKRW'], format: '₩0,0.00', sign: '₩' },
NZD: { steps: ['LBCBTC', 'BTCNZD'], format: '$0,0.00', sign: 'NZD ' },
PLN: { steps: ['LBCBTC', 'BTCPLN'], format: 'zł 0,0.00', sign: 'zł' },
RUB: { steps: ['LBCBTC', 'BTCRUB'], format: 'RUB 0,0.00', sign: 'RUB' },
SEK: { steps: ['LBCBTC', 'BTCSEK'], format: 'kr 0,0.00', sign: 'kr' },
SGD: { steps: ['LBCBTC', 'BTCSGD'], format: '$0,0.00', sign: 'SGD ' },
THB: { steps: ['LBCBTC', 'BTCTHB'], format: '฿0,0.00', sign: '฿' },
TWD: { steps: ['LBCBTC', 'BTCTWD'], format: 'NT$0,0.00', sign: 'NT$' },
IDR: { steps: ['LBCBTC', 'BTCIDR'], format: 'Rp0,0.00', sign: 'Rp' },
BTC: { steps: ['LBCBTC'], format: '0,0[.][00000000] BTC', sign: 'BTC' }
},
// api steps
api: {
LBCBTC: { url: 'https://bittrex.com/api/v1.1/public/getticker?market=BTC-LBC', path: '$.result.Bid' },
BTCUSD: { url: 'https://blockchain.info/ticker', path: '$.USD.buy' },
BTCGBP: { url: 'https://blockchain.info/ticker', path: '$.GBP.buy' },
BTCAUD: { url: 'https://blockchain.info/ticker', path: '$.AUD.buy' },
BTCBRL: { url: 'https://blockchain.info/ticker', path: '$.BRL.buy' },
BTCCAD: { url: 'https://blockchain.info/ticker', path: '$.CAD.buy' },
BTCCHF: { url: 'https://blockchain.info/ticker', path: '$.CHF.buy' },
BTCCLP: { url: 'https://blockchain.info/ticker', path: '$.CLP.buy' },
BTCCNY: { url: 'https://blockchain.info/ticker', path: '$.CNY.buy' },
BTCDKK: { url: 'https://blockchain.info/ticker', path: '$.DKK.buy' },
BTCEUR: { url: 'https://blockchain.info/ticker', path: '$.EUR.buy' },
BTCHKD: { url: 'https://blockchain.info/ticker', path: '$.HKD.buy' },
BTCINR: { url: 'https://blockchain.info/ticker', path: '$.INR.buy' },
BTCISK: { url: 'https://blockchain.info/ticker', path: '$.ISK.buy' },
BTCJPY: { url: 'https://blockchain.info/ticker', path: '$.JPY.buy' },
BTCKRW: { url: 'https://blockchain.info/ticker', path: '$.KRW.buy' },
BTCNZD: { url: 'https://blockchain.info/ticker', path: '$.NZD.buy' },
BTCPLN: { url: 'https://blockchain.info/ticker', path: '$.PLN.buy' },
BTCRUB: { url: 'https://blockchain.info/ticker', path: '$.RUB.buy' },
BTCSEK: { url: 'https://blockchain.info/ticker', path: '$.SEK.buy' },
BTCSGD: { url: 'https://blockchain.info/ticker', path: '$.SGD.buy' },
BTCTHB: { url: 'https://blockchain.info/ticker', path: '$.THB.buy' },
BTCTWD: { url: 'https://blockchain.info/ticker', path: '$.TWD.buy' },
BTCIDR: { url: 'https://min-api.cryptocompare.com/data/price?fsym=BTC&tsyms=IDR', path: '$.IDR'}
},
// display date/time format
dtFormat: 'Do MMM YYYY h:mma [UTC]',
// refresh rate in milliseconds to retrieve a new price (default to 10 minutes)
refreshTime: 100000
};
var words = suffix.trim().split(' ').filter( function(n){return n !== "";} );
var currency = (words.length > 0) ? words[0].toUpperCase() : options.defaultCurrency;
var amount = (words.length > 1) ? parseFloat(words[1], 10) : 1;
var showHelp = (isNaN(amount)) || (Object.keys(options.currencies).indexOf(currency) === -1);
// store the last retrieved rate
var cachedRates = {};
var command = "!price"
var currencies = Object.keys(options.currencies);
for (var i = 0; i < currencies.length; i++) {
cachedRates[currencies[i]] = { rate: 0, time: null };
}
if (showHelp) {
doHelp(bot,msg,suffix);
} else {
if(!hasPriceBotChannels(msg) && !inPrivate(msg)){
msg.channel.send('Please use <#' + ChannelID + '> or DMs to talk to price bot.');
return;
}
doSteps(bot, currency, amount);
}
function doHelp(bot,msg,suffix) {
if(!hasPriceBotChannels(msg) && !inPrivate(msg)){
msg.channel.send('Please use <#' + ChannelID + '> or DMs to talk to price bot.');
return;
}
var message =
'**' + command + '**: show the price of 1 LBC in ' + options.defaultCurrency + '\n' +
'**' + command + ' help**: this message\n' +
'**' + command + ' CURRENCY**: show the price of 1 LBC in CURRENCY. Supported values for CURRENCY are Listed Below\n' +
'**' + command + ' CURRENCY AMOUNT**: show the price of AMOUNT LBC in CURRENCY\n' +
'**Supported Currencies:** *usd*, *gbp*, *eur*, *aud*, *brl*, *cad*, *chf*, *clp*, *cny*, *dkk*, *hkd*, *inr*, *isk*, *jpy*, *krw*, *nzd*, *pln* ,*rub*, *sek*, *sgd*, *thb*, *twd*, *idr* and *btc* (case-insensitive)';
msg.channel.send(message);
}
function formatMessage(amount, rate, option) {
var cur = option.sign;
var value = numeral(rate.rate * amount).format(option.format);
return '*' + numeral(amount).format('0,0[.][00000000]') + ' LBC = ' + cur +' ' + value + '*\n_last updated ' + rate.time.utc().format(options.dtFormat) + '_';
}
function doSteps(bot, currency, amount) {
var option = options.currencies[currency];
var shouldReload = true;
if (cachedRates[currency]) {
var cache = cachedRates[currency];
shouldReload = cache.time === null || moment().diff(cache.time) >= options.refreshTime;
if (!shouldReload) {
var message = formatMessage(amount, cache, option);
msg.channel.send(message);
// supported currencies and api steps to arrive at the final value
currencies: {
USD: {
steps: ["LBCBTC", "BTCUSD"],
format: "$0,0.00",
sign: "USD "
},
GBP: {
steps: ["LBCBTC", "BTCGBP"],
format: "£0,0.00",
sign: "£"
},
AUD: {
steps: ["LBCBTC", "BTCAUD"],
format: "$0,0.00",
sign: "AUD "
},
BRL: {
steps: ["LBCBTC", "BTCBRL"],
format: "R$0,0.00",
sign: "R$"
},
CAD: {
steps: ["LBCBTC", "BTCCAD"],
format: "$0,0.00",
sign: "CAD "
},
CHF: {
steps: ["LBCBTC", "BTCCHF"],
format: "CHF 0,0.00",
sign: "CHF"
},
CLP: {
steps: ["LBCBTC", "BTCCLP"],
format: "$0,0.00",
sign: "CLP "
},
CNY: {
steps: ["LBCBTC", "BTCCNY"],
format: "¥0,0.00",
sign: "¥"
},
DKK: {
steps: ["LBCBTC", "BTCDKK"],
format: "kr 0,0.00",
sign: "kr"
},
EUR: {
steps: ["LBCBTC", "BTCEUR"],
format: "€0,0.00",
sign: "€"
},
HKD: {
steps: ["LBCBTC", "BTCHKD"],
format: "$0,0.00",
sign: "HKD "
},
INR: {
steps: ["LBCBTC", "BTCINR"],
format: "₹0,0.00",
sign: "₹"
},
ISK: {
steps: ["LBCBTC", "BTCISK"],
format: "kr 0,0.00",
sign: "kr"
},
JPY: {
steps: ["LBCBTC", "BTCJPY"],
format: "¥0,0.00",
sign: "¥"
},
KRW: {
steps: ["LBCBTC", "BTCKRW"],
format: "₩0,0.00",
sign: "₩"
},
NZD: {
steps: ["LBCBTC", "BTCNZD"],
format: "$0,0.00",
sign: "NZD "
},
PLN: {
steps: ["LBCBTC", "BTCPLN"],
format: "zł 0,0.00",
sign: "zł"
},
RUB: {
steps: ["LBCBTC", "BTCRUB"],
format: "RUB 0,0.00",
sign: "RUB"
},
SEK: {
steps: ["LBCBTC", "BTCSEK"],
format: "kr 0,0.00",
sign: "kr"
},
SGD: {
steps: ["LBCBTC", "BTCSGD"],
format: "$0,0.00",
sign: "SGD "
},
THB: {
steps: ["LBCBTC", "BTCTHB"],
format: "฿0,0.00",
sign: "฿"
},
TWD: {
steps: ["LBCBTC", "BTCTWD"],
format: "NT$0,0.00",
sign: "NT$"
},
IDR: {
steps: ["LBCBTC", "BTCIDR"],
format: "Rp0,0.00",
sign: "Rp"
},
BTC: {
steps: ["LBCBTC"],
format: "0,0[.][00000000] BTC",
sign: "BTC"
}
},
// api steps
api: {
LBCBTC: {
url: "https://bittrex.com/api/v1.1/public/getticker?market=BTC-LBC",
path: "$.result.Bid"
},
BTCUSD: {
url: "https://blockchain.info/ticker",
path: "$.USD.buy"
},
BTCGBP: {
url: "https://blockchain.info/ticker",
path: "$.GBP.buy"
},
BTCAUD: {
url: "https://blockchain.info/ticker",
path: "$.AUD.buy"
},
BTCBRL: {
url: "https://blockchain.info/ticker",
path: "$.BRL.buy"
},
BTCCAD: {
url: "https://blockchain.info/ticker",
path: "$.CAD.buy"
},
BTCCHF: {
url: "https://blockchain.info/ticker",
path: "$.CHF.buy"
},
BTCCLP: {
url: "https://blockchain.info/ticker",
path: "$.CLP.buy"
},
BTCCNY: {
url: "https://blockchain.info/ticker",
path: "$.CNY.buy"
},
BTCDKK: {
url: "https://blockchain.info/ticker",
path: "$.DKK.buy"
},
BTCEUR: {
url: "https://blockchain.info/ticker",
path: "$.EUR.buy"
},
BTCHKD: {
url: "https://blockchain.info/ticker",
path: "$.HKD.buy"
},
BTCINR: {
url: "https://blockchain.info/ticker",
path: "$.INR.buy"
},
BTCISK: {
url: "https://blockchain.info/ticker",
path: "$.ISK.buy"
},
BTCJPY: {
url: "https://blockchain.info/ticker",
path: "$.JPY.buy"
},
BTCKRW: {
url: "https://blockchain.info/ticker",
path: "$.KRW.buy"
},
BTCNZD: {
url: "https://blockchain.info/ticker",
path: "$.NZD.buy"
},
BTCPLN: {
url: "https://blockchain.info/ticker",
path: "$.PLN.buy"
},
BTCRUB: {
url: "https://blockchain.info/ticker",
path: "$.RUB.buy"
},
BTCSEK: {
url: "https://blockchain.info/ticker",
path: "$.SEK.buy"
},
BTCSGD: {
url: "https://blockchain.info/ticker",
path: "$.SGD.buy"
},
BTCTHB: {
url: "https://blockchain.info/ticker",
path: "$.THB.buy"
},
BTCTWD: {
url: "https://blockchain.info/ticker",
path: "$.TWD.buy"
},
BTCIDR: {
url:
"https://min-api.cryptocompare.com/data/price?fsym=BTC&tsyms=IDR",
path: "$.IDR"
}
},
// display date/time format
dtFormat: "Do MMM YYYY h:mma [UTC]",
// refresh rate in milliseconds to retrieve a new price (default to 10 minutes)
refreshTime: 100000
};
var words = suffix
.trim()
.split(" ")
.filter(function(n) {
return n !== "";
});
var currency =
words.length > 0 ? words[0].toUpperCase() : options.defaultCurrency;
var amount = words.length > 1 ? parseFloat(words[1], 10) : 1;
var showHelp =
isNaN(amount) || Object.keys(options.currencies).indexOf(currency) === -1;
// store the last retrieved rate
var cachedRates = {};
var command = "!price";
var currencies = Object.keys(options.currencies);
for (var i = 0; i < currencies.length; i++) {
cachedRates[currencies[i]] = {
rate: 0,
time: null
};
}
if (showHelp) {
doHelp(bot, msg, suffix);
} else {
if (!hasPriceBotChannels(msg) && !inPrivate(msg)) {
msg.channel.send(
"Please use <#" + ChannelID + "> or DMs to talk to price bot."
);
return;
}
doSteps(bot, currency, amount);
}
if (shouldReload) {
function doHelp(bot, msg, suffix) {
if (!hasPriceBotChannels(msg) && !inPrivate(msg)) {
msg.channel.send(
"Please use <#" + ChannelID + "> or DMs to talk to price bot."
);
return;
}
var message =
"**" +
command +
"**: show the price of 1 LBC in " +
options.defaultCurrency +
"\n" +
"**" +
command +
" help**: this message\n" +
"**" +
command +
" CURRENCY**: show the price of 1 LBC in CURRENCY. Supported values for CURRENCY are Listed Below\n" +
"**" +
command +
" CURRENCY AMOUNT**: show the price of AMOUNT LBC in CURRENCY\n" +
"**Supported Currencies:** *usd*, *gbp*, *eur*, *aud*, *brl*, *cad*, *chf*, *clp*, *cny*, *dkk*, *hkd*, *inr*, *isk*, *jpy*, *krw*, *nzd*, *pln* ,*rub*, *sek*, *sgd*, *thb*, *twd*, *idr* and *btc* (case-insensitive)";
msg.channel.send(message);
}
function formatMessage(amount, rate, option) {
var cur = option.sign;
var value = numeral(rate.rate * amount).format(option.format);
return (
"*" +
numeral(amount).format("0,0[.][00000000]") +
" LBC = " +
cur +
" " +
value +
"*\n_last updated " +
rate.time.utc().format(options.dtFormat) +
"_"
);
}
function doSteps(bot, currency, amount) {
var option = options.currencies[currency];
var shouldReload = true;
if (cachedRates[currency]) {
var cache = cachedRates[currency];
shouldReload =
cache.time === null ||
moment().diff(cache.time) >= options.refreshTime;
if (!shouldReload) {
var message = formatMessage(amount, cache, option);
msg.channel.send(message);
}
}
if (shouldReload) {
// copy the steps array
var steps = [];
for (var i = 0; i < option.steps.length; i++) {
steps.push(option.steps[i]);
steps.push(option.steps[i]);
}
processSteps(bot, currency, 0, amount, steps, option);
}
}
}
function processSteps(bot, currency, rate, amount, steps, option) {
if (steps.length > 0) {
function processSteps(bot, currency, rate, amount, steps, option) {
if (steps.length > 0) {
var pairName = steps[0];
if (!options.api[pairName]) {
msg.channel.send('There was a configuration error. ' + pairName + ' pair was not found.');
return;
msg.channel.send(
"There was a configuration error. " +
pairName +
" pair was not found."
);
return;
}
var pair = options.api[pairName];
request.get(pair.url, function(error, response, body) {
if (error) {
msg.channel.send( err.message ? err.message : 'The request could not be completed at this time. Please try again later.');
return;
if (error) {
msg.channel.send(
err.message
? err.message
: "The request could not be completed at this time. Please try again later."
);
return;
}
var pairRate = 0;
try {
pairRate = jp.query(JSON.parse(body), pair.path);
if (Array.isArray(pairRate) && pairRate.length > 0) {
pairRate = pairRate[0];
}
var pairRate = 0;
try {
pairRate = jp.query(JSON.parse(body), pair.path);
if (Array.isArray(pairRate) && pairRate.length > 0) {
pairRate = pairRate[0];
}
} catch (ignored) {
// invalid response or pair rate
} catch (ignored) {
// invalid response or pair rate
}
if (pairRate > 0) {
rate = rate === 0 ? pairRate : rate * pairRate;
steps.shift();
if (steps.length > 0) {
processSteps(bot, currency, rate, amount, steps, option);
return;
}
if (pairRate > 0) {
rate = (rate === 0) ? pairRate : rate * pairRate;
steps.shift();
if (steps.length > 0) {
processSteps(bot, currency, rate, amount, steps, option);
return;
}
// final step, cache and then response
var result = { rate: rate, time: moment() };
cachedRates[currency] = result;
msg.channel.send(formatMessage(amount, result, option));
} else {
msg.channel.send('The rate returned for the ' + pairName + ' pair was invalid.');
}
// final step, cache and then response
var result = {
rate: rate,
time: moment()
};
cachedRates[currency] = result;
msg.channel.send(formatMessage(amount, result, option));
} else {
msg.channel.send(
"The rate returned for the " + pairName + " pair was invalid."
);
}
});
}
}
}
}
}
}
};

View file

@ -1,44 +1,53 @@
let hasPerms = require('../helpers.js').hasPerms;
let inPrivate = require('../helpers.js').inPrivate;
let hasPerms = require("../helpers.js").hasPerms;
let inPrivate = require("../helpers.js").inPrivate;
exports.commands = [
"purge" // command that is in this file, every command needs it own export as shown below
]
exports.commands = [
"purge" // command that is in this file, every command needs it own export as shown below
];
exports.purge = {
usage: "<number of messages>",
description: 'Deletes Messages',
process: function(bot,msg,suffix){
if (inPrivate(msg)) {
msg.channel.send("You Cant Purge Message In DM's!");
return
}
if (hasPerms(msg)) {
if (!suffix) {
var newamount = "2"
} else {
var amount = Number(suffix)
var adding = 1
var newamount = amount + adding
}
let messagecount = newamount.toString();
msg.channel.fetchMessages({limit: messagecount})
.then(messages => {
msg.channel.bulkDelete(messages);
// Logging the number of messages deleted on both the channel and console.
msg.channel
.send("Deletion of messages successful. \n Total messages deleted including command: "+ newamount)
.then(message => message.delete(5000));
console.log('Deletion of messages successful. \n Total messages deleted including command: '+ newamount)
})
.catch(err => {
console.log('Error while doing Bulk Delete');
console.log(err);
});
} else {
msg.channel
.send('only moderators can use this command!')
.then(message => message.delete(5000));
}
}
}
usage: "<number of messages>",
description: "Deletes Messages",
process: function(bot, msg, suffix) {
if (inPrivate(msg)) {
msg.channel.send("You Cant Purge Message In DM's!");
return;
}
if (hasPerms(msg)) {
if (!suffix) {
var newamount = "2";
} else {
var amount = Number(suffix);
var adding = 1;
var newamount = amount + adding;
}
let messagecount = newamount.toString();
msg.channel
.fetchMessages({
limit: messagecount
})
.then(messages => {
msg.channel.bulkDelete(messages);
// Logging the number of messages deleted on both the channel and console.
msg.channel
.send(
"Deletion of messages successful. \n Total messages deleted including command: " +
newamount
)
.then(message => message.delete(5000));
console.log(
"Deletion of messages successful. \n Total messages deleted including command: " +
newamount
);
})
.catch(err => {
console.log("Error while doing Bulk Delete");
console.log(err);
});
} else {
msg.channel
.send("only moderators can use this command!")
.then(message => message.delete(5000));
}
}
};

View file

@ -1,48 +1,62 @@
let request = require('request');
let config = require('config');
let hasPerms = require('../helpers.js').hasPerms;
let inPrivate = require('../helpers.js').inPrivate;
let ChannelID = config.get('gitrelease').channel;
let request = require("request");
let config = require("config");
let hasPerms = require("../helpers.js").hasPerms;
let inPrivate = require("../helpers.js").inPrivate;
let ChannelID = config.get("gitrelease").channel;
exports.commands = [
"releasenotes" // command that is in this file, every command needs it own export as shown below
]
"releasenotes" // command that is in this file, every command needs it own export as shown below
];
exports.releasenotes = {
usage: "",
description: 'gets current release notes from GITHUB',
process: function(bot,msg,suffix){
usage: "",
description: "gets current release notes from GITHUB",
process: function(bot, msg, suffix) {
var headers = {
"Content-Type": "application/json",
"User-Agent": "Super Agent/0.0.1"
};
// Configure the request
var options = {
url: "https://api.github.com/repos/lbryio/lbry-app/releases/latest",
method: "GET",
headers: headers
};
var headers = {
'Content-Type': 'application/json',
'User-Agent': 'Super Agent/0.0.1'
}
// Configure the request
var options = {
url: 'https://api.github.com/repos/lbryio/lbry-app/releases/latest',
method: 'GET',
headers: headers,
}
// Start the request
request(options, function (error, response, body) {
releasemessage = JSON.parse(body).body
releasename = JSON.parse(body).name
releasedate = JSON.parse(body).published_at
releaseurl = JSON.parse(body).html_url
message = {"embed": {"title": "*Download " + releasename + " here!*","description": releasemessage,"url": releaseurl,"color": 7976557,"timestamp": releasedate,"author": {"name": "Lbry-app Release Notes for " + releasename,"icon_url": "http://www.pngall.com/wp-content/uploads/2016/04/Github-PNG-Image.png"},"footer": {"icon_url": "https://i.imgur.com/yWf5USu.png","text": "Lbry-app Updated "}}}
if (inPrivate(msg)) {
msg.channel.send(message);
return;
}
if (hasPerms(msg) && suffix === "post") {
bot.channels.get(ChannelID).send(message)
} else {
msg.channel.send(msg.author + " Release notes sent via DM")
msg.author.send(message)
}
})
}
}
// Start the request
request(options, function(error, response, body) {
releasemessage = JSON.parse(body).body;
releasename = JSON.parse(body).name;
releasedate = JSON.parse(body).published_at;
releaseurl = JSON.parse(body).html_url;
message = {
embed: {
title: "*Download " + releasename + " here!*",
description: releasemessage,
url: releaseurl,
color: 7976557,
timestamp: releasedate,
author: {
name: "Lbry-app Release Notes for " + releasename,
icon_url:
"http://www.pngall.com/wp-content/uploads/2016/04/Github-PNG-Image.png"
},
footer: {
icon_url: "https://i.imgur.com/yWf5USu.png",
text: "Lbry-app Updated "
}
}
};
if (inPrivate(msg)) {
msg.channel.send(message);
return;
}
if (hasPerms(msg) && suffix === "post") {
bot.channels.get(ChannelID).send(message);
} else {
msg.channel.send(msg.author + " Release notes sent via DM");
msg.author.send(message);
}
});
}
};

View file

@ -1,100 +1,113 @@
var config = require('config');
rolelist = config.get('rolelist');
var config = require("config");
rolelist = config.get("rolelist");
exports.commands = [
"addrole", // command that is in this file, every command needs it own export as shown below
"delrole",
"roles"
]
"addrole", // command that is in this file, every command needs it own export as shown below
"delrole",
"roles"
];
exports.addrole = {
usage: "<role to add>",
description: 'description of command',
process: function(bot,msg,suffix){
// Here the bot,msg and suffix is avaible, this function can be async if needed.
//amsg.reply(rolelist.allowedroles.includes(suffix));
var newrole = msg.guild.roles.find('name', suffix);
//var rolecheck = msg.guild.roles;
//var rolecheckvar = JSON.parse(rolecheck).find('name', suffix);
//console.log('Addrole Event firing.');
//console.log(rolelist);
//console.log(rolelist.allowedroles);
//console.log(config.get('allowedroles'));
if (rolelist.allowedroles.includes(suffix)) {
//console.log('Role is in allowed roles.');
//console.log('Role to add: ' + newrole);
if (!msg.member.roles.find('name', suffix)) {
msg.member.addRole(newrole)
.then(msg.channel.send(msg.member + ' has been added to the ' + suffix + ' role!'));
//console.log('Added role')
//msg.channel.send(msg.member + ' has been added to the ' + suffix + ' role!');
}
else{
msg.channel.send('It seems that you already have that role! Try removing it first with the delrole command!');
}
}
else {
msg.channel.send("That role isn't one you can add yourself too! Please run the roles command to find out which ones are allowed.");
}
usage: "<role to add>",
description: "description of command",
process: function(bot, msg, suffix) {
// Here the bot,msg and suffix is avaible, this function can be async if needed.
//amsg.reply(rolelist.allowedroles.includes(suffix));
var newrole = msg.guild.roles.find("name", suffix);
//var rolecheck = msg.guild.roles;
//var rolecheckvar = JSON.parse(rolecheck).find('name', suffix);
//console.log('Addrole Event firing.');
//console.log(rolelist);
//console.log(rolelist.allowedroles);
//console.log(config.get('allowedroles'));
if (rolelist.allowedroles.includes(suffix)) {
//console.log('Role is in allowed roles.');
//console.log('Role to add: ' + newrole);
if (!msg.member.roles.find("name", suffix)) {
msg.member
.addRole(newrole)
.then(
msg.channel.send(
msg.member + " has been added to the " + suffix + " role!"
)
);
//console.log('Added role')
//msg.channel.send(msg.member + ' has been added to the ' + suffix + ' role!');
} else {
msg.channel.send(
"It seems that you already have that role! Try removing it first with the delrole command!"
);
}
} else {
msg.channel.send(
"That role isn't one you can add yourself too! Please run the roles command to find out which ones are allowed."
);
}
}
};
exports.delrole = {
usage: "<role to remove>",
description: 'description of command',
process: function(bot,msg,suffix) {
// Here the bot,msg and suffix is avaible, this function can be async if needed.
let oldrole = msg.guild.roles.find('name', suffix);
//console.log(oldrole);
//console.log('Delrole Event firing.');
//console.log(msg);
//console.log('Printing Suffix! ' + suffix);
if (rolelist.allowedroles.includes(suffix)) {
if (msg.member.roles.find('name', suffix)) {
msg.member.removeRole(oldrole)
.then(msg.channel.send(msg.member + ' has been removed from the ' + suffix + ' role!'));
}
else {
msg.channel.send("You don't seem to have that role! Try adding it first with the addrole command!");
}
}
else {
msg.channel.send("That role isn't one you can add yourself too! Please run the roles command to find out which ones are allowed.");
}
usage: "<role to remove>",
description: "description of command",
process: function(bot, msg, suffix) {
// Here the bot,msg and suffix is avaible, this function can be async if needed.
let oldrole = msg.guild.roles.find("name", suffix);
//console.log(oldrole);
//console.log('Delrole Event firing.');
//console.log(msg);
//console.log('Printing Suffix! ' + suffix);
if (rolelist.allowedroles.includes(suffix)) {
if (msg.member.roles.find("name", suffix)) {
msg.member
.removeRole(oldrole)
.then(
msg.channel.send(
msg.member + " has been removed from the " + suffix + " role!"
)
);
} else {
msg.channel.send(
"You don't seem to have that role! Try adding it first with the addrole command!"
);
}
} else {
msg.channel.send(
"That role isn't one you can add yourself too! Please run the roles command to find out which ones are allowed."
);
}
}
};
exports.roles = {
usage: "",
description: 'description of command',
process: function(bot,msg,suffix){
// Here the bot,msg and suffix is avaible, this function can be async if needed.
msg.channel.send({embed: {
color: 3447003,
title: "Wunderbot",
description: "You have accessed the rolebot function of Wunderbot!",
fields: [{
name: "List of roles",
value: buildRoleString(rolelist.allowedroles),
inline: false
}],
footer:{
icon_url: msg.author.avatarURL,
text: 'Requested by: ' + JSON.stringify(msg.author.username)
}
}});
usage: "",
description: "description of command",
process: function(bot, msg, suffix) {
// Here the bot,msg and suffix is avaible, this function can be async if needed.
msg.channel.send({
embed: {
color: 3447003,
title: "Wunderbot",
description: "You have accessed the rolebot function of Wunderbot!",
fields: [
{
name: "List of roles",
value: buildRoleString(rolelist.allowedroles),
inline: false
}
],
footer: {
icon_url: msg.author.avatarURL,
text: "Requested by: " + JSON.stringify(msg.author.username)
}
}
});
//msg.channel.send(JSON.stringify(rolelist.allowedroles));
}
}
};
function buildRoleString(roles) {
let str = "";
for (let i = 0; i < roles.length; i++) {
str += "`" + roles[i] + "`" + '\n';
}
return str;
let str = "";
for (let i = 0; i < roles.length; i++) {
str += "`" + roles[i] + "`" + "\n";
}
return str;
}

View file

@ -2,12 +2,12 @@ const authors = [];
let warned = [];
let banned = [];
let messagelog = [];
let config = require('config');
let botlog = config.get('moderation').logchannel;
let hasPerms = require('../helpers.js').hasPerms;
let inPrivate = require('../helpers.js').inPrivate;
let hasExcludedSpamChannels = require('../helpers.js').hasExcludedSpamChannels;
let hasExcludedSpamUsers = require('../helpers.js').hasExcludedSpamUsers;
let config = require("config");
let botlog = config.get("moderation").logchannel;
let hasPerms = require("../helpers.js").hasPerms;
let inPrivate = require("../helpers.js").inPrivate;
let hasExcludedSpamChannels = require("../helpers.js").hasExcludedSpamChannels;
let hasExcludedSpamUsers = require("../helpers.js").hasExcludedSpamUsers;
/**
* Add simple spam protection to your discord server.
@ -16,39 +16,47 @@ let hasExcludedSpamUsers = require('../helpers.js').hasExcludedSpamUsers;
* @return {[type]} [description]
*/
exports.custom = [
"antiSpam"
]
exports.custom = ["antiSpam"];
exports.antiSpam = function(bot) {
const warnBuffer = 5;
const maxBuffer = 10;
const interval = 1500;
const warningMessage = ", Stop spamming or you will be banned! This is your warning!";
const warningMessage =
", Stop spamming or you will be banned! This is your warning!";
const banMessage = "has been banned for spamming!";
const maxDuplicatesWarning = 5;
const maxDuplicatesBan = 10;
bot.on('message', msg => {
if(inPrivate(msg) || hasPerms(msg) || msg.author.bot || hasExcludedSpamChannels(msg) || hasExcludedSpamUsers(msg)) {
return
}
if(msg.author.id != bot.user.id){
bot.on("message", msg => {
if (
inPrivate(msg) ||
hasPerms(msg) ||
msg.author.bot ||
hasExcludedSpamChannels(msg) ||
hasExcludedSpamUsers(msg)
) {
return;
}
if (msg.author.id != bot.user.id) {
var now = Math.floor(Date.now());
authors.push({
"time": now,
"author": msg.author.id
time: now,
author: msg.author.id
});
messagelog.push({
"message": msg.content,
"author": msg.author.id
message: msg.content,
author: msg.author.id
});
// Check how many times the same message has been sent.
var msgMatch = 0;
for (var i = 0; i < messagelog.length; i++) {
if (messagelog[i].message == msg.content && (messagelog[i].author == msg.author.id) && (msg.author.id !== bot.user.id)) {
if (
messagelog[i].message == msg.content &&
messagelog[i].author == msg.author.id &&
msg.author.id !== bot.user.id
) {
msgMatch++;
}
}
@ -67,14 +75,12 @@ exports.antiSpam = function(bot) {
matched++;
if (matched == warnBuffer && !warned.includes(msg.author.id)) {
warn(msg, msg.author.id);
}
else if (matched == maxBuffer) {
} else if (matched == maxBuffer) {
if (!banned.includes(msg.author.id)) {
ban(msg, msg.author.id);
}
}
}
else if (authors[i].time < now - interval) {
} else if (authors[i].time < now - interval) {
authors.splice(i);
warned.splice(warned.indexOf(authors[i]));
banned.splice(warned.indexOf(authors[i]));
@ -106,22 +112,28 @@ exports.antiSpam = function(bot) {
for (var i = 0; i < messagelog.length; i++) {
if (messagelog[i].author == msg.author.id) {
messagelog.splice(i);
}
}
banned.push(msg.author.id);
var user = msg.channel.guild.members.find(member => member.user.id === msg.author.id);
var user = msg.channel.guild.members.find(
member => member.user.id === msg.author.id
);
if (user) {
user.ban().then((member) => {
msg.channel.send(msg.author + " " +banMessage);
bot.channels.get(botlog).send(msg.author + " " +banMessage);
return true;
}).catch(() => {
msg.channel.send("insufficient permission to kick " + msg.author + " for spamming.");
return false;
});
user
.ban()
.then(member => {
msg.channel.send(msg.author + " " + banMessage);
bot.channels.get(botlog).send(msg.author + " " + banMessage);
return true;
})
.catch(() => {
msg.channel.send(
"insufficient permission to kick " + msg.author + " for spamming."
);
return false;
});
}
}
}
};

View file

@ -1,245 +1,292 @@
let request = require('request');
let wget = require('wget');
let fs = require('fs');
let config = require('config');
let hasSpeechBotChannels = require('../helpers.js').hasSpeechBotChannels;
let inPrivate = require('../helpers.js').inPrivate;
let ChannelID = config.get('speechbot').mainchannel;
let request = require("request");
let wget = require("wget");
let fs = require("fs");
let config = require("config");
let hasSpeechBotChannels = require("../helpers.js").hasSpeechBotChannels;
let inPrivate = require("../helpers.js").inPrivate;
let ChannelID = config.get("speechbot").mainchannel;
//debug output "true/false" outputs same error as slack message in console if set to true
//if set to false console will be left blank like normal
//some have more info on file details of error
let FullDebug = "true"
let FullDebug = "true";
//outputs response from speech, very bulk reply
let ResponseDebug = "false"
let ResponseDebug = "false";
exports.commands = [
"speech" // command that is in this file, every command needs it own export as shown below
]
"speech" // command that is in this file, every command needs it own export as shown below
];
exports.speech = {
usage: "<name>",
description: "gets top claim from spee.ch, coming soon post to spee.ch",
process: function(bot,msg,suffix){
if(!hasSpeechBotChannels(msg) && !inPrivate(msg)){
msg.channel.send('Please use <#' + ChannelID + '> or DMs to talk to speech bot.');
return;
}
var command = "!speech"
words = suffix.trim().split(' ').filter( function(n){return n !== "";} );
var imagename = words[0];
//check if image name is help, if it is then do help message
if (imagename == "help") {
doHelp(bot,msg,suffix)
return;
} else {
//check if imagename is defined if not do error
if (imagename === undefined) {
if (FullDebug === "true") {
var message = "`no name provided`"
console.log('no name provided');
msg.channel.send(message);
doHelp(bot,msg,suffix)
return
} else {
var message = "`no name provided`"
msg.channel.send(message);
doHelp(bot,msg,suffix)
return
}
}
//set second word to url
var filepath = words[1];
//check if a url is provided if none do help message
if (filepath === undefined) {
if (FullDebug === "true") {
var message = "`no url provided, fetching image from:`\n" +
"https://spee.ch/" + imagename
console.log('no url provided');
msg.channel.send(message);
return
} else {
var message = "`no url provided, fetching image from:`\n" +
"https://spee.ch/" + imagename
msg.channel.send(message);
return
}}
//prepare url for other uses
//we will just set filepath to url to be safe
var url = filepath;
//parse first 4 letters of url should be http
var linkvalid = url.slice(0, 4)
//check of url provided begins with http in not throw error and help message
if (linkvalid !== "http") {
if (FullDebug === "true") {
var message = '`error not a valid url, please start with http or https`'
console.log('invalid url provided: ' + filepath);
msg.channel.send(message);
return
} else {
var message = '`error not a valid url, please start with http or https`'
msg.channel.send(message);
return;
}}
//function to check if url is an image
var isUriImage = function(uri) {
//make sure we remove any nasty GET params
uri = uri.split('?')[0];
//moving on, split the uri into parts that had dots before them
var parts = uri.split('.');
//get the last part ( should be the extension )
var extension = parts[parts.length-1];
//define some image types to test against
var imageTypes = ['jpg','jpeg','tiff','png','gif','bmp'];
//check if the extension matches anything in the list. if it does set true if not set false
if(imageTypes.indexOf(extension) !== -1) {
return true;
} else {
return false
}
}
//check if url is an image if its not throw error and help message
if (isUriImage(url) === false) {
if (FullDebug === "true"){
var message = '`error not a valid image url, be sure the link includes a file type`'
console.log('invalid url provided: ' + url);
msg.channel.send(message);
return
} else {
var message = '`error not a valid image url, be sure the link includes a file type`'
msg.channel.send(message);
return
}
}
//set third word to nsfw, with it being an optional functionality
var eighteen = words[2];
//check is NSFW if yes or no sets proper value if none
if (eighteen == "" || eighteen == "none" || eighteen == undefined || eighteen == null || eighteen == "no"|| eighteen == "false" || eighteen == false || eighteen == "n") {
eighteen = "no";
} else {
eighteen = "yes"
}
//prepare url for wget
var source = url;
//parse the filename to use to save file
filepath = source.split('/').pop();
//set proper directory for downloading image
var outputFile = 'speech-uploads/' + filepath;
//set download directory to current working directory
var dir = process.cwd() ;
//set full path to directory for speech uploading
var fullpath = dir + '\\speech-uploads\\' + filepath;
//download url via wget
var download = wget.download(url, outputFile);
//check if url is reachable if not throw error
download.on('error', function(err) {
if (FullDebug === "true") {
console.log("error could not reach: " + url + " : " + err);
var message = '`error url could not be reached`'
msg.channel.send(message);
return
} else {
var message = '`error url could not be reached`'
msg.channel.send(message);
return
}
});
download.on('end', (output) => {
//if no errors and file ready -> do the request
output && doSteps(bot, imagename, url, eighteen);
});}
//send help message
function doHelp(bot,msg,suffix) {
msg.channel.send(
{
"embed": {
"title": "",
"description": '**!speech `<Name>`** : *displays top claim on speech* \n\n\n' +
"**COMING SOON POSTING TO SPEECH** \n\n" +
'**!speech `<Name> <URL> <NSFW>`** : *Uploads Image URL to Spee.ch* \n' +
'**NOTE : dont include spaces in name (NSFW is optional true/false, if left blank will defualt to false)** \n' +
'EXAMPLE : `!speech my-image-name https://url/to/image.png false`',
"color": 7976557,
"author": {
"name": "Speech Bot Help",
"icon_url": "https://i.imgur.com/yWf5USu.png"
}
}
}
);
}
//send post request to speech
function doSteps(bot, imagename, url, eighteen) {
request.post(
//url to send post request
'https://spee.ch/api/publish',
//json payload
{ json: { name: imagename ,file: fullpath,nsfw: eighteen } },
//get response from server
function (error, response, body) {
//output response if ResponseDebug set to true
if (ResponseDebug === "true") {
console.log(response);
console.log(error);
console.log(body.success);
console.log(body.message);
}
//check speech response for file path error, if found throw internal error!
if (body.message === "no files found in request") {
if (FullDebug === "true") {
console.log("no file found: " + fullpath);
var message = '`Failed to upload file internally!!`\n please contact <@244245498746241025> or another moderator if the issue persists';
msg.channel.send(message);
return
} else {
var message = '`Failed to upload file internally!!`\n please contact <@244245498746241025> or another moderator if the issue persists';
msg.channel.send(message);
return
}
}
//check speech response for filename error, if found throw internal error!
if (body.message === "no name field found in request") {
if (FullDebug === "true") {
console.log("no name field found: " + imagename);
var message = '`Failed to upload file internally!!`\n please contact <@244245498746241025> or another moderator if the issue persists';
msg.channel.send(message);
return
} else {
var message = '`Failed to upload file internally!!`\n please contact <@244245498746241025> or another moderator if the issue persists';
msg.channel.send(message);
return
}
}
//if no errors post this message
var message = 'uploading... \n "name":"' + imagename + '",\n "URL": "' + url + '",\n "nsfw":"' + eighteen + '"\n to spee.ch';
console.log('uploading... \n "name":"' + imagename + '",\n "file name": "' + filepath + '",\n "url":"' + url + '"\n "path":"' + fullpath + '"\n "nsfw": "' + eighteen + '"' );
msg.channel.send(message);
}
);
};
usage: "<name>",
description: "gets top claim from spee.ch, coming soon post to spee.ch",
process: function(bot, msg, suffix) {
if (!hasSpeechBotChannels(msg) && !inPrivate(msg)) {
msg.channel.send(
"Please use <#" + ChannelID + "> or DMs to talk to speech bot."
);
return;
}
}
var command = "!speech";
words = suffix
.trim()
.split(" ")
.filter(function(n) {
return n !== "";
});
var imagename = words[0];
//check if image name is help, if it is then do help message
if (imagename == "help") {
doHelp(bot, msg, suffix);
return;
} else {
//check if imagename is defined if not do error
if (imagename === undefined) {
if (FullDebug === "true") {
var message = "`no name provided`";
console.log("no name provided");
msg.channel.send(message);
doHelp(bot, msg, suffix);
return;
} else {
var message = "`no name provided`";
msg.channel.send(message);
doHelp(bot, msg, suffix);
return;
}
}
//set second word to url
var filepath = words[1];
//check if a url is provided if none do help message
if (filepath === undefined) {
if (FullDebug === "true") {
var message =
"`no url provided, fetching image from:`\n" +
"https://spee.ch/" +
imagename;
console.log("no url provided");
msg.channel.send(message);
return;
} else {
var message =
"`no url provided, fetching image from:`\n" +
"https://spee.ch/" +
imagename;
msg.channel.send(message);
return;
}
}
//prepare url for other uses
//we will just set filepath to url to be safe
var url = filepath;
//parse first 4 letters of url should be http
var linkvalid = url.slice(0, 4);
//check of url provided begins with http in not throw error and help message
if (linkvalid !== "http") {
if (FullDebug === "true") {
var message =
"`error not a valid url, please start with http or https`";
console.log("invalid url provided: " + filepath);
msg.channel.send(message);
return;
} else {
var message =
"`error not a valid url, please start with http or https`";
msg.channel.send(message);
return;
}
}
//function to check if url is an image
var isUriImage = function(uri) {
//make sure we remove any nasty GET params
uri = uri.split("?")[0];
//moving on, split the uri into parts that had dots before them
var parts = uri.split(".");
//get the last part ( should be the extension )
var extension = parts[parts.length - 1];
//define some image types to test against
var imageTypes = ["jpg", "jpeg", "tiff", "png", "gif", "bmp"];
//check if the extension matches anything in the list. if it does set true if not set false
if (imageTypes.indexOf(extension) !== -1) {
return true;
} else {
return false;
}
};
//check if url is an image if its not throw error and help message
if (isUriImage(url) === false) {
if (FullDebug === "true") {
var message =
"`error not a valid image url, be sure the link includes a file type`";
console.log("invalid url provided: " + url);
msg.channel.send(message);
return;
} else {
var message =
"`error not a valid image url, be sure the link includes a file type`";
msg.channel.send(message);
return;
}
}
//set third word to nsfw, with it being an optional functionality
var eighteen = words[2];
//check is NSFW if yes or no sets proper value if none
if (
eighteen == "" ||
eighteen == "none" ||
eighteen == undefined ||
eighteen == null ||
eighteen == "no" ||
eighteen == "false" ||
eighteen == false ||
eighteen == "n"
) {
eighteen = "no";
} else {
eighteen = "yes";
}
//prepare url for wget
var source = url;
//parse the filename to use to save file
filepath = source.split("/").pop();
//set proper directory for downloading image
var outputFile = "speech-uploads/" + filepath;
//set download directory to current working directory
var dir = process.cwd();
//set full path to directory for speech uploading
var fullpath = dir + "\\speech-uploads\\" + filepath;
//download url via wget
var download = wget.download(url, outputFile);
//check if url is reachable if not throw error
download.on("error", function(err) {
if (FullDebug === "true") {
console.log("error could not reach: " + url + " : " + err);
var message = "`error url could not be reached`";
msg.channel.send(message);
return;
} else {
var message = "`error url could not be reached`";
msg.channel.send(message);
return;
}
});
download.on("end", output => {
//if no errors and file ready -> do the request
output && doSteps(bot, imagename, url, eighteen);
});
}
//send help message
function doHelp(bot, msg, suffix) {
msg.channel.send({
embed: {
title: "",
description:
"**!speech `<Name>`** : *displays top claim on speech* \n\n\n" +
"**COMING SOON POSTING TO SPEECH** \n\n" +
"**!speech `<Name> <URL> <NSFW>`** : *Uploads Image URL to Spee.ch* \n" +
"**NOTE : dont include spaces in name (NSFW is optional true/false, if left blank will defualt to false)** \n" +
"EXAMPLE : `!speech my-image-name https://url/to/image.png false`",
color: 7976557,
author: {
name: "Speech Bot Help",
icon_url: "https://i.imgur.com/yWf5USu.png"
}
}
});
}
//send post request to speech
function doSteps(bot, imagename, url, eighteen) {
request.post(
//url to send post request
"https://spee.ch/api/publish",
//json payload
{
json: {
name: imagename,
file: fullpath,
nsfw: eighteen
}
},
//get response from server
function(error, response, body) {
//output response if ResponseDebug set to true
if (ResponseDebug === "true") {
console.log(response);
console.log(error);
console.log(body.success);
console.log(body.message);
}
//check speech response for file path error, if found throw internal error!
if (body.message === "no files found in request") {
if (FullDebug === "true") {
console.log("no file found: " + fullpath);
var message =
"`Failed to upload file internally!!`\n please contact <@244245498746241025> or another moderator if the issue persists";
msg.channel.send(message);
return;
} else {
var message =
"`Failed to upload file internally!!`\n please contact <@244245498746241025> or another moderator if the issue persists";
msg.channel.send(message);
return;
}
}
//check speech response for filename error, if found throw internal error!
if (body.message === "no name field found in request") {
if (FullDebug === "true") {
console.log("no name field found: " + imagename);
var message =
"`Failed to upload file internally!!`\n please contact <@244245498746241025> or another moderator if the issue persists";
msg.channel.send(message);
return;
} else {
var message =
"`Failed to upload file internally!!`\n please contact <@244245498746241025> or another moderator if the issue persists";
msg.channel.send(message);
return;
}
}
//if no errors post this message
var message =
'uploading... \n "name":"' +
imagename +
'",\n "URL": "' +
url +
'",\n "nsfw":"' +
eighteen +
'"\n to spee.ch';
console.log(
'uploading... \n "name":"' +
imagename +
'",\n "file name": "' +
filepath +
'",\n "url":"' +
url +
'"\n "path":"' +
fullpath +
'"\n "nsfw": "' +
eighteen +
'"'
);
msg.channel.send(message);
}
);
}
}
};

View file

@ -1,198 +1,304 @@
let jp = require('jsonpath');
let moment = require('moment');
let numeral = require('numeral');
let request = require('request');
let config = require('config');
let hasStatsBotChannels = require('../helpers.js').hasStatsBotChannels;
let inPrivate = require('../helpers.js').inPrivate;
let ChannelID = config.get('statsbot').mainchannel;
let jp = require("jsonpath");
let moment = require("moment");
let numeral = require("numeral");
let request = require("request");
let config = require("config");
let hasStatsBotChannels = require("../helpers.js").hasStatsBotChannels;
let inPrivate = require("../helpers.js").inPrivate;
let ChannelID = config.get("statsbot").mainchannel;
exports.commands = [
"stats" // command that is in this file, every command needs it own export as shown below
]
"stats" // command that is in this file, every command needs it own export as shown below
];
exports.stats = {
usage: "",
description: 'Displays current a list of current Market stats',
process: function(bot,msg,suffix){
var options = {
defaultCurrency: 'USD',
usage: "",
description: "Displays current a list of current Market stats",
process: function(bot, msg, suffix) {
var options = {
defaultCurrency: "USD",
// supported currencies and api steps to arrive at the final value
currencies: {
USD: { steps: ['LBCUSD'], format: '$0,0.00', sign:'USD $' },
BTC: { steps: ['LBCBTC'], format: 'BTC 0,0.00000000', sign:'BTC' },
ETH: { steps: ['LBCETH'], format: 'ETH 0,0.00000000', sign: 'ETH' },
GBP: { steps: ['LBCGBP'], format: '£0,0.00', sign: '£' },
EUR: { steps: ['LBCEUR'], format: '€0,0.00', sign: '€' },
CAD: { steps: ['LBCCAD'], format: '$0,0.00', sign: 'CAD $' },
AUD: { steps: ['LBCAUD'], format: '$0,0.00', sign: 'AUD $' },
IDR: { steps: ['LBCIDR'], format: 'Rp0,0.00', sign: 'Rp' }
},
// supported currencies and api steps to arrive at the final value
currencies: {
USD: {
steps: ["LBCUSD"],
format: "$0,0.00",
sign: "USD $"
},
BTC: {
steps: ["LBCBTC"],
format: "BTC 0,0.00000000",
sign: "BTC"
},
ETH: {
steps: ["LBCETH"],
format: "ETH 0,0.00000000",
sign: "ETH"
},
GBP: {
steps: ["LBCGBP"],
format: "£0,0.00",
sign: "£"
},
EUR: {
steps: ["LBCEUR"],
format: "€0,0.00",
sign: "€"
},
CAD: {
steps: ["LBCCAD"],
format: "$0,0.00",
sign: "CAD $"
},
AUD: {
steps: ["LBCAUD"],
format: "$0,0.00",
sign: "AUD $"
},
IDR: {
steps: ["LBCIDR"],
format: "Rp0,0.00",
sign: "Rp"
}
},
// api steps
api: {
LBCBTC: { url: 'https://bittrex.com/api/v1.1/public/getticker?market=BTC-LBC', path: '$.result.Bid' },
LBCUSD: { url: 'https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=usd', path: '$[0].price_usd' },
LBCGBP: { url: 'https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=gbp', path: '$[0].price_gbp' },
LBCETH: { url: 'https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=eth', path: '$[0].price_eth' },
LBCEUR: { url: 'https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=eur', path: '$[0].price_eur' },
LBCAUD: { url: 'https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=aud', path: '$[0].price_aud' },
LBCCAD: { url: 'https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=cad', path: '$[0].price_cad' },
LBCIDR: { url: 'https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=idr', path: '$[0].price_idr'}
},
// api steps
api: {
LBCBTC: {
url: "https://bittrex.com/api/v1.1/public/getticker?market=BTC-LBC",
path: "$.result.Bid"
},
LBCUSD: {
url:
"https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=usd",
path: "$[0].price_usd"
},
LBCGBP: {
url:
"https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=gbp",
path: "$[0].price_gbp"
},
LBCETH: {
url:
"https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=eth",
path: "$[0].price_eth"
},
LBCEUR: {
url:
"https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=eur",
path: "$[0].price_eur"
},
LBCAUD: {
url:
"https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=aud",
path: "$[0].price_aud"
},
LBCCAD: {
url:
"https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=cad",
path: "$[0].price_cad"
},
LBCIDR: {
url:
"https://api.coinmarketcap.com/v1/ticker/library-credit/?convert=idr",
path: "$[0].price_idr"
}
},
// display date/time format
dtFormat: 'Do MMM YYYY h:mma [UTC]',
// display date/time format
dtFormat: "Do MMM YYYY h:mma [UTC]",
// refresh rate in milliseconds to retrieve a new price (default to 10 minutes)
refreshTime: 300000
};
// refresh rate in milliseconds to retrieve a new price (default to 10 minutes)
refreshTime: 300000
};
// store the last retrieved rate
var command = '!stats';
// store the last retrieved rate
var command = "!stats";
var currency = options.defaultCurrency;
var amount = 1;
if(!inPrivate(msg) && !hasStatsBotChannels(msg)){
msg.channel.send('Please use <#' + ChannelID + '> or DMs to talk to stats bot.');
return;
} else {
doSteps(bot, msg, 'USD', amount);
doSteps(bot, msg, 'EUR', amount);
doSteps(bot, msg, 'GBP', amount);
doSteps(bot, msg, 'ETH', amount);
doSteps(bot, msg, 'BTC', amount);
doSteps(bot, msg, 'CAD', amount);
doSteps(bot, msg, 'AUD', amount);
doSteps(bot, msg, 'IDR', amount);
setTimeout(function() { marketstats(bot,msg,suffix); }, 250);
//marketstats(bot,msg);
//volume24(bot,msg); can't get this part to work, someone help me fix - i think it's because 24h_volume_usd starts with number
}
function formatMessage(amount, rate, option) {
var cur = option.sign;
var value = rate.rate * amount;
if (option.sign == 'USD $' || option.sign == 'CAD $' || option.sign == 'AUD $' || option.sign == '£' || option.sign == '€'|| option.sign == 'Rp'){
return '*' + numeral(amount).format('0,0[.][00000000]') + ' LBC = ' + cur +' '+ value.toFixed(2) + '*';
var currency = options.defaultCurrency;
var amount = 1;
if (!inPrivate(msg) && !hasStatsBotChannels(msg)) {
msg.channel.send(
"Please use <#" + ChannelID + "> or DMs to talk to stats bot."
);
return;
} else {
doSteps(bot, msg, "USD", amount);
doSteps(bot, msg, "EUR", amount);
doSteps(bot, msg, "GBP", amount);
doSteps(bot, msg, "ETH", amount);
doSteps(bot, msg, "BTC", amount);
doSteps(bot, msg, "CAD", amount);
doSteps(bot, msg, "AUD", amount);
doSteps(bot, msg, "IDR", amount);
setTimeout(function() {
marketstats(bot, msg, suffix);
}, 250);
//marketstats(bot,msg);
//volume24(bot,msg); can't get this part to work, someone help me fix - i think it's because 24h_volume_usd starts with number
}
else {
return '*' + numeral(amount).format('0,0[.][00000000]') + ' LBC = ' + cur +' ' + numeral(value).format('0,0[.][00000000]') + '*';
function formatMessage(amount, rate, option) {
var cur = option.sign;
var value = rate.rate * amount;
if (
option.sign == "USD $" ||
option.sign == "CAD $" ||
option.sign == "AUD $" ||
option.sign == "£" ||
option.sign == "€" ||
option.sign == "Rp"
) {
return (
"*" +
numeral(amount).format("0,0[.][00000000]") +
" LBC = " +
cur +
" " +
value.toFixed(2) +
"*"
);
} else {
return (
"*" +
numeral(amount).format("0,0[.][00000000]") +
" LBC = " +
cur +
" " +
numeral(value).format("0,0[.][00000000]") +
"*"
);
}
}
}
function formaty(n, decimals, currency) {
n = parseFloat(n);
return currency + " " + n.toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1,");
}
function formaty(n, decimals, currency) {
n = parseFloat(n);
return (
currency + " " + n.toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, "$1,")
);
}
function doSteps(bot, msg, currency, amount) {
function doSteps(bot, msg, currency, amount) {
var option = options.currencies[currency];
// copy the steps array
var steps = [];
for (var i = 0; i < option.steps.length; i++) {
steps.push(option.steps[i]);
}
var option = options.currencies[currency];
// copy the steps array
var steps = [];
for (var i = 0; i < option.steps.length; i++) {
steps.push(option.steps[i]);
processSteps(bot, msg, currency, 0, amount, steps, option);
}
function marketstats(bot, msg, suffix) {
var statsurl = "https://api.coinmarketcap.com/v1/ticker/library-credit/";
request.get(statsurl, function(error, response, body) {
if (error) {
msg.channel.send(
err.message
? err.message
: "The request could not be completed at this time. Please try again later."
);
return;
}
var marketcap = 0;
try {
marketcap = jp.query(JSON.parse(body), "$[0].market_cap_usd");
if (Array.isArray(marketcap) && marketcap.length > 0) {
marketcap = marketcap[0];
marketcap = formaty(marketcap, 2, "$");
}
} catch (ignored) {
// invalid response or pair rate
}
processSteps(bot, msg, currency, 0, amount, steps, option);
}
var statmsg = "*" + "Marketcap: " + marketcap + "*\n";
function marketstats(bot,msg,suffix) {
var statsurl='https://api.coinmarketcap.com/v1/ticker/library-credit/';
msg.channel.send(statmsg);
});
}
request.get(statsurl, function(error, response, body) {
if (error) {
msg.channel.send(err.message ? err.message : 'The request could not be completed at this time. Please try again later.');
return;
}
var marketcap = 0;
try {
marketcap = jp.query(JSON.parse(body), '$[0].market_cap_usd');
if (Array.isArray(marketcap) && marketcap.length > 0) {
marketcap = marketcap[0];
marketcap = formaty(marketcap,2,'$')
}
function volume24(bot, msg, suffix) {
var statsurl = "https://api.coinmarketcap.com/v1/ticker/library-credit/";
} catch (ignored) {
// invalid response or pair rate
}
request.get(statsurl, function(error, response, body) {
if (error) {
msg.channel.send(
err.message
? err.message
: "The request could not be completed at this time. Please try again later."
);
return;
}
var volume24 = 0;
try {
volume24 = jp.query(JSON.parse(body), "$[0].24h_volume_usd");
if (Array.isArray(volume24) && volume24.length > 0) {
volume24 = volume24[0];
}
} catch (ignored) {
// invalid response or pair rate
}
var statmsg = '*'+'Marketcap: '+marketcap+'*\n';
var statmsg = "*" + "Volume: $" + volume24 + "*\n";
msg.channel.send(statmsg);
msg.channel.send(statmsg);
});
}
});
}
function volume24(bot,msg,suffix) {
var statsurl='https://api.coinmarketcap.com/v1/ticker/library-credit/';
request.get(statsurl, function(error, response, body) {
if (error) {
msg.channel.send(err.message ? err.message : 'The request could not be completed at this time. Please try again later.');
return;
}
var volume24 = 0;
try {
volume24 = jp.query(JSON.parse(body),'$[0].24h_volume_usd');
if (Array.isArray(volume24) && volume24.length > 0) {
volume24 = volume24[0];
}
} catch (ignored) {
// invalid response or pair rate
}
var statmsg = '*'+'Volume: $'+volume24+'*\n';
msg.channel.send(statmsg);
});
}
function processSteps(bot, msg, currency, rate, amount, steps, option) {
if (steps.length > 0) {
function processSteps(bot, msg, currency, rate, amount, steps, option) {
if (steps.length > 0) {
var pairName = steps[0];
if (!options.api[pairName]) {
msg.channel.send('There was a configuration error. ' + pairName + ' pair was not found.');
return;
msg.channel.send(
"There was a configuration error. " +
pairName +
" pair was not found."
);
return;
}
var pair = options.api[pairName];
request.get(pair.url, function(error, response, body) {
if (error) {
msg.channel.send(err.message ? err.message : 'The request could not be completed at this time. Please try again later.');
return;
if (error) {
msg.channel.send(
err.message
? err.message
: "The request could not be completed at this time. Please try again later."
);
return;
}
var pairRate = 0;
try {
pairRate = jp.query(JSON.parse(body), pair.path);
if (Array.isArray(pairRate) && pairRate.length > 0) {
pairRate = pairRate[0];
}
var pairRate = 0;
try {
pairRate = jp.query(JSON.parse(body), pair.path);
if (Array.isArray(pairRate) && pairRate.length > 0) {
pairRate = pairRate[0];
}
} catch (ignored) {
// invalid response or pair rate
} catch (ignored) {
// invalid response or pair rate
}
if (pairRate > 0) {
rate = rate === 0 ? pairRate : rate * pairRate;
steps.shift();
if (steps.length > 0) {
processSteps(bot, currency, rate, amount, steps, option);
return;
}
if (pairRate > 0) {
rate = (rate === 0) ? pairRate : rate * pairRate;
steps.shift();
if (steps.length > 0) {
processSteps(bot, currency, rate, amount, steps, option);
return;
}
// final step, cache and then response
var result = {
rate: rate,
time: moment()
};
// final step, cache and then response
var result = { rate: rate, time: moment() };
msg.channel.send(formatMessage(amount, result, option));
} else {
msg.channel.send('The rate returned for the ' + pairName + ' pair was invalid.');
}
msg.channel.send(formatMessage(amount, result, option));
} else {
msg.channel.send(
"The rate returned for the " + pairName + " pair was invalid."
);
}
});
}
}
}
}
}
}
};

View file

@ -1,17 +1,16 @@
'use strict';
"use strict";
const bitcoin = require('bitcoin');
let config = require('config');
config = config.get('lbrycrd');
const bitcoin = require("bitcoin");
let config = require("config");
config = config.get("lbrycrd");
const lbry = new bitcoin.Client(config);
exports.commands = [
"tip"
]
exports.commands = ["tip"];
exports.tip = {
usage: "<subcommand>",
description: 'balance: get your balance\n deposit: get address for your deposits\n withdraw ADDRESS AMOUNT: withdraw AMOUNT credits to ADDRESS\n <user> <amount>: mention a user with @ and then the amount to tip them',
process: async function(bot,msg,suffix){
usage: "<subcommand>",
description:
"balance: get your balance\n deposit: get address for your deposits\n withdraw ADDRESS AMOUNT: withdraw AMOUNT credits to ADDRESS\n <user> <amount>: mention a user with @ and then the amount to tip them",
process: async function(bot, msg, suffix) {
return; // Tipping is now handled by the separate tipbot(in branch tipbot_dc), no need to to anything here...
}
}
}
};

View file

@ -1,226 +1,218 @@
let hasPerms = require('../helpers.js').hasPerms;
let inPrivate = require('../helpers.js').inPrivate;
let hasPerms = require("../helpers.js").hasPerms;
let inPrivate = require("../helpers.js").inPrivate;
exports.custom = [
"onUserJoin"
]
exports.custom = ["onUserJoin"];
exports.onUserJoin = function(bot) {
bot.on('guildMemberAdd', member => {
member.send(
{
"embed": {
"title": "*Click here for more info about LBRY!*",
"description": "**Welcome to LBRY Discord Community, you are now officially a LBRYian!** \n" +
"If you are new to LBRY and would like to learn more, see the links at the end of this message. \n" +
"This community allows LBRYians to interact with the team directly and for us to engage users in order to grow the LBRY platform! \n" +
"**Looking for *Rewards Verification*? Please make a request in the #verification channel. A mod will reach out to you, please be patient. Only 1 Reward account is allowed per person** \n",
"url": "https://lbry.io/what",
"color": 7976557,
"author": {
"name": "Welcome to LBRY Discord Community",
"icon_url": "https://i.imgur.com/yWf5USu.png"
}
}
}
);
member.send(
{
"embed": {
"description": "1. Be respectful to other community members. Harrasment and vulgarity will not be tolerated \n" +
"2. Do not spam, advertise or post referral links \n" +
"3. Use appropriate channels for your discussions/questions. If you are looking for help with LBRY, use #help, for price talk, use #market-and-trading \n" +
"4. #general discussions should be at least somewhat related to LBRY, otherwise there is #random \n" +
"5. Do not post **not safe for work (NFSW)** content in any non-marked channels, there is #random-nsfw for that \n" +
"6. Do not direct message and LBRY team or mods without being asked to do so \n" +
"7. Do not request free LBC, begging will not be tolerated \n",
"color": 7976557,
"author": {
"name": "Ground rules",
"icon_url": "https://i.imgur.com/yWf5USu.png"
}
}
}
);
member.send(
{
"embed": {
"description": "1. Type !tip help to interact with our Tipbot which can be used to send and receive LBRY Credits (LBC). **Enable 2FA in your Discord account settings!** \n" +
"2. See the Frequently Asked Questions (FAQ) section below prior to asking for help or information on LBRY \n" +
"3. Backing up your LBRY wallet is your responsbility, see FAQ link below \n" +
"4. You can find the LBRY Block explorer at https://explorer.lbry.io \n" +
"5. Want to contribute more? Check out https://lbry.io/faq/contributing \n" +
"6. Are you a dev? Check out the #dev channel \n" +
"7. Want to share something you published? Post it on the #publishers channel \n",
"color": 7976557,
"author": {
"name": "Helpful hints",
"icon_url": "https://i.imgur.com/yWf5USu.png"
}
}
}
);
member.send(
{
"embed": {
"title": "*Click here for more info about LBRY!*",
"description": "[**LBRY**](https://lbry.io) is a protocol providing fully decentralized network for the discovery, distribution, and payment of data. It utilizes the [**LBRY blockchain**](https://lbry.io/what#the-network) as a global namespace and database of digital content. Blockchain entries contain searchable content metadata, identities, and rights and access rules. \n[_**Download the LBRY App here**_](https://lbry.io/get)",
"url": "https://lbry.io/what",
"color": 7976557,
"author": {
"name": "What is LBRY?",
"url": "https://lbry.io/what",
"icon_url": "https://i.imgur.com/yWf5USu.png"
}
}
});
member.send(
{
"embed": {
"title": "*Click here to see all LBRY Frequently Asked Questions (FAQ)!*",
"description": "Want to backup your LBRY wallet? [**Backup**](https://lbry.io/faq/how-to-backup-wallet) \nLooking for LBRY data? [**Behind the scenes files**](https://lbry.io/faq/lbry-directories) \nTrouble starting LBRY? [**Startup troubleshooting**](https://lbry.io/faq/startup-troubleshooting) \nNeed help finding your log files (will help us troubleshoot!)? [**Find logs**](https://lbry.io/faq/how-to-find-lbry-log-file) \nNot able to stream any content? [**Troublshoot streaming**](https://lbry.io/faq/unable-to-stream)\nNeed help with publishing? [**How to Publish**](https://lbry.io/faq/how-to-publish) \nWant more LBRY Credits (LBC)? [**Get LBC**](https://lbry.io/faq/earn-credits) \nLooking for referral information? [**Referrals**](https://lbry.io/faq/referrals)",
"url": "https://lbry.io/faq",
"color": 7976557,
"author": {
"name": "LBRY FAQ",
"url": "https://lbry.io/faq",
"icon_url": "https://spee.ch/8/Id5Qoc3w.png"
}
}
});
member.send(
{
"embed": {
"title": "*Have you checked out spee.ch yet?!*",
"description": "[**spee.ch**](https://spee.ch) runs on top of the LBRY network - it's essentially an open source, censorship resistent and decentralized image and video sharing site with the added benefit of being a web-based (works on mobile too!) gateway into the LBRY network. spee.ch can be used to retrieve LBRY images/videos that are free by accessing them through a web browser. \nFor example, if content is located at lbry://loose-cannons-episode1#12c87bb42dd8832167b1e54edf72bbd37bc47622, you can view it on spee.ch at: https://spee.ch/12c87bb42dd8832167b1e54edf72bbd37bc47622/loose-cannons-episode1. You can also view channels on spee.ch, such as: https://spee.ch/@copchronicles:5c039dc7423657e59d78939df72c186e43273675 or https://spee.ch/@MinutePhysics:589276465a23c589801d874f484cc39f307d7ec7 \n\nspee.ch also allows you to create a channel to group your uploads and retreive them easily. These channels are separate from any you may have in the LBRY app since they exist on the spee.ch site via a login process. You can even share your channel name and password so that others can contribute to it.",
"url": "https://spee.ch/about",
"color": 7976557,
"author": {
"name": "spee.ch",
"url": "https://spee.ch",
"icon_url": "http://www.pd4pic.com/images/flag-green-blue-purple-indigo-bars-background.png"
}
}
});
});
}
bot.on("guildMemberAdd", member => {
member.send({
embed: {
title: "*Click here for more info about LBRY!*",
description:
"**Welcome to LBRY Discord Community, you are now officially a LBRYian!** \n" +
"If you are new to LBRY and would like to learn more, see the links at the end of this message. \n" +
"This community allows LBRYians to interact with the team directly and for us to engage users in order to grow the LBRY platform! \n" +
"**Looking for *Rewards Verification*? Please make a request in the #verification channel. A mod will reach out to you, please be patient. Only 1 Reward account is allowed per person** \n",
url: "https://lbry.io/what",
color: 7976557,
author: {
name: "Welcome to LBRY Discord Community",
icon_url: "https://i.imgur.com/yWf5USu.png"
}
}
});
member.send({
embed: {
description:
"1. Be respectful to other community members. Harrasment and vulgarity will not be tolerated \n" +
"2. Do not spam, advertise or post referral links \n" +
"3. Use appropriate channels for your discussions/questions. If you are looking for help with LBRY, use #help, for price talk, use #market-and-trading \n" +
"4. #general discussions should be at least somewhat related to LBRY, otherwise there is #random \n" +
"5. Do not post **not safe for work (NFSW)** content in any non-marked channels, there is #random-nsfw for that \n" +
"6. Do not direct message and LBRY team or mods without being asked to do so \n" +
"7. Do not request free LBC, begging will not be tolerated \n",
color: 7976557,
author: {
name: "Ground rules",
icon_url: "https://i.imgur.com/yWf5USu.png"
}
}
});
member.send({
embed: {
description:
"1. Type !tip help to interact with our Tipbot which can be used to send and receive LBRY Credits (LBC). **Enable 2FA in your Discord account settings!** \n" +
"2. See the Frequently Asked Questions (FAQ) section below prior to asking for help or information on LBRY \n" +
"3. Backing up your LBRY wallet is your responsbility, see FAQ link below \n" +
"4. You can find the LBRY Block explorer at https://explorer.lbry.io \n" +
"5. Want to contribute more? Check out https://lbry.io/faq/contributing \n" +
"6. Are you a dev? Check out the #dev channel \n" +
"7. Want to share something you published? Post it on the #publishers channel \n",
color: 7976557,
author: {
name: "Helpful hints",
icon_url: "https://i.imgur.com/yWf5USu.png"
}
}
});
member.send({
embed: {
title: "*Click here for more info about LBRY!*",
description:
"[**LBRY**](https://lbry.io) is a protocol providing fully decentralized network for the discovery, distribution, and payment of data. It utilizes the [**LBRY blockchain**](https://lbry.io/what#the-network) as a global namespace and database of digital content. Blockchain entries contain searchable content metadata, identities, and rights and access rules. \n[_**Download the LBRY App here**_](https://lbry.io/get)",
url: "https://lbry.io/what",
color: 7976557,
author: {
name: "What is LBRY?",
url: "https://lbry.io/what",
icon_url: "https://i.imgur.com/yWf5USu.png"
}
}
});
member.send({
embed: {
title: "*Click here to see all LBRY Frequently Asked Questions (FAQ)!*",
description:
"Want to backup your LBRY wallet? [**Backup**](https://lbry.io/faq/how-to-backup-wallet) \nLooking for LBRY data? [**Behind the scenes files**](https://lbry.io/faq/lbry-directories) \nTrouble starting LBRY? [**Startup troubleshooting**](https://lbry.io/faq/startup-troubleshooting) \nNeed help finding your log files (will help us troubleshoot!)? [**Find logs**](https://lbry.io/faq/how-to-find-lbry-log-file) \nNot able to stream any content? [**Troublshoot streaming**](https://lbry.io/faq/unable-to-stream)\nNeed help with publishing? [**How to Publish**](https://lbry.io/faq/how-to-publish) \nWant more LBRY Credits (LBC)? [**Get LBC**](https://lbry.io/faq/earn-credits) \nLooking for referral information? [**Referrals**](https://lbry.io/faq/referrals)",
url: "https://lbry.io/faq",
color: 7976557,
author: {
name: "LBRY FAQ",
url: "https://lbry.io/faq",
icon_url: "https://spee.ch/8/Id5Qoc3w.png"
}
}
});
member.send({
embed: {
title: "*Have you checked out spee.ch yet?!*",
description:
"[**spee.ch**](https://spee.ch) runs on top of the LBRY network - it's essentially an open source, censorship resistent and decentralized image and video sharing site with the added benefit of being a web-based (works on mobile too!) gateway into the LBRY network. spee.ch can be used to retrieve LBRY images/videos that are free by accessing them through a web browser. \nFor example, if content is located at lbry://loose-cannons-episode1#12c87bb42dd8832167b1e54edf72bbd37bc47622, you can view it on spee.ch at: https://spee.ch/12c87bb42dd8832167b1e54edf72bbd37bc47622/loose-cannons-episode1. You can also view channels on spee.ch, such as: https://spee.ch/@copchronicles:5c039dc7423657e59d78939df72c186e43273675 or https://spee.ch/@MinutePhysics:589276465a23c589801d874f484cc39f307d7ec7 \n\nspee.ch also allows you to create a channel to group your uploads and retreive them easily. These channels are separate from any you may have in the LBRY app since they exist on the spee.ch site via a login process. You can even share your channel name and password so that others can contribute to it.",
url: "https://spee.ch/about",
color: 7976557,
author: {
name: "spee.ch",
url: "https://spee.ch",
icon_url:
"http://www.pd4pic.com/images/flag-green-blue-purple-indigo-bars-background.png"
}
}
});
});
};
exports.commands = [
"welcome" // command that is in this file, every command needs it own export as shown below
]
"welcome" // command that is in this file, every command needs it own export as shown below
];
exports.welcome = {
usage: "<@username>",
description: 'send welcome message to specified user',
process: function(bot,msg,suffix){
console.log(suffix)
if (inPrivate(msg)) {
msg.channel.send("command cannot be used in a DM")
return
}
if (suffix == "") {
msg.channel.send("no user defined")
return
}
if (!hasPerms(msg)) {
msg.channel.send("You Dont Have Permission To Use This Command!")
return
}
msg.mentions.members.first().send(
{
"embed": {
"title": "*Click here for more info about LBRY!*",
"description": "**Welcome to LBRY Discord Community, you are now officially a LBRYian!** \n" +
"If you are new to LBRY and would like to learn more, see the links at the end of this message. \n" +
"This community allows LBRYians to interact with the team directly and for us to engage users in order to grow the LBRY platform! \n" +
"**Looking for *Rewards Verification*? Please make a request in the #verification channel. A mod will reach out to you, please be patient. Only 1 Reward account is allowed per person** \n",
"url": "https://lbry.io/what",
"color": 7976557,
"author": {
"name": "Welcome to LBRY Discord Community",
"icon_url": "https://i.imgur.com/yWf5USu.png"
}
}
}
);
msg.mentions.members.first().send(
{
"embed": {
"description": "1. Be respectful to other community members. Harrasment and vulgarity will not be tolerated \n" +
"2. Do not spam, advertise or post referral links \n" +
"3. Use appropriate channels for your discussions/questions. If you are looking for help with LBRY, use #help, for price talk, use #market-and-trading \n" +
"4. #general discussions should be at least somewhat related to LBRY, otherwise there is #random \n" +
"5. Do not post **not safe for work (NFSW)** content in any non-marked channels, there is #random-nsfw for that \n" +
"6. Do not direct message and LBRY team or mods without being asked to do so \n" +
"7. Do not request free LBC, begging will not be tolerated \n",
"color": 7976557,
"author": {
"name": "Ground rules",
"icon_url": "https://i.imgur.com/yWf5USu.png"
}
}
}
);
msg.mentions.members.first().send(
{
"embed": {
"description": "1. Type !tip help to interact with our Tipbot which can be used to send and receive LBRY Credits (LBC). **Enable 2FA in your Discord account settings!** \n" +
"2. See the Frequently Asked Questions (FAQ) section below prior to asking for help or information on LBRY \n" +
"3. Backing up your LBRY wallet is your responsbility, see FAQ link below \n" +
"4. You can find the LBRY Block explorer at https://explorer.lbry.io \n" +
"5. Want to contribute more? Check out https://lbry.io/faq/contributing \n" +
"6. Are you a dev? Check out the #dev channel \n" +
"7. Want to share something you published? Post it on the #publishers channel \n",
"color": 7976557,
"author": {
"name": "Helpful hints",
"icon_url": "https://i.imgur.com/yWf5USu.png"
}
}
}
);
msg.mentions.members.first().send(
{
"embed": {
"title": "*Click here for more info about LBRY!*",
"description": "[**LBRY**](https://lbry.io) is a protocol providing fully decentralized network for the discovery, distribution, and payment of data. It utilizes the [**LBRY blockchain**](https://lbry.io/what#the-network) as a global namespace and database of digital content. Blockchain entries contain searchable content metadata, identities, and rights and access rules. \n[_**Download the LBRY App here**_](https://lbry.io/get)",
"url": "https://lbry.io/what",
"color": 7976557,
"author": {
"name": "What is LBRY?",
"url": "https://lbry.io/what",
"icon_url": "https://i.imgur.com/yWf5USu.png"
}
}
});
msg.mentions.members.first().send(
{
"embed": {
"title": "*Click here to see all LBRY Frequently Asked Questions (FAQ)!*",
"description": "Want to backup your LBRY wallet? [**Backup**](https://lbry.io/faq/how-to-backup-wallet) \nLooking for LBRY data? [**Behind the scenes files**](https://lbry.io/faq/lbry-directories) \nTrouble starting LBRY? [**Startup troubleshooting**](https://lbry.io/faq/startup-troubleshooting) \nNeed help finding your log files (will help us troubleshoot!)? [**Find logs**](https://lbry.io/faq/how-to-find-lbry-log-file) \nNot able to stream any content? [**Troublshoot streaming**](https://lbry.io/faq/unable-to-stream)\nNeed help with publishing? [**How to Publish**](https://lbry.io/faq/how-to-publish) \nWant more LBRY Credits (LBC)? [**Get LBC**](https://lbry.io/faq/earn-credits) \nLooking for referral information? [**Referrals**](https://lbry.io/faq/referrals)",
"url": "https://lbry.io/faq",
"color": 7976557,
"author": {
"name": "LBRY FAQ",
"url": "https://lbry.io/faq",
"icon_url": "https://spee.ch/8/Id5Qoc3w.png"
}
}
});
msg.mentions.members.first().send(
{
"embed": {
"title": "*Have you checked out spee.ch yet?!*",
"description": "[**spee.ch**](https://spee.ch) runs on top of the LBRY network - it's essentially an open source, censorship resistent and decentralized image and video sharing site with the added benefit of being a web-based (works on mobile too!) gateway into the LBRY network. spee.ch can be used to retrieve LBRY images/videos that are free by accessing them through a web browser. \nFor example, if content is located at lbry://loose-cannons-episode1#12c87bb42dd8832167b1e54edf72bbd37bc47622, you can view it on spee.ch at: https://spee.ch/12c87bb42dd8832167b1e54edf72bbd37bc47622/loose-cannons-episode1. You can also view channels on spee.ch, such as: https://spee.ch/@copchronicles:5c039dc7423657e59d78939df72c186e43273675 or https://spee.ch/@MinutePhysics:589276465a23c589801d874f484cc39f307d7ec7 \n\nspee.ch also allows you to create a channel to group your uploads and retreive them easily. These channels are separate from any you may have in the LBRY app since they exist on the spee.ch site via a login process. You can even share your channel name and password so that others can contribute to it.",
"url": "https://spee.ch/about",
"color": 7976557,
"author": {
"name": "spee.ch",
"url": "https://spee.ch",
"icon_url": "http://www.pd4pic.com/images/flag-green-blue-purple-indigo-bars-background.png"
}
}
});
usage: "<@username>",
description: "send welcome message to specified user",
process: function(bot, msg, suffix) {
console.log(suffix);
if (inPrivate(msg)) {
msg.channel.send("command cannot be used in a DM");
return;
}
}
if (suffix == "") {
msg.channel.send("no user defined");
return;
}
if (!hasPerms(msg)) {
msg.channel.send("You Dont Have Permission To Use This Command!");
return;
}
msg.mentions.members.first().send({
embed: {
title: "*Click here for more info about LBRY!*",
description:
"**Welcome to LBRY Discord Community, you are now officially a LBRYian!** \n" +
"If you are new to LBRY and would like to learn more, see the links at the end of this message. \n" +
"This community allows LBRYians to interact with the team directly and for us to engage users in order to grow the LBRY platform! \n" +
"**Looking for *Rewards Verification*? Please make a request in the #verification channel. A mod will reach out to you, please be patient. Only 1 Reward account is allowed per person** \n",
url: "https://lbry.io/what",
color: 7976557,
author: {
name: "Welcome to LBRY Discord Community",
icon_url: "https://i.imgur.com/yWf5USu.png"
}
}
});
msg.mentions.members.first().send({
embed: {
description:
"1. Be respectful to other community members. Harrasment and vulgarity will not be tolerated \n" +
"2. Do not spam, advertise or post referral links \n" +
"3. Use appropriate channels for your discussions/questions. If you are looking for help with LBRY, use #help, for price talk, use #market-and-trading \n" +
"4. #general discussions should be at least somewhat related to LBRY, otherwise there is #random \n" +
"5. Do not post **not safe for work (NFSW)** content in any non-marked channels, there is #random-nsfw for that \n" +
"6. Do not direct message and LBRY team or mods without being asked to do so \n" +
"7. Do not request free LBC, begging will not be tolerated \n",
color: 7976557,
author: {
name: "Ground rules",
icon_url: "https://i.imgur.com/yWf5USu.png"
}
}
});
msg.mentions.members.first().send({
embed: {
description:
"1. Type !tip help to interact with our Tipbot which can be used to send and receive LBRY Credits (LBC). **Enable 2FA in your Discord account settings!** \n" +
"2. See the Frequently Asked Questions (FAQ) section below prior to asking for help or information on LBRY \n" +
"3. Backing up your LBRY wallet is your responsbility, see FAQ link below \n" +
"4. You can find the LBRY Block explorer at https://explorer.lbry.io \n" +
"5. Want to contribute more? Check out https://lbry.io/faq/contributing \n" +
"6. Are you a dev? Check out the #dev channel \n" +
"7. Want to share something you published? Post it on the #publishers channel \n",
color: 7976557,
author: {
name: "Helpful hints",
icon_url: "https://i.imgur.com/yWf5USu.png"
}
}
});
msg.mentions.members.first().send({
embed: {
title: "*Click here for more info about LBRY!*",
description:
"[**LBRY**](https://lbry.io) is a protocol providing fully decentralized network for the discovery, distribution, and payment of data. It utilizes the [**LBRY blockchain**](https://lbry.io/what#the-network) as a global namespace and database of digital content. Blockchain entries contain searchable content metadata, identities, and rights and access rules. \n[_**Download the LBRY App here**_](https://lbry.io/get)",
url: "https://lbry.io/what",
color: 7976557,
author: {
name: "What is LBRY?",
url: "https://lbry.io/what",
icon_url: "https://i.imgur.com/yWf5USu.png"
}
}
});
msg.mentions.members.first().send({
embed: {
title: "*Click here to see all LBRY Frequently Asked Questions (FAQ)!*",
description:
"Want to backup your LBRY wallet? [**Backup**](https://lbry.io/faq/how-to-backup-wallet) \nLooking for LBRY data? [**Behind the scenes files**](https://lbry.io/faq/lbry-directories) \nTrouble starting LBRY? [**Startup troubleshooting**](https://lbry.io/faq/startup-troubleshooting) \nNeed help finding your log files (will help us troubleshoot!)? [**Find logs**](https://lbry.io/faq/how-to-find-lbry-log-file) \nNot able to stream any content? [**Troublshoot streaming**](https://lbry.io/faq/unable-to-stream)\nNeed help with publishing? [**How to Publish**](https://lbry.io/faq/how-to-publish) \nWant more LBRY Credits (LBC)? [**Get LBC**](https://lbry.io/faq/earn-credits) \nLooking for referral information? [**Referrals**](https://lbry.io/faq/referrals)",
url: "https://lbry.io/faq",
color: 7976557,
author: {
name: "LBRY FAQ",
url: "https://lbry.io/faq",
icon_url: "https://spee.ch/8/Id5Qoc3w.png"
}
}
});
msg.mentions.members.first().send({
embed: {
title: "*Have you checked out spee.ch yet?!*",
description:
"[**spee.ch**](https://spee.ch) runs on top of the LBRY network - it's essentially an open source, censorship resistent and decentralized image and video sharing site with the added benefit of being a web-based (works on mobile too!) gateway into the LBRY network. spee.ch can be used to retrieve LBRY images/videos that are free by accessing them through a web browser. \nFor example, if content is located at lbry://loose-cannons-episode1#12c87bb42dd8832167b1e54edf72bbd37bc47622, you can view it on spee.ch at: https://spee.ch/12c87bb42dd8832167b1e54edf72bbd37bc47622/loose-cannons-episode1. You can also view channels on spee.ch, such as: https://spee.ch/@copchronicles:5c039dc7423657e59d78939df72c186e43273675 or https://spee.ch/@MinutePhysics:589276465a23c589801d874f484cc39f307d7ec7 \n\nspee.ch also allows you to create a channel to group your uploads and retreive them easily. These channels are separate from any you may have in the LBRY app since they exist on the spee.ch site via a login process. You can even share your channel name and password so that others can contribute to it.",
url: "https://spee.ch/about",
color: 7976557,
author: {
name: "spee.ch",
url: "https://spee.ch",
icon_url:
"http://www.pd4pic.com/images/flag-green-blue-purple-indigo-bars-background.png"
}
}
});
}
};

View file

@ -1,4 +1,4 @@
'use strict';
"use strict";
const fs = require("fs"),
path = require("path");
@ -33,15 +33,19 @@ function load_plugins() {
}
}
}
if("custom" in plugin){
if ("custom" in plugin) {
for (let j = 0; j < plugin.custom.length; j++) {
if (plugin.custom[j] in plugin) {
dbot.addCustomFunc(plugin[plugin.custom[j]]);
otherFunc++;
}
}
}
}
}
}
console.log(`Loaded ${dbot.commandCount()} chat commands and ${otherFunc} custom functions.`);
console.log(
`Loaded ${dbot.commandCount()} chat commands and ${
otherFunc
} custom functions.`
);
}

View file

@ -17,10 +17,13 @@
"scripts": {
"prettier": "prettier * --write",
"build": "babel bot -d dist",
"prod": "babel bot -d dist & node dist/bot.js"
"prod": "babel bot -d dist & node dist/bot.js",
"lint": "prettier --write bot/**/*.js",
"precommit": "lint"
},
"devDependencies": {
"prettier": "1.7.4"
"husky": "^0.14.3",
"prettier": "1.8.1"
},
"name": "wunderbot-discord",
"version": "0.0.1",

483
yarn.lock
View file

@ -26,14 +26,28 @@ ajv@^5.1.0:
json-schema-traverse "^0.3.0"
json-stable-stringify "^1.0.1"
ansi-escapes@^1.0.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
ansi-regex@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
ansi-regex@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
ansi-styles@^3.1.0, ansi-styles@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88"
dependencies:
color-convert "^1.9.0"
anymatch@^1.3.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a"
@ -41,6 +55,10 @@ anymatch@^1.3.0:
micromatch "^2.1.5"
normalize-path "^2.0.0"
app-root-path@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.0.1.tgz#cd62dcf8e4fd5a417efc664d2e5b10653c651b46"
aproba@^1.0.3:
version "1.2.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
@ -52,6 +70,12 @@ are-we-there-yet@~1.1.2:
delegates "^1.0.0"
readable-stream "^2.0.6"
argparse@^1.0.7:
version "1.0.9"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
dependencies:
sprintf-js "~1.0.2"
arr-diff@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf"
@ -469,7 +493,7 @@ caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
chalk@^1.1.3:
chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
dependencies:
@ -479,6 +503,14 @@ chalk@^1.1.3:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
chalk@^2.0.1, chalk@^2.1.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba"
dependencies:
ansi-styles "^3.1.0"
escape-string-regexp "^1.0.5"
supports-color "^4.0.0"
chokidar@^1.6.1:
version "1.7.0"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
@ -500,10 +532,31 @@ chrono-node@^1.3.5:
dependencies:
moment "^2.10.3"
ci-info@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.1.tgz#47b44df118c48d2597b56d342e7e25791060171a"
cjson@~0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/cjson/-/cjson-0.2.1.tgz#73cd8aad65d9e1505f9af1744d3b79c1527682a5"
cli-cursor@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987"
dependencies:
restore-cursor "^1.0.1"
cli-spinners@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c"
cli-truncate@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574"
dependencies:
slice-ansi "0.0.4"
string-width "^1.0.1"
co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
@ -512,6 +565,16 @@ code-point-at@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
color-convert@^1.9.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a"
dependencies:
color-name "^1.1.1"
color-name@^1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
colors@0.5.x:
version "0.5.1"
resolved "https://registry.yarnpkg.com/colors/-/colors-0.5.1.tgz#7d0023eaeb154e8ee9fce75dcb923d0ed1667774"
@ -522,7 +585,7 @@ combined-stream@^1.0.5, combined-stream@~1.0.5:
dependencies:
delayed-stream "~1.0.0"
commander@^2.11.0:
commander@^2.11.0, commander@^2.9.0:
version "2.11.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563"
@ -553,6 +616,27 @@ core-util-is@1.0.2, core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
cosmiconfig@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-1.1.0.tgz#0dea0f9804efdfb929fbb1b188e25553ea053d37"
dependencies:
graceful-fs "^4.1.2"
js-yaml "^3.4.3"
minimist "^1.2.0"
object-assign "^4.0.1"
os-homedir "^1.0.1"
parse-json "^2.2.0"
pinkie-promise "^2.0.0"
require-from-string "^1.1.0"
cross-spawn@^5.0.1:
version "5.1.0"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
dependencies:
lru-cache "^4.0.1"
shebang-command "^1.2.0"
which "^1.2.9"
cryptiles@2.x.x:
version "2.0.5"
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
@ -571,6 +655,10 @@ dashdash@^1.12.0:
dependencies:
assert-plus "^1.0.0"
date-fns@^1.27.2:
version "1.29.0"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6"
debug@^2.2.0, debug@^2.6.8, debug@^2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
@ -615,15 +703,25 @@ ecc-jsbn@~0.1.1:
dependencies:
jsbn "~0.1.0"
elegant-spinner@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e"
embed-creator@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/embed-creator/-/embed-creator-1.1.4.tgz#7f8a783db6ae384d029e746837d65553e6ff0f9e"
error-ex@^1.2.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc"
dependencies:
is-arrayish "^0.2.1"
es6-promise@3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.2.1.tgz#ec56233868032909207170c39448e24449dd1fc4"
escape-string-regexp@^1.0.2:
escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
@ -653,6 +751,10 @@ esprima@1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.2.2.tgz#76a0fd66fcfe154fd292667dc264019750b1657b"
esprima@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804"
estraverse@~0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-0.0.4.tgz#01a0932dfee574684a598af5a67c3bf9b6428db2"
@ -665,6 +767,22 @@ esutils@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
execa@^0.8.0:
version "0.8.0"
resolved "https://registry.yarnpkg.com/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da"
dependencies:
cross-spawn "^5.0.1"
get-stream "^3.0.0"
is-stream "^1.1.0"
npm-run-path "^2.0.0"
p-finally "^1.0.0"
signal-exit "^3.0.0"
strip-eof "^1.0.0"
exit-hook@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
expand-brackets@^0.1.4:
version "0.1.5"
resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b"
@ -695,6 +813,13 @@ fast-deep-equal@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff"
figures@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
dependencies:
escape-string-regexp "^1.0.5"
object-assign "^4.1.0"
filename-regex@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26"
@ -784,6 +909,14 @@ gauge@~2.7.3:
strip-ansi "^3.0.1"
wide-align "^1.1.0"
get-own-enumerable-property-symbols@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-2.0.1.tgz#5c4ad87f2834c4b9b4e84549dc1e0650fb38c24b"
get-stream@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
getpass@^0.1.1:
version "0.1.7"
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
@ -850,6 +983,10 @@ has-ansi@^2.0.0:
dependencies:
ansi-regex "^2.0.0"
has-flag@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51"
has-unicode@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@ -907,6 +1044,24 @@ http-signature@~1.2.0:
jsprim "^1.2.2"
sshpk "^1.7.0"
husky@^0.14.3:
version "0.14.3"
resolved "https://registry.yarnpkg.com/husky/-/husky-0.14.3.tgz#c69ed74e2d2779769a17ba8399b54ce0b63c12c3"
dependencies:
is-ci "^1.0.10"
normalize-path "^1.0.0"
strip-indent "^2.0.0"
indent-string@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80"
dependencies:
repeating "^2.0.0"
indent-string@^3.0.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289"
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
@ -928,6 +1083,10 @@ invariant@^2.2.2:
dependencies:
loose-envify "^1.0.0"
is-arrayish@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
is-binary-path@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898"
@ -938,6 +1097,12 @@ is-buffer@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc"
is-ci@^1.0.10:
version "1.0.10"
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e"
dependencies:
ci-info "^1.0.0"
is-dotfile@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1"
@ -956,6 +1121,10 @@ is-extglob@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0"
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
is-finite@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa"
@ -974,6 +1143,12 @@ is-glob@^2.0.0, is-glob@^2.0.1:
dependencies:
is-extglob "^1.0.0"
is-glob@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0"
dependencies:
is-extglob "^2.1.1"
is-number@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f"
@ -986,6 +1161,10 @@ is-number@^3.0.0:
dependencies:
kind-of "^3.0.2"
is-obj@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
is-posix-bracket@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4"
@ -994,6 +1173,18 @@ is-primitive@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575"
is-promise@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
is-regexp@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069"
is-stream@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
@ -1002,6 +1193,10 @@ isarray@1.0.0, isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
isobject@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"
@ -1012,6 +1207,19 @@ isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
jest-get-type@^21.2.0:
version "21.2.0"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-21.2.0.tgz#f6376ab9db4b60d81e39f30749c6c466f40d4a23"
jest-validate@^21.1.0:
version "21.2.1"
resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-21.2.1.tgz#cc0cbca653cd54937ba4f2a111796774530dd3c7"
dependencies:
chalk "^2.0.1"
jest-get-type "^21.2.0"
leven "^2.1.0"
pretty-format "^21.2.1"
jison-lex@0.2.x:
version "0.2.1"
resolved "https://registry.yarnpkg.com/jison-lex/-/jison-lex-0.2.1.tgz#ac4b815e8cce5132eb12b5dfcfe8d707b8844dfe"
@ -1036,6 +1244,13 @@ js-tokens@^3.0.0, js-tokens@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
js-yaml@^3.4.3:
version "3.10.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc"
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
@ -1108,10 +1323,81 @@ kind-of@^4.0.0:
dependencies:
is-buffer "^1.1.5"
leven@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580"
lex-parser@0.1.x, lex-parser@~0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/lex-parser/-/lex-parser-0.1.4.tgz#64c4f025f17fd53bfb45763faeb16f015a747550"
lint-staged@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-4.3.0.tgz#ed0779ad9a42c0dc62bb3244e522870b41125879"
dependencies:
app-root-path "^2.0.0"
chalk "^2.1.0"
commander "^2.11.0"
cosmiconfig "^1.1.0"
execa "^0.8.0"
is-glob "^4.0.0"
jest-validate "^21.1.0"
listr "^0.12.0"
lodash "^4.17.4"
log-symbols "^2.0.0"
minimatch "^3.0.0"
npm-which "^3.0.1"
p-map "^1.1.1"
staged-git-files "0.0.4"
stringify-object "^3.2.0"
listr-silent-renderer@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e"
listr-update-renderer@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz#ca80e1779b4e70266807e8eed1ad6abe398550f9"
dependencies:
chalk "^1.1.3"
cli-truncate "^0.2.1"
elegant-spinner "^1.0.1"
figures "^1.7.0"
indent-string "^3.0.0"
log-symbols "^1.0.2"
log-update "^1.0.2"
strip-ansi "^3.0.1"
listr-verbose-renderer@^0.4.0:
version "0.4.1"
resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#8206f4cf6d52ddc5827e5fd14989e0e965933a35"
dependencies:
chalk "^1.1.3"
cli-cursor "^1.0.2"
date-fns "^1.27.2"
figures "^1.7.0"
listr@^0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/listr/-/listr-0.12.0.tgz#6bce2c0f5603fa49580ea17cd6a00cc0e5fa451a"
dependencies:
chalk "^1.1.3"
cli-truncate "^0.2.1"
figures "^1.7.0"
indent-string "^2.1.0"
is-promise "^2.1.0"
is-stream "^1.1.0"
listr-silent-renderer "^1.1.1"
listr-update-renderer "^0.2.0"
listr-verbose-renderer "^0.4.0"
log-symbols "^1.0.2"
log-update "^1.0.2"
ora "^0.2.3"
p-map "^1.1.1"
rxjs "^5.0.0-beta.11"
stream-to-observable "^0.1.0"
strip-ansi "^3.0.1"
lodash.some@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d"
@ -1120,6 +1406,25 @@ lodash@^4.14.0, lodash@^4.17.4:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
log-symbols@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18"
dependencies:
chalk "^1.0.0"
log-symbols@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.1.0.tgz#f35fa60e278832b538dc4dddcbb478a45d3e3be6"
dependencies:
chalk "^2.0.1"
log-update@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1"
dependencies:
ansi-escapes "^1.0.0"
cli-cursor "^1.0.2"
long@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b"
@ -1130,6 +1435,13 @@ loose-envify@^1.0.0:
dependencies:
js-tokens "^3.0.0"
lru-cache@^4.0.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55"
dependencies:
pseudomap "^1.0.2"
yallist "^2.1.2"
micromatch@^2.1.5:
version "2.3.11"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565"
@ -1276,12 +1588,36 @@ nopt@^4.0.1:
abbrev "1"
osenv "^0.1.4"
normalize-path@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379"
normalize-path@^2.0.0, normalize-path@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9"
dependencies:
remove-trailing-separator "^1.0.1"
npm-path@^2.0.2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.3.tgz#15cff4e1c89a38da77f56f6055b24f975dfb2bbe"
dependencies:
which "^1.2.10"
npm-run-path@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
dependencies:
path-key "^2.0.0"
npm-which@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/npm-which/-/npm-which-3.0.1.tgz#9225f26ec3a285c209cae67c3b11a6b4ab7140aa"
dependencies:
commander "^2.9.0"
npm-path "^2.0.2"
which "^1.2.10"
npmlog@^4.0.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
@ -1303,7 +1639,7 @@ oauth-sign@~0.8.1, oauth-sign@~0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
object-assign@^4.1.0:
object-assign@^4.0.1, object-assign@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
@ -1320,7 +1656,20 @@ once@^1.3.0, once@^1.3.3:
dependencies:
wrappy "1"
os-homedir@1.0.2, os-homedir@^1.0.0:
onetime@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789"
ora@^0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4"
dependencies:
chalk "^1.1.1"
cli-cursor "^1.0.2"
cli-spinners "^0.1.2"
object-assign "^4.0.1"
os-homedir@1.0.2, os-homedir@^1.0.0, os-homedir@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
@ -1343,6 +1692,14 @@ output-file-sync@^1.1.2:
mkdirp "^0.5.1"
object-assign "^4.1.0"
p-finally@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
p-map@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b"
parse-glob@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c"
@ -1352,10 +1709,20 @@ parse-glob@^3.0.4:
is-extglob "^1.0.0"
is-glob "^2.0.0"
parse-json@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
dependencies:
error-ex "^1.2.0"
path-is-absolute@^1.0.0, path-is-absolute@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
path-key@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
performance-now@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
@ -1364,13 +1731,30 @@ performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
pinkie-promise@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
dependencies:
pinkie "^2.0.0"
pinkie@^2.0.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
preserve@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
prettier@1.7.4:
version "1.7.4"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.7.4.tgz#5e8624ae9363c80f95ec644584ecdf55d74f93fa"
prettier@1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.8.1.tgz#91064d778c08c85ac1cbe6b23195c34310d039f9"
pretty-format@^21.2.1:
version "21.2.1"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-21.2.1.tgz#ae5407f3cf21066cd011aa1ba5fce7b6a2eddb36"
dependencies:
ansi-regex "^3.0.0"
ansi-styles "^3.2.0"
prism-media@^0.0.1:
version "0.0.1"
@ -1384,6 +1768,10 @@ process-nextick-args@~1.0.6:
version "1.0.7"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
pseudomap@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
punycode@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
@ -1535,6 +1923,10 @@ request@^2.83.0:
tunnel-agent "^0.6.0"
uuid "^3.1.0"
require-from-string@^1.1.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418"
require_optional@~1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/require_optional/-/require_optional-1.0.1.tgz#4cf35a4247f64ca3df8c2ef208cc494b1ca8fc2e"
@ -1546,12 +1938,25 @@ resolve-from@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57"
restore-cursor@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541"
dependencies:
exit-hook "^1.0.0"
onetime "^1.0.0"
rimraf@2, rimraf@^2.5.1, rimraf@^2.6.1:
version "2.6.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
dependencies:
glob "^7.0.5"
rxjs@^5.0.0-beta.11:
version "5.5.2"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.2.tgz#28d403f0071121967f18ad665563255d54236ac3"
dependencies:
symbol-observable "^1.0.1"
safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
@ -1568,6 +1973,16 @@ set-immediate-shim@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
shebang-command@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
dependencies:
shebang-regex "^1.0.0"
shebang-regex@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
signal-exit@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
@ -1576,6 +1991,10 @@ slash@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
slice-ansi@0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
sliced@0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/sliced/-/sliced-0.0.5.tgz#5edc044ca4eb6f7816d50ba2fc63e25d8fe4707f"
@ -1614,6 +2033,10 @@ source-map@^0.5.6:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
sshpk@^1.7.0:
version "1.13.1"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3"
@ -1628,12 +2051,20 @@ sshpk@^1.7.0:
jsbn "~0.1.0"
tweetnacl "~0.14.0"
staged-git-files@0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-0.0.4.tgz#d797e1b551ca7a639dec0237dc6eb4bb9be17d35"
static-eval@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/static-eval/-/static-eval-0.2.3.tgz#023f17ac9fee426ea788c12ea39206dc175f8b2a"
dependencies:
escodegen "~0.0.24"
stream-to-observable@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.1.0.tgz#45bf1d9f2d7dc09bed81f1c307c430e68b84cffe"
string-width@^1.0.1, string-width@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
@ -1648,6 +2079,14 @@ string_decoder@~1.0.0, string_decoder@~1.0.3:
dependencies:
safe-buffer "~5.1.0"
stringify-object@^3.2.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.2.1.tgz#2720c2eff940854c819f6ee252aaeb581f30624d"
dependencies:
get-own-enumerable-property-symbols "^2.0.1"
is-obj "^1.0.1"
is-regexp "^1.0.0"
stringstream@~0.0.4, stringstream@~0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
@ -1658,6 +2097,14 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1:
dependencies:
ansi-regex "^2.0.0"
strip-eof@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
strip-indent@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68"
strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
@ -1666,6 +2113,16 @@ supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
supports-color@^4.0.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b"
dependencies:
has-flag "^2.0.0"
symbol-observable@^1.0.1:
version "1.0.4"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d"
tar-pack@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.0.tgz#23be2d7f671a8339376cbdb0b8fe3fdebf317984"
@ -1757,6 +2214,12 @@ verror@1.10.0:
core-util-is "1.0.2"
extsprintf "^1.2.0"
which@^1.2.10, which@^1.2.9:
version "1.3.0"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a"
dependencies:
isexe "^2.0.0"
wide-align@^1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710"
@ -1774,3 +2237,7 @@ ws@^3.1.0:
async-limiter "~1.0.0"
safe-buffer "~5.1.0"
ultron "~1.1.0"
yallist@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"