2017-12-07 03:30:56 +01:00
|
|
|
var express = require("express");
|
|
|
|
var request = require("request");
|
|
|
|
var Discord = require('discord.js');
|
|
|
|
|
|
|
|
const Canvas = require("canvas");
|
2017-12-10 15:03:09 +01:00
|
|
|
const Image = Canvas.Image;
|
2017-12-07 03:30:56 +01:00
|
|
|
|
|
|
|
const twemoji = require("./twemoji");
|
|
|
|
|
|
|
|
var app = express()
|
|
|
|
var config = require("./config");
|
|
|
|
|
|
|
|
var cache = {};
|
|
|
|
|
2017-12-10 15:03:09 +01:00
|
|
|
templates = {
|
|
|
|
bee: {
|
|
|
|
template: "./BeeTemplate.png",
|
|
|
|
leftOffset: 475,
|
|
|
|
widthTarget: 600,
|
|
|
|
bottomTarget: 530
|
|
|
|
},
|
|
|
|
turtle: {
|
|
|
|
template: "./TurtleTemplate.png",
|
|
|
|
leftOffset: 210,
|
|
|
|
widthTarget: 150,
|
|
|
|
bottomTarget: 150
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for(templateName in templates) {
|
|
|
|
const data = templates[templateName];
|
|
|
|
data.image = new Image();
|
|
|
|
data.image.src = data.template;
|
|
|
|
}
|
2017-12-07 03:30:56 +01:00
|
|
|
|
|
|
|
|
2017-12-10 15:56:37 +01:00
|
|
|
function render(template, img, size) {
|
|
|
|
var width = img.width;
|
|
|
|
var height = img.height;
|
|
|
|
if (size && size.height) {
|
|
|
|
height = size.height;
|
|
|
|
if (!size.width) width = width * size.height / img.height;
|
|
|
|
}
|
|
|
|
if (size && size.width) {
|
|
|
|
width = size.width;
|
|
|
|
if (!size.height) height = height * size.width / img.width;
|
|
|
|
}
|
2017-12-07 03:30:56 +01:00
|
|
|
|
2017-12-10 15:56:37 +01:00
|
|
|
const templateScale = width / template.widthTarget; // scale the template to fit the image
|
2017-12-07 03:30:56 +01:00
|
|
|
|
|
|
|
|
2017-12-10 15:56:37 +01:00
|
|
|
let resultingWidth = template.image.width * templateScale;
|
|
|
|
let resultingHeight = template.image.height * templateScale;
|
2017-12-07 03:30:56 +01:00
|
|
|
|
2017-12-10 15:56:37 +01:00
|
|
|
let imgTop = template.bottomTarget * templateScale - height; // naive top center position
|
2017-12-07 03:30:56 +01:00
|
|
|
|
2017-12-10 15:56:37 +01:00
|
|
|
if (imgTop < 0) {
|
|
|
|
resultingHeight -= imgTop;
|
|
|
|
imgTop = 0;
|
|
|
|
}
|
2017-12-07 03:30:56 +01:00
|
|
|
|
2017-12-10 15:56:37 +01:00
|
|
|
const resultingImgTop = imgTop;
|
|
|
|
const resultingImgLeft = template.leftOffset * templateScale - width / 2.0;
|
2017-12-10 15:03:09 +01:00
|
|
|
|
2017-12-10 15:56:37 +01:00
|
|
|
if(resultingImgLeft + width > resultingWidth) {
|
|
|
|
resultingWidth = resultingImgLeft + width;
|
|
|
|
}
|
2017-12-07 03:30:56 +01:00
|
|
|
|
2017-12-10 15:56:37 +01:00
|
|
|
const resultingTemplateTop = resultingHeight - template.image.height * templateScale;
|
|
|
|
const resultingTemplateLeft = 0.0;
|
|
|
|
|
|
|
|
var canvas = new Canvas(resultingWidth, resultingHeight);
|
|
|
|
var ctx = canvas.getContext("2d");
|
|
|
|
console.log("Drawing template "+template.template)
|
|
|
|
try {
|
|
|
|
ctx.drawImage(template.image, resultingTemplateLeft, resultingTemplateTop, template.image.width * templateScale, template.image.height * templateScale);
|
|
|
|
console.log("Drawing done.")
|
|
|
|
} catch (err) {
|
2017-12-10 23:42:10 +01:00
|
|
|
throw new Error(JSON.stringify({ status: 400, error: "Invalid template" }))
|
2017-12-10 15:56:37 +01:00
|
|
|
}
|
|
|
|
console.log("Drawing image")
|
|
|
|
try {
|
|
|
|
ctx.drawImage(img, resultingImgLeft, resultingImgTop, width, height);
|
|
|
|
console.log("Drawing done.")
|
|
|
|
} catch (err) {
|
|
|
|
console.error(err);
|
2017-12-10 23:42:10 +01:00
|
|
|
throw new Error(JSON.stringify({ status: 400, error: "Invalid image" }))
|
2017-12-10 15:56:37 +01:00
|
|
|
}
|
2017-12-10 15:03:09 +01:00
|
|
|
|
2017-12-10 15:56:37 +01:00
|
|
|
// return the image and cache it
|
|
|
|
return(canvas);
|
2017-12-07 03:30:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
const circleScale = 0.4;
|
|
|
|
const lineWidthScale = 0.2;
|
2017-12-10 15:03:09 +01:00
|
|
|
const lowerRightFactor = 0.5 + 0.7071 * circleScale; // %-ual location of the lower right end of the strikethrough line
|
|
|
|
const upperLeftFactor = 0.5 - 0.7071 * circleScale; // %-ual location of the upper left end of the strikethrough line
|
2017-12-07 03:30:56 +01:00
|
|
|
|
2017-12-10 15:56:37 +01:00
|
|
|
app.get("/:templateName/", async function (req, res) {
|
2017-12-10 15:03:09 +01:00
|
|
|
if(!templates[req.params.templateName]) return res.status(404).end();
|
2017-12-10 23:42:10 +01:00
|
|
|
try {
|
|
|
|
const canvas = render(templates[req.params.templateName], await loadImage(req.query.url))
|
2017-12-07 03:30:56 +01:00
|
|
|
console.log(canvas)
|
|
|
|
res.setHeader('Content-Type', 'image/png');
|
2017-12-10 23:42:10 +01:00
|
|
|
return canvas.pngStream().pipe(res);
|
|
|
|
} catch(err) {
|
|
|
|
console.log(err.message);
|
|
|
|
return res.status(400).end(err.message);
|
|
|
|
}
|
2017-12-07 03:30:56 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
app.listen(3002, function () {
|
2017-12-10 15:03:09 +01:00
|
|
|
console.log('Beebot app listening on port 3002!')
|
2017-12-07 03:30:56 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Discord stuff
|
|
|
|
|
|
|
|
|
|
|
|
var client = new Discord.Client({
|
2017-12-10 15:03:09 +01:00
|
|
|
autoReconnect: true
|
2017-12-07 03:30:56 +01:00
|
|
|
});
|
|
|
|
// manage roles permission is required
|
|
|
|
const invitelink = 'https://discordapp.com/oauth2/authorize?client_id='
|
2017-12-10 15:03:09 +01:00
|
|
|
+ config.discord.client_id + '&scope=bot&permissions=0';
|
2017-12-07 03:30:56 +01:00
|
|
|
const authlink = 'https://discordapp.com/oauth2/authorize?client_id='
|
2017-12-10 15:03:09 +01:00
|
|
|
+ config.discord.client_id + '&scope=email';
|
|
|
|
console.log("Bot invite link: " + invitelink);
|
2017-12-07 03:30:56 +01:00
|
|
|
|
|
|
|
client.login(config.discord.token).catch(function (error) {
|
2017-12-10 15:03:09 +01:00
|
|
|
if (error) {
|
|
|
|
console.error("Couldn't login: ", error);
|
|
|
|
process.exit(15);
|
|
|
|
}
|
2017-12-07 03:30:56 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
function findEmoji(str) {
|
|
|
|
const discordEmote = /<:(\w+):(\d+)>/g.exec(str)
|
2017-12-10 15:03:09 +01:00
|
|
|
if (discordEmote) {
|
2017-12-07 03:30:56 +01:00
|
|
|
return {
|
|
|
|
name: discordEmote[1],
|
|
|
|
id: discordEmote[2],
|
|
|
|
url: `https://cdn.discordapp.com/emojis/${discordEmote[2]}.png`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let unicodeEmoji;
|
2017-12-10 15:03:09 +01:00
|
|
|
twemoji.parse(str, (name, emoji) => {
|
|
|
|
if (unicodeEmoji) return false;
|
2017-12-07 03:30:56 +01:00
|
|
|
unicodeEmoji = {
|
2017-12-10 15:03:09 +01:00
|
|
|
name,
|
2017-12-07 03:30:56 +01:00
|
|
|
id: name,
|
|
|
|
url: emoji.base + emoji.size + "/" + name + emoji.ext
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
return unicodeEmoji;
|
|
|
|
}
|
|
|
|
|
2017-12-10 15:56:37 +01:00
|
|
|
function loadImage(url) {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
console.log("Getting " + url);
|
|
|
|
if (url) {
|
|
|
|
request.get({ url: url, encoding: null }, function (e, r, data) {
|
|
|
|
if (e) {
|
|
|
|
return reject({ status: (r && r.statusCode || 500), error: e });
|
|
|
|
}
|
|
|
|
var img = new Image();
|
|
|
|
img.src = data;
|
|
|
|
resolve(img);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
client.on('message', async function (message) {
|
2017-12-07 03:30:56 +01:00
|
|
|
console.log(message.cleanContent);
|
2017-12-10 15:56:37 +01:00
|
|
|
|
|
|
|
const messageSplit = message.cleanContent.split(" ");
|
|
|
|
const emoji = findEmoji(message.cleanContent);
|
|
|
|
let result = null;
|
2017-12-10 23:42:10 +01:00
|
|
|
let count = 0;
|
2017-12-10 15:56:37 +01:00
|
|
|
try {
|
|
|
|
if (emoji) {
|
|
|
|
let name = emoji.name;
|
2017-12-10 23:42:10 +01:00
|
|
|
for (var i = 0; i < messageSplit.length && count < 4; ++i) {
|
2017-12-10 15:56:37 +01:00
|
|
|
const commandParsed = /^\/(\w+)\b/.exec(messageSplit[i]);
|
|
|
|
if (commandParsed && templates[commandParsed[1]]) {
|
2017-12-10 23:42:10 +01:00
|
|
|
count++;
|
2017-12-10 15:56:37 +01:00
|
|
|
name += commandParsed[1];
|
|
|
|
if (result === null) result = await loadImage(emoji.url);
|
|
|
|
result = render(templates[commandParsed[1]], result);
|
2017-12-10 23:42:10 +01:00
|
|
|
} else {
|
|
|
|
if(i===0) return;
|
2017-12-10 15:56:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (result) {
|
|
|
|
var messageOptions = {
|
|
|
|
files: [
|
|
|
|
{ attachment: result.toBuffer(), name: name + ".png" }
|
|
|
|
]
|
|
|
|
}
|
|
|
|
message.channel.send("", messageOptions);
|
2017-12-10 15:03:09 +01:00
|
|
|
}
|
2017-12-10 15:56:37 +01:00
|
|
|
}
|
|
|
|
} catch(err) {
|
|
|
|
console.error(err);
|
2017-12-10 15:03:09 +01:00
|
|
|
}
|
2017-12-07 03:30:56 +01:00
|
|
|
});
|