· 7 years ago · Dec 10, 2018, 07:40 PM
1const Discord = require('discord.js');
2const client = new Discord.Client();
3const sqlite = require('sqlite');
4const database = sqlite.open('./requests.sqlite');
5
6let guild;
7
8const BOT_TOKEN = '';
9
10const CHANNELS = {
11 GUILD_ID: '',
12 REQUEST_CHANNEL: '',
13 CATEGORY_OPEN_REQUESTS: '',
14 CATEGORY_ONGOING_REQUESTS: '',
15};
16
17// Save numbers as TEXT (javascript doesn't understand numbers as big as discord IDs).
18database.then(realDB => {
19 realDB.run(
20 `CREATE TABLE IF NOT EXISTS admin_requests (
21 channelID TEXT,
22 requester TEXT,
23 requesterID TEXT,
24 admin TEXT,
25 adminID TEXT,
26 timestampUnix INTEGER,
27 state TEXT
28 )
29 `);
30});
31
32// the ready event is vital, it means that your bot will only start reacting to information
33// from Discord _after_ ready is emitted.
34client.on('ready', () => {
35
36 guild = client.guilds.get(CHANNELS.GUILD_ID);
37
38 console.log('I am ready!');
39});
40
41client.on('message', async message => {
42
43 const { author, member, content, channel } = message;
44
45 // Handle messages typed in an Open Request channel.
46 if (channel.parent &&
47 channel.parent.id === CHANNELS.CATEGORY_OPEN_REQUESTS) {
48
49 const adminRole = member.roles.find(role => role.name === 'admin');
50
51 if (!adminRole) return; // Means the user doesn't belong to the admin group.
52
53 // The request is now ongoing and has a dedicated admin.
54 const realDB = await database;
55 await realDB.run(`
56 UPDATE admin_requests SET (
57 state,
58 adminID,
59 admin
60 ) = (?, ?, ?)
61 `, [
62 'ongoing',
63 author.id,
64 author.username,
65 ]
66 );
67
68 // Move it to the Ongoing Requests category.
69 await channel.setParent(CHANNELS.CATEGORY_ONGOING_REQUESTS);
70 }
71
72 // Handle messages typed in an Ongoing Request channel.
73 if (channel.parent &&
74 channel.parent.id === CHANNELS.CATEGORY_ONGOING_REQUESTS) {
75
76 if (content.startsWith('!close')) {
77
78 const realDB = await database;
79 await realDB.run(`
80 UPDATE admin_requests SET
81 state = 'closed'
82 WHERE channelID = ${channel.id}
83 `);
84
85 await channel.delete();
86 }
87 }
88
89 // Handle messages typed in the Requests channel.
90 if (channel.id === CHANNELS.REQUEST_CHANNEL) {
91 handleAdminRequest(message);
92 }
93
94});
95
96const handleAdminRequest = async message => {
97 const { author } = message;
98
99 const permissions = [
100 {
101 // Deny @everyone by default.
102 id: guild.roles.find(item => item.name === '@everyone'),
103 denied: [
104 'MANAGE_CHANNELS',
105 'READ_MESSAGES',
106 ]
107 },
108 {
109 // Allow admins.
110 id: guild.roles.find(item => item.name === 'admin'),
111 allowed: [
112 'READ_MESSAGES',
113 ]
114 },
115 {
116 // Allow the requester.
117 id: author,
118 allowed: [
119 'READ_MESSAGES',
120 ]
121 }
122 ];
123
124 const requestChannel = await guild.createChannel(
125 author.username,
126 'text',
127 permissions,
128 );
129
130 // Move it to the Open Requests category.
131 await requestChannel.setParent(CHANNELS.CATEGORY_OPEN_REQUESTS);
132
133 await requestChannel.send(`
134 Hello, ${author.toString()}, once an admin is free he\'ll respond to your request in this channel.
135 The reason for this request was: **${message.content}**.
136 Please provide additional info while you are waiting, they will see all messages written in here.
137 `);
138
139 const realDB = await database;
140 await realDB.run(
141 `INSERT INTO admin_requests (
142 channelID,
143 requester,
144 requesterID,
145 timestampUnix,
146 state
147 ) VALUES (?, ?, ?, ?, ?)`,
148 [
149 requestChannel.id,
150 author.username,
151 author.id,
152 new Date(),
153 'open'
154 ]
155 );
156
157 await message.delete();
158}
159
160client.on('disconnect', message => {
161 // There was an issue with the bot silently disconnecting randomly, this should be fixed. Keeping code as fallback for now
162 // https://github.com/hydrabolt/discord.js/issues/1233
163
164 console.log(message);
165 client.destroy().then(() => client.login());
166});
167
168client.login(BOT_TOKEN);