@@ -2,7 +2,7 @@ import { _getUserAliases, Aliases } from '../../database'
import { findUser } from '../../slack.js'
import { capitalize } from 'lodash'

export const plugin_info = [{
export const pluginInfo = [{
alias: ['alias'],
command: 'alias',
usage: 'alias [user] [set|view|delete] [service]'
@@ -12,7 +12,7 @@ const validServices = ['steam', 'overwatch']

export function alias(sender, channel, input, ts, plugins, userLevel) {
return new Promise((resolve, reject) => {
if (!input) return resolve({ type: 'dm', message: 'Usage: alias [user] [set|view|delete] [service] [value] - Sets a users alias for a service (steam, overwatch)'})
if (!input) return resolve({ type: 'dm', message: 'Usage: alias [user] [set|view|delete] [service] [value] - Sets a users alias for a service (steam, overwatch)' })
var [username, method, service, userAlias] = input.split(' ')
var usernameIsNotName = username.match(/^(set|view|del|delete)$/)
if (usernameIsNotName) {
@@ -44,8 +44,10 @@ export function alias(sender, channel, input, ts, plugins, userLevel) {
data.service = service
data.alias = userAlias
return data.Persist().then(() => {
resolve({ type: 'channel', message: `Successfully set alias for ${user.name} for service \`${service}\` with the alias \`${userAlias}\`` +
(previousAlias ? `\n*Previous alias was* \`${previousAlias}\`` : '')})
resolve({
type: 'channel',
message: `Successfully set alias for ${user.name} for service \`${service}\` with the alias \`${userAlias}\`` +
(previousAlias ? `\n*Previous alias was* \`${previousAlias}\`` : '')})
})
}).catch(err => {
console.error(err)
@@ -59,7 +61,7 @@ export function alias(sender, channel, input, ts, plugins, userLevel) {
_getUserAliases(user.id, service).then(data => {
if (!data[0]) return reject("User has no alias for this service")
return data[0].Delete().then(() => {
resolve({ type: 'channel', message: `Successfully removed users alias for \`${service}\``})
resolve({ type: 'channel', message: `Successfully removed users alias for \`${service}\`` })
})
}).catch(err => {
console.error(err)
@@ -70,13 +72,12 @@ export function alias(sender, channel, input, ts, plugins, userLevel) {
case 'view':
_getUserAliases(user.id).then(data => {
if (!data.length) return reject("User has no aliases set")
return resolve({ type: 'channel', message: `*Aliases found for ${user.name}:*\n` + data.map(a => ` > ${capitalize(a.service)} - ${a.alias}`).join('\n')})
return resolve({ type: 'channel', message: `*Aliases found for ${user.name}:*\n` + data.map(a => ` > ${capitalize(a.service)} - ${a.alias}`).join('\n') })
}).catch(err => {
console.error(err)
return reject("Error: sumfin went wrong")
})
break
}

})
}
}
@@ -4,7 +4,7 @@ import moment from 'moment'
import needle from 'needle'
import config from '../../../config.json'

export const plugin_info = [{
export const pluginInfo = [{
alias: ['hellolady', 'bonjourmadame'],
command: 'bonjourmadame',
usage: 'hellolady [void, \'today\', <MM.DD.YYYY>]'
@@ -23,10 +23,10 @@ export function bonjourmadame(user, channel, input) {
let url, diff, attempts = 0

if (input) {
if (input == 'today') {
if (input === 'today') {
url = 'http://dites.bonjourmadame.fr/'
} else if (input.match(/[0-9\.-]/g)) {
diff = moment(new Date(input.match(/[0-9\.-]/g).join(''))).diff(moment(), 'days')
} else if (input.match(/[0-9.-]/g)) {
diff = moment(new Date(input.match(/[0-9.-]/g).join(''))).diff(moment(), 'days')
if (diff === 0) {
url = 'http://dites.bonjourmadame.fr/'
} else if (diff < 0) {
@@ -39,8 +39,8 @@ export function bonjourmadame(user, channel, input) {

let client = new MetaInspector(url, { timeout: 5000 })

client.on('fetch', () => (client.images && !client.images[3].match(/logo|avatar/i)) ?
resolve({ type: 'channel', message: client.images[3] }) : reject('No picture found'))
client.on('fetch', () => (client.images && !client.images[3].match(/logo|avatar/i))
? resolve({ type: 'channel', message: client.images[3] }) : reject('No picture found'))

client.on('error', () => {
if (attempts < 3) {
@@ -55,12 +55,12 @@ export function bonjourmadame(user, channel, input) {

export function bonjourmonsieur(user, channel, input) {
return new Promise((resolve, reject) => {
let url = (input == 'today') ? 'http://www.bonjourmonsieur.fr/' : 'http://www.bonjourmonsieur.fr/monsieur/random.html'
let url = input === 'today' ? 'http://www.bonjourmonsieur.fr/' : 'http://www.bonjourmonsieur.fr/monsieur/random.html'

let client = new MetaInspector(url, { timeout: 5000 })

client.on('fetch', () => (client.images && client.images[2].match(/uploads/i)) ?
resolve({ type: 'channel', message: client.images[2] }) : reject('No picture found'))
client.on('fetch', () => (client.images && client.images[2].match(/uploads/i))
? resolve({ type: 'channel', message: client.images[2] }) : reject('No picture found'))

client.on('error', () => reject('Error loading page'))

@@ -1,7 +1,7 @@
import { map } from 'lodash'
var canIUse = require('caniuse-api')

export const plugin_info = [{
export const pluginInfo = [{
alias: ['ciu', 'caniuse'],
command: 'caniuse',
usage: 'ciu <feature>'
@@ -27,7 +27,7 @@ const browserIDs = {
export function css(user, channel, input) {
return new Promise(resolve => {
var matches = canIUse.find(input)
return resolve({ type: 'channel', message: matches.length ? `*Found ${matches.length} matches:* \n ${matches.map(a => `\`${a}\``).join(' ')}` : 'Found no matches'})
return resolve({ type: 'channel', message: matches.length ? `*Found ${matches.length} matches:* \n ${matches.map(a => `\`${a}\``).join(' ')}` : 'Found no matches' })
})
}

This file was deleted.

@@ -4,19 +4,21 @@ import striptags from 'striptags'

const langs = ['C', 'C++', 'D', 'Haskell', 'Lua', 'OCaml', 'PHP', 'Perl', 'Python', 'Ruby', 'Scheme', 'Tcl']

export const plugin_info = [{
export const pluginInfo = [{
alias: ['eval'],
command: 'codep',
usage: 'eval <language> <code>'
}]

export function codep(user, channel, input) {
return new Promise((resolve, reject) => {
if (!input || !input.split('```')[1])
if (!input || !input.split('```')[1]) {
return resolve({
type: 'dm',
message: 'Usage: eval <langage> <code> | Evals the code in the specified language, valid languages are: ' + langs.join(' ')
})
}

let type = input.split(' ')[0].split('\n')[0]
let code = unescape(input.split('```')[1])
let rejected = false
@@ -1,7 +1,7 @@
import { slice, includes } from 'lodash'
import crypto from 'crypto'

export const plugin_info = [{
export const pluginInfo = [{
alias: ['hash', 'encrypt'],
command: 'encrypt',
usage: 'hash <algorithm> <text> - encrypts input as algorithm'
@@ -30,14 +30,14 @@ export function encrypt(user, channel, input) {
case 'sha1':
case 'sha256':
try {
hash = ((crypto.createHash(type)).update(toHash)).digest('hex');
hash = ((crypto.createHash(type)).update(toHash)).digest('hex')
} catch (err) {
return reject(err);
return reject(err)
}
break;
break
case 'base64':
hash = (new Buffer(toHash)).toString('base64');
break;
hash = (new Buffer(toHash)).toString('base64')
break
}
return resolve({ type: 'channel', message: hash })
})
@@ -50,7 +50,7 @@ export function randomData(user, channel, input) {
if (!count || count > 90) return reject(count ? 'Count must be less <= 90' : 'Invalid number')

crypto.randomBytes(count, (err, buf) => {
if (err) return reject(err);
if (err) return reject(err)
return resolve({ type: 'channel', message: buf.toString('hex') })
})
})
@@ -1,6 +1,6 @@
import needle from 'needle'

export const plugin_info = [{
export const pluginInfo = [{
alias: ['devexcuse'],
command: 'devexcuse',
usage: 'devexcuse - returns a dev excuse'
@@ -2,7 +2,7 @@ import Giphy from 'giphy'

const giphy = new Giphy('dc6zaTOxFJmzC')

export const plugin_info = [{
export const pluginInfo = [{
alias: ['gif'],
command: 'gif',
usage: 'gif <query>'
@@ -18,11 +18,8 @@ export function gif(user, channel, input = false) {
rating: 'r',
fmt: 'json'
}, (err, res) => {
if (res.pagination.count > 0)
return resolve({
type: 'channel',
message: res.data[Math.floor(Math.random() * res.pagination.count)].images.fixed_height.url
});
if (err) return reject("Error finding gif")
if (res.pagination.count > 0) return resolve({ type: 'channel', message: res.data[Math.floor(Math.random() * res.pagination.count)].images.fixed_height.url })
else return reject('No Gifs Found :(')
})
})
@@ -3,7 +3,7 @@ import needle from 'needle'
import config from '../../../config.json'
import { last } from 'lodash'

export const plugin_info = [{
export const pluginInfo = [{
alias: ['g', 'google'],
command: 'googleSearch',
usage: 'google <query> [-i] - returns first or specified google result for query'
@@ -33,7 +33,7 @@ export function googleSearch(user, channel, input) {
if (!config.googleAPIKey || !config.cseSearchID) return reject("Error: Google API Key and CSE Key are required to use this function")

const lastWord = last(input.split(' '))
const index = lastWord.startsWith('-') ? parseInt(lastWord.slice(1)) || 0 : 0
const index = lastWord.startsWith('-') ? parseInt(lastWord.slice(1)) || 0 : 0

const url = `${baseURL}&q=${input}&cx=${config.cseSearchID}`

@@ -74,9 +74,9 @@ export function googleImage(user, channel, input) {

export function youtubeSearch(user, channel, input) {
return new Promise((resolve, reject) => {
if (!input) return resolve({ type: 'dm', message: 'Usage: youtube <query> | Returns the Youtube result for query' });
if (!input) return resolve({ type: 'dm', message: 'Usage: youtube <query> | Returns the Youtube result for query' })

if (!config.googleAPIKey) return reject("Error: Google APIKey required to use this function");
if (!config.googleAPIKey) return reject("Error: Google APIKey required to use this function")

ytSearch(input, ytOpts, (err, resp) => {
if (err) return reject(`ytSearchErr: ${err}`)
@@ -1,4 +1,4 @@
export const plugin_info = [{
export const pluginInfo = [{
alias: ['rip', 'gravestone'],
command: 'rip',
usage: 'rip "username" startdate-enddate "message"'
@@ -8,15 +8,17 @@ const url = 'http://www.futuregravestone.com/image.php'

export function rip(user, channel, input) {
return new Promise((resolve, reject) => {
if (!input) return resolve({
type: 'dm',
message: 'rip "username" startdate-enddate "message" - Username and message must be surrounded by `" "` and date must be seperpated by `-` can be year or text'
})
if (!input) {
return resolve({
type: 'dm',
message: 'rip "username" startdate-enddate "message" - Username and message must be surrounded by `" "` and date must be seperpated by `-` can be year or text'
})
}

let texts = input.match(/["'”“][\w+ ']+["'”“]/g)
let time = input.match(/\w+-\w+/)

if (texts && time && texts.length == 2) {
if (texts && time && texts.length === 2) {
texts = texts.map(t => t.slice(1, -1).replace(/ /g, '+'))
time = time[0].split('-')
let imageUrl = `${url}?id=${randomNumber()}.JPG&name=${texts[0]}&byear=${time[0]}&dyear=${time[1]}&insc=${texts[1]}`
@@ -2,7 +2,7 @@ import { flatten } from 'lodash'
import config from '../../../config.json'
import { sendMessage } from '../../slack'

export const plugin_info = [{
export const pluginInfo = [{
alias: ['help', 'h'],
command: 'help',
usage: 'shows help for commands'
@@ -25,22 +25,24 @@ export function help(user, channel, context = 0, ts, plugins, userLevel) {
] // stupid js beautify

plugins.forEach(plugin => {
if (plugin.plugin_info && Array.isArray(plugin.plugin_info)) {
plugin.plugin_info.forEach(help => {
if (plugin.pluginInfo && Array.isArray(plugin.pluginInfo)) {
plugin.pluginInfo.forEach(help => {
if (!help.alias || !help.usage || (help.userLevel && help.userLevel.indexOf(userLevel) === -1) || (help.userLevel && noAdmin)) return

let cmdalias = '';
help.alias.forEach(cmd => cmdalias += config.prefix + cmd + ' ')
let cmdalias = ''
help.alias.forEach(cmd => {
cmdalias += config.prefix + cmd + ' '
})
if (aliases[0].length < 45) {
aliases[0].push(cmdalias)
commands[0].push(`${cmdalias}%pad%| ${help.usage}`)
} else { // dirty cheat
aliases[1].push(cmdalias)
commands[1].push(`${cmdalias}%pad%| ${help.usage}`)
}
});
})
}
});
})

commands.forEach((thing, i) => {
let padding = aliases[i].sort((a, b) => {
@@ -1,6 +1,6 @@
import lodashFunctions from './utils/lodash'

export const plugin_info = [{
export const pluginInfo = [{
alias: ['lodash'],
command: 'lodash',
usage: 'lodash <command> - returns info for command'
@@ -10,18 +10,17 @@ export function lodash(user, channel, input) {
return new Promise((resolve, reject) => {
if (!input) return resolve({ type: 'dm', message: 'Usage: lodash <command> | Searches for lodash function' })

let method = input == '_' ? input : input.replace('_.', '').replace('_', '')
let method = input === '_' ? input : input.replace('_.', '').replace('_', '')
if (lodashFunctions[method.toLowerCase()]) {
let cmd = lodashFunctions[method.toLowerCase()];
let cmd = lodashFunctions[method.toLowerCase()]
let msg = cmd.dontShow ? [`<https://lodash.com/docs#${cmd.name}|lodash.com/docs#${cmd.name}>`] : [
`*Method:* _.${cmd.name}`,
`*Command:* \`${cmd.command}\``,
`*Since:* ${cmd.since}`,
`*Description:* ${cmd.description}`,
`https://lodash.com/docs#${cmd.name}`
];
return resolve({ type: 'channel', messages: msg, options: { unfurl_links: false }})
]
return resolve({ type: 'channel', messages: msg, options: { unfurl_links: false } })
} else reject("No function with that name")

})
}
@@ -1,6 +1,6 @@
import MetaInspector from 'node-metainspector'

export const plugin_info = [{
export const pluginInfo = [{
alias: ['maybensfw', 'ita'],
command: 'maybensfw',
usage: 'maybensfw'
@@ -17,6 +17,6 @@ export function maybensfw() {
})

client.on('error', () => reject('Error loading page'))
client.fetch();
client.fetch()
})
}
@@ -1,7 +1,7 @@
import scrapeMDN from 'scrape-mdn'
import { find } from 'lodash'

export const plugin_info = [{
export const pluginInfo = [{
alias: ['mdn'],
command: 'mdn',
usage: 'mdn <query> - returns MDN info for query'
@@ -1,6 +1,6 @@
const mcping = require('mc-ping-updated');
const mcping = require('mc-ping-updated')

export const plugin_info = [{
export const pluginInfo = [{
alias: ['mc', 'minecraft'],
command: 'mc',
usage: 'mc <ip> [port] - returns info about a MC server'
@@ -14,12 +14,14 @@ export function mc(user, channel, input) {
mcping(split[0], parseInt(split[1]) || 25565, (err, resp) => {
if (err || !resp) return reject("Error fetching server info")
if (!resp.players || !resp.players.online) return resolve({ type: 'channel', message: 'No players are currently on the server' })
var players = (resp.players || { sample: []}).sample.map(player => player.name.length ? player.name : undefined).filter(a => a ? true : false)
return resolve({ type: 'channel', messages: [
`*Current players on the server (${resp.players.online}/${resp.players.max}):*`,
players.length ? ` - ${players.join("\n - ")}` : "Unable to view players"
]})

var players = (resp.players || { sample: [] }).sample.map(player => player.name.length ? player.name : undefined).filter(Boolean)
return resolve({
type: 'channel',
messages: [
`*Current players on the server (${resp.players.online}/${resp.players.max}):*`,
players.length ? ` - ${players.join("\n - ")}` : "Unable to view players"
]
})
})
})
}
}
@@ -1,6 +1,6 @@
import needle from 'needle'

export const plugin_info = [{
export const pluginInfo = [{
alias: ['npm'],
command: 'npm',
usage: 'npm <package>'
@@ -10,17 +10,17 @@ export function npm(user, channel, input) {
return new Promise((resolve, reject) => {
if (!input) return resolve({ type: 'dm', message: 'Usage: npm <package> - Returns information on package' })
let split = input.split(' ')[0].split('|')
let p = split.length == 2 ? split[1].slice(0, -1) : split[0]
let p = split.length === 2 ? split[1].slice(0, -1) : split[0]
needle.get(`https://registry.npmjs.com/${p}`, (err, resp, body) => {
if (!err && body) {
if (resp.statusCode == 404) return reject("Couldn't find a package with that name")
if (resp.statusCode === 404) return reject("Couldn't find a package with that name")

let msg = [`*Package:* ${body.name}`,
`*Latest Version:* ${body['dist-tags'].latest}`,
`*Description:* ${body.description ? body.description : 'No description'}`,
`https://npmjs.com/package/${p}`
]
return resolve({ type: 'channel', messages: msg, options: { unfurl_links: false }})
return resolve({ type: 'channel', messages: msg, options: { unfurl_links: false } })
} else return reject("Error contacting npmjs")
})
})
@@ -1,17 +1,16 @@
import { sendMessage } from '../../slack'
import moment from 'moment'
import config from '../../../config.json'
import fs from 'fs'
import { exec as execCmd } from 'child_process'

try {
var getIP = require('external-ip')
} catch(e) {} // eslint-disable-line

var version = require('../../../package.json').version
var updating;
var updating

export const plugin_info = [{
export const pluginInfo = [{
alias: ['shutdown'],
command: 'shutdown',
usage: 'shutdown',
@@ -139,7 +138,7 @@ export function ip(user) {
if (!getIP) return reject("Missing `external-ip` NPM Module")
if (!config.viewConfigs || !config.viewConfigs.includes(user.id)) return reject("*Access DENIED!!1!111!!eleven!*")
getIP()((err, ip) => {
return resolve({ type: 'dm', message: err ? 'Unable to find IP :(' : `My IP is ${ip}`})
return resolve({ type: 'dm', message: err ? 'Unable to find IP :(' : `My IP is ${ip}` })
})
})
}
@@ -2,8 +2,8 @@ import { getUserStats, getUserInfo, getHeroesPlaytime, getHero } from './utils/o
import { filter, capitalize, isEmpty, uniq, compact } from 'lodash'
import { getUserAliases } from '../../database'

export const plugin_info = [{
alias: ['overwatch'],
export const pluginInfo = [{
alias: ['ow', 'overwatch'],
command: 'userInfo',
usage: 'overwatch <battletag> <type> [hero] [version] [-r us] [-p pc]'
}]
@@ -24,69 +24,58 @@ const usage = [
"-p platfm - Platform of th user, defaults to 'pc', valid platforms are 'pc', 'xbl', 'psn' (optional)```"
]

export function userInfo(user, channel, input) {
return new Promise((resolve, reject) => {
if (!input) return resolve({ type: 'dm', messages: usage })
export async function userInfo(user, channel, input) {
if (!input) return { type: 'dm', messages: usage }

const split = input.split(' ')
if (split.length < 1) return resolve({ type: 'dm', messages: usage })
const split = input.split(' ')
if (split.length < 1) return { type: 'dm', messages: usage }

getUserAliases(split[0]).then(newName => {
const battletag = newName.replace('#', '-')
const type = split[1] || 'info'
if (!validTypes.includes(type.toLowerCase())) return reject("Invalid type, valid types are " + validTypes.join(', '))
const newName = await getUserAliases(split[0])
const battletag = newName.replace('#', '-')
const type = split[1] || 'info'
if (!validTypes.includes(type.toLowerCase())) return Promise.reject("Invalid type, valid types are " + validTypes.join(', '))

const hero = split[2]
if (type == 'hero' && (!hero || (hero && !validHeroes.includes(hero)))) return reject("Invalid hero, valid heroes are: " + validHeroes.join(', '))
const hero = split[2]
if (type === 'hero' && (!hero || (hero && !validHeroes.includes(hero)))) return Promise.reject("Invalid hero, valid heroes are: " + validHeroes.join(', '))

const version = input.includes('quickplay') ? 'quickplay' : (input.includes('competitive') || input.includes('competetive')) ? 'competitive' : undefined
const version = input.includes('quickplay') ? 'quickplay' : (input.includes('competitive') || input.includes('competetive')) ? 'competitive' : undefined

const regionRegex = /-r (..)/g
const platformRegex = /-p (...?)/g
const region = (regionRegex.exec(input) || [])[1]
const platform = (platformRegex.exec(input) || [])[1]
if (region && !validRegs.includes(region.toLowerCase())) return reject("Invalid region, valid regions are " + validRegs.join(', '))
if (platform && !validPlats.includes(platform.toLowerCase())) return reject("Invalid platform, valid platforms are " + validPlats.join(', '))
const regionRegex = /-r (..)/g
const platformRegex = /-p (...?)/g
const region = (regionRegex.exec(input) || [])[1]
const platform = (platformRegex.exec(input) || [])[1]
if (region && !validRegs.includes(region.toLowerCase())) return Promise.reject("Invalid region, valid regions are " + validRegs.join(', '))
if (platform && !validPlats.includes(platform.toLowerCase())) return Promise.reject("Invalid platform, valid platforms are " + validPlats.join(', '))

switch (type) {
case 'info':
getUserInfo(battletag, region, platform).then(info => {
if (!info) return reject("Error: No info returned?")
return resolve({ type: 'channel', message: generateInfoResp(info) })
}).catch(reject)
break;
case 'stats':
getUserStats(battletag, region, platform).then(stats => {
if (!stats) return reject("Error: No stats returned?")
return resolve({ type: 'channel', 'message': generateStatsResp(stats, version) })
}).catch(reject)
break;
case 'hero':
getHero(battletag, region, platform, hero).then(stats => {
if (!stats) return reject("Error: No hero stats returned?")
return resolve({ type: 'channel', message: generateHeroResp(stats, version, battletag) })
}).catch(reject)
break;
case 'heroes':
getHeroesPlaytime(battletag, region, platform).then(heroes => {
if (!heroes) return reject("Error: No heroes returned?")
return resolve({ type: 'channel', message: generateHeroesResp(heroes, battletag) })
}).catch(reject)
break;
}
}).catch(reject)
})
switch (type) {
case 'info':
var userInfo = await getUserInfo(battletag, region, platform)
if (!userInfo) return Promise.reject("Error: No info returned?")
return { type: 'channel', message: generateInfoResp(userInfo) }
case 'stats':
var userStats = await getUserStats(battletag, region, platform)
if (!userStats) return Promise.reject("Error: No stats returned?")
return { type: 'channel', 'message': generateStatsResp(userStats, version) }
case 'hero':
var userHero = await getHero(battletag, region, platform, hero)
if (!userHero) return Promise.reject("Error: No hero stats returned?")
return { type: 'channel', message: generateHeroResp(userHero, version, battletag) }
case 'heroes':
var userHeroes = await getHeroesPlaytime(battletag, region, platform)
if (!userHeroes) return Promise.reject("Error: No heroes returned?")
return { type: 'channel', message: generateHeroesResp(userHeroes, battletag) }
}
}

const generateInfoResp = player => {
player.region = player.platform == 'pc' ? player.region : 'n/a'
player.region = player.platform === 'pc' ? player.region : 'n/a'
var level = player.rank ? `${player.rank}${player.level < 10 ? '0' : ''}${player.level}` : player.level
let out = {
attachments: [{
"title": player.battletag,
"fallback": `Overwatch Info for ${player.battletag}, Region: ${player.region.toUpperCase()}, Platform: ${player.platform.toUpperCase()}, Level: ${player.rank || ''}${player.level}, Competitive Rank: ${player.comprank || 'None'}`,
"color": "#ff9c00",
"title_link": `${pageURL}/${player.platform}${player.platform == 'pc' ? '/' + player.region : ''}/${player.battletag}`,
"title_link": `${pageURL}/${player.platform}${player.platform === 'pc' ? '/' + player.region : ''}/${player.battletag}`,
"thumb_url": player.avatar,
"mrkdwn_in": ["text"],
text: [
@@ -108,20 +97,20 @@ const generateHeroesResp = (heroes, battletag) => {
"mrkdwn_in": ["fields"],
"fields": filter([{
"title": "Quickplay",
"value": uniq(compact(heroes.quickplay.map(hero => hero.name.includes('.guid') ? null : `*${capitalize(hero.name)}*: ${hero.time == '0' ? '--' : hero.time}`))).join('\n'),
"value": uniq(compact(heroes.quickplay.map(hero => hero.name.includes('.guid') ? null : `*${capitalize(hero.name)}*: ${parseInt(hero.time) === 0 ? '--' : hero.time}`))).join('\n'),
short: true
}, {
"title": "Competitive",
"value": heroes.competitive ? uniq(compact(heroes.competitive.map(hero => hero.name.includes('.guid') ? null : `*${capitalize(hero.name)}*: ${hero.time == '0' ? '--' : hero.time}`))).join('\n') : null,
"value": heroes.competitive ? uniq(compact(heroes.competitive.map(hero => hero.name.includes('.guid') ? null : `*${capitalize(hero.name)}*: ${parseInt(hero.time) === 0 ? '--' : hero.time}`))).join('\n') : null,
"short": true
}], 'value')
}]
}
}

const getOverallStats = ({ losses, ties, wins, win_rate, games }, isHero) => {
const getOverallStats = ({ losses, ties, wins, win_rate: winRate, games }, isHero) => {
if (wins !== null && losses !== null) {
return `${wins}/${losses}/${ties}` + (win_rate !== null ? ` (${win_rate*100}%)` : '') + (isHero ? ` out of ${games} games` : '')
return `${wins}/${losses}/${ties}` + (winRate !== null ? ` (${winRate * 100}%)` : '') + (isHero ? ` out of ${games} games` : '')
}
return wins !== null ? wins : "Unknown"
}
@@ -131,17 +120,17 @@ const generateStatsResp = (data, version = 'quickplay') => {
if (data.stats.is_empty) return `I have no ${version} stats for this user`
if (data && data.player && data.stats) {
const { player, stats: { featured_stats, overall_stats, playtimes } } = data
player.region = player.platform == 'pc' ? player.region.toUpperCase() : 'N/A'
player.region = player.platform === 'pc' ? player.region.toUpperCase() : 'N/A'
const level = player.rank ? `${player.rank}${player.level < 10 ? '0' : ''}${player.level}` : player.level
const topHeroes = playtimes.filter(h => h.time != '0')
const topHeroes = playtimes.filter(h => parseInt(h.time) !== '0')
const out = {
attachments: [{
"fallback": `Overwatch Stats for ${player.battletag}, Level: ${level}. Overall Stats: Wins: ${overall_stats.wins || 'N/A'} | Losses ${overall_stats.losses || 'N/A'} out of ${overall_stats.games || 'N/A'} games`,
"mrkdwn_in": ["fields"],
"color": "#ff9c00",
"author_name": `${player.battletag} (${player.region}) (${capitalize(version)})`,
"author_icon": player.avatar,
"author_link": `${pageURL}/${player.platform}${player.platform == 'pc' ? '/' + player.region : ''}/${player.battletag}`
"author_link": `${pageURL}/${player.platform}${player.platform === 'pc' ? '/' + player.region : ''}/${player.battletag}`
}]
}
out.attachments[0].fields = [{
@@ -183,7 +172,7 @@ const generateHeroResp = (hero, version = 'quickplay', battletag) => {
"fallback": `Overwatch Data for ${hero.name}`,
"mrkdwn_in": ["text", "fields"],
"color": "#ff9c00",
"text": `Overwatch Hero Data for ${hero.name} - ${battletag} _(${capitalize(version)})_`,
"text": `Overwatch Hero Data for ${hero.name} - ${battletag} _(${capitalize(version)})_`
}]
}
out.attachments[0].fields = [{
@@ -2,12 +2,9 @@ import permissions from '../../permissions'
import permsUtil from './utils/permUtil'

const getUserLevel = user => {
if ((permissions.superadmins.indexOf(user) > -1))
return 'superadmin'
else if ((permissions.admins.indexOf(user) > -1))
return 'admin'
else
return 'user'
if ((permissions.superadmins.indexOf(user) > -1)) return 'superadmin'
else if ((permissions.admins.indexOf(user) > -1)) return 'admin'
else return 'user'
}

const setPermission = (user, channel, input, ts, plugin, adminLevel, action) => {
@@ -16,7 +13,7 @@ const setPermission = (user, channel, input, ts, plugin, adminLevel, action) =>
.catch(reject))
}

export const plugin_info = [{
export const pluginInfo = [{
alias: ['set'],
command: 'set',
usage: 'set <username> <level> - set users permissions level',
@@ -105,21 +102,21 @@ export function permaIgnore(user, channel, input, ts, plugin, adminLevel) {

export function set(admin, channel, input, ts, plugin, adminLevel) {
return new Promise((resolve, reject) => {
if (!input) return reject("Please specify a user");
if (!input) return reject("Please specify a user")

let user = input.split(' ')[0].toLowerCase()
let userLevel = getUserLevel(user)
let level = input.split(' ')[1] ? input.split(' ')[1].toLowerCase().replace(/[s]$/, '') : 'user'
let levels = ((adminLevel === 'superadmin' && userLevel === 'superadmin')) ? -1 :
(adminLevel === 'admin' && userLevel === 'admin') ? -1 :
(adminLevel === 'admin') ? ['user', 'admin'] : ['user', 'admin', 'superadmin']
let levels = ((adminLevel === 'superadmin' && userLevel === 'superadmin')) ? -1
: (adminLevel === 'admin' && userLevel === 'admin') ? -1
: (adminLevel === 'admin') ? ['user', 'admin'] : ['user', 'admin', 'superadmin']

if (user) {
if (levels == -1) return reject("You cannot change the level of yourself or other admins")
if (levels === -1) return reject("You cannot change the level of yourself or other admins")
else if (levels.indexOf(level) > -1) {
permissions.add(user, level)
return resolve({ type: 'channel', message: `Set ${user} to ${level}` })
} else return reject("Invalid User Level");
} else return reject("Invalid User Level")
}
})
}
@@ -4,18 +4,14 @@ import { findUser } from '../../../slack'
import config from '../../../../config.json'

const getUserLevel = user => {
if ((permissions.superadmins.indexOf(user) > -1))
return 'superadmin'
else if ((permissions.admins.indexOf(user) > -1))
return 'admin'
else
return 'user'
if ((permissions.superadmins.indexOf(user) > -1)) return 'superadmin'
else if ((permissions.admins.indexOf(user) > -1)) return 'admin'
else return 'user'
}

const canDoTheThing = (user, adminLevel) => {
let userLevel = getUserLevel(user);
let iCan = ((adminLevel === 'superadmin' && userLevel === 'superadmin')) ? false :
(adminLevel === 'admin' && userLevel === 'admin') ? false : true
let userLevel = getUserLevel(user)
let iCan = ((adminLevel === 'superadmin' && userLevel === 'superadmin') || (adminLevel === 'admin' && userLevel === 'admin'))
if (iCan) return true
else return false
}
@@ -36,24 +32,18 @@ module.exports = {
if (!user) return reject("Couldn't find a user by that name")

// If you're trying to pull shit on the bot
if (user.name == config.botname || user.id == config.botid)
return reject("Error: Bitch. No.")
if (user.name === config.botname || user.id === config.botid) return reject("Error: Bitch. No.")

// If you're trying to pull shit on ur m8s
if (!canDoTheThing(user.name, adminLevel)) return reject("Error: lolno")

if (type == 'ignore' && includes(permissions.allIgnored, user.name))
return reject("This user is already ignored")
if (type == 'mute' && includes(permissions.muted, user.name))
return reject("This user is already muted")
if (type == 'unignore' && !includes(permissions.allIgnored, user.name))
return reject("This user is not ignored")
if (type == 'unmute' && !includes(permissions.muted, user.name))
return reject("This user is not muted")
if (type == 'permaignore' && includes(permissions.permaIgnored, user.name))
return reject("This user is already permanently ignored")
if (type === 'ignore' && includes(permissions.allIgnored, user.name)) return reject("This user is already ignored")
if (type === 'mute' && includes(permissions.muted, user.name)) return reject("This user is already muted")
if (type === 'unignore' && !includes(permissions.allIgnored, user.name)) return reject("This user is not ignored")
if (type === 'unmute' && !includes(permissions.muted, user.name)) return reject("This user is not muted")
if (type === 'permaignore' && includes(permissions.permaIgnored, user.name)) return reject("This user is already permanently ignored")

if (type == 'unignore' || type == 'unmute') {
if (type === 'unignore' || type === 'unmute') {
permissions.add(user.name, type)
return resolve(`${responses[type]} ${user.name}`)
} else {
@@ -1,6 +1,6 @@
import { getQuote, grabQuote } from './utils/quote'

export const plugin_info = [{
export const pluginInfo = [{
alias: ['grab'],
command: 'grab',
usage: 'grab <username> - grabs a users message'
@@ -19,9 +19,9 @@ export function grab(user, channel, input) {
if (!input) return resolve({ type: 'dm', message: 'Usage: grab <username> [index] - Grabs a message from a user. Index can be up to 3 messages back where 0 is latest' })
let grabee = input.split(' ')[0].toLowerCase()
let index = input.split(' ')[1] ? input.split(' ')[1] : 0
if (!index || (index < 4 && index >= 0))
if (!index || (index < 4 && index >= 0)) {
grabQuote(grabee, channel, index, user).then(resp => resolve({ type: 'channel', message: resp })).catch(reject)
else return reject("Can't grab a quote that far back")
} else return reject("Can't grab a quote that far back")
})
}

@@ -17,7 +17,7 @@ export function getQuote(user, quotenum = 0) {
let quoteindex = quotenum < 0 ? quotes.length + parseInt(quotenum) : parseInt(quotenum)
if (quotes[quoteindex]) return resolve(urlify(`<${user.name}> ${quotes[quoteindex].message}`))
else {
if (quotes.length > 0) return reject("I don't have quotes that far back for " + user.name);
if (quotes.length > 0) return reject("I don't have quotes that far back for " + user.name)
else return reject(`No quotes found for ${user.name}, grab a quote via \`${config.prefix}grab <username>\``)
}
}
@@ -30,11 +30,11 @@ export function grabQuote(grabee, channel, index = 0, grabber) {
let user = findUser(grabee)
if (!user) return reject("Couldn't find a user by that name")
let i = 0
if (grabber.id == user.id) { index++ }
if (grabber.id === user.id) { index++ }

let uID = _(messages)
.filter(message => {
if (parseInt(index) == i) return message.user === user.id
if (parseInt(index) === i) return message.user === user.id
else if (message.user === user.id) i++
})
.map('text')
@@ -52,7 +52,7 @@ export function grabQuote(grabee, channel, index = 0, grabber) {
}

const urlify = text => {
let urlRegex = /(<https?:\/\/[^\s]+)/g;
let urlRegex = /(<https?:\/\/[^\s]+)/g
return text.replace(urlRegex, url => {
url = url.substr(1)
return url.substring(0, url.length - 1) + '#' + generatechars()
@@ -1,6 +1,6 @@
import Random from './utils/random'

export const plugin_info = [{
export const pluginInfo = [{
alias: ['rand', 'random'],
command: 'rand',
usage: 'rand <A-B> - A-B can be chars, ints or floats separated by any character'
@@ -19,12 +19,12 @@ export function rand(user, channel, input) {
var random, match

if (!input) match = { type: 'num', match: [0, 9] }
else match = Random.findMatch(input);
else match = Random.findMatch(input)

switch (match.type) {
case 'num':
random = Random.randFloat(match.match[0], match.match[1])
break;
break
case 'char':
random = Random.randChar(match.match[0], match.match[1])
break
@@ -33,8 +33,8 @@ export function rand(user, channel, input) {
}

// add some magic
if (Random.randFloat(1, 100) == 100) random = 'Forty-two'
else if (random == 42) random = 'The Answer to the Ultimate Question of Life, the Universe, and Everything'
if (Random.randFloat(1, 100) === 100) random = 'Forty-two'
else if (random === 42) random = 'The Answer to the Ultimate Question of Life, the Universe, and Everything'

return resolve({ type: 'channel', message: messages[Random.randFloat(0, messages.length - 1)] + random })
})
@@ -1,44 +1,44 @@
module.exports = {
findMatch(word) {
var out = {};
var out = {}

let numbers = word.replace(',', '.').match(/[0-9\.]+/g),
letters = word.toLowerCase().match(/[a-z]/g);
let numbers = word.replace(',', '.').match(/[0-9.]+/g),
letters = word.toLowerCase().match(/[a-z]/g)

if (numbers) {
out.type = 'num';
out.match = [parseFloat(numbers[0]), parseFloat(numbers[1])];
out.type = 'num'
out.match = [parseFloat(numbers[0]), parseFloat(numbers[1])]
} else if (letters) {
out.type = 'char';
out.match = [letters[0], letters[1]];
out.type = 'char'
out.match = [letters[0], letters[1]]
}

return out;
return out
},
getDecimals(num) {
try {
return num.toString().split('.')[1].length;
return num.toString().split('.')[1].length
} catch (e) {
return 0;
return 0
}
},
randFloat(a, b) {
if (!b) b = 0;
if (!b) b = 0
let _a = a < b ? a : b,
_b = a < b ? b : a,
__a = this.getDecimals(_a),
__b = this.getDecimals(_b),
c = __a > __b ? __a : __b;
c = __a > __b ? __a : __b

return (Math.random() * (_b - _a) + _a).toFixed(c);
return (Math.random() * (_b - _a) + _a).toFixed(c)
},
randChar(a, b) {
if (!b) b = 'a';
if (!b) b = 'a'
let _a = a < b ? a : b,
_b = a < b ? b : a,
str = 'abcdefghijklmnopqrstuvwxyz';
str = 'abcdefghijklmnopqrstuvwxyz'

return str.charAt(this.randFloat(str.indexOf(_a), str.indexOf(_b)));
return str.charAt(this.randFloat(str.indexOf(_a), str.indexOf(_b)))
}
};
}

@@ -5,7 +5,7 @@ import normalinsult from 'insultgenerator'
import { sendMessage, findUser } from '../../slack'
import data from './utils/data'

export const plugin_info = [{
export const pluginInfo = [{
alias: ['ddos'],
command: 'ddos',
usage: 'ddos <user> - :)'
@@ -49,7 +49,7 @@ export const plugin_info = [{

const _cleanInput = input => {
if (input.includes('<mailto:')) return input.substr(8).split('|')[0]
if (input.slice(0, 2) == "<@") return findUser(input).name || input
if (input.slice(0, 2) === "<@") return findUser(input).name || input
if (input.includes('<http:')) return input.split('|')[1].slice(0, -1)
return input
}
@@ -123,7 +123,7 @@ export function clap(user, channel, input) {
message: (clapee ? `(${clapee})` : '') + data.clap.insincere[Math.floor(Math.random() * data.clap.insincere.length)]
})
default:
clapee = type;
clapee = type
return resolve({
type: 'channel',
message: (clapee ? `(${clapee})` : '') + data.clap.sincere[Math.floor(Math.random() * data.clap.sincere.length)]
@@ -134,7 +134,7 @@ export function clap(user, channel, input) {

export function flirt(user, channel, input) {
return new Promise(resolve => {
input = input ? (input.slice(0, 2) == "<@" ? findUser(input).name : input) : user.name
input = input ? (input.slice(0, 2) === "<@" ? findUser(input).name : input) : user.name
return resolve({
type: 'channel',
message: data.flirts[Math.floor(Math.random() * data.flirts.length)].replace('%s', input)
@@ -146,7 +146,7 @@ export function insult(user, channel, input) {
return new Promise(resolve => {
if (!input) return resolve({ type: 'channel', message: 'Who am I insulting?' })

new normalinsult((meanMessage) => resolve({ type: 'channel', message: `${input}: ${meanMessage || 'you suk'}` }))
normalinsult((meanMessage) => resolve({ type: 'channel', message: `${input}: ${meanMessage || 'you suk'}` }))
})
}

@@ -6,7 +6,7 @@ import perms from '../../permissions'
import config from '../../../config.json'
import { InviteUsers } from '../../database'

export const plugin_info = [{
export const pluginInfo = [{
alias: ['kick'],
command: 'kickUser',
usage: 'kick <username> [reason] - kicks user from channel',
@@ -88,7 +88,7 @@ export function inviteUser(user, channel, input) {
invite(email).then(resp => {
resolve({ type: 'channel', message: resp })
InviteUsers.findOneByEmail(email).then(res => {
let newInv = res ? res : new InviteUsers()
let newInv = res || new InviteUsers()
newInv.inviter = user.name
newInv.email = email.toLowerCase()
newInv.date = moment().utc().format()
@@ -138,21 +138,21 @@ export function modifyInvite(user, channel, input) {
if (!email.includes('<mailto:')) return reject(`Invalid email recieved: ${email}`)
if (moment(new Date(inviter)).isValid()) return reject("Invalid inviter")
if (!moment(new Date(date)).isValid()) {
if (date == 'today') date = moment()
if (date === 'today') date = moment()
else return reject("Invalid date")
}

email = email.substr(8).split('|')[0].toLowerCase()
date = moment(new Date(date))

InviteUsers.findOneByEmail(email).then(resp => {
if (resp && type == 'add') return reject("Error: Email already in DB, if you wish to edit it you can use the `edit` type")
let newInv = type == 'add' ? new InviteUsers() : resp
if (resp && type === 'add') return reject("Error: Email already in DB, if you wish to edit it you can use the `edit` type")
let newInv = type === 'add' ? new InviteUsers() : resp
newInv.inviter = inviter.toLowerCase()
newInv.email = email
newInv.date = date.utc().format()
newInv.Persist()
return resolve({ type: 'channel', message: `Successfully ${type == 'add' ? 'added' : 'edited'} invite for: ${email}, invited by ${inviter} on ${date.format("dddd, Do MMM YYYY")}` })
return resolve({ type: 'channel', message: `Successfully ${type === 'add' ? 'added' : 'edited'} invite for: ${email}, invited by ${inviter} on ${date.format("dddd, Do MMM YYYY")}` })
})
})
}
@@ -185,8 +185,9 @@ export function addLoadMessage(user, channel, input) {

export function delLoadMessage(user, channel, input) {
return new Promise((resolve, reject) => {
if (!input)
return resolve({ type: 'dm', message: 'Usage: removeloadingmessage <id> - Remove a loading message from the team - ID is required and can only be viewed within the Slack Admin Page' });
if (!input) {
return resolve({ type: 'dm', message: 'Usage: removeloadingmessage <id> - Remove a loading message from the team - ID is required and can only be viewed within the Slack Admin Page' })
}

deleteLoadingMsg(input).then(() => resolve({ type: 'channel', message: `Successfully removed message with id ${input}` })).catch(reject)
})
@@ -237,7 +238,7 @@ export function enableUser(user, channel, input) {
})
}

const cantDisable = u => u.id == config.botid || perms.superadmins.includes(u.name) || (config.noDisable && config.noDisable.includes(u.id))
const cantDisable = u => u.id === config.botid || perms.superadmins.includes(u.name) || (config.noDisable && config.noDisable.includes(u.id))

export function disableUser(user, channel, input) {
return new Promise((resolve, reject) => {
@@ -265,7 +266,7 @@ export function reconnect(user, channel, input) {
enableOrDisableUser(1, u).then(() => {
return resolve("Dun")
}).catch(reject)
}, 5000);
}, 5000)
}).catch(reject)
})
}
@@ -275,7 +276,7 @@ export function ban(user, channel, input) {
return new Promise((resolve, reject) => {
if (!input) return reject("Please specify a user")
let split = input.split(' ')
if (split.length != 2) return resolve({ type: 'dm', message: 'Usage: ban <user> [duration] - bans user for duration in minutes or 5 minutes' })
if (split.length !== 2) return resolve({ type: 'dm', message: 'Usage: ban <user> [duration] - bans user for duration in minutes or 5 minutes' })

let u = findUser(split[0])
if (!u) return reject("Found no user by that name")
@@ -1,5 +1,5 @@
import _ from 'lodash'
import { findUser, sendPMThroughSlackbot, getHistory, deleteMessage, kickUser, setInactive, setRegular, updateUsersCache, usersCache } from '../../../slack.js';
import { findUser, sendPMThroughSlackbot, getHistory, deleteMessage, kickUser, setInactive, setRegular, updateUsersCache, usersCache } from '../../../slack.js'
import config from '../../../../config.json'
import request from 'request'
import moment from 'moment'
@@ -26,7 +26,7 @@ export function kick(user, channel, input) {

if (!user) return reject("Found no user by that name")

if (user.name == config.botname || user.id === config.botid) return reject('Error: Bitch. No.')
if (user.name === config.botname || user.id === config.botid) return reject('Error: Bitch. No.')

kickUser(channel.id, user.id).then(() => {
sendPMThroughSlackbot(user.name, `You were kicked from #${channel.name} ${reason || 'for no reason'}`)
@@ -44,11 +44,11 @@ export function deleteLastMessage(channel, messagets) {
.map('ts')
.value()[0]

if (!ts) return resolve(false);
if (!ts) return resolve(false)

deleteMessage(channel, ts)
return resolve()
}).catch(reject);
}).catch(reject)
})
}

@@ -60,7 +60,7 @@ const _getSpecialToken = () => {
return new Promise((resolve, reject) => {
if (specialToken && nextUpdate && moment().isBefore(nextUpdate)) return resolve(specialToken)
let url = `https://${config.teamName}.slack.com`
let cookieJar = request.jar();
let cookieJar = request.jar()
let cookie1 = request.cookie(config.cookies[0])
let cookie2 = request.cookie(config.cookies[1])
let cookie3 = request.cookie(config.cookies[2])
@@ -70,7 +70,7 @@ const _getSpecialToken = () => {
request({ url: `${url}/admin`, jar: cookieJar }, (err, resp, body) => {
if (!err && body) {
let token = tokenRegex.exec(body)
if (token && token.length == 2) {
if (token && token.length === 2) {
specialToken = token[1]
nextUpdate = moment().add(1, 'd').format()
return resolve(specialToken)
@@ -82,17 +82,20 @@ const _getSpecialToken = () => {

export function enableOrDisableUser(enable, user) {
return new Promise((resolve, reject) => {
if (config.cookies && config.teamName && config.cookies.length == 3) {
if (config.cookies && config.teamName && config.cookies.length === 3) {
_getSpecialToken().then(token => {
if (enable) setRegular(user, token).then(resp => {
if (typeof user.real_name == 'undefined') updateUsersCache().then(console.log, console.error)
else usersCache[user.id].deleted = false
return resolve(resp)
}, reject)
else setInactive(user, token).then(resp => {
usersCache[user.id].deleted = true
return resolve(resp)
}, reject)
if (enable) {
setRegular(user, token).then(resp => {
if (typeof user.real_name === 'undefined') updateUsersCache().then(console.log, console.error)
else usersCache[user.id].deleted = false
return resolve(resp)
}, reject)
} else {
setInactive(user, token).then(resp => {
usersCache[user.id].deleted = true
return resolve(resp)
}, reject)
}
}).catch(reject)
} else return reject("Where be da cookies")
})
@@ -3,7 +3,7 @@ import { generatePlayersResponse, generateProfileResponse, generateAppDetailsRes
import { getNextSale, getSaleTime } from './utils/sales'
import moment from 'moment'

export const plugin_info = [{
export const pluginInfo = [{
alias: ['sp', 'steamprofile'],
command: 'steamProfile',
usage: 'steamprofile <steamid/vanityid> - returns user steam profile'
@@ -25,51 +25,41 @@ export const plugin_info = [{
usage: 'steamsale - tells u wen da sale is, durh'
}]

export function steamProfile(user, channel, input) {
return new Promise((resolve, reject) => {
if (!input) return resolve({ type: 'dm', message: 'Usage: steamprofile <SteamID/64 or VanityURL ID> - Returns a users basic Steam Information' })

getProfileInfo(input).then(resp => resolve({ type: 'channel', message: generateProfileResponse(resp) })).catch(reject)
})
export async function steamProfile(user, channel, input) {
if (!input) return { type: 'dm', message: 'Usage: steamprofile <SteamID/64 or VanityURL ID> - Returns a users basic Steam Information' }
const profileData = await getProfileInfo(input)
return { type: 'channel', message: generateProfileResponse(profileData) }
}

export function players(user, channel, input) {
return new Promise((resolve, reject) => {
if (!input) return resolve({ type: 'dm', message: 'Usage: players <appid> - Returns the current amount of players for the game' })

getAppInfo(input, null, true).then(resp => resolve({ type: 'channel', message: generatePlayersResponse(resp) })).catch(reject)
})
export async function players(user, channel, input) {
if (!input) return { type: 'dm', message: 'Usage: players <appid> - Returns the current amount of players for the game' }
const playersInfo = await getAppInfo(input, null, true)
return { type: 'channel', message: generatePlayersResponse(playersInfo) }
}

export function game(user, channel, input) {
return new Promise((resolve, reject) => {
if (!input) return resolve({ type: 'dm', message: 'Usage: game <appid or game name> [-cc us] - Returns basic game info such as price and name, optinally include the country code via -cc AU' })
if (input.match(/-cc.../)) {
var cc = input.match(/-cc.../)[0].split(' ')[1]
input = input.replace(input.match(/-cc.../)[0], '').trim()
}
getAppInfo(input, cc).then(resp => resolve({ type: 'channel', message: generateAppDetailsResponse(resp, cc) })).catch(reject)
})
export async function game(user, channel, input) {
if (!input) return { type: 'dm', message: 'Usage: game <appid or game name> [-cc us] - Returns basic game info such as price and name, optinally include the country code via -cc AU' }
if (input.match(/-cc.../)) {
var cc = input.match(/-cc.../)[0].split(' ')[1]
input = input.replace(input.match(/-cc.../)[0], '').trim()
}
const appInfo = await getAppInfo(input, cc)
return { type: 'channel', message: generateAppDetailsResponse(appInfo, cc) }
}

export function steamid(user, channel, input) {
return new Promise((resolve, reject) => {
if (!input) return resolve({ type: 'dm', message: 'Usage: steamid <id> - ID can be any form of SteamID' })

getSteamIDInfo(input).then(resp => resolve({ type: 'channel', message: resp })).catch(reject)
})
export async function steamid(user, channel, input) {
if (!input) return { type: 'dm', message: 'Usage: steamid <id> - ID can be any form of SteamID' }
const steamInfo = await getSteamIDInfo(input)
return { type: 'channel', message: steamInfo }
}

export function steamSale() {
return new Promise((resolve, reject) => {
getNextSale().then(sale => {
const currentTime = moment()
const saleDate = moment(sale.date)
const isActive = saleDate.isBefore(currentTime)
const time = getSaleTime(moment.duration((isActive ? moment(sale.enddate) : saleDate).diff(currentTime)))
const msg = `The Steam ${sale.name} ${isActive ? 'is here! It ends' : 'starts'} ${time}${sale.confirmed ? '' : ', I think.'}`
return resolve({ type: 'channel', message: msg })
}).catch(reject)
})
export async function steamSale() {
const sale = await getNextSale()
const currentTime = moment()
const saleDate = moment(sale.date)
const isActive = saleDate.isBefore(currentTime)
const time = getSaleTime(moment.duration((isActive ? moment(sale.enddate) : saleDate).diff(currentTime)))
const msg = `The Steam ${sale.name} ${isActive ? 'is here! It ends' : 'starts'} ${time}${sale.confirmed ? '' : ', I think.'}`
return { type: 'channel', message: msg }
}

@@ -4,7 +4,7 @@ import moment from 'moment'

try {
var { salesAPI: [url, auth, key] } = require('../../../../config.json')
} catch(e) {
} catch (e) {
var noWorkie = true
}

@@ -15,16 +15,15 @@ const options = {
}
}

var sales = undefined
var nextUpdate = undefined

var sales
var nextUpdate
function getSaleData() {
return new Promise((resolve, reject) => {
if (noWorkie) return reject("Unable to use this function")
needle.get(url, options, (err, resp, body) => {
if (!err && body) {
nextUpdate = moment().add(2, 'd')
return resolve(typeof body == 'string' ? JSON.parse(body) : body)
return resolve(typeof body === 'string' ? JSON.parse(body) : body)
}
return reject("Error fetching data")
})
@@ -43,13 +42,13 @@ function formatDates(data) {
return _.map(data, ({ name, date, enddate, confirmed }) => {
date = formatDate(date)
enddate = formatDate(enddate)
return { name, date, enddate, confirmed: (confirmed === 'true' ? true : false) }
return { name, date, enddate, confirmed: confirmed === 'true' }
})
}

function findNextSale(sales) {
let currentTime = new Date().getTime()
let nextSale = undefined
let nextSale
sales.forEach(sale => {
let diff = sale.enddate.getTime() - currentTime
if (diff > 0 && (!nextSale || nextSale.date.getTime() - currentTime > diff)) nextSale = sale
@@ -28,10 +28,10 @@ const getUrl = (type, param, cc) => {

const getIDFromProfile = id => {
return new Promise((resolve, reject) => needle.get(getUrl('resolveVanity', id), (err, resp, body) => {
if (!err && body && body.response)
if (body.response.success == 1) return resolve(body.response.steamid)
if (!err && body && body.response) {
if (body.response.success === 1) return resolve(body.response.steamid)
else return reject("Invalid Vanity ID")
else return reject('Error retrieving profile ID')
} else return reject('Error retrieving profile ID')
}))
}

@@ -75,10 +75,10 @@ const getUserRecentlyPlayedGames = id => {

const getAppDetails = (appid, cc, basic) => {
return new Promise((resolve, reject) => needle.get(getUrl(basic ? 'appDetailsBasic' : 'appDetails', appid, cc), (err, resp, body) => {
if (!err && body)
if (!err && body) {
if (get(body, `[${appid}].success`)) return resolve(body[appid].data)
else return reject(`Couldn't fetch app details for that AppID, invalid? ${appid}`)
else return reject('Error retrieving game details')
} else return reject('Error retrieving game details')
}))
}

@@ -94,17 +94,17 @@ const searchForApp = (query, isAppID) => {

const getPlayersForApp = appid => {
return new Promise((resolve, reject) => needle.get(getUrl('numPlayers', appid), (err, resp, body) => {
if (!err && body && body.response)
if (typeof body.response.player_count != 'undefined') return resolve(body.response)
if (!err && body && body.response) {
if (typeof body.response.player_count !== 'undefined') return resolve(body.response)
else return reject('Unable to view player counts for this app')
else return reject('Error retrieving player counts')
} else return reject('Error retrieving player counts')
}))
}

export function getProfileInfo(id) {
return new Promise((resolve, reject) => formatProfileID(id).then(newID => needle.get(getUrl('profileSummary', newID), (err, resp, body) => {
if (!err && body) {
let profile = body.response.players[0];
let profile = body.response.players[0]
Promise.all([getUserLevel(newID), getUserBans(newID), getUserGames(newID), getUserRecentlyPlayedGames(newID)]).then(([level, bans, games, recentlyPlayed]) => {
profile.user_level = level
profile.bans = bans
@@ -118,7 +118,7 @@ export function getProfileInfo(id) {
profile.mostplayed = sortedGames[0]
getAppDetails(sortedGames[0].appid, false, true).then(game => {
if (game) {
profile.mostplayed.name = game.name;
profile.mostplayed.name = game.name
return resolve(profile)
}
}).catch(reject)
@@ -150,24 +150,24 @@ export function getSteamIDInfo(id) {
let sid = new SteamID(newID)
let i, details = []
for (i in SteamID.Universe) {
if (sid.universe == SteamID.Universe[i]) {
if (sid.universe === SteamID.Universe[i]) {
details.push(`*Universe:* ${capitalize(i.toLowerCase())} (${sid.universe})`)
break
}
}
for (i in SteamID.Type) {
if (sid.type == SteamID.Type[i]) {
if (sid.type === SteamID.Type[i]) {
details.push(`*Type:* ${i.split('_').map(j => capitalize(j.toLowerCase())).join(' ')} (${sid.type})`)
break
}
}
for (i in SteamID.Instance) {
if (sid.instance == SteamID.Instance[i]) {
if (sid.instance === SteamID.Instance[i]) {
details.push(`*Instance:* ${capitalize(i.toLowerCase())} (${sid.instance})`)
break
}
}
let msg = `${sid.getSteam3RenderedID()} ${sid.type == SteamID.Type.INDIVIDUAL ? '/ ' + sid.getSteam2RenderedID() : ''} / ${sid.getSteamID64()} \n *Valid:* ${sid.isValid() ? 'True' : 'False'}, ${details.join(', ')}, *AccountID:* ${sid.accountid}`;
let msg = `${sid.getSteam3RenderedID()} ${sid.type === SteamID.Type.INDIVIDUAL ? '/ ' + sid.getSteam2RenderedID() : ''} / ${sid.getSteamID64()} \n *Valid:* ${sid.isValid() ? 'True' : 'False'}, ${details.join(', ')}, *AccountID:* ${sid.accountid}`
return resolve(msg)
}).catch(reject))
}
@@ -1,13 +1,13 @@
import moment from 'moment'
import needle from 'needle'
import { filter, capitalize, truncate } from 'lodash'
var AUDRate;
var AUDRate

const formatTimeCreated = time => {
if (!time) return null
const timeCreated = moment(time * 1000)
const diff = moment().diff(timeCreated, 'years')
return `${timeCreated.format("dddd, Do MMMM YYYY")} _(${diff == 0 ? 'Less than a year' : (diff + ' year' + (diff == 1 ? '' : 's'))})_`
return `${timeCreated.format("dddd, Do MMMM YYYY")} _(${diff === 0 ? 'Less than a year' : (diff + ' year' + (diff === 1 ? '' : 's'))})_`
}

const formatLastOnline = time => {
@@ -21,9 +21,9 @@ const getGameTime = game => {
const duration = moment.duration(game.playtime_2weeks, 'm')
const hours = Math.round(duration.asHours())
if (hours) {
return `${hours} hour` + (hours == 1 ? '' : 's')
return `${hours} hour` + (hours === 1 ? '' : 's')
} else {
return `${game.playtime_2weeks} minute` + (game.playtime_2weeks == 1 ? '' : 's')
return `${game.playtime_2weeks} minute` + (game.playtime_2weeks === 1 ? '' : 's')
}
}

@@ -35,11 +35,11 @@ export function generateProfileResponse(profile) {
const msg = [
`*Profile Name:* ${profile.personaname} ${realname}`,
`*Level:* ${profile.user_level} | *Status:* ${status}`,
status == 'Offline' ? `*Last Online:* ${formatLastOnline(profile.lastlogoff)}` : null,
status === 'Offline' ? `*Last Online:* ${formatLastOnline(profile.lastlogoff)}` : null,
joined ? `*Joined Steam:* ${joined}` : null,
profile.totalgames ? `*Total Games:* ${profile.totalgames || "Unknown"} | *Most Played:* ${profile.mostplayed.name || "Unknown"} w/ ${formatPlaytime(profile.mostplayed.playtime_forever)}` : null,
profile.bans ? profile.bans.VACBanned ? `*This user has ${profile.bans.NumberOfVACBans} VAC ban/s on record!*` : null : null,
profile.communityvisibilitystate == 1 ? '*This is a private profile*' : null
profile.communityvisibilitystate === 1 ? '*This is a private profile*' : null
]

const out = {
@@ -49,8 +49,8 @@ export function generateProfileResponse(profile) {
"author_icon": profile.avatar,
"author_link": profile.profileurl,
"color": "#14578b",
//"text": msg.filter(Boolean).join('\n'),
"fallback": msg.filter(Boolean).join(' | ').replace(/[\*\_]/g, '')
// "text": msg.filter(Boolean).join('\n'),
"fallback": msg.filter(Boolean).join(' | ').replace(/[*_]/g, '')
}]
}

@@ -85,7 +85,7 @@ export function generateAppDetailsResponse(app, cc = 'US') {
"short": true
}, {
"title": "Real Cost",
"value": (AUDRate && cc.toUpperCase() == 'AU') ? '~$' + formatCurrency((app.price_overview.final / 100) * AUDRate, 'AUD') : null,
"value": (AUDRate && cc.toUpperCase() === 'AU') ? '~$' + formatCurrency((app.price_overview.final / 100) * AUDRate, 'AUD') : null,
"short": true
}, {
"title": app.release_date ? (app.release_date.coming_soon ? "Release Date" : "Released") : null,
@@ -119,7 +119,7 @@ export function generateAppDetailsResponse(app, cc = 'US') {
return out
}

export function generatePlayersResponse(app) {
export function generatePlayersResponse(app) {
return `There are currently *${formatNumber(app.player_count)}* people playing _${app.name}_ right now`
}

@@ -128,14 +128,11 @@ const formatCurrency = (n, currency) => n.toFixed(2).replace(/(\d)(?=(\d{3})+\.)
const formatPlaytime = time => !time ? "Unknown" : time < 120 ? `${time} minutes` : `${Math.floor(time / 60)} hours`

const getPriceForApp = app => {
if (app.is_free)
return 'This game is Free 2 Play, yay :)'
else if (app.price_overview && app.price_overview.discount_percent > 0)
return (`~$${formatCurrency(app.price_overview.initial/100, app.price_overview.currency)}~ - *$${formatCurrency(app.price_overview.final/100, app.price_overview.currency)}* \n ${app.price_overview.discount_percent}% OFF!!! :eyes::scream:`)
else if (app.price_overview)
return (`$${formatCurrency(app.price_overview.initial/100, app.price_overview.currency)}`)
else
return '_Unknown_'
if (app.is_free) return 'This game is Free 2 Play, yay :)'
else if (app.price_overview && app.price_overview.discount_percent > 0) {
return (`~$${formatCurrency(app.price_overview.initial / 100, app.price_overview.currency)}~ - *$${formatCurrency(app.price_overview.final / 100, app.price_overview.currency)}* \n ${app.price_overview.discount_percent}% OFF!!! :eyes::scream:`)
} else if (app.price_overview) return (`$${formatCurrency(app.price_overview.initial / 100, app.price_overview.currency)}`)
else return '_Unknown_'
}

const getDateForApp = app => {
@@ -144,19 +141,19 @@ const getDateForApp = app => {
else return app.release_date.date
}

const getPersonaState = (state => {
const getPersonaState = state => {
switch (state) {
case 1: //Online
case 2: //Busy
case 3: //Away
case 4: //Snooze
case 5: //Looking to trade
case 6: //Looking to play
case 1: // Online
case 2: // Busy
case 3: // Away
case 4: // Snooze
case 5: // Looking to trade
case 6: // Looking to play
return 'Online'
default: // 0
return 'Offline'
}
})
}

const getAUDRate = () => needle.get('http://api.fixer.io/latest?base=USD', (err, resp, body) => {
if (!err && body && body.rates) AUDRate = body.rates.AUD
@@ -5,7 +5,7 @@ import { getSerieDetails, getMovieDetails } from './utils/trakt'

if (!config.traktAPIKey) console.error("Error: Trakt Plugin requires traktAPIKey")

export const plugin_info = [{
export const pluginInfo = [{
alias: ['movie'],
command: 'searchMovies',
usage: 'movie <name> - fetches info for a movie'
@@ -107,8 +107,8 @@ const generateMovieResponse = movie => {

const generateShowResponse = serie => {
if (!serie) return 'Error: Missing serie data while generating response'
if (serie.seasons[0].number == 0) serie.seasons.shift() // Don't count specials season
if (serie.seasons[serie.seasons.length-1].aired_episodes == 0) serie.seasons.pop() // Ignore last season if no aired episodes
if (serie.seasons[0].number === 0) serie.seasons.shift() // Don't count specials season
if (serie.seasons[serie.seasons.length - 1].aired_episodes === 0) serie.seasons.pop() // Ignore last season if no aired episodes
let out = {
attachments: [{
"title": `${serie.title} (${serie.year || 'Unknown'})`,
@@ -134,7 +134,7 @@ const generateShowResponse = serie => {
"short": true
}, {
"title": "Aired Episodes",
"value": `${serie.aired_episodes} Episode${serie.aired_episodes == 1 ? '' : 's'} | ${serie.seasons.length} Season${serie.seasons.length == 1 ? '' : 's'}`,
"value": `${serie.aired_episodes} Episode${serie.aired_episodes === 1 ? '' : 's'} | ${serie.seasons.length} Season${serie.seasons.length === 1 ? '' : 's'}`,
"short": true
}, {
"title": "Genres",
@@ -26,11 +26,11 @@ const getShowORMovieWithSlughOrSearch = (input, type) => {
let isID = input.includes('-s')
let name = isID ? input.replace('-s', '').trim() : input
needle.get(getURL(isID ? type : 'search', name, type), options, (err, resp, body) => {
if (resp.statusCode == 404) return reject("No results found")
if (resp.statusCode === 404) return reject("No results found")
if (err || !body) return reject("Error fetching data from Trakt.tv")
if (isID) return resolve(body)
if (!body.length) return reject("No results found")
resolve(body[0][type == 'movie' ? 'movie' : 'show'])
resolve(body[0][type === 'movie' ? 'movie' : 'show'])
})
})
}
@@ -48,5 +48,4 @@ export function getMovieDetails(input) {

export function getSerieDetails(input) {
return getShowORMovieWithSlughOrSearch(input, 'serie').then(getSeasonInfo)

}
@@ -1,7 +1,7 @@
import { unescape } from 'lodash'
import Urban from 'urban'

export const plugin_info = [{
export const pluginInfo = [{
alias: ['urban'],
command: 'urbandictionary',
usage: 'urban <word> - returns urban definition for word'
@@ -26,7 +26,7 @@ export function urbandictionary(user, channel, input) {
}

export function randomurban() {
return new Promise((resolve, reject) => new Urban.random().first((definition) => {
return new Promise((resolve, reject) => Urban.random().first((definition) => {
if (!definition) return reject("Error fetching urban")
return resolve({
type: 'channel',
@@ -1,6 +1,6 @@
import { query } from './utils/wolfram'

export const plugin_info = [{
export const pluginInfo = [{
alias: ['calc', 'wolfram'],
command: 'wolfram',
usage: 'wolfram <query> - returns wolfram calculation for query'
@@ -10,7 +10,7 @@ export function query(input) {

needle.get(url, (err, resp, body) => {
if (!err && body) {
if (result(body, 'queryresult.$.error', 'true') == 'false' && result(body, 'queryresult.$.success', 'false') == 'true') {
if (result(body, 'queryresult.$.error', 'true') === 'false' && result(body, 'queryresult.$.success', 'false') === 'true') {
let response = result(body, 'queryresult.pod[1].subpod.plaintext', undefined)
if (response) return resolve(response)
else return reject("Error parsing data")
@@ -37,7 +37,7 @@ export function sendMessage(channel, input, attachments) {
as_user: 'true',
token: config.slackBotToken,
icon_url: config.imageURL,
attachments: typeof attachments == 'string' ? attachments : JSON.stringify(attachments)
attachments: typeof attachments === 'string' ? attachments : JSON.stringify(attachments)
}, (err, resp, { error }) => {
if (err || error) return reject(_logErr('sendMsgErr', err || error))
resolve()
@@ -70,7 +70,7 @@ export function sendPMThroughSlackbot(channel, input) {
* @return array of messages
*/
export function getHistory(channel, limit = 100) {
return new Promise((resolve, reject) => needle.post(`https://slack.com/api/${channel[0] == 'C' ? 'channels.history' : channel[0] == 'G' ? 'groups.history' : 'im.history'}`, {
return new Promise((resolve, reject) => needle.post(`https://slack.com/api/${channel[0] === 'C' ? 'channels.history' : channel[0] === 'G' ? 'groups.history' : 'im.history'}`, {
channel: channel,
token: config.slackBotToken,
count: limit
@@ -87,7 +87,7 @@ export function getHistory(channel, limit = 100) {
* @return true or an error
*/
export function kickUser(channel, user) {
return new Promise((resolve, reject) => needle.post(`https://slack.com/api/${channel[0] == 'C' ? 'channels.kick' : 'groups.kick'}`, {
return new Promise((resolve, reject) => needle.post(`https://slack.com/api/${channel[0] === 'C' ? 'channels.kick' : 'groups.kick'}`, {
channel: channel,
token: config.slackAPIToken,
user: user
@@ -104,8 +104,8 @@ export function kickUser(channel, user) {
*/
export function findUser(user) {
if (!user) return undefined
let userID = user.slice(0, 2) == "<@" ? user.slice(2, -1).toUpperCase() : false
let member = usersCache[userID ? userID : userNamesCache[user.toLowerCase()]]
let userID = user.slice(0, 2) === "<@" ? user.slice(2, -1).toUpperCase() : false
let member = usersCache[userID || userNamesCache[user.toLowerCase()]]
return member || usersCache[user]
}

@@ -118,12 +118,12 @@ export function findUser(user) {
*/
export function findUserByParam(what, equals) {
// Switch to ID if the username is a SlackID <@UDJHF739J>
if (what == 'name' && equals.slice(0, 2) == "<@") {
if (what === 'name' && equals.slice(0, 2) === "<@") {
what = 'id'
equals = equals.slice(2, -1)
}
return find(usersCache, user => {
return get(user, what, 0) == equals
return get(user, what, 0) === equals
})
}

@@ -5,9 +5,9 @@ import config from '../config.json'
import { parse as parseMsg } from './parseMessage'

var errors = 0
var firstStart = true;
var firstStart = true

const DEVMODE = process.env.NODE_ENV == 'development'
const DEVMODE = process.env.NODE_ENV === 'development'

if (!config.prefix || !config.slackAPIToken || !config.slackBotToken) {
console.error("Invalid config, please fill in the first 3 required config fields")
@@ -40,13 +40,13 @@ class Slack extends RtmClient {

this.on(CLIENT_EVENTS.RTM.AUTHENTICATED, () => {
if (firstStart) {
firstStart = false;
return;
firstStart = false
return
}
this._sendErrorToDebugChannel(null, 'Successfully reconnected to Slack', true)
})

this.on(RTM_EVENTS.MESSAGE, ::this._handleMessage)
this.on(RTM_EVENTS.MESSAGE, this._handleMessage)

this.on(RTM_EVENTS.TEAM_JOIN, () => updateUsersCache())

@@ -66,12 +66,12 @@ class Slack extends RtmClient {
parseMsg(user, channel, text, ts).then(response => {
if (!response) return

if (typeof response == 'string' || (!response.type == 'dm' || !response.type == 'channel')) {
if (typeof response === 'string' || (!response.type === 'dm' || !response.type === 'channel')) {
response = { type: 'channel', message: response }
console.warn("No response type, assuming channel response")
}

if (response.type == 'dm') {
if (response.type === 'dm') {
if (response.user) channel = this.dataStore.getDMByName(response.user.name ? response.user.name : response.user)
else channel = channel.id.startsWith('D') ? channel : this.dataStore.getDMByName(user.name)
}
@@ -88,23 +88,25 @@ class Slack extends RtmClient {
if (!err) return
console.error(`parseMsg Error: ${err}`)
if (typeof err === 'string') this._sendMessage(err, channel.id, thread_ts)
else throw(err)
else throw (err)
})
}
}

// Custom sendMessage function to send through RTM or API
_sendMessage(text, channel, thread_ts, attachments = [], options = {}) {
// If we don't have any attachments or options and there is no thread_ts, send the message through RTM
if (!attachments.length && !Object.keys(options).length && options !== true && !thread_ts) {
_sendMessage(text, channel, threadTS, attachments = [], options = {}) {
// If we don't have any attachments or options and there is no threadTS, send the message through RTM
if (!attachments.length && !Object.keys(options).length && options !== true && !threadTS) {
this.sendMessage(text, channel)
return
}
needle.post("https://slack.com/api/chat.postMessage", Object.assign({}, {
channel, thread_ts, text,
channel,
threadTS,
text,
token: config.slackBotToken,
as_user: true,
attachments: typeof attachments == 'string' ? attachments : JSON.stringify(attachments)
attachments: typeof attachments === 'string' ? attachments : JSON.stringify(attachments)
}, options), (err, resp, body) => {
if (err || !body.ok) console.error("_sendMessageError", err, body)
})
@@ -130,7 +132,7 @@ class Slack extends RtmClient {
if (errors < 3) {
errors++
setTimeout(() => {
if (errors > 0) errors--;
if (errors > 0) errors--
}, 20000)
} else {
console.error("Warning! Error spam, stopping bot")