Skip to content

Commit

Permalink
Add /ocr, move /serverinfo and userinfo, fix error message and /repeat.
Browse files Browse the repository at this point in the history
  • Loading branch information
retrixe committed Oct 22, 2018
1 parent 5522bb7 commit 819f3ad
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 138 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ Make a file named `config.json5` in the top-level directory. It should be someth
},
"host": "<your user ID to give you certain privileges like /remoteexec>",
"weatherAPIkey": "<an http://openweathermap.org API key to enable /weather>",
"fixerAPIkey": "<an http://fixer.io API key to enable /currencyconvert>",
"fixerAPIkey": "<an http://fixer.io API key to enable /currency>",
"cvAPIkey": "<a http://cloud.google.com/vision API key for /ocr and text recognition>",
"mongoURL": "<the link to your MongoDB database instance>"
}
```
Expand Down
6 changes: 3 additions & 3 deletions server/bot/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export default class CommandParser {
} catch (e) {}
}

onMessage (message: Message) {
async onMessage (message: Message) {
if (!message.content.split(' ')[0].startsWith('/')) {
botCallback(message, this.client, this.tempDB, this.db)
return // Don't process it if it's not a command.
Expand All @@ -174,15 +174,15 @@ export default class CommandParser {
if (commandExec === keys[i]) {
// Execute command.
try {
this.executeCommand(this.commands[keys[i]], message)
await this.executeCommand(this.commands[keys[i]], message)
} catch (e) { message.channel.createMessage(this.commands[keys[i]].errorMessage) }
return
} else if (
this.commands[keys[i]].aliases && this.commands[keys[i]].aliases.includes(commandExec)
) {
// Execute command.
try {
this.executeCommand(this.commands[keys[i]], message)
await this.executeCommand(this.commands[keys[i]], message)
} catch (e) { message.channel.createMessage('IveBot has experienced an internal error.') }
return
}
Expand Down
56 changes: 54 additions & 2 deletions server/bot/commands/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,62 @@ import { Command } from '../imports/types'
// All the tools!
import * as fetch from 'isomorphic-unfetch'
import * as moment from 'moment'
import { zeroWidthSpace } from '../imports/tools'
import { zeroWidthSpace, getInsult } from '../imports/tools'
// Get the NASA API token.
import 'json5/lib/require'
import { NASAtoken, fixerAPIkey, weatherAPIkey, oxfordAPI } from '../../../config.json5'
import {
NASAtoken, fixerAPIkey, weatherAPIkey, oxfordAPI, cvAPIkey
} from '../../../config.json5'

export const handleOcr: Command = {
name: 'ocr',
aliases: ['textrecognition', 'itt', 'textr', 'text'],
opts: {
description: 'Get text from an image.',
fullDescription: 'Get text from an image. Powered by Google Cloud Vision.',
example: '/ocr <with uploaded image>',
usage: '/ocr <link to image/uploaded image>',
argsRequired: false
},
generator: async (message, args) => {
// Get the image and convert it to Base64.
const url = args.length ? args.join('%20') : message.attachments[0].url
try {
const image = Buffer.from(await (await fetch(url)).arrayBuffer()).toString('base64')
// Now send the request.
const res = await fetch(`https://vision.googleapis.com/v1/images:annotate?key=${cvAPIkey}`, {
body: JSON.stringify({
requests: [{
image: { content: image }, features: [{ type: 'TEXT_DETECTION' }]
}]
}),
method: 'POST'
})
// Parse the response.
const result = (await res.json())
// If no text was found.
if (!result.responses[0].fullTextAnnotation
) return 'I was unable to get any results for the image.'
// Return our answer.
return {
content: '🤔 **Text recognition result:**\n' + result.responses[0].fullTextAnnotation.text,
embed: {
color: 0x666666,
author: {
name: `${message.author.username}#${message.author.discriminator}'s Image`,
icon_url: message.author.avatarURL
},
footer: {
text: 'Powered by Google Cloud Vision API',
icon_url: 'https://cloud.google.com' +
'/_static/7e8fbbc4f5/images/cloud/icons/favicons/onecloud/favicon.ico'
},
timestamp: new Date(message.timestamp).toISOString()
}
}
} catch (e) { return `Invalid image URL, you ${getInsult()}.` }
}
}

