Skip to content

Commit

Permalink
Add /xkcd search, use db for reminders and unmute tasks, update /uptime.
Browse files Browse the repository at this point in the history
- /uptime uses process.uptime now instead of client.uptime.
- Add new /help aliases.
  • Loading branch information
retrixe committed Jul 9, 2020
1 parent c4444b6 commit b2698fb
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 37 deletions.
35 changes: 16 additions & 19 deletions server/bot/commands/admin/mute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const handleMute: Command = {
guildOnly: true,
requirements: { permissions: { 'manageMessages': true } }
},
generator: async (message, args, { client, tempDB }) => {
generator: async (message, args, { client, tempDB, db }) => {
// Find the user ID.
let user = getUser(message, args.shift())
if (!user) return `Specify a valid member of this guild, ${getInsult()}.`
Expand Down Expand Up @@ -77,33 +77,29 @@ export const handleMute: Command = {
} catch (e) { return 'Could not mute that person.' }
// Persist the mute.
const guildID = message.member.guild.id
/* TODO: Some database stuff.
// If time given, set timeout to remove role in database.
try {
const mute = await db.collection('mute').findOne({ guild: guildID, user: user.id })
// Figure out the time for which the user is muted.
let time = 0
try { time = ms(args[0]) || 0 } catch (e) { }
if (time && time >= 2073600000) return 'Mute limit is 24 days.'
const mute = await db.collection('tasks').findOne({ type: 'unmute', guild: guildID, user: user.id })
if (!mute && time > 0) {
// Insert the persisted mute.
await db.collection('mute').insertOne({
guild: guildID, user: user.id, till: Date.now() + time, time
await db.collection('tasks').insertOne({
type: 'unmute', guild: guildID, user: user.id, target: role.id, time: time + Date.now()
})
} else if (!mute) await db.collection('mute').insertOne({ guild: guildID, user: user.id })
// If this was modifying a previous mute.
else if (mute && time > 0) {
await db.collection('mute').updateOne({ guild: guildID, user: user.id }, {
$set: { till: Date.now() + time, time }
})
} else if (mute) {
await db.collection('mute').updateOne({ guild: guildID, user: user.id }, {
$set: { till: 0, time: 0 }
// If this was modifying a previous mute.
} else if (mute && time > 0) {
await db.collection('tasks').updateOne({ type: 'unmute', guild: guildID, user: user.id }, {
$set: { time: time + Date.now() }
})
}
} catch (e) { return 'Failed to persist mute! However, user has been muted.' }
*/
if (!tempDB.mute[guildID]) tempDB.mute[guildID] = []
if (!tempDB.mute[guildID].includes(user.id)) tempDB.mute[guildID].push(user.id)
// If time given, set timeout.
} catch (e) { return 'Failed to add mute timer! However, user has been muted.' }
// Persist in cache.
if (!tempDB.mute[guildID]) tempDB.mute[guildID] = [user.id]
else if (!tempDB.mute[guildID].includes(user.id)) tempDB.mute[guildID].push(user.id)
/*
try {
if (ms(args[0]) && ms(args[0]) >= 2073600000) return 'Mute limit is 24 days.'
else if (ms(args[0])) {
Expand All @@ -117,6 +113,7 @@ export const handleMute: Command = {
}, ms(args[0]))
}
} catch (e) {}
*/
return 'Muted.'
}
}
Expand Down
29 changes: 24 additions & 5 deletions server/bot/commands/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -560,19 +560,38 @@ export const handleDefine: Command = {
}
}

const noimageposts = [1037, 1608, 1663].map(e => 'https://xkcd.com' + e)
export const handleXkcd: Command = {
name: 'xkcd',
opts: {
description: 'Get the latest or a random xkcd comic.',
fullDescription: 'Get the latest or a random xkcd comic.',
usage: '/xkcd (latest (default)|random)',
description: 'Get the latest, random or search for an xkcd comic.',
fullDescription: 'Get the latest, random or search for an xkcd comic.',
usage: '/xkcd (latest (default)|random|search) (search query, if searching)',
example: '/xkcd random',
argsRequired: false
},
generator: async (message, args) => {
if (
if (args.length >= 2 && args[0] === 'search') {
try {
// Fetch all posts and parse the HTML.
const req = await fetch('https://xkcd.com/archive')
if (!req.ok) return 'Failed to fetch list of xkcd comics!\nhttps://xkcd.com/1348'
const posts = (await req.text()).split('<br/>').map(e => ({
name: e.substring(0, e.length - 4).split('>').pop(),
url: 'https://xkcd.com/' + e.substring(e.lastIndexOf('href="/') + 7).split('/"').shift()
})).slice(4)
posts.splice(posts.length - 11, 11) // Slice and splice invalid elements.
// Construct search result.
// TODO: More powerful search required.
const res = posts.filter(post => post.name.toLowerCase().startsWith(args.slice(1).join(' ').toLowerCase()))
.map(e => e && noimageposts.includes(e.url) ? { ...e, url: e.url + '(no image)' } : e)
if (!res.length) return 'No results were found for your search criteria!'
return `**Top results:**
1. ${res[0].url}${res[1] ? `\n2. <${res[1].url}>` : ''}${res[2] ? `\n3. <${res[2].url}>` : ''}`
} catch (e) { console.error(e); return 'Failed to fetch list of xkcd comics!\nhttps://xkcd.com/1348' }
} else if (
args.length > 1 || (args.length === 1 && args[0] !== 'latest' && args[0] !== 'random')
) return 'Correct usage: /xkcd (latest|random)'
) return 'Correct usage: /xkcd (latest|random|search) (search query if searching)'
// Get the latest xkcd comic.
try {
const { num } = await (await fetch('http://xkcd.com/info.0.json')).json()
Expand Down
2 changes: 1 addition & 1 deletion server/bot/commands/help.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ Arguments in () are optional :P

export const handleHelp: IveBotCommand = {
name: 'help',
aliases: ['halp', 'commands'],
aliases: ['halp', 'hulp', 'gethelp', 'commands'],
opts: {
description: 'The most innovative help.',
fullDescription: 'The most innovative halp.',
Expand Down
4 changes: 2 additions & 2 deletions server/bot/commands/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ export const handleUptime: Command = {
example: '/uptime',
argsRequired: false
},
generator: (message, args, { client }) => {
const d = moment.duration(client.uptime)
generator: () => {
const d = moment.duration(Math.floor(process.uptime() * 1000))
const days = Math.floor(d.asDays())
if (days) {
return `${days} days ${d.hours()} hours ${d.minutes()} minutes ${d.seconds()} seconds`
Expand Down
35 changes: 25 additions & 10 deletions server/bot/commands/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,21 +306,36 @@ export const handleRemindme: Command = {
usage: '/remindme <time in 1d|1h|1m|1s> (--channel|-c) <description>',
example: '/remindme 1h do your homework'
},
generator: (message, args) => {
generator: async (message, args, { db }) => {
if (args.length < 2 || !ms(args[0])) {
return 'Correct usage: /remindme <time in 1d|1h|1m|1s> <description>'
}
let channel = false
if (args[1] === '-c' || args[1] === '--channel') channel = true
setTimeout(async () => {
channel
? message.channel.createMessage(
`⏰ ${message.author.mention} ${args.slice(2).join(' ')}\nReminder set ${args[0]} ago.`
)
: (await message.author.getDMChannel()).createMessage(
`⏰ ${args.slice(1).join(' ')}\nReminder set ${args[0]} ago.`
)
}, ms(args[0]))
if (ms(args[0]) > 61 * 1000) { // Greater than 61 seconds and it's relegated to the database.
try {
const res = await db.collection('tasks').insertOne({
type: 'reminder',
time: Date.now() + ms(args[0]),
user: message.author.id,
target: channel ? message.channel.id : 'dm',
message: `⏰${
channel ? message.author.mention + ' ' : ''
} ${args.slice(channel ? 2 : 1).join(' ')}\nReminder set ${args[0]} ago.`
})
if (res.insertedCount !== 1) return 'Failed to add a reminder to the database!'
} catch (e) { return 'Failed to add a reminder to the database!' }
} else {
setTimeout(async () => {
channel
? message.channel.createMessage(
`⏰ ${message.author.mention} ${args.slice(2).join(' ')}\nReminder set ${args[0]} ago.`
)
: (await message.author.getDMChannel()).createMessage(
`⏰ ${args.slice(1).join(' ')}\nReminder set ${args[0]} ago.`
)
}, ms(args[0]))
}
return `You will be reminded in ${args[0]} through a ${channel ? 'mention' : 'DM'}.`
}
}
Expand Down
16 changes: 16 additions & 0 deletions server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,22 @@ MongoClient.connect(mongoURL === 'dotenv' ? process.env.MONGO_URL : mongoURL, {
}
})
})
// Register setInterval to fulfill delayed tasks.
setInterval(async () => {
const tasks = await db.collection('tasks').find({ time: { $lte: Date.now() + 60000 } }).toArray()
if (tasks) {
tasks.forEach(task => setTimeout(() => {
if (task.type === 'unmute') {
client.removeGuildMemberRole(task.guild, task.user, task.target, 'Muted for fixed duration.')
.catch(e => e.res.statusCode !== 404 && console.error(e))
} else if (task.type === 'reminder') {
client.createMessage(task.target, task.message)
.catch(e => e.res.statusCode !== 404 && console.error(e))
}
db.collection('tasks').deleteOne({ _id: task._id })
}, task.time - Date.now()))
}
}, 60000)
})

// On connecting..
Expand Down

0 comments on commit b2698fb

Please sign in to comment.