Compare commits
No commits in common. "master" and "v0.1.0" have entirely different histories.
7 changed files with 14 additions and 161 deletions
11
CHANGELOG.md
11
CHANGELOG.md
|
|
@ -1,11 +0,0 @@
|
||||||
|
|
||||||
## 0.2.0
|
|
||||||
|
|
||||||
- Moved all configuration to `config/config.toml`, contains:
|
|
||||||
+ join gate
|
|
||||||
+ guild aliases
|
|
||||||
- Now you can see what guilds is your bot in
|
|
||||||
|
|
||||||
## 0.1.0
|
|
||||||
|
|
||||||
- Initial commit
|
|
||||||
11
package-lock.json
generated
11
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "csinsol",
|
"name": "csinsol",
|
||||||
"version": "0.2.0",
|
"version": "0.1.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "csinsol",
|
"name": "csinsol",
|
||||||
"version": "0.2.0",
|
"version": "0.1.0",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": "^24.3.0",
|
"@types/node": "^24.3.0",
|
||||||
|
|
@ -14,7 +14,6 @@
|
||||||
"discord.js": "^14.21.0",
|
"discord.js": "^14.21.0",
|
||||||
"dotenv": "^17.2.1",
|
"dotenv": "^17.2.1",
|
||||||
"luxon": "^3.7.1",
|
"luxon": "^3.7.1",
|
||||||
"toml": "^3.0.0",
|
|
||||||
"tsx": "^4.20.4"
|
"tsx": "^4.20.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -791,12 +790,6 @@
|
||||||
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
|
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/toml": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/ts-mixer": {
|
"node_modules/ts-mixer": {
|
||||||
"version": "6.0.4",
|
"version": "6.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "csinsol",
|
"name": "csinsol",
|
||||||
"version": "0.2.0",
|
"version": "0.1.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"author": "Sakuragasaki46",
|
"author": "Sakuragasaki46",
|
||||||
|
|
@ -17,7 +17,6 @@
|
||||||
"discord.js": "^14.21.0",
|
"discord.js": "^14.21.0",
|
||||||
"dotenv": "^17.2.1",
|
"dotenv": "^17.2.1",
|
||||||
"luxon": "^3.7.1",
|
"luxon": "^3.7.1",
|
||||||
"toml": "^3.0.0",
|
|
||||||
"tsx": "^4.20.4"
|
"tsx": "^4.20.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
85
src/bot.ts
85
src/bot.ts
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
|
|
||||||
import { ChatInputCommandInteraction, Events, GatewayIntentBits, Guild, GuildMember, Interaction } from 'discord.js';
|
import { ChatInputCommandInteraction, Events, GatewayIntentBits, GuildMember, Interaction } from 'discord.js';
|
||||||
import { MyClient } from './client';
|
import { MyClient } from './client';
|
||||||
import commands from './commands';
|
import commands from './commands';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
|
|
@ -13,8 +13,6 @@ for (let command of commands) {
|
||||||
client.addCommand(command);
|
client.addCommand(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
const guildDetail = !!process.env.GUILD_DETAIL_SHOW;
|
|
||||||
|
|
||||||
client.on(Events.InteractionCreate, async (interaction: Interaction) => {
|
client.on(Events.InteractionCreate, async (interaction: Interaction) => {
|
||||||
if (interaction instanceof ChatInputCommandInteraction) {
|
if (interaction instanceof ChatInputCommandInteraction) {
|
||||||
const { commandName } = interaction;
|
const { commandName } = interaction;
|
||||||
|
|
@ -42,75 +40,16 @@ client.on(Events.GuildMemberAdd, async (member: GuildMember) => {
|
||||||
const { joinedAt } = member;
|
const { joinedAt } = member;
|
||||||
if (joinedAt === null) return;
|
if (joinedAt === null) return;
|
||||||
|
|
||||||
const rules = client.config.getRules(member.guild.id) || [];
|
|
||||||
const hours = (joinedAt.getUTCHours() * 60 + joinedAt.getUTCMinutes() + 120) % 1440;
|
const hours = (joinedAt.getUTCHours() * 60 + joinedAt.getUTCMinutes() + 120) % 1440;
|
||||||
const age = Math.floor((joinedAt.getTime() - createdAt.getTime()) / 10800);
|
if (hours < 540) {
|
||||||
const ops: Record<string, (x: number) => boolean> = {
|
console.info(`Member: ${chalk.green(member.user.id)} ${chalk.grey(`(@${member.user.username})`)} kicked: Join at night not allowed`);
|
||||||
"age <": x => age < x,
|
await member.kick();
|
||||||
"age >=": x => age >= x,
|
return;
|
||||||
"now <": x => hours < x,
|
}
|
||||||
"now >=": x => hours >= x
|
if (joinedAt.getTime() - createdAt.getTime() < 10800000) {
|
||||||
};
|
console.info(`Member: ${chalk.green(member.user.id)} ${chalk.grey(`(@${member.user.username})`)} kicked: Account too young`);
|
||||||
for (let rule of rules.filter(x => x.type === 'join')) {
|
await member.kick();
|
||||||
let { action, where, message = void 0, private_message = null } = rule;
|
return;
|
||||||
let privMessage = private_message || message;
|
|
||||||
|
|
||||||
let result: boolean;
|
|
||||||
try {
|
|
||||||
let matches = where.match(/^([a-z]+) *([<=>]+) *([0-9]+) *$/);
|
|
||||||
if (!matches) continue;
|
|
||||||
let op = `${matches[1]} ${matches[2]}`;
|
|
||||||
let opf = ops[op];
|
|
||||||
if (!opf) continue;
|
|
||||||
let rval = parseInt(matches[3]);
|
|
||||||
result = opf(rval);
|
|
||||||
} catch(ex) {
|
|
||||||
console.warn(`malformed rule skipped: '${rule}'`)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result) {
|
|
||||||
const actionMessage = ({
|
|
||||||
kick: 'kicked', ban:'banned',
|
|
||||||
'24h': 'muted for 24 hours', '3d': 'muted for 3 days','7d': 'muted for 7 days',
|
|
||||||
})[action];
|
|
||||||
|
|
||||||
// apply the rule
|
|
||||||
if (message) try {
|
|
||||||
// try messaging the user
|
|
||||||
|
|
||||||
await member.user.send({
|
|
||||||
content: `Sei statə espulsə da **${member.guild.name}**: ${message}`
|
|
||||||
});
|
|
||||||
} catch(ex) { }
|
|
||||||
|
|
||||||
try {
|
|
||||||
switch(action) {
|
|
||||||
case 'kick':
|
|
||||||
await member.kick(message);
|
|
||||||
break;
|
|
||||||
case 'ban':
|
|
||||||
await member.ban({ reason: message, deleteMessageSeconds: 0 });
|
|
||||||
break;
|
|
||||||
case '24h':
|
|
||||||
await member.timeout(24 * 3600000, message);
|
|
||||||
break;
|
|
||||||
case '3d':
|
|
||||||
await member.timeout(3 * 24 * 3600000, message);
|
|
||||||
break;
|
|
||||||
case '7d':
|
|
||||||
await member.timeout(7 * 24 * 3600000, message);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.warn(`unknown action: ${action}`);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.info(`Member: ${chalk.green(member.user.id)} ${chalk.grey(`(@${member.user.username})`)} ${actionMessage}: ${privMessage}`);
|
|
||||||
} catch (ex) {
|
|
||||||
console.error(chalk.red(`Member: ${chalk.white(member.user.id)} ${chalk.grey(`(@${member.user.username})`)} not ${actionMessage}: ${ex}\x1b[0m`));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.info(`Member: ${chalk.green(member.user.id)} ${chalk.grey(`(@${member.user.username})`)} accepted`);
|
console.info(`Member: ${chalk.green(member.user.id)} ${chalk.grey(`(@${member.user.username})`)} accepted`);
|
||||||
|
|
@ -119,9 +58,5 @@ client.on(Events.GuildMemberAdd, async (member: GuildMember) => {
|
||||||
|
|
||||||
client.once(Events.ClientReady, (c) => {
|
client.once(Events.ClientReady, (c) => {
|
||||||
console.log(`Logged in as ${c.user.tag}`);
|
console.log(`Logged in as ${c.user.tag}`);
|
||||||
console.log(`Currently in ${chalk.bold(c.guilds.cache.size)} guilds` + (guildDetail? ':' : `; rerun with GUILD_DETAIL_SHOW=1 for details`));
|
|
||||||
if (guildDetail) {
|
|
||||||
console.log(c.guilds.cache.map((x: Guild) => `* ${chalk.bold(x.name)} ${chalk.grey('(ID: ')}${chalk.green(x.id)}${chalk.grey(`, ${x.memberCount} members)`)}`).join('\n'));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,17 @@
|
||||||
import { Client, ClientOptions, Collection } from "discord.js";
|
import { Client, ClientOptions, Collection } from "discord.js";
|
||||||
import { CommandInfo } from "./commands";
|
import { CommandInfo } from "./commands";
|
||||||
import { ConfigFile } from "./configFile";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export class MyClient extends Client {
|
export class MyClient extends Client {
|
||||||
commands: Collection<string, CommandInfo>;
|
commands: Collection<string, CommandInfo>;
|
||||||
config: ConfigFile;
|
|
||||||
|
|
||||||
constructor (opts: ClientOptions) {
|
constructor (opts: ClientOptions) {
|
||||||
super(opts);
|
super(opts);
|
||||||
this.commands = new Collection();
|
this.commands = new Collection();
|
||||||
this.config = new ConfigFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
override async login(token?: string): Promise<string> {
|
|
||||||
await this.config.load();
|
|
||||||
return super.login(token);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addCommand (command: CommandInfo) {
|
addCommand (command: CommandInfo) {
|
||||||
this.commands.set(command.data.name, command);
|
this.commands.set(command.data.name, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -7,7 +7,7 @@ const nodejsVersion = process.versions.node;
|
||||||
|
|
||||||
const data = new SlashCommandBuilder()
|
const data = new SlashCommandBuilder()
|
||||||
.setName('version')
|
.setName('version')
|
||||||
.setDescription('Informazioni sul bot');
|
.setDescription('Informaz. sul bot');
|
||||||
|
|
||||||
async function execute (interaction: ChatInputCommandInteraction) {
|
async function execute (interaction: ChatInputCommandInteraction) {
|
||||||
await interaction.deferReply();
|
await interaction.deferReply();
|
||||||
|
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
|
|
||||||
import fs from "node:fs/promises";
|
|
||||||
import toml from "toml";
|
|
||||||
|
|
||||||
type ConfigGuildRule = {
|
|
||||||
type: "join",
|
|
||||||
action: "kick" | "ban" | "24h" | "3d" | "7d",
|
|
||||||
where: string,
|
|
||||||
message?: string,
|
|
||||||
private_message?: string
|
|
||||||
};
|
|
||||||
|
|
||||||
export class ConfigFile{
|
|
||||||
guilds?: {
|
|
||||||
aliases?: Record<string, string>,
|
|
||||||
rules?: Record<string, ConfigGuildRule[]>
|
|
||||||
}
|
|
||||||
globals?: {
|
|
||||||
timezone?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
async load () {
|
|
||||||
let content = await fs.readFile("config/config.toml", "utf-8");
|
|
||||||
|
|
||||||
let data = toml.parse(content);
|
|
||||||
|
|
||||||
this.globals = data.globals;
|
|
||||||
this.guilds = data.guilds;
|
|
||||||
}
|
|
||||||
|
|
||||||
getRules (guildId: string) : ConfigGuildRule[] | null {
|
|
||||||
if(!this?.guilds?.rules) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let aliases = this?.guilds?.aliases || {};
|
|
||||||
for(let key in this.guilds.rules) {
|
|
||||||
if (key.startsWith('@')) {
|
|
||||||
key = aliases[key.slice(1)];
|
|
||||||
if (!key) continue;
|
|
||||||
}
|
|
||||||
if (key === guildId) {
|
|
||||||
return this.guilds.rules[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue