mirror of
https://github.com/BluemediaGER/muse.git
synced 2024-11-23 09:15:29 +01:00
Add custom shortcut support
This commit is contained in:
parent
5eb1389a6f
commit
32cb3ca4ae
44
src/bot.ts
44
src/bot.ts
|
@ -1,9 +1,7 @@
|
||||||
import makeDir from 'make-dir';
|
|
||||||
import {Client, Message, Collection} from 'discord.js';
|
import {Client, Message, Collection} from 'discord.js';
|
||||||
import {inject, injectable} from 'inversify';
|
import {inject, injectable} from 'inversify';
|
||||||
import {TYPES} from './types';
|
import {TYPES} from './types';
|
||||||
import {Settings} from './models';
|
import {Settings, Shortcut} from './models';
|
||||||
import {sequelize} from './utils/db';
|
|
||||||
import handleGuildCreate from './events/guild-create';
|
import handleGuildCreate from './events/guild-create';
|
||||||
import container from './inversify.config';
|
import container from './inversify.config';
|
||||||
import Command from './commands';
|
import Command from './commands';
|
||||||
|
@ -13,16 +11,12 @@ export default class {
|
||||||
private readonly client: Client;
|
private readonly client: Client;
|
||||||
private readonly token: string;
|
private readonly token: string;
|
||||||
private readonly clientId: string;
|
private readonly clientId: string;
|
||||||
private readonly dataDir: string;
|
|
||||||
private readonly cacheDir: string;
|
|
||||||
private readonly commands!: Collection<string, Command>;
|
private readonly commands!: Collection<string, Command>;
|
||||||
|
|
||||||
constructor(@inject(TYPES.Client) client: Client, @inject(TYPES.Config.DISCORD_TOKEN) token: string, @inject(TYPES.Config.DISCORD_CLIENT_ID) clientId: string, @inject(TYPES.Config.DATA_DIR) dataDir: string, @inject(TYPES.Config.CACHE_DIR) cacheDir: string) {
|
constructor(@inject(TYPES.Client) client: Client, @inject(TYPES.Config.DISCORD_TOKEN) token: string, @inject(TYPES.Config.DISCORD_CLIENT_ID) clientId: string) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.token = token;
|
this.token = token;
|
||||||
this.clientId = clientId;
|
this.clientId = clientId;
|
||||||
this.dataDir = dataDir;
|
|
||||||
this.cacheDir = cacheDir;
|
|
||||||
this.commands = new Collection();
|
this.commands = new Collection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,17 +52,31 @@ export default class {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const args = msg.content.slice(prefix.length).split(/ +/);
|
let args = msg.content.slice(prefix.length).split(/ +/);
|
||||||
const command = args.shift()!.toLowerCase();
|
const command = args.shift()!.toLowerCase();
|
||||||
|
|
||||||
if (!this.commands.has(command)) {
|
// Get possible shortcut
|
||||||
|
const shortcut = await Shortcut.findOne({where: {guildId: msg.guild.id, shortcut: command}});
|
||||||
|
|
||||||
|
let handler: Command;
|
||||||
|
|
||||||
|
if (this.commands.has(command)) {
|
||||||
|
handler = this.commands.get(command) as Command;
|
||||||
|
} else if (shortcut) {
|
||||||
|
const possibleHandler = this.commands.get(shortcut.command.split(' ')[0]);
|
||||||
|
|
||||||
|
if (possibleHandler) {
|
||||||
|
handler = possibleHandler;
|
||||||
|
args = shortcut.command.split(/ +/).slice(1);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const handler = this.commands.get(command);
|
handler.execute(msg, args);
|
||||||
|
|
||||||
handler!.execute(msg, args);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
msg.reply('there was an error trying to execute that command!');
|
msg.reply('there was an error trying to execute that command!');
|
||||||
|
@ -76,15 +84,13 @@ export default class {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.client.on('ready', async () => {
|
this.client.on('ready', async () => {
|
||||||
// Create directory if necessary
|
|
||||||
await makeDir(this.dataDir);
|
|
||||||
await makeDir(this.cacheDir);
|
|
||||||
|
|
||||||
await sequelize.sync({});
|
|
||||||
|
|
||||||
console.log(`Ready! Invite the bot with https://discordapp.com/oauth2/authorize?client_id=${this.clientId}&scope=bot`);
|
console.log(`Ready! Invite the bot with https://discordapp.com/oauth2/authorize?client_id=${this.clientId}&scope=bot`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.client.on('error', error => {
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
|
|
||||||
// Register event handlers
|
// Register event handlers
|
||||||
this.client.on('guildCreate', handleGuildCreate);
|
this.client.on('guildCreate', handleGuildCreate);
|
||||||
|
|
||||||
|
|
88
src/commands/shortcuts.ts
Normal file
88
src/commands/shortcuts.ts
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
import {Message} from 'discord.js';
|
||||||
|
import {injectable} from 'inversify';
|
||||||
|
import {Shortcut, Settings} from '../models';
|
||||||
|
import Command from '.';
|
||||||
|
|
||||||
|
@injectable()
|
||||||
|
export default class implements Command {
|
||||||
|
public name = 'shortcuts';
|
||||||
|
public description = 'edit shortcuts';
|
||||||
|
|
||||||
|
public async execute(msg: Message, args: string []): Promise<void> {
|
||||||
|
if (args.length === 0) {
|
||||||
|
// Get shortcuts for guild
|
||||||
|
const shortcuts = await Shortcut.findAll({where: {guildId: msg.guild!.id}});
|
||||||
|
|
||||||
|
if (shortcuts.length === 0) {
|
||||||
|
await msg.channel.send('no shortcuts exist');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get prefix for guild
|
||||||
|
const {prefix} = await Settings.findOne({where: {guildId: msg.guild!.id}}) as Settings;
|
||||||
|
|
||||||
|
const res = shortcuts.reduce((accum, shortcut) => {
|
||||||
|
accum += `${prefix}${shortcut.shortcut}: ${shortcut.command}\n`;
|
||||||
|
|
||||||
|
return accum;
|
||||||
|
}, '');
|
||||||
|
|
||||||
|
await msg.channel.send(res);
|
||||||
|
} else {
|
||||||
|
const action = args[0];
|
||||||
|
|
||||||
|
const shortcutName = args[1];
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case 'set': {
|
||||||
|
const shortcut = await Shortcut.findOne({where: {guildId: msg.guild!.id, shortcut: shortcutName}});
|
||||||
|
|
||||||
|
const command = args.slice(2).join(' ');
|
||||||
|
|
||||||
|
const newShortcut = {shortcut: shortcutName, command, guildId: msg.guild!.id, authorId: msg.author.id};
|
||||||
|
|
||||||
|
if (shortcut) {
|
||||||
|
if (shortcut.authorId !== msg.author.id && msg.author.id !== msg.guild!.owner!.id) {
|
||||||
|
await msg.channel.send('error: you do not have permission to do that');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await shortcut.update(newShortcut);
|
||||||
|
await msg.channel.send('shortcut updated');
|
||||||
|
} else {
|
||||||
|
await Shortcut.create(newShortcut);
|
||||||
|
await msg.channel.send('shortcut created');
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'delete': {
|
||||||
|
// Check if shortcut exists
|
||||||
|
const shortcut = await Shortcut.findOne({where: {guildId: msg.guild!.id, shortcut: shortcutName}});
|
||||||
|
|
||||||
|
if (!shortcut) {
|
||||||
|
await msg.channel.send('error: shortcut does not exist');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check permissions
|
||||||
|
if (shortcut.authorId !== msg.author.id && msg.author.id !== msg.guild!.owner!.id) {
|
||||||
|
await msg.channel.send('error: you do not have permission to do that');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await shortcut.destroy();
|
||||||
|
|
||||||
|
await msg.channel.send('shortcut deleted');
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
await msg.channel.send('error: unknown command');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
src/index.ts
10
src/index.ts
|
@ -1,7 +1,9 @@
|
||||||
import container from './inversify.config';
|
|
||||||
import Spotify from 'spotify-web-api-node';
|
import Spotify from 'spotify-web-api-node';
|
||||||
|
import makeDir from 'make-dir';
|
||||||
|
import container from './inversify.config';
|
||||||
import {TYPES} from './types';
|
import {TYPES} from './types';
|
||||||
import Bot from './bot';
|
import Bot from './bot';
|
||||||
|
import {sequelize} from './utils/db';
|
||||||
|
|
||||||
let bot = container.get<Bot>(TYPES.Bot);
|
let bot = container.get<Bot>(TYPES.Bot);
|
||||||
const spotify = container.get<Spotify>(TYPES.Lib.Spotify);
|
const spotify = container.get<Spotify>(TYPES.Lib.Spotify);
|
||||||
|
@ -11,5 +13,11 @@ const spotify = container.get<Spotify>(TYPES.Lib.Spotify);
|
||||||
|
|
||||||
spotify.setAccessToken(auth.body.access_token);
|
spotify.setAccessToken(auth.body.access_token);
|
||||||
|
|
||||||
|
// Create data directories if necessary
|
||||||
|
await makeDir(container.get(TYPES.Config.DATA_DIR));
|
||||||
|
await makeDir(container.get(TYPES.Config.CACHE_DIR));
|
||||||
|
|
||||||
|
await sequelize.sync({});
|
||||||
|
|
||||||
bot.listen();
|
bot.listen();
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -28,6 +28,7 @@ import Pause from './commands/pause';
|
||||||
import Play from './commands/play';
|
import Play from './commands/play';
|
||||||
import QueueCommad from './commands/queue';
|
import QueueCommad from './commands/queue';
|
||||||
import Seek from './commands/seek';
|
import Seek from './commands/seek';
|
||||||
|
import Shortcuts from './commands/shortcuts';
|
||||||
import Shuffle from './commands/shuffle';
|
import Shuffle from './commands/shuffle';
|
||||||
import Skip from './commands/skip';
|
import Skip from './commands/skip';
|
||||||
import Unskip from './commands/unskip';
|
import Unskip from './commands/unskip';
|
||||||
|
@ -50,6 +51,7 @@ container.bind<Command>(TYPES.Command).to(Pause).inSingletonScope();
|
||||||
container.bind<Command>(TYPES.Command).to(Play).inSingletonScope();
|
container.bind<Command>(TYPES.Command).to(Play).inSingletonScope();
|
||||||
container.bind<Command>(TYPES.Command).to(QueueCommad).inSingletonScope();
|
container.bind<Command>(TYPES.Command).to(QueueCommad).inSingletonScope();
|
||||||
container.bind<Command>(TYPES.Command).to(Seek).inSingletonScope();
|
container.bind<Command>(TYPES.Command).to(Seek).inSingletonScope();
|
||||||
|
container.bind<Command>(TYPES.Command).to(Shortcuts).inSingletonScope();
|
||||||
container.bind<Command>(TYPES.Command).to(Shuffle).inSingletonScope();
|
container.bind<Command>(TYPES.Command).to(Shuffle).inSingletonScope();
|
||||||
container.bind<Command>(TYPES.Command).to(Skip).inSingletonScope();
|
container.bind<Command>(TYPES.Command).to(Skip).inSingletonScope();
|
||||||
container.bind<Command>(TYPES.Command).to(Unskip).inSingletonScope();
|
container.bind<Command>(TYPES.Command).to(Unskip).inSingletonScope();
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import Settings from './settings';
|
import Settings from './settings';
|
||||||
|
import Shortcut from './shortcut';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Settings
|
Settings,
|
||||||
|
Shortcut
|
||||||
};
|
};
|
||||||
|
|
23
src/models/shortcut.ts
Normal file
23
src/models/shortcut.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import {Table, Column, PrimaryKey, Model, AutoIncrement, Index} from 'sequelize-typescript';
|
||||||
|
|
||||||
|
@Table
|
||||||
|
export default class Shortcut extends Model<Shortcut> {
|
||||||
|
@PrimaryKey
|
||||||
|
@AutoIncrement
|
||||||
|
@Column
|
||||||
|
id!: number;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Index
|
||||||
|
guildId!: string;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
authorId!: string;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Index
|
||||||
|
shortcut!: string;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
command!: string;
|
||||||
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
import {Sequelize} from 'sequelize-typescript';
|
import {Sequelize} from 'sequelize-typescript';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import {DATA_DIR} from '../utils/config';
|
import {DATA_DIR} from '../utils/config';
|
||||||
import {Settings} from '../models';
|
import {Settings, Shortcut} from '../models';
|
||||||
|
|
||||||
export const sequelize = new Sequelize({
|
export const sequelize = new Sequelize({
|
||||||
dialect: 'sqlite',
|
dialect: 'sqlite',
|
||||||
database: 'muse',
|
database: 'muse',
|
||||||
storage: path.join(DATA_DIR, 'db.sqlite'),
|
storage: path.join(DATA_DIR, 'db.sqlite'),
|
||||||
models: [Settings]
|
models: [Settings, Shortcut]
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue