mirror of
https://github.com/BluemediaDev/muse.git
synced 2025-05-08 11:21:37 +02:00
Inital commit
This commit is contained in:
parent
afadcb9ee5
commit
eca84c8b69
14 changed files with 2884 additions and 0 deletions
24
src/commands/config.ts
Normal file
24
src/commands/config.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
import {CommandHandler} from '../interfaces';
|
||||
|
||||
const config: CommandHandler = {
|
||||
name: 'config',
|
||||
description: 'Change various bot settings.',
|
||||
execute: (msg, args) => {
|
||||
const setting = args[0];
|
||||
|
||||
switch (setting) {
|
||||
case 'prefix':
|
||||
msg.channel.send('Prefix set');
|
||||
break;
|
||||
|
||||
case 'channel':
|
||||
msg.channel.send('Channel bound');
|
||||
break;
|
||||
|
||||
default:
|
||||
msg.channel.send('Unknown setting');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default config;
|
73
src/events/guild-create.ts
Normal file
73
src/events/guild-create.ts
Normal file
|
@ -0,0 +1,73 @@
|
|||
import {Guild, MessageReaction, TextChannel} from 'discord.js';
|
||||
import emoji from 'node-emoji';
|
||||
import {Settings} from '../models';
|
||||
|
||||
const DEFAULT_PREFIX = '!';
|
||||
|
||||
export default async (guild: Guild): Promise<void> => {
|
||||
await Settings.upsert({guildId: guild.id, prefix: DEFAULT_PREFIX});
|
||||
|
||||
const owner = await guild.client.users.fetch(guild.ownerID);
|
||||
|
||||
let firstStep = '👋 Hi!\n';
|
||||
firstStep += 'I just need to ask a few questions before you start listening to music.\n\n';
|
||||
firstStep += 'First, what channel should I listen to for music commands?\n\n';
|
||||
|
||||
interface EmojiChannel {
|
||||
name: string;
|
||||
id: string;
|
||||
emoji: string;
|
||||
}
|
||||
|
||||
const emojiChannels: EmojiChannel[] = [];
|
||||
|
||||
for (const [channelId, channel] of guild.channels.cache) {
|
||||
if (channel.type === 'text') {
|
||||
emojiChannels.push({
|
||||
name: channel.name,
|
||||
id: channelId,
|
||||
emoji: emoji.random().emoji
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for (const channel of emojiChannels) {
|
||||
firstStep += `${channel.emoji}: #${channel.name}\n`;
|
||||
}
|
||||
|
||||
firstStep += '\n';
|
||||
|
||||
// Send message
|
||||
const msg = await owner.send(firstStep);
|
||||
|
||||
// Add reactions
|
||||
for await (const channel of emojiChannels) {
|
||||
await msg.react(channel.emoji);
|
||||
}
|
||||
|
||||
const reactions = await msg.awaitReactions((reaction, user) => user.id !== msg.author.id && emojiChannels.map(e => e.emoji).includes(reaction.emoji.name), {max: 1});
|
||||
|
||||
const choice = reactions.first() as MessageReaction;
|
||||
|
||||
const chosenChannel = emojiChannels.find(e => e.emoji === choice.emoji.name) as EmojiChannel;
|
||||
|
||||
// Second setup step (get prefix)
|
||||
let secondStep = `👍 Cool, I'll listen to **#${chosenChannel.name}** \n\n`;
|
||||
secondStep += 'Last question: what character should I use for a prefix? Type a single character and hit enter.';
|
||||
|
||||
await owner.send(secondStep);
|
||||
|
||||
const prefixResponses = await msg.channel.awaitMessages(r => r.content.length === 1, {max: 1});
|
||||
|
||||
const prefixCharacter = prefixResponses.first()!.content;
|
||||
|
||||
// Save settings
|
||||
await Settings.update({prefix: prefixCharacter, channel: chosenChannel.id}, {where: {guildId: guild.id}});
|
||||
|
||||
// Send welcome
|
||||
const boundChannel = guild.client.channels.cache.get(chosenChannel.id) as TextChannel;
|
||||
|
||||
await boundChannel.send(`hey <@${owner.id}> try \`${prefixCharacter}play https://www.youtube.com/watch?v=dQw4w9WgXcQ\``);
|
||||
|
||||
await msg.channel.send(`Sounds good. Check out **#${chosenChannel.name}** to get started.`);
|
||||
};
|
58
src/index.ts
Normal file
58
src/index.ts
Normal file
|
@ -0,0 +1,58 @@
|
|||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import makeDir from 'make-dir';
|
||||
import Discord from 'discord.js';
|
||||
import {DISCORD_TOKEN, DISCORD_CLIENT_ID, DATA_DIR} from './utils/config';
|
||||
import {sequelize} from './utils/db';
|
||||
import {CommandHandler} from './interfaces';
|
||||
import handleGuildCreate from './events/guild-create';
|
||||
|
||||
const PREFIX = '!';
|
||||
|
||||
const client = new Discord.Client();
|
||||
const commands = new Discord.Collection();
|
||||
|
||||
// Load in commands
|
||||
const commandFiles = fs.readdirSync(path.join(__dirname, 'commands')).filter(file => file.endsWith('.js'));
|
||||
|
||||
for (const file of commandFiles) {
|
||||
const command = require(`./commands/${file}`).default;
|
||||
|
||||
commands.set(command.name, command);
|
||||
}
|
||||
|
||||
// Generic message handler
|
||||
client.on('message', (msg: Discord.Message) => {
|
||||
if (!msg.content.startsWith(PREFIX) || msg.author.bot) {
|
||||
return;
|
||||
}
|
||||
|
||||
const args = msg.content.slice(PREFIX.length).split(/ +/);
|
||||
const command = args.shift()!.toLowerCase();
|
||||
|
||||
if (!commands.has(command)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const handler = commands.get(command) as CommandHandler;
|
||||
|
||||
handler.execute(msg, args);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
msg.reply('there was an error trying to execute that command!');
|
||||
}
|
||||
});
|
||||
|
||||
client.on('ready', async () => {
|
||||
// Create directory if necessary
|
||||
await makeDir(DATA_DIR);
|
||||
|
||||
await sequelize.sync({});
|
||||
|
||||
console.log(`Ready! Invite the bot with https://discordapp.com/oauth2/authorize?client_id=${DISCORD_CLIENT_ID}&scope=bot`);
|
||||
});
|
||||
|
||||
client.on('guildCreate', handleGuildCreate);
|
||||
|
||||
client.login(DISCORD_TOKEN);
|
7
src/interfaces.ts
Normal file
7
src/interfaces.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import Discord from 'discord.js';
|
||||
|
||||
export interface CommandHandler {
|
||||
name: string;
|
||||
description: string;
|
||||
execute: (msg: Discord.Message, args: string[]) => void;
|
||||
}
|
5
src/models/index.ts
Normal file
5
src/models/index.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
import Settings from './settings';
|
||||
|
||||
export {
|
||||
Settings
|
||||
};
|
18
src/models/settings.ts
Normal file
18
src/models/settings.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
import {Table, Column, PrimaryKey, Model, Default} from 'sequelize-typescript';
|
||||
|
||||
@Table
|
||||
export default class Settings extends Model<Settings> {
|
||||
@PrimaryKey
|
||||
@Column
|
||||
guildId!: string;
|
||||
|
||||
@Column
|
||||
prefix!: string;
|
||||
|
||||
@Column
|
||||
channel!: string;
|
||||
|
||||
@Default(false)
|
||||
@Column
|
||||
finishedSetup!: boolean;
|
||||
}
|
1
src/packages.d.ts
vendored
Normal file
1
src/packages.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
declare module 'node-emoji';
|
7
src/utils/config.ts
Normal file
7
src/utils/config.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import dotenv from 'dotenv';
|
||||
import path from 'path';
|
||||
dotenv.config();
|
||||
|
||||
export const DISCORD_TOKEN: string = process.env.DISCORD_TOKEN ? process.env.DISCORD_TOKEN : '';
|
||||
export const DISCORD_CLIENT_ID: string = process.env.DISCORD_CLIENT_ID ? process.env.DISCORD_CLIENT_ID : '';
|
||||
export const DATA_DIR = path.resolve(process.env.DATA_DIR ? process.env.DATA_DIR : './data');
|
11
src/utils/db.ts
Normal file
11
src/utils/db.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import {Sequelize} from 'sequelize-typescript';
|
||||
import path from 'path';
|
||||
import {DATA_DIR} from '../utils/config';
|
||||
import {Settings} from '../models';
|
||||
|
||||
export const sequelize = new Sequelize({
|
||||
dialect: 'sqlite',
|
||||
database: 'muse',
|
||||
storage: path.join(DATA_DIR, 'db.sqlite'),
|
||||
models: [Settings]
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue