Compare commits

..

10 Commits

Author SHA1 Message Date
a0b5be0633 Fixed a bug in a welcome message 2025-12-08 23:29:01 +01:00
3098a128d8 Add custom welcome messages with mention 2025-12-02 16:39:38 +01:00
2d7f13bb27 Enable onClientReady message 2025-12-02 13:03:09 +01:00
4bcdb4aa93 Fixed namecard fonts 2025-12-02 11:41:18 +01:00
fe4c03357a Fixed worker termination and result retrieving 2025-12-02 11:31:34 +01:00
ec9f14c9e7 Fixed stuff 2025-11-11 22:42:14 +01:00
e3218af147 Change shitty lib canvas for @napi-rs/canva 2025-11-11 21:31:34 +01:00
9cc2f7c169 Update name card tests 2025-11-11 19:50:25 +01:00
d1143cff12 Log some stuff 2025-11-11 19:24:44 +01:00
a302b6288e oopsie 2025-11-11 18:40:32 +01:00
8 changed files with 101 additions and 38 deletions

View File

@@ -8,9 +8,16 @@ RUN npm install
COPY . .
RUN apt-get update && apt-get install -y fontconfig
#Installing fonts
RUN apt-get update || true
RUN apt-get install -y --no-install-recommends \
gnupg \
ca-certificates \
fontconfig || true
RUN mkdir -p /usr/local/share/fonts/truetype/fredoka
COPY ./wwwroot/assets/fonts/Fredoka/fredoka.ttf /usr/local/share/fonts/truetype/fredoka/fredoka.ttf
RUN fc-cache -fv
CMD ["npm", "run", "name-card-test"]
CMD ["npm", "run", "start"]

27
bot.js
View File

@@ -3,6 +3,7 @@ import JsonManager from "./wwwroot/core/utils/jsonManager.js";
import {Logger} from "./wwwroot/core/logging/logger.js";
import {launchWorker} from "./wwwroot/core/namecards/workerLauncher.js";
import {AttachmentBuilder} from "discord.js";
import StringFormatter from "./wwwroot/core/utils/stringFormatter.js";
const launch = async () => {
try{
@@ -32,9 +33,20 @@ const launch = async () => {
});
data.client.on('guildMemberAdd', async (member) => {
const possibleMessages = [
"<@:user> is one of us!",
"I know what you are, <@:user>...",
"Osmanthus wine tastes the same as I— oop, wrong line <@:user>",
"Yeah yeah, welcome or whatever <@:user>",
"OH. MY. GOD Y'ALL— <@:user> is here!",
"So... we're all seeing <@:user>, right?",
"<@:user> is right behind me, aren't they...?"
]
const choseMessage = possibleMessages[Math.floor(Math.random() * possibleMessages.length)];
try {
const avatarUrl = member.user.displayAvatarURL({ extension: 'png', size: 512 });
const username = member.displayName;
const username = member.displayName || member.user.username;
const result = await launchWorker({
templatePath: data.nameCardTemplate,
@@ -42,16 +54,23 @@ const launch = async () => {
username: username,
});
const attachment = new AttachmentBuilder(result, { name: 'namecard.png' });
const attachment = new AttachmentBuilder(Buffer.from(result.result), { name: 'namecard.png' });
const channel = await member.guild.channels.fetch(data.welcomeChannelID);
await channel.send({ files: [attachment] });
await channel.send({
content: StringFormatter.format(choseMessage, [ {key : "user", value : member.id} ]),
allowedMentions: {
users: [member.id]
},
files: [attachment]
});
} catch (err) {
console.error('Failed to generate/send name card:', err);
await Logger.error('Failed to generate/send name card:', err);
}
});
process.on('SIGINT', async () => {
try {
await data.sender.send(data.updateChannelID, "I'm shutting down, now. Bye! 👋")

View File

@@ -21,7 +21,7 @@
"author": "Naaturel",
"license": "MIT",
"dependencies": {
"canvas": "^3.2.0",
"@napi-rs/canvas": "^0.1.82",
"discord.js": "^14.22.1",
"dotenv": "^16.0.3",
"express": "^4.21.2",

View File

@@ -1,21 +1,55 @@
import {NameCardCreator} from "../wwwroot/core/namecards/nameCardCreator.js";
import {launchWorker} from "../wwwroot/core/namecards/workerLauncher.js";
import {data} from "../wwwroot/core/appData.js";
import {launchWorker} from "../wwwroot/core/namecards/workerLauncher.js";
import {AttachmentBuilder} from "discord.js";
import {Logger} from "../wwwroot/core/logging/logger.js";
import StringFormatter from "../wwwroot/core/utils/stringFormatter.js";
const templatePath = "./wwwroot/assets/name-card-template.png";
const avatarPath = "./tests/assets/avatar-test.png";
const name = "Aude Vaiselle";
data.client.on('clientReady', async () => {
console.log("Ready!");
const guild = await data.client.guilds.fetch(data.testGuildID);
const member = await guild.members.fetch(data.testUserID);
try {
launchWorker({
templatePath : data.nameCardTemplate,
avatarURL: avatarPath,
username: name,
}).then(buffer => {
//Send name card here...
console.log('Name card sent!');
}).catch(console.error);
} catch (err) {
console.error('Failed to generate/send name card:', err);
}
console.log("Emitting fake guildMemberAdd...");
data.client.emit("guildMemberAdd", member);
});
data.client.on('guildMemberAdd', async (member) => {
const possibleMessages = [
"<@:user> is one of us!",
"I know what you are, <@:user>...",
"Osmanthus wine tastes the same as I— oop, wrong line <@:user>",
"Yeah yeah, welcome or whatever <@:user>",
"OH. MY. GOD Y'ALL— <@:user> is here!",
"So... we're all seeing <@:user, right?>",
"<@:user> is right behind me, aren't they...?"
]
const choseMessage = possibleMessages[Math.floor(Math.random() * possibleMessages.length)];
try {
const avatarUrl = member.user.displayAvatarURL({ extension: 'png', size: 512 });
const username = member.displayName || member.user.username;
const result = await launchWorker({
templatePath: data.nameCardTemplate,
avatarURL: avatarUrl,
username: username,
});
const attachment = new AttachmentBuilder(Buffer.from(result.result), { name: 'namecard.png' });
const channel = await member.guild.channels.fetch(data.welcomeChannelID);
await channel.send({
content: StringFormatter.format(choseMessage, [ {key : "user", value : member.id} ]),
allowedMentions: {
users: [member.id]
},
files: [attachment]
});
} catch (err) {
await Logger.error('Failed to generate/send name card:', err);
}
});
await data.client.login(process.env.DISCORD_TOKEN);

View File

@@ -24,6 +24,9 @@ const updateChannelID = process.env.BOT_UPDATE_CHANNEL_ID;
const socialChannelID = process.env.SOCIAL_CHANNEL_ID
const welcomeChannelID = process.env.WELCOME_CHANNEL_ID
const testGuildID = process.env.TEST_GUILD_ID;
const testUserID = process.env.TEST_USER_ID;
const filePath = ".instagram_client_tokens.json";
const usersToken = new UsersToken(filePath)
@@ -41,6 +44,8 @@ export const data = {
updateChannelID,
socialChannelID,
welcomeChannelID,
testGuildID,
testUserID,
instagramTokenManager,
nameCardTemplate
//tiktokTokenManager

View File

@@ -1,19 +1,16 @@
import fs from "fs";
import {createCanvas, GlobalFonts, loadImage} from "@napi-rs/canvas";
import path from "path";
import { createCanvas, loadImage, registerFont } from "canvas";
import { fileURLToPath } from "url";
export class NameCardCreator {
constructor(templatePath) {
this.templatePath = templatePath;
this.loadFont("./wwwroot/assets/fonts/Fredoka/static/Fredoka-Bold.ttf");
}
loadFont(fontPath) {
const fullPath = path.resolve(fontPath);
if (!fs.existsSync(fullPath)) {
throw new Error(`Font file not found at ${fullPath}`);
}
registerFont(fullPath, { family: "Fredoka Bold" });
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const fullPath = path.join(__dirname, "../../assets/fonts/Fredoka/static/Fredoka-Bold.ttf");
GlobalFonts.registerFromPath(
fullPath,
"Fredoka Bold"
);
}
/**
@@ -85,7 +82,7 @@ export class NameCardCreator {
smallCtx = smallCanvas.getContext("2d");
smallCtx.drawImage(canvas, 0, 0, 1500, 500);
return smallCanvas.toBuffer();
return smallCanvas.toBuffer("image/png");
} catch (err) {
console.error("Error creating name card:", err);
throw err;

View File

@@ -8,9 +8,11 @@ parentPort.on("message", async (data) => {
const creator = new NameCardCreator(templatePath);
const buffer = await creator.getWelcomeCard(avatarURL, username);
parentPort.postMessage({ result: buffer }, [buffer.buffer]);
parentPort.postMessage({ result: buffer });
} catch (err) {
parentPort.postMessage({ error: err.message });
} finally {
parentPort.close();
}
});

View File

@@ -21,7 +21,6 @@ function launchWorker({ templatePath, avatarURL, username }) {
worker.postMessage({ templatePath, avatarURL, username });
worker.once('message', async (result) => {
console.log("worker terminated");
resolve(result);
});