export const handleCat: Command = {
name: 'cat',
Expand Down
10 changes: 5 additions & 5 deletions server/bot/commands/games.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,16 +127,16 @@ export const handleRepeat: Command = {
},
generator: (message, args) => {
// All arguments.
if (+args[1] * message.content.substring(8 + args[1].length + 1).length >= 2001) {
const number = +args.shift()
if (isNaN(number)) return 'Correct usage: /repeat <number of times> <string to repeat>'
else if (number * args.join(' ').length >= 2001) {
return 'To prevent spam, your excessive message has not been repeated.'
} else if (
args[1] === '_' || args[1] === '*' || args[1] === '~'
args.join(' ') === '_' || args.join(' ') === '*' || args.join(' ') === '~'
) return 'This is known to lag users and is disabled.'
// Generate the repeated string.
let generatedMessage = ''
for (let x = 0; x < +args[1]; x++) {
generatedMessage += message.content.substring(8 + args[1].length + 1)
}
for (let x = 0; x < number; x++) { generatedMessage += args.join() }
return generatedMessage
}
}
Expand Down
126 changes: 0 additions & 126 deletions server/bot/commands/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,133 +4,7 @@ import * as ms from 'ms'
import { version } from '../../../package.json'
import { execSync } from 'child_process'
import 'json5/lib/require'
import * as moment from 'moment'
import { host } from '../../../config.json5'
import { getUser, getInsult } from '../imports/tools'

export const handleServerinfo: Command = {
name: 'serverinfo',
aliases: ['serveri', 'guildinfo', 'si'],
opts: {
description: 'Displays info on the current servers.',
fullDescription: 'Displays info on the current servers (or other mutual servers).',
example: '/serverinfo',
usage: '/serverinfo (mutual server ID)',
argsRequired: false
},

generator: async (message, args, { client }) => {
// Check if a guild was specified.
let guild = args.length ? client.guilds.find(
i => i.members.find(f => f.id === message.author.id) && i.id === args[0]
) : message.member.guild
if (!guild) return `Specify a valid mutual guild, ${getInsult()}.`
// Owner.
const owner = guild.members.find(i => i.id === guild.ownerID)
// Display information.
return {
content: `⌨ **Server info on ${guild.name}:**`,
embed: {
author: { name: guild.name, icon_url: guild.iconURL },
thumbnail: { url: guild.iconURL },
color: Math.floor(Math.random() * 1000000 - 1),
footer: { text: `ID: ${guild.id}` },
timestamp: new Date().toISOString(),
fields: [
{ name: 'Owner', value: `${owner.username}#${owner.discriminator}`, inline: true },
{ name: 'Owner ID', value: guild.ownerID, inline: true },
{ name: 'Region', value: guild.region, inline: true },
{
name: 'Channel Categories',
inline: true,
value: guild.channels.filter(i => i.type === 4).length.toString()
},
{
name: 'Text Channels',
inline: true,
value: guild.channels.filter(i => i.type === 0).length.toString()
},
{
name: 'Voice Channels',
inline: true,
value: guild.channels.filter(i => i.type === 2).length.toString()
},
{ name: 'Members', inline: true, value: guild.memberCount.toString() },
{
name: 'Humans',
inline: true,
value: guild.members.filter(i => !i.bot).length.toString()
},
{
name: 'Bots',
inline: true,
value: guild.members.filter(i => i.bot).length.toString()
},
{ name: 'Roles', inline: true, value: guild.roles.size.toString() }
]
}
}
}
}

export const handleUserinfo: Command = {
name: 'userinfo',
aliases: ['useri', 'uinfo', 'ui'],
opts: {
description: 'Displays info on a particular user.',
fullDescription: 'Displays info on a particular user.',
example: '/userinfo voldemort#6931',
usage: '/userinfo (user by ID/mention/username)',
argsRequired: false
},
generator: async (message, args, { client }) => {
// Find the user ID.
const toGet = args.length === 0 ? message.author.id : args.shift()
let user = getUser(message, toGet)
if (!user && message.author.id === host && [18, 17].includes(toGet.length) && !isNaN(+toGet)) {
try { user = await client.getRESTUser(toGet) } catch (e) {}
}
if (!user) return `Specify a valid member of this guild, ${getInsult()}.`
// Display information.
const member = message.member.guild.members.find(i => i.user.id === user.id)
const color = member
? member.roles.map(i => member.guild.roles.get(i)).sort(
(a, b) => a.position > b.position ? 0 : 1
).shift().color : 0
return {
content: `👥 **Userinfo on ${user.username}:**`,
embed: {
author: { name: `User info`, icon_url: user.avatarURL },
title: `${user.username}#${user.discriminator}`,
description: user.mention,
thumbnail: { url: user.avatarURL },
color,
fields: [
{ name: 'Status', value: member ? member.status : 'N/A', inline: true },
// { name: 'Join Position }
// { name: 'Name', value: user.username, inline: true },
// { name: 'Discriminator', value: user.discriminator, inline: true },
{
name: 'Joined server at',
value: member ? moment(member.joinedAt).format('DD/MM/YYYY, hh:mm:ss A') : 'N/A',
inline: true
},
{ name: 'User ID', value: user.id, inline: true },
{
name: 'Registered at',
value: moment(user.createdAt).format('DD/MM/YYYY, hh:mm:ss A'),
inline: true
},
{
name: `Roles (${member ? member.roles.length : 'N/A'})`,
value: member ? member.roles.map(i => `<@&${i}>`).join(' ') : 'N/A'
}
// { name: 'Permissions' }
]
}
}
}
}

export const handleToken: Command = {
name: 'token',
Expand Down
127 changes: 126 additions & 1 deletion server/bot/commands/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,135 @@
import { Message } from 'eris' // eslint-disable-line no-unused-vars
import { Command } from '../imports/types'
// All the needs!
import { getIdFromMention, getDesc } from '../imports/tools'
import { getIdFromMention, getDesc, getInsult, getUser } from '../imports/tools'
import * as ms from 'ms'
import 'json5/lib/require'
import { host, testPilots } from '../../../config.json5'
import * as moment from 'moment'

export const handleServerinfo: Command = {
name: 'serverinfo',
aliases: ['serveri', 'guildinfo', 'si'],
opts: {
description: 'Displays info on the current servers.',
fullDescription: 'Displays info on the current servers (or other mutual servers).',
example: '/serverinfo',
usage: '/serverinfo (mutual server ID)',
argsRequired: false
},

generator: async (message, args, { client }) => {
// Check if a guild was specified.
let guild = args.length ? client.guilds.find(
i => i.members.find(f => f.id === message.author.id) && i.id === args[0]
) : message.member.guild
if (!guild) return `Specify a valid mutual guild, ${getInsult()}.`
// Owner.
const owner = guild.members.find(i => i.id === guild.ownerID)
// Display information.
return {
content: `⌨ **Server info on ${guild.name}:**`,
embed: {
author: { name: guild.name, icon_url: guild.iconURL },
thumbnail: { url: guild.iconURL },
color: Math.floor(Math.random() * 1000000 - 1),
footer: { text: `ID: ${guild.id}` },
timestamp: new Date().toISOString(),
fields: [
{ name: 'Owner', value: `${owner.username}#${owner.discriminator}`, inline: true },
{ name: 'Owner ID', value: guild.ownerID, inline: true },
{ name: 'Region', value: guild.region, inline: true },
{
name: 'Channel Categories',
inline: true,
value: guild.channels.filter(i => i.type === 4).length.toString()
},
{
name: 'Text Channels',
inline: true,
value: guild.channels.filter(i => i.type === 0).length.toString()
},
{
name: 'Voice Channels',
inline: true,
value: guild.channels.filter(i => i.type === 2).length.toString()
},
{ name: 'Members', inline: true, value: guild.memberCount.toString() },
{
name: 'Humans',
inline: true,
value: guild.members.filter(i => !i.bot).length.toString()
},
{
name: 'Bots',
inline: true,
value: guild.members.filter(i => i.bot).length.toString()
},
{ name: 'Roles', inline: true, value: guild.roles.size.toString() }
]
}
}
}
}

export const handleUserinfo: Command = {
name: 'userinfo',
aliases: ['useri', 'uinfo', 'ui'],
opts: {
description: 'Displays info on a particular user.',
fullDescription: 'Displays info on a particular user.',
example: '/userinfo voldemort#6931',
usage: '/userinfo (user by ID/mention/username)',
argsRequired: false
},
generator: async (message, args, { client }) => {
// Find the user ID.
const toGet = args.length === 0 ? message.author.id : args.shift()
let user = getUser(message, toGet)
if (!user && message.author.id === host && [18, 17].includes(toGet.length) && !isNaN(+toGet)) {
try { user = await client.getRESTUser(toGet) } catch (e) { }
}
if (!user) return `Specify a valid member of this guild, ${getInsult()}.`
// Display information.
const member = message.member.guild.members.find(i => i.user.id === user.id)
const color = member
? member.roles.map(i => member.guild.roles.get(i)).sort(
(a, b) => a.position > b.position ? 0 : 1
).shift().color : 0
return {
content: `👥 **Userinfo on ${user.username}:**`,
embed: {
author: { name: `User info`, icon_url: user.avatarURL },
title: `${user.username}#${user.discriminator}`,
description: user.mention,
thumbnail: { url: user.avatarURL },
color,
fields: [
{ name: 'Status', value: member ? member.status : 'N/A', inline: true },
// { name: 'Join Position }
// { name: 'Name', value: user.username, inline: true },
// { name: 'Discriminator', value: user.discriminator, inline: true },
{
name: 'Joined server at',
value: member ? moment(member.joinedAt).format('DD/MM/YYYY, hh:mm:ss A') : 'N/A',
inline: true
},
{ name: 'User ID', value: user.id, inline: true },
{
name: 'Registered at',
value: moment(user.createdAt).format('DD/MM/YYYY, hh:mm:ss A'),
inline: true
},
{
name: `Roles (${member ? member.roles.length : 'N/A'})`,
value: member ? member.roles.map(i => `<@&${i}>`).join(' ') : 'N/A'
}
// { name: 'Permissions' }
]
}
}
}
}

export const handleRequest: Command = {
name: 'request',
Expand Down

0 comments on commit 819f3ad

Please sign in to comment.