Compare commits
No commits in common. "master" and "v0.3.0" have entirely different histories.
22 changed files with 300 additions and 1302 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -24,4 +24,4 @@ dist/
|
||||||
.err
|
.err
|
||||||
.vscode
|
.vscode
|
||||||
/run.sh
|
/run.sh
|
||||||
|
drizzle
|
||||||
|
|
|
||||||
14
CHANGELOG.md
14
CHANGELOG.md
|
|
@ -1,19 +1,5 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## 0.4.0 (TBA)
|
|
||||||
|
|
||||||
* Switched database to PostgreSQL
|
|
||||||
* Added `/userinfo` command and balance
|
|
||||||
|
|
||||||
## 0.3.2 (February 20, 2026)
|
|
||||||
|
|
||||||
* Fixed `/wiki` loading non-existent pages.
|
|
||||||
* Added [Wikicord](https://wikicord.wikioasis.org/) and [Italian Mapping Wiki](https://it.mappingwiki.org/) as sources for `/wiki`.
|
|
||||||
|
|
||||||
## 0.3.1 (February 20, 2026)
|
|
||||||
|
|
||||||
* Updated package-lock.json
|
|
||||||
|
|
||||||
## 0.3.0 (February 20, 2026)
|
## 0.3.0 (February 20, 2026)
|
||||||
|
|
||||||
* Now the bot may show list of server the bot is in at startup, given the flag `GUILD_DETAIL_SHOW=1` in env.
|
* Now the bot may show list of server the bot is in at startup, given the flag `GUILD_DETAIL_SHOW=1` in env.
|
||||||
|
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
import { configDotenv } from "dotenv";
|
|
||||||
|
|
||||||
configDotenv();
|
|
||||||
|
|
||||||
import { defineConfig } from "drizzle-kit";
|
|
||||||
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
dialect: 'postgresql',
|
|
||||||
schema: './src/db/schema.ts',
|
|
||||||
dbCredentials: {
|
|
||||||
url: process.env.DATABASE_URL!
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
CREATE TABLE "balances" (
|
|
||||||
"userId" integer,
|
|
||||||
"guildId" integer,
|
|
||||||
"balance" bigint DEFAULT 0::bigint,
|
|
||||||
"lastMessageHour" integer,
|
|
||||||
CONSTRAINT "balances_userId_guildId_pk" PRIMARY KEY("userId","guildId")
|
|
||||||
);
|
|
||||||
--> statement-breakpoint
|
|
||||||
CREATE TABLE "guilds" (
|
|
||||||
"id" serial PRIMARY KEY NOT NULL,
|
|
||||||
"discordId" bigint,
|
|
||||||
"displayName" varchar(80),
|
|
||||||
CONSTRAINT "guilds_discordId_unique" UNIQUE("discordId")
|
|
||||||
);
|
|
||||||
--> statement-breakpoint
|
|
||||||
CREATE TABLE "users" (
|
|
||||||
"id" serial PRIMARY KEY NOT NULL,
|
|
||||||
"discordId" bigint,
|
|
||||||
"username" varchar(34),
|
|
||||||
"displayName" varchar(64),
|
|
||||||
"reputation" smallint DEFAULT 0,
|
|
||||||
CONSTRAINT "users_discordId_unique" UNIQUE("discordId")
|
|
||||||
);
|
|
||||||
--> statement-breakpoint
|
|
||||||
ALTER TABLE "balances" ADD CONSTRAINT "balances_userId_users_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
||||||
ALTER TABLE "balances" ADD CONSTRAINT "balances_guildId_guilds_id_fk" FOREIGN KEY ("guildId") REFERENCES "public"."guilds"("id") ON DELETE no action ON UPDATE no action;
|
|
||||||
|
|
@ -1,183 +0,0 @@
|
||||||
{
|
|
||||||
"id": "4602e85b-a3cf-4168-881e-a95e9316f325",
|
|
||||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
|
||||||
"version": "7",
|
|
||||||
"dialect": "postgresql",
|
|
||||||
"tables": {
|
|
||||||
"public.balances": {
|
|
||||||
"name": "balances",
|
|
||||||
"schema": "",
|
|
||||||
"columns": {
|
|
||||||
"userId": {
|
|
||||||
"name": "userId",
|
|
||||||
"type": "integer",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"guildId": {
|
|
||||||
"name": "guildId",
|
|
||||||
"type": "integer",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"balance": {
|
|
||||||
"name": "balance",
|
|
||||||
"type": "bigint",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false,
|
|
||||||
"default": "0::bigint"
|
|
||||||
},
|
|
||||||
"lastMessageHour": {
|
|
||||||
"name": "lastMessageHour",
|
|
||||||
"type": "integer",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {},
|
|
||||||
"foreignKeys": {
|
|
||||||
"balances_userId_users_id_fk": {
|
|
||||||
"name": "balances_userId_users_id_fk",
|
|
||||||
"tableFrom": "balances",
|
|
||||||
"tableTo": "users",
|
|
||||||
"columnsFrom": [
|
|
||||||
"userId"
|
|
||||||
],
|
|
||||||
"columnsTo": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"onDelete": "no action",
|
|
||||||
"onUpdate": "no action"
|
|
||||||
},
|
|
||||||
"balances_guildId_guilds_id_fk": {
|
|
||||||
"name": "balances_guildId_guilds_id_fk",
|
|
||||||
"tableFrom": "balances",
|
|
||||||
"tableTo": "guilds",
|
|
||||||
"columnsFrom": [
|
|
||||||
"guildId"
|
|
||||||
],
|
|
||||||
"columnsTo": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"onDelete": "no action",
|
|
||||||
"onUpdate": "no action"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"compositePrimaryKeys": {
|
|
||||||
"balances_userId_guildId_pk": {
|
|
||||||
"name": "balances_userId_guildId_pk",
|
|
||||||
"columns": [
|
|
||||||
"userId",
|
|
||||||
"guildId"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"uniqueConstraints": {},
|
|
||||||
"policies": {},
|
|
||||||
"checkConstraints": {},
|
|
||||||
"isRLSEnabled": false
|
|
||||||
},
|
|
||||||
"public.guilds": {
|
|
||||||
"name": "guilds",
|
|
||||||
"schema": "",
|
|
||||||
"columns": {
|
|
||||||
"id": {
|
|
||||||
"name": "id",
|
|
||||||
"type": "serial",
|
|
||||||
"primaryKey": true,
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
"discordId": {
|
|
||||||
"name": "discordId",
|
|
||||||
"type": "bigint",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"displayName": {
|
|
||||||
"name": "displayName",
|
|
||||||
"type": "varchar(80)",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {},
|
|
||||||
"foreignKeys": {},
|
|
||||||
"compositePrimaryKeys": {},
|
|
||||||
"uniqueConstraints": {
|
|
||||||
"guilds_discordId_unique": {
|
|
||||||
"name": "guilds_discordId_unique",
|
|
||||||
"nullsNotDistinct": false,
|
|
||||||
"columns": [
|
|
||||||
"discordId"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"policies": {},
|
|
||||||
"checkConstraints": {},
|
|
||||||
"isRLSEnabled": false
|
|
||||||
},
|
|
||||||
"public.users": {
|
|
||||||
"name": "users",
|
|
||||||
"schema": "",
|
|
||||||
"columns": {
|
|
||||||
"id": {
|
|
||||||
"name": "id",
|
|
||||||
"type": "serial",
|
|
||||||
"primaryKey": true,
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
"discordId": {
|
|
||||||
"name": "discordId",
|
|
||||||
"type": "bigint",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"username": {
|
|
||||||
"name": "username",
|
|
||||||
"type": "varchar(34)",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"displayName": {
|
|
||||||
"name": "displayName",
|
|
||||||
"type": "varchar(64)",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"reputation": {
|
|
||||||
"name": "reputation",
|
|
||||||
"type": "smallint",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false,
|
|
||||||
"default": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {},
|
|
||||||
"foreignKeys": {},
|
|
||||||
"compositePrimaryKeys": {},
|
|
||||||
"uniqueConstraints": {
|
|
||||||
"users_discordId_unique": {
|
|
||||||
"name": "users_discordId_unique",
|
|
||||||
"nullsNotDistinct": false,
|
|
||||||
"columns": [
|
|
||||||
"discordId"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"policies": {},
|
|
||||||
"checkConstraints": {},
|
|
||||||
"isRLSEnabled": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"enums": {},
|
|
||||||
"schemas": {},
|
|
||||||
"sequences": {},
|
|
||||||
"roles": {},
|
|
||||||
"policies": {},
|
|
||||||
"views": {},
|
|
||||||
"_meta": {
|
|
||||||
"columns": {},
|
|
||||||
"schemas": {},
|
|
||||||
"tables": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
{
|
|
||||||
"version": "7",
|
|
||||||
"dialect": "postgresql",
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"idx": 0,
|
|
||||||
"version": "7",
|
|
||||||
"when": 1771929740316,
|
|
||||||
"tag": "0000_strange_fabian_cortez",
|
|
||||||
"breakpoints": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
1087
package-lock.json
generated
1087
package-lock.json
generated
File diff suppressed because it is too large
Load diff
11
package.json
11
package.json
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "sknsybot",
|
"name": "sknsybot",
|
||||||
"version": "0.4.0.b5",
|
"version": "0.3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "",
|
"description": "",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
|
@ -14,18 +14,15 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chalk": "^5.4.1",
|
"chalk": "^5.4.1",
|
||||||
"discord.js": "^14.14.1",
|
"discord.js": "^14.14.1",
|
||||||
"dotenv": "^17.3.1",
|
"dotenv": "^16.4.7",
|
||||||
"drizzle-orm": "^0.45.1",
|
"mysql": "^2.18.1",
|
||||||
|
"mysql2": "^3.12.0",
|
||||||
"node-cron": "^3.0.3",
|
"node-cron": "^3.0.3",
|
||||||
"pg": "^8.18.0",
|
|
||||||
"wikijs": "^6.4.1"
|
"wikijs": "^6.4.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/chalk": "^0.4.31",
|
|
||||||
"@types/node": "^22.10.7",
|
"@types/node": "^22.10.7",
|
||||||
"@types/node-cron": "^3.0.11",
|
"@types/node-cron": "^3.0.11",
|
||||||
"@types/pg": "^8.16.0",
|
|
||||||
"drizzle-kit": "^0.31.9",
|
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"tsx": "^4.19.2",
|
"tsx": "^4.19.2",
|
||||||
"typescript": "^5.7.3"
|
"typescript": "^5.7.3"
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import "./initConfig";
|
||||||
|
|
||||||
import { GatewayIntentBits, Events, Interaction, ChatInputCommandInteraction, Guild } from 'discord.js';
|
import { GatewayIntentBits, Events, Interaction, ChatInputCommandInteraction, Guild } from 'discord.js';
|
||||||
import { MyClient } from './client';
|
import { MyClient } from './client';
|
||||||
import commandList from './commandList';
|
import commandList from './commandList';
|
||||||
|
|
@ -41,10 +43,6 @@ client.on(Events.InteractionCreate, async (interaction: Interaction) => {
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
console.error(`${chalk.red('Error in command')} ${chalk.bold(`/${commandName}`)}`);
|
console.error(`${chalk.red('Error in command')} ${chalk.bold(`/${commandName}`)}`);
|
||||||
console.error(ex);
|
console.error(ex);
|
||||||
await interaction.followUp({
|
|
||||||
content: `Errore nel comando /${commandName}. Contattare l'amministratore del bot.`,
|
|
||||||
ephemeral: true
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ import { ChatInputCommandInteraction, MessageFlags, SlashCommandBuilder } from '
|
||||||
import yroo from './commands/yroo';
|
import yroo from './commands/yroo';
|
||||||
import wiki from './commands/wiki';
|
import wiki from './commands/wiki';
|
||||||
import coal from './commands/coal';
|
import coal from './commands/coal';
|
||||||
import userinfo from './commands/userinfo';
|
|
||||||
import version from './commands/version';
|
import version from './commands/version';
|
||||||
|
|
||||||
function fakeCommand(name: string, description?: string) {
|
function fakeCommand(name: string, description?: string) {
|
||||||
|
|
@ -41,8 +40,8 @@ const commandList = [
|
||||||
wiki,
|
wiki,
|
||||||
coal,
|
coal,
|
||||||
version,
|
version,
|
||||||
userinfo,
|
|
||||||
fakeCommand('dict', 'Cerca una parola nel dizionario nassiryota'),
|
fakeCommand('dict', 'Cerca una parola nel dizionario nassiryota'),
|
||||||
|
fakeCommand('userinfo', 'Mostra informazioni sull\'utente'),
|
||||||
fakeCommand('bible', 'Leggi un versetto della Bibbia'),
|
fakeCommand('bible', 'Leggi un versetto della Bibbia'),
|
||||||
fakeCommand('rllaw', 'Leggi un articolo della legge italiana')
|
fakeCommand('rllaw', 'Leggi un articolo della legge italiana')
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
import { ChatInputCommandInteraction, EmbedBuilder, SlashCommandBuilder } from 'discord.js';
|
|
||||||
import { findUser } from '../db/users';
|
|
||||||
|
|
||||||
const data = new SlashCommandBuilder()
|
|
||||||
.setName("userinfo")
|
|
||||||
.setDescription("Informazioni su un utente")
|
|
||||||
.addUserOption((o) => o.setName("u")
|
|
||||||
.setDescription("L'utente")
|
|
||||||
.setRequired(true)
|
|
||||||
)
|
|
||||||
;
|
|
||||||
|
|
||||||
async function execute (interaction: ChatInputCommandInteraction) {
|
|
||||||
await interaction.deferReply();
|
|
||||||
|
|
||||||
const user = interaction.options.getUser("u");
|
|
||||||
|
|
||||||
const dbUser = await findUser({
|
|
||||||
id: user.id,
|
|
||||||
username: user.username,
|
|
||||||
globalName: user.globalName
|
|
||||||
});
|
|
||||||
|
|
||||||
const uEmbed = new EmbedBuilder()
|
|
||||||
.setTitle(`${user.globalName} (@${user.username})`)
|
|
||||||
.setThumbnail(user.avatarURL())
|
|
||||||
.addFields([
|
|
||||||
{name: 'Bilancio', value: '<bilancio>', inline: true}
|
|
||||||
]);
|
|
||||||
|
|
||||||
await interaction.followUp({
|
|
||||||
embeds: [uEmbed]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export default { data, execute };
|
|
||||||
|
|
@ -5,21 +5,11 @@ const pageSources = {
|
||||||
'cittadeldank': {
|
'cittadeldank': {
|
||||||
url: 'https://wiki.cittadeldank.it',
|
url: 'https://wiki.cittadeldank.it',
|
||||||
name: 'Città del Dank'
|
name: 'Città del Dank'
|
||||||
},
|
|
||||||
'wikicord': {
|
|
||||||
url: 'https://wikicord.wikioasis.org/api.php',
|
|
||||||
name: 'Wikicord'
|
|
||||||
},
|
|
||||||
'mappingwikiit': {
|
|
||||||
url: 'https://it.mappingwiki.org',
|
|
||||||
name: 'Mapping Wiki IT'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const pageSourcesAuto = [
|
const pageSourcesAuto = [
|
||||||
'cittadeldank',
|
'cittadeldank'
|
||||||
'wikicord',
|
|
||||||
'mappingwikiit'
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const data = new SlashCommandBuilder()
|
const data = new SlashCommandBuilder()
|
||||||
|
|
@ -33,8 +23,6 @@ const data = new SlashCommandBuilder()
|
||||||
.setDescription('Dove guardare')
|
.setDescription('Dove guardare')
|
||||||
.addChoices([
|
.addChoices([
|
||||||
{name: 'Città del Dank', value: 'cittadeldank'},
|
{name: 'Città del Dank', value: 'cittadeldank'},
|
||||||
{name: 'Wikicord', value: 'wikicord'},
|
|
||||||
{name: 'Mapping Wiki IT', value: 'mappingwikiit'},
|
|
||||||
{name: 'Automatico', value: 'auto'}
|
{name: 'Automatico', value: 'auto'}
|
||||||
])
|
])
|
||||||
.setRequired(false)
|
.setRequired(false)
|
||||||
|
|
@ -57,13 +45,7 @@ async function execute (interaction: ChatInputCommandInteraction) {
|
||||||
|
|
||||||
if (siteChoice === 'auto') {
|
if (siteChoice === 'auto') {
|
||||||
for (let site of pageSourcesAuto) {
|
for (let site of pageSourcesAuto) {
|
||||||
try {
|
pageData = await fetchPageFromSite(site, pageName);
|
||||||
pageData = await fetchPageFromSite(site, pageName);
|
|
||||||
} catch (error) {
|
|
||||||
console.warn(`Skipping source ${site}: ${error}`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pageData) break;
|
if (pageData) break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -75,7 +57,7 @@ async function execute (interaction: ChatInputCommandInteraction) {
|
||||||
const pageEmbed = new EmbedBuilder()
|
const pageEmbed = new EmbedBuilder()
|
||||||
.setTitle(pageData.title)
|
.setTitle(pageData.title)
|
||||||
.setURL(pageData.url)
|
.setURL(pageData.url)
|
||||||
.setDescription(pageData.summary || '...')
|
.setDescription(pageData.summary)
|
||||||
.setFooter({
|
.setFooter({
|
||||||
text: `Informazioni da ${pageData.origin}`
|
text: `Informazioni da ${pageData.origin}`
|
||||||
});
|
});
|
||||||
|
|
@ -89,7 +71,7 @@ async function execute (interaction: ChatInputCommandInteraction) {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await interaction.followUp({
|
await interaction.followUp({
|
||||||
content: `Pagina **${pageName}** non trovata!`
|
content: `Pagina **${pageName}** non trovata`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
9
src/cron/calendar.ts
Normal file
9
src/cron/calendar.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
|
||||||
|
import * as cron from 'node-cron';
|
||||||
|
|
||||||
|
|
||||||
|
//cron.schedule('0 7 * * *', () => {
|
||||||
|
// // TODO send good morning to channel
|
||||||
|
//});
|
||||||
|
|
||||||
19
src/database.ts
Normal file
19
src/database.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
Copyright 2025 Sakuragasaki46
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
|
|
||||||
import { drizzle } from "drizzle-orm/node-postgres";
|
|
||||||
import * as schema from "./schema";
|
|
||||||
import { Pool } from "pg";
|
|
||||||
|
|
||||||
function urlToObj(url: string) {
|
|
||||||
if (!url) {
|
|
||||||
console.warn("DATABASE_URL is not set, expect the database to not connect");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { username, password, hostname, port, pathname } = URL.parse(url);
|
|
||||||
|
|
||||||
return {
|
|
||||||
user: username,
|
|
||||||
password,
|
|
||||||
host: hostname,
|
|
||||||
port: +(port || 5432),
|
|
||||||
database: pathname.split('/')[1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const client = new Pool({
|
|
||||||
...urlToObj(process.env.DATABASE_URL!)
|
|
||||||
});
|
|
||||||
|
|
||||||
export const db = drizzle({
|
|
||||||
client,
|
|
||||||
// casing: 'snake_case', [DOES NOT WORK ON DRIZZLEKIT]
|
|
||||||
schema
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
|
|
||||||
import { sql } from "drizzle-orm";
|
|
||||||
import * as p from "drizzle-orm/pg-core";
|
|
||||||
|
|
||||||
|
|
||||||
export const users = p.pgTable('users', {
|
|
||||||
id: p.serial().primaryKey(),
|
|
||||||
discordId: p.bigint({mode: "bigint"}).unique(),
|
|
||||||
username: p.varchar({length: 34}),
|
|
||||||
displayName: p.varchar({length: 64}),
|
|
||||||
/** reputation values:
|
|
||||||
* 0 = unscreened
|
|
||||||
* 1 = exempt
|
|
||||||
* 2 = suspicious
|
|
||||||
* 3 = dangerous
|
|
||||||
*/
|
|
||||||
reputation: p.smallint().default(0)
|
|
||||||
});
|
|
||||||
|
|
||||||
export const guilds = p.pgTable('guilds', {
|
|
||||||
id: p.serial().primaryKey(),
|
|
||||||
discordId: p.bigint({mode: "bigint"}).unique(),
|
|
||||||
displayName: p.varchar(({length: 80}))
|
|
||||||
// TODO channel IDs
|
|
||||||
});
|
|
||||||
|
|
||||||
export const balances = p.pgTable('balances', {
|
|
||||||
userId: p.integer().references(() => users.id),
|
|
||||||
guildId: p.integer().references(() => guilds.id),
|
|
||||||
balance: p.bigint({mode: "bigint"}).default(sql`0::bigint`),
|
|
||||||
lastMessageHour: p.integer(),
|
|
||||||
}, (t) => [
|
|
||||||
p.primaryKey({
|
|
||||||
columns: [t.userId, t.guildId]
|
|
||||||
})
|
|
||||||
]);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
import { eq } from "drizzle-orm";
|
|
||||||
import { db } from "./database";
|
|
||||||
import { users } from "./schema";
|
|
||||||
|
|
||||||
|
|
||||||
export type UserUpdate = {
|
|
||||||
id: string | bigint,
|
|
||||||
username: string
|
|
||||||
globalName: string
|
|
||||||
};
|
|
||||||
|
|
||||||
export type NewUser = typeof users.$inferInsert;
|
|
||||||
|
|
||||||
export async function findUser (userData: UserUpdate) {
|
|
||||||
let user = await db.query.users.findFirst({
|
|
||||||
where: () => eq(users.discordId, BigInt(userData.id))
|
|
||||||
}) as NewUser;
|
|
||||||
|
|
||||||
if (!user) {
|
|
||||||
// upsert the user
|
|
||||||
user = await db.insert(users).values({
|
|
||||||
discordId: BigInt(userData.id),
|
|
||||||
username: userData.username,
|
|
||||||
displayName: userData.globalName,
|
|
||||||
} as NewUser).returning() as NewUser;
|
|
||||||
} else if (
|
|
||||||
user.username !== userData.username ||
|
|
||||||
user.displayName !== userData.globalName
|
|
||||||
) {
|
|
||||||
await db.update(users).set({
|
|
||||||
username: userData.username,
|
|
||||||
displayName: userData.globalName
|
|
||||||
}).where(eq(users.discordId, BigInt(userData.id)))
|
|
||||||
}
|
|
||||||
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
9
src/initConfig.ts
Normal file
9
src/initConfig.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
|
||||||
|
import { config as configDotenv } from 'dotenv';
|
||||||
|
|
||||||
|
|
||||||
|
export default function init (){
|
||||||
|
configDotenv();
|
||||||
|
}
|
||||||
|
|
||||||
21
src/main.ts
21
src/main.ts
|
|
@ -1,22 +1,7 @@
|
||||||
|
import client from "./bot";
|
||||||
|
import init from "./initConfig";
|
||||||
|
|
||||||
import { configDotenv } from "dotenv";
|
init();
|
||||||
|
|
||||||
configDotenv();
|
|
||||||
|
|
||||||
const client = (await import("./bot")).default;
|
|
||||||
|
|
||||||
|
|
||||||
// query TEST
|
|
||||||
(async function () {
|
|
||||||
// async imports because yes
|
|
||||||
const { db } = await import("./db/database");
|
|
||||||
const { count } = await import("drizzle-orm");
|
|
||||||
const { users } = await import("./db/schema");
|
|
||||||
const chalk = (await import("chalk")).default;
|
|
||||||
const uCount = (await db.select({ count: count() }).from(users))[0].count;
|
|
||||||
console.log(`Watching over ${chalk.bold(uCount)} users`);
|
|
||||||
})().then(() => { });
|
|
||||||
// END query TEST
|
|
||||||
|
|
||||||
client.login(process.env.TOKEN);
|
client.login(process.env.TOKEN);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ function strToObjArr(s: string | object[]): object[] {
|
||||||
|
|
||||||
export type SectionObject = {title: string, content: string};
|
export type SectionObject = {title: string, content: string};
|
||||||
|
|
||||||
|
type WithPageId = {pageId: any};
|
||||||
|
|
||||||
export class MediaWikiClient {
|
export class MediaWikiClient {
|
||||||
apiUrl: string
|
apiUrl: string
|
||||||
siteName: string | null
|
siteName: string | null
|
||||||
|
|
@ -27,7 +29,7 @@ export class MediaWikiClient {
|
||||||
const wikiClient = wiki({
|
const wikiClient = wiki({
|
||||||
apiUrl: this.apiUrl,
|
apiUrl: this.apiUrl,
|
||||||
origin: null
|
origin: null
|
||||||
}) as any;
|
});
|
||||||
const page = await wikiClient.page(title);
|
const page = await wikiClient.page(title);
|
||||||
const pageId = page.raw.pageid;
|
const pageId = page.raw.pageid;
|
||||||
const pageUrl = page.url();
|
const pageUrl = page.url();
|
||||||
|
|
|
||||||
|
|
@ -14,14 +14,12 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import init from "./initConfig";
|
||||||
import { configDotenv } from "dotenv";
|
|
||||||
|
|
||||||
configDotenv();
|
|
||||||
|
|
||||||
import commandList from "./commandList";
|
import commandList from "./commandList";
|
||||||
import { REST, Routes } from 'discord.js';
|
import { REST, Routes } from 'discord.js';
|
||||||
|
|
||||||
|
init();
|
||||||
|
|
||||||
function registerGlobal(rest: REST, clientId: string, commands: any){
|
function registerGlobal(rest: REST, clientId: string, commands: any){
|
||||||
rest.put(Routes.applicationCommands(clientId), { body: commands })
|
rest.put(Routes.applicationCommands(clientId), { body: commands })
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es2017",
|
|
||||||
"module": "preserve",
|
|
||||||
"rootDir": "src/",
|
"rootDir": "src/",
|
||||||
"outDir": "build/",
|
"outDir": "build/",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue