/[sudobot]/branches/4.x/setup.js
ViewVC logotype

Contents of /branches/4.x/setup.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 577 - (show annotations)
Mon Jul 29 18:52:37 2024 UTC (8 months ago) by rakinar2
File MIME type: text/javascript
File size: 7193 byte(s)
chore: add old version archive branches (2.x to 9.x-dev)
1 #!/bin/node
2
3 /**
4 * setup.js -- the installer script
5 *
6 * This file is part of SudoBot.
7 *
8 * Copyright (C) 2021-2022 OSN Inc.
9 *
10 * SudoBot is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Affero General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * SudoBot is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Affero General Public License for more details.
19 *
20 * You should have received a copy of the GNU Affero General Public License
21 * along with SudoBot. If not, see <https://www.gnu.org/licenses/>.
22 */
23
24 const path = require('path');
25 const fs = require('fs/promises');
26 const readline = require('readline');
27 const bcrypt = require('bcrypt');
28
29 const CONFIG_DIR = path.resolve(__dirname, 'config');
30 const { version } = require('./package.json');
31 const { existsSync } = require('fs');
32 const SAMPLE_CONFIG_PATH = path.resolve(CONFIG_DIR, 'sample-config.json');
33 const CONFIG_PATH = path.resolve(CONFIG_DIR, 'config.json');
34
35 const isSnowflake = text => /^\d+$/.test(text);
36
37 const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
38
39 const prompt = text => new Promise(resolve => {
40 rl.question(text, resolve);
41 });
42
43 const promptDefault = async (text, defaultValue) => {
44 const input = await prompt(text);
45
46 if (input.toString().trim() === '') {
47 return defaultValue;
48 }
49
50 return input;
51 };
52
53 const promptLoop = async (text, validator, defaultValue) => {
54 let fn = promptDefault;
55
56 if (defaultValue === undefined) {
57 fn = prompt;
58 }
59
60 const input = await fn(text, defaultValue);
61
62 if (!(await validator(input ?? ''))) {
63 return promptLoop(text, validator, defaultValue);
64 }
65
66 return input ?? '';
67 };
68
69 const snowflakeValidator = input => {
70 if (!isSnowflake(input)) {
71 console.log(`That's not a valid snowflake! Please enter a valid ID.`);
72 return false;
73 }
74
75 return true;
76 };
77
78 (async () => {
79 console.log(`SudoBot version ${version}`);
80 console.log(`Copyright (C) OSN Inc 2022`);
81 console.log(`Thanks for using SudoBot! We'll much appreciate if you star the repository on GitHub.\n`);
82
83 let prefix = '-', homeGuild = '', owners = [];
84 let config = Object.entries(JSON.parse((await fs.readFile(SAMPLE_CONFIG_PATH)).toString()));
85
86 config[1][1].prefix = (await promptLoop(`What will be the bot prefix? [${prefix}]: `, input => {
87 if (input.trim().includes(' ')) {
88 console.log(`Prefixes must not contain spaces!`);
89 return false;
90 }
91
92 return true;
93 }, "-")).trim();
94
95 homeGuild = await promptLoop(`What will be the Home/Support Guild ID?: `, snowflakeValidator);
96 config[1][0] = homeGuild;
97
98 config = Object.fromEntries(config);
99
100 config.global.id = homeGuild;
101 config.global.owners = (await promptLoop(`Who will be the owner? Specify the owner user IDs separated with comma (,): `, input => {
102 const splitted = input.split(',');
103
104 for (const snowflake of splitted) {
105 if (!snowflakeValidator(snowflake)) {
106 console.log(`Invalid snowflake given! Make sure that the IDs are correctly given!`);
107 return false;
108 }
109 }
110
111 return true;
112 })).split(',').map(s => s.trim());
113
114 // config[1][0] = homeGuild;
115 // config[1][1].prefix = prefix;
116
117 // config.global.owners = owners;
118
119 const guildConfig = {...config[homeGuild]};
120
121 guildConfig.mod_role = await promptLoop(`What will be the moderator role ID?: `, snowflakeValidator);
122 guildConfig.admin = await promptLoop(`What will be the safe role ID?: `, snowflakeValidator);
123 guildConfig.mute_role = await promptLoop(`What will be the muted role ID?: `, snowflakeValidator);
124 guildConfig.gen_role = await promptLoop(`What will be the general role ID? [${homeGuild}]: `, snowflakeValidator, homeGuild);
125 guildConfig.logging_channel = await promptLoop(`What will be the main logging channel ID?: `, snowflakeValidator);
126 guildConfig.logging_channel_join_leave = await promptLoop(`What will be the join/leave logging channel ID?: `, snowflakeValidator);
127
128 config[homeGuild] = guildConfig;
129
130 console.log(config);
131
132 if (existsSync(CONFIG_PATH)) {
133 const input = await promptDefault("The config file (config/config.json) already exists. Do you want to overwrite the file? [y/N]: ", "n");
134
135 if (input.trim().toLowerCase() !== "y" && input.trim().toLowerCase() !== "yes") {
136 console.log("Aborting setup.");
137 rl.close();
138 process.exit(1);
139 }
140 }
141
142 if (existsSync(CONFIG_PATH))
143 await fs.rename(CONFIG_PATH, path.join(CONFIG_DIR, 'config-old-' + Math.round(Math.random() * 100000) + '.json'));
144
145 await fs.writeFile(CONFIG_PATH, JSON.stringify(config, undefined, ' '));
146
147 console.log("Config File Created!");
148 console.table([
149 {
150 prefix,
151 homeGuild
152 }
153 ]);
154
155 if (!existsSync(path.join(__dirname, ".env"))) {
156 const input = (await promptDefault("Generate a `.env' file? [y/N]: ", "n")).toLowerCase();
157
158 if (input !== 'yes' && input !== 'y') {
159 return;
160 }
161
162 const token = await promptLoop("What's your bot token? ", input => {
163 if (input.trim() !== '' && input.indexOf(' ') === -1) {
164 return true;
165 }
166
167 console.log("That's not a valid token.");
168 return false;
169 });
170
171 const clientID = await promptLoop("What's your bot's client ID? ", snowflakeValidator);
172
173 const mongoURI = await promptLoop("Enter the MongoDB URI for the bot to connect: ", input => {
174 if (input.trim() !== '' && input.indexOf(' ') === -1) {
175 return true;
176 }
177
178 console.log("That's not a valid MongoDB URI.");
179 return false;
180 });
181
182 const jwtSecret = (await promptLoop("Enter a JWT secret key (hit enter to generate automatically): ", input => {
183 if (input.trim() !== '') {
184 return true;
185 }
186
187 console.log("That's not a valid secret.");
188 return false;
189 }, null)) ?? bcrypt.hashSync(Math.random() + '', bcrypt.genSaltSync());
190
191 const webhook = await promptLoop("Enter a webhook URL for sending debug logs: ", input => {
192 if (input.trim() !== '' && input.indexOf(' ') === -1) {
193 return true;
194 }
195
196 console.log("That's not a valid webhook URL.");
197 return false;
198 });
199
200 await fs.writeFile(path.join(__dirname, ".env"), `# Environment Configuration
201
202 TOKEN=${token}
203 ENV=dev
204 CLIENT_ID=${clientID}
205 GUILD_ID=${homeGuild}
206 MONGO_URI=${mongoURI}
207 JWT_SECRET=${jwtSecret}
208 DEBUG_WEBHOOK_URL=${webhook}
209 `);
210
211 console.log("`.env` file generated successfully!");
212 }
213
214 rl.close();
215 })().catch(console.error);

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26