Compare commits

..

58 Commits

Author SHA1 Message Date
lamp ab43d009b0 masto auto reconnect stream 2022-07-18 13:02:23 -07:00
lamp b18c90996e fix 2022-07-17 22:21:01 -07:00
lamp 1f4dec517f masto bridge v1 2022-07-17 22:17:24 -07:00
lamp 1704537a13 fix missing eval emoji 2022-07-17 21:28:15 -07:00
lamp 69c5a106b5 2022-07-17 21:27:40 -07:00
lamp a2966b1475 fix [object Object] 2022-07-17 21:26:54 -07:00
lamp d04200742d fix undefined unhandled rejection 2022-07-17 21:24:35 -07:00
lamp fbb082fee8 init masto stream (testing) 2022-07-17 21:21:13 -07:00
lamp bb80d22568 2022-07-17 21:07:05 -07:00
lamp 721435f039 icon thing 2022-05-20 19:15:30 -07:00
lamp e85d88de69 delete masto 2022-05-20 19:13:11 -07:00
lamp a4730289a0 fuk u type explicicy 2022-05-10 22:21:10 -07:00
lamp 02be479a15 fix size options 2022-05-10 22:18:38 -07:00
lamp 1b2df7a1cb fix formatting break embed 2022-05-10 14:20:26 -07:00
lamp 7eb01dda9d command to get emoji url 2022-05-10 14:03:15 -07:00
lamp c130ef1506 fix bug 2022-05-08 00:13:50 -07:00
lamp 660234acfd delete archive command and permissions set 2022-05-07 22:36:08 -07:00
lamp c0470e89b6 mastodon pixiv bot 2022-05-07 22:32:09 -07:00
lamp 823c398a5a disable verification 2022-04-11 22:58:36 -07:00
lamp 9b84e4ff7c delay the welcome message 2022-04-06 01:52:04 -07:00
lamp e19f11acae command to change server icon 2022-04-06 01:25:03 -07:00
lamp 0fcd5f125c rm vrchat 2022-04-06 01:22:30 -07:00
lamp 1316460838 vrchat command only 2022-03-31 17:37:49 -07:00
lamp ed76ad6044 small refactor 2022-03-31 17:33:48 -07:00
lamp c0036e7471 fix 2022-03-31 17:28:01 -07:00
lamp 55812d6422 ok.. 2022-03-31 17:04:51 -07:00
lamp 93b40700e0 vrc user monitor 2022-03-31 17:01:08 -07:00
lamp 345e368faa fix 2022-03-31 13:23:12 -07:00
lamp 523f057ea3 enable pinging deactivated members by role 2022-03-31 13:20:46 -07:00
lamp a0a9383d32 undot am pm 2022-03-31 12:27:54 -07:00
lamp 06685d0ad4 phlag 2022-03-19 12:39:35 -07:00
lamp 17d295043f welcome message 2022-03-14 16:43:54 -05:00
lamp e069b80a1d regular pin 2022-03-08 14:23:09 -06:00
lamp a016217a06 update channel ids 2022-03-08 14:13:47 -06:00
lamp 6dcd1b2665 fking discord 2022-01-18 16:26:16 -06:00
lamp 6f369ee441 :sGrimace:
also allow removing role icon
2022-01-13 19:28:15 -08:00
lamp 79611c34ae update discord.js 2022-01-13 19:22:06 -08:00
lamp bec6a886b1 /setbanner 2022-01-13 19:14:04 -08:00
lamp 0cd23ff738 Merge branch 'master' of gitea.moe:lamp/lampdiscordbot 2022-01-10 14:05:01 -08:00
lamp ba8d2f5cb9 fix detection url abuse 2022-01-10 14:04:57 -08:00
lamp fdbf05b846 fix t %% 2022-01-03 21:36:02 -06:00
lamp 25ec6a1906 rename tr to tolang 2022-01-03 16:13:48 -08:00
lamp f73217e282 normalization broke other lang 2022-01-03 16:01:37 -08:00
lamp e0122e5365 fix 2022-01-03 15:56:33 -08:00
lamp 7ccfe95b33 show detected lang if no flag 2022-01-03 15:51:46 -08:00
lamp eb48b90c96 rename to to tr because it can't be used without clicking 2022-01-03 15:44:18 -08:00
lamp f62d629b1f bruh 2022-01-03 15:37:32 -08:00
lamp 2772a16525 d 2022-01-03 15:34:22 -08:00
lamp 502cffbf06 flags 2022-01-03 15:23:54 -08:00
lamp 8fde14112b wrong key :sGrimace: 2022-01-03 14:37:48 -08:00
lamp dd159fa854 max 25 options 2022-01-03 14:34:26 -08:00
lamp dec7d3a50a add /to 2021-12-31 21:25:51 -08:00
lamp 978e08b713 bruh
also update .gitignore
%%
2021-12-23 10:40:25 -08:00
lamp fd9cc47836 un-simplify 2021-12-23 00:27:04 -08:00
lamp 75fa8fce66 bruh 2021-12-22 21:25:51 -08:00
lamp 51691595ce simplified 2021-12-22 21:24:45 -08:00
lamp 3f64f2e8e5 aaaa api message order is reversed 2021-12-22 21:09:23 -08:00
lamp 8db44d917c bug 2021-12-22 20:57:27 -08:00
18 changed files with 1048 additions and 445 deletions
+2 -1
View File
@@ -1,3 +1,4 @@
node_modules
secrets.env
data
data
tokens.txt
+20 -7
View File
@@ -6,10 +6,11 @@ var DataStore = require("./datastore");
var ds = new DataStore("activity");
app.get("/detect/:userid", (req, res) => {
app.get("/detect/:code", (req, res) => {
res.sendFile(process.cwd() + "/track-image.png");
if (req.headers["user-agent"].includes("Discordbot")) return;
onActivity(req.params.userid);
onActivity(ds.get(req.params.code));
ds.del(req.params.code);
});
@@ -54,9 +55,9 @@ module.exports.interval = setInterval(async () => {
async function deactivateMember(member) {
//if (ds.get(member.id + "deactivated")) return "member is already deactivated";
await member.roles.add(config.inactive_role);
ds.put(member.id + "deactivated");
ds.put(member.id, Date.now());
var magic_channel = client.channels.resolve(ds.get(member.id + "magicchannelid"));
if (!magic_channel) {
@@ -82,17 +83,19 @@ async function deactivateMember(member) {
}
var magic_channel_message_id = ds.get(member.id + "magicchannelmessage");
var unique_code = Math.random().toString();
ds.put(unique_code, member.id);
var content = `${config.base_uri}/detect/${unique_code}`;
if (!magic_channel_message_id) {
var magic_channel_message = await magic_channel.send(`${config.base_uri}/detect/${member.id}?${Math.random()}`);
var magic_channel_message = await magic_channel.send({content});
ds.put(member.id + "magicchannelmessage", magic_channel_message.id)
} else {
await magic_channel.messages.edit(magic_channel_message_id, {content: `${config.base_uri}/detect/${member.id}?${Math.random()}`});
await magic_channel.messages.edit(magic_channel_message_id, {content});
}
}
async function reactivateMember(member) {
//if (!ds.get(member.id + "deactivated")) return "member is not deactivated";
await member.roles.remove(config.inactive_role);
ds.del(member.id + "deactivated");
var magic_channel = client.channels.resolve(ds.get(member.id + "magicchannelid"));
@@ -100,4 +103,14 @@ async function reactivateMember(member) {
}
module.exports.deactivateMember = deactivateMember;
module.exports.reactivateMember = reactivateMember;
module.exports.reactivateMember = reactivateMember;
client.on("messageCreate", async message => {
if (message.guildId != config.guild) return;
let deactivatedMembersMentionedViaRoles = [...new Set(message.mentions.roles.flatMap(r => r.members).values())].filter(x => ds.get(x.id + "deactivated"));
if (deactivatedMembersMentionedViaRoles.length) {
for (let m of deactivatedMembersMentionedViaRoles) await reactivateMember(m);
await message.reply({content: deactivatedMembersMentionedViaRoles.map(String).join(' '), allowedMentions:{repliedUser: false}});
}
});
+17 -16
View File
@@ -1,5 +1,4 @@
class DiscordBackup {
module.exports = class DiscordBackup {
constructor(guild) {
this.guild = guild;
this.data = {};
@@ -14,33 +13,35 @@ class DiscordBackup {
this.data.members = await this.guild.client.api.guilds(this.guild.id).members.get({query: {limit: 1000}});
}
async backupChannel(channel) {
async backupChannel(channelId) {
var data = {
channel: await client.api.channels[channel.id].get(),
channel: await this.guild.client.api.channels[channelId].get(),
messages: []
};
do {
var messages = await client.api.channels[channel.id].messages.get({ query: {options: {
before: messages?.[0].id, limit: 100
}}});
data.messages.unshift(...messages);
} while (messages.length > 0);
this.data.channels ||= [];
this.data.channels.push(data);
do {
var messages = await this.guild.client.api.channels[channelId].messages.get({query: {
before: messages?.at(-1)?.id, limit: 100
}});
data.messages.push(...messages);
} while (messages.length > 0);
}
async backupEverything() {
await this.backupGuild();
await this.backupMembers();
for (let [id, channel] of this.guild.channels) {
await this.backupChannel(channel);
for (let channelId of this.guild.channels.cache.keys()) {
try {
await this.backupChannel(channelId);
} catch (error) {
console.error(error.stack);
}
}
}
async serialize() {
serialize() {
return JSON.stringify(this.data);
}
}
module.exports.DiscordBackup = DiscordBackup;
}
-73
View File
@@ -10,76 +10,3 @@ client.login(config.token).then(async () => {
console.log("ready");
(await client.channels.fetch(config.bot_channel))?.send('a');
});
/* small misc stuff here */
////////////////////////////////////////////////////////////////////////////////////////
client.on("guildMemberAdd", member => {
if (member.guild.id != config.guild) return;
// add role
member.roles.add(member.user.bot ? config.bot_role : config.human_role);
});
// join message
client.on("messageDelete", message => {
if (message.channel.id != config.default_channel) return;
if (message.type != "GUILD_MEMBER_JOIN") return;
client.channels.resolve(config.default_channel)?.send(
`sussy baka ${message.author} deleted their join message ||(from <t:${message.createdAt.valueOf()}>)||`
);
});
client.on("guildMemberRemove", member => {
if (member.guild.id != config.guild) return;
// leave message
client.channels.resolve(config.default_channel)?.send(random([
`${member.user.username} left`,
`${member.user.username} disappeared`,
`${member.user.username.toLowerCase()} is gone`
]));
});
client.on("messageCreate", message => {
// comment thread on announcements
message.channel.id == config.announcement_channel && message.startThread({name: "Comments"});
// stupid m bot
message.author.id == "732072478519722096" && message.content.endsWith("is bad letter m is much better") && message.delete();
});
// add reactions to video and audio
{
let a = async m => {
if (m.guild?.id != config.guild) return;
if ((m.embeds.some(e => e.type == "video") || m.attachments.some(a => a.contentType?.startsWith('video'))) && !m.g) {
m.g = true;
m.react(config.mi_emoji);
}
if (m.attachments.some(a => a.contentType?.startsWith('audio')) && !m.d) {
m.d = true;
m.react(config.ki_emoji);
}
}
client.on("messageCreate", a);
client.on("messageUpdate", (r, q) => a(q));
}
// thing to access archived channels
client.on("voiceStateUpdate", (oldState, newState) => {
if (newState.guild.id != config.guild) return;
if (oldState.channelId != config.archive_portal_voice_channel && newState.channelId == config.archive_portal_voice_channel) {
// join
newState.member?.roles.add(config.view_archived_channels_role);
} else if (oldState.channelId == config.archive_portal_voice_channel && newState.channelId != config.archive_portal_voice_channel) {
// leave
newState.member?.roles.remove(config.view_archived_channels_role);
}
});
// save deleted emojis
client.on("emojiDelete", emoji => {
client.channels.resolve(config.bot_channel)?.send({
content: "emoji deleted",
files: [{attachment: emoji.url, name: `${emoji.name}.${emoji.url.split('.').pop()}`}]
});
});
+6 -4
View File
@@ -115,8 +115,7 @@ commands.push({
{
name: "icon",
description: "Image URL or an emoji",
type: "STRING",
required: true
type: "STRING"
}
],
exec: async i => {
@@ -125,13 +124,13 @@ commands.push({
if (!colorRole) return void i.editReply({content: "You don't have color role!"});
try {
let icon = i.options.getString("icon");
if (icon.startsWith("http")) {
if (/^https?:\/\//i.test(icon)) {
await colorRole.setIcon(icon);
await i.editReply({files: [{
attachment: icon,
name: icon.match(/\/(\w*(?:\.png|\.jpg|\.jpeg|\.gif|\.webp))$/i)?.[1] || "icon.png"
}]});
} else {
} else if (icon) {
var emoji = Discord.Util.parseEmoji(icon);
if (emoji?.id) {
await colorRole.setIcon(i.client.rest.cdn.Emoji(emoji.id, emoji.animated ? 'gif' : 'png'));
@@ -139,6 +138,9 @@ commands.push({
await colorRole.setUnicodeEmoji(icon);
}
await i.editReply({content: icon});
} else {
await colorRole.setIcon(null);
await i.editReply({content: "icon removed"});
}
} catch (error) {
await i.editReply({content: error.message});
+109 -35
View File
@@ -38,32 +38,6 @@ var commands = module.exports = [
i.reply(owo);
}
},
{
name: "archive",
description: "Delete a channel without actually deleting it",
options: [
{
name: "channel",
description: "channel",
type: "CHANNEL",
required: true
}
],
defaultPermission: false,
permissions: [
{
id: config.admin_role,
type: "ROLE",
permission: true
}
],
exec: async i => {
let channel = i.options.getChannel("channel");
await channel.setParent(config.archive_category);
await channel.lockPermissions();
await i.reply({content: channel.toString()});
}
},
{
name: "avatar",
description: "View a user's original avatar (and save permanently as attachment)",
@@ -121,6 +95,115 @@ var commands = module.exports = [
name: "Steal Emoji",
type: "MESSAGE",
exec: i => commands.find(x => x.name == "steal").exec(i)
},
{
name: "setserverbanner",
description: "Set the server banner image",
options: [
{
name: "url",
description: "HTTP(S) URL to an image",
type: "STRING"
}
],
exec: async i => {
var url = i.options.getString("url");
try {
if (!url) {
await i.guild.setBanner(null);
await i.reply("cleared the server banner");
} else {
if (/^https?:\/\//i.test(url)) {
await i.guild.setBanner(url);
await i.reply(url);
} else {
await i.reply("http image url only!");
}
}
} catch (error) {
await i.reply(error.message);
}
}
},
{
name: "setservericon",
description: "Change the server icon",
options: [
{
name: "url",
description: "HTTP(S) URL to an image",
type: "STRING"
}
],
exec: async i => {
var url = i.options.getString("url");
try {
if (!url) {
await i.guild.setIcon(null);
await i.reply("cleared the server icon");
} else {
if (/^https?:\/\//i.test(url)) {
await i.guild.setIcon(url);
await i.reply(url);
} else {
await i.reply("http image url only!");
}
}
} catch (error) {
await i.reply(error.message);
}
}
},
{
name: "getemoji",
description: "Generate a URL for an emoji",
options: [
{
name: "emoji",
description: "The emoji (code) or the name of the emoji (case-sensitive)",
type: "STRING",
required: true
},
{
name: "format",
description: "choose image format",
type: "STRING",
choices: [
{name: "PNG", value: "png"},
{name: "JPG", value: "jpg"},
{name: "WEBP", value: "webp"},
{name: "GIF", value: "gif"}
]
},
{
name: "size",
description: "choose image size",
type: "INTEGER",
choices: "16,20,22,24,28,32,40,44,48,56,60,64,80,96,100,128".split(',').map(s => ({name: s, value: Number(s)}))
}
],
exec: i => {
var emojiname = i.options.getString("emoji");
if (emojiname.startsWith('<') && emojiname.endsWith('>')) emoji = Discord.Util.parseEmoji(emojiname);
else {
if (emojiname.startsWith(':')) emojiname = emojiname.slice(1);
if (emojiname.endsWith(':')) emojiname = emojiname.slice(-1);
var emoji = client.emojis.cache.find(e => e.name == emojiname);
if (!emoji) emoji = client.emojis.cache.find(e => e.name.toLowerCase() == emojiname.toLowerCase());
if (!emoji) return void i.reply(`could not find emoji named ${emojiname}`);
}
if (!emoji.id) return void i.reply(`invalid input`);
var qs = [];
var size = i.options.getInteger("size");
if (size) qs.push(`size=${size}`);
var format = i.options.getString("format");
if (!format) format = emoji.animated ? "gif" : "png";
if (format == "gif" && !emoji.animated) return void i.reply(`Non-animated emoji is not available as GIF.`);
if (format == "webp") qs.push(`quality=lossless`);
var url = `https://media.discordapp.net/emojis/${emoji.id}.${format}`;
if (qs.length > 0) url += '?' + qs.join('&');
i.reply(`${emoji.name}.${format}\n${url}`);
}
}
];
@@ -133,14 +216,5 @@ client.once("ready", async () => {
let guild_commands = commands.filter(x => !x.global);
let guild = client.guilds.resolve(config.guild);
await guild.commands.set(guild_commands);
await guild.commands.permissions.set({
fullPermissions: guild_commands.map(local_command => {
let discord_command = guild.commands.cache.find(discord_command => local_command.name == discord_command.name);
return {
id: discord_command.id,
permissions: local_command.permissions || []
}
})
});
await client.application.commands.set(global_commands);
});
+23 -5
View File
@@ -8,15 +8,16 @@ module.exports = {
human_role: "672956630962274306",
bot_role: "673671040010027034",
inactive_role: "892869309603389500",
verified_role: "949064806030254130",
view_archived_channels_role: "916056534402863125",
eval_undefined_emoji: "707729833601531935",
eval_undefined_emoji: "🅱️",
mi_emoji: "887931046086185060",
ki_emoji: "887935846710394910",
default_channel: "672956424162115586",
bot_channel: "782353314137505793",
default_channel: "949831184957980722",
bot_channel: "949831221981097984",
archive_channel: "802280618636869663",
moe_channel: "871864787213111366",
porn_channel: "835734868427669574",
porn_channel: "949831237927862333",
announcement_channel: "876010629490683955",
miku_channel: "900583427483516938",
archive_category: "887838689533771776",
@@ -25,26 +26,32 @@ module.exports = {
base_uri: "https://ldb.owo69.me",
world_clock: [
{
flag: "🇺🇸",
timezone: "America/Los_Angeles",
channel: "887897732428226660"
},
{
flag: "🇺🇸",
timezone: "America/New_York",
channel: "888507872932143155"
},
{
flag: "🇩🇪",
timezone: "Europe/Berlin",
channel: "887897886879281203"
},
{
flag: "🇷🇺",
timezone: "Europe/Moscow",
channel: "887897904738599002"
},
{
flag: "🇵🇭",
timezone: "Asia/Manila",
channel: "888505937315389451"
},
{
flag: "🇯🇵",
timezone: "Asia/Tokyo",
channel: "887897753198419999"
}
@@ -66,5 +73,16 @@ module.exports = {
tag: "巡音ルカ",
channel: "916444961958928394"
}
]
],
vrchat_status_category: "959236139913445376",
vrchat_configuration: {
username: process.env.VRCHAT_USERNAME,
password: process.env.VRCHAT_PASSWORD
},
masto: {
url: "https://mastodong.lol",
accessToken: process.env.MASTO_TOKEN
},
masto_account_id: "108643271047165149",
masto_webhook: process.env.DISCORD_WEBHOOK_FOR_MASTO
}
+81
View File
@@ -0,0 +1,81 @@
var client = require("./client.js");
var config = require("./config");
client.on("guildMemberAdd", member => {
if (member.guild.id != config.guild) return;
// add role
member.roles.add(member.user.bot ? config.bot_role : config.human_role);
// welcome message
/*setTimeout(() => {
client.channels.resolve(config.default_channel)?.send(
`Welcome ${member}. Please tell from where you entered this server and some other info about yourself in order to gain access to message history.`
);
}, 3000);*/
member.roles.add(config.verified_role);
});
// join message
/*client.on("messageDelete", message => {
if (message.channel.id != config.default_channel) return;
if (message.type != "GUILD_MEMBER_JOIN") return;
client.channels.resolve(config.default_channel)?.send(
`sussy baka ${message.author} deleted their join message ||(from <t:${Math.floor(message.createdAt.valueOf()/1000)}>)||`
);
});*/
client.on("guildMemberRemove", member => {
if (member.guild.id != config.guild) return;
// leave message
client.channels.resolve(config.default_channel)?.send(random([
`${member.user.username} left`,
`${member.user.username} disappeared`,
`${member.user.username.toLowerCase()} is gone`
]));
});
client.on("messageCreate", message => {
// comment thread on announcements
message.channel.id == config.announcement_channel && message.startThread({name: "Comments"});
// stupid m bot
message.author.id == "732072478519722096" && message.content.endsWith("is bad letter m is much better") && message.delete();
});
// add reactions to video and audio
{
let a = async m => {
if (m.guild?.id != config.guild) return;
if ((m.embeds.some(e => e.type == "video") || m.attachments.some(a => a.contentType?.startsWith('video'))) && !m.g) {
m.g = true;
m.react(config.mi_emoji);
}
if (m.attachments.some(a => a.contentType?.startsWith('audio')) && !m.d) {
m.d = true;
m.react(config.ki_emoji);
}
}
client.on("messageCreate", a);
client.on("messageUpdate", (r, q) => a(q));
}
// thing to access archived channels
client.on("voiceStateUpdate", (oldState, newState) => {
if (newState.guild.id != config.guild) return;
if (oldState.channelId != config.archive_portal_voice_channel && newState.channelId == config.archive_portal_voice_channel) {
// join
newState.member?.roles.add(config.view_archived_channels_role);
} else if (oldState.channelId == config.archive_portal_voice_channel && newState.channelId != config.archive_portal_voice_channel) {
// leave
newState.member?.roles.remove(config.view_archived_channels_role);
}
});
// save deleted emojis
client.on("emojiDelete", emoji => {
client.channels.resolve(config.bot_channel)?.send({
content: "emoji deleted",
files: [{attachment: emoji.url, name: `${emoji.name}.${emoji.url.split('.').pop()}`}]
});
});
//g=setInterval(() => client.guilds.resolve(config.guild)?.setIcon(`mf/${Math.floor(Math.random()*14548)}.png`), 1800000);
+1 -1
View File
@@ -9,7 +9,7 @@ client.on("messageCreate", async function (message) {
if (message.content.startsWith("!>")) {
with (message) {
try {
var x = await eval(message.content.substr(2).trim());
var x = await eval(message.content.substring(2).trim());
} catch(e) {
var x = e.message;
}
+4 -2
View File
@@ -1,10 +1,11 @@
process.title = "lamp discord bot";
process.on("unhandledRejection", error => {
console.error("Unhandled Rejection:\n" + error.stack);
console.error("Unhandled Rejection:\n", error.stack || error);
});
require("./util"); // global variables set in here
require("./client");
require("./discord-misc");
require('./eval-exec');
require('./colors');
require('./www');
@@ -16,4 +17,5 @@ require('./buttonthing');
require("./activitytracker");
require("./vocabularygame");
require("./pixiv-subscribe");
require("./count-cmd");
require("./count-cmd");
require("./masto");
+39
View File
@@ -0,0 +1,39 @@
var {login} = require("masto");
var config = require("./config");
var client = require("./client");
var {WebhookClient} = require("discord.js");
var webhook = new WebhookClient({url: config.masto_webhook});
module.exports.webhook = webhook;
client.once("ready", async () => {
var donger = await login(config.masto);
console.log("donger logged in");
module.exports.donger = donger;
(async function openStream() {
try {
var stream = await donger.stream.streamUser();
module.exports.stream = stream;
stream.on("update", toot => {
if (toot.account.id != config.masto_account_id) return;
if (toot.visibility != "public") return;
if (toot.inReplyToAccountId && toot.inReplyToAccountId != toot.account.id) return;
webhook.send(toot.url || toot.reblog.url); //todo maybe custom embed
//todo maybe handle deletes
});
stream.ws.on("close", () => {
console.log("donger stream closed");
setTimeout(openStream, 10000);
});
} catch (error) {
console.error("donger stream", error.message);
setTimeout(openStream, 60000);
}
})();
});
+627 -272
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -2,12 +2,13 @@
"dependencies": {
"@discordjs/voice": "^0.7.5",
"deepl": "^1.0.12",
"discord.js": "github:iShibi/discord.js#feat-role-icon",
"discord.js": "^13.6.0",
"express": "^4.17.1",
"fast-average-color-node": "^1.0.3",
"kuroshiro": "^1.2.0",
"kuroshiro-analyzer-kuromoji": "^1.1.0",
"libsodium-wrappers": "^0.7.9",
"masto": "^4.4.0",
"node-fetch": "^2.6.1"
}
}
+5 -5
View File
@@ -8,7 +8,7 @@ var app = require("./www");
var commands = require("./commands");
commands.push({
/*commands.push({
type: "MESSAGE",
name: "Archive",
exec: async i => {
@@ -19,17 +19,17 @@ commands.push({
ephemeral: true
});
}
});
});*/
client.on("messageReactionAdd", async (reaction, user) => {
if (reaction.emoji.name == '📍' || reaction.emoji.name == '📌') {
if (!reaction.message.guild) return;
if (reaction.message.channel.id == config.archive_channel) return;
if (reaction.message['has been "pinned"'] || reaction.count > 1) return;
reaction.message['has been "pinned"'] = true;
if (reaction.message['has been pinned'] || reaction.count > 1) return;
reaction.message['has been pinned'] = true;
if (reaction.message.channel.id == config.porn_channel) {
/*if (reaction.message.channel.id == config.porn_channel)*/ {
try {
await reaction.message.pin();
} catch (e) {
+1 -1
View File
@@ -67,7 +67,7 @@ async function embedPixiv(/*message*/ channel, /*array of*/ links, send = channe
}
} else await fallback();
function fallback() {
let urls = images.map(image => image.url.replace("i.pximg.net", "pximg-proxy.cf"));
let urls = images.map(image => image.url.replace("i.pximg.net", "px.owo39.me"));
if (illust.xRestrict && !channel.nsfw) urls = urls.map(url => `||${url} ||`);
urls = urls.join('\n');
if (urls.length > 2000) {
+2 -1
View File
@@ -17,9 +17,10 @@ async function check(tag, channel) {
} else break;
}
for (let i = newPosts.length - 1; i >= 0; i--) {
let url = `https://www.pixiv.net/en/artworks/${newPosts[i].id}`;
await embedPixiv(
client.channels.resolve(channel),
[`https://www.pixiv.net/en/artworks/${newPosts[i].id}`],
[url],
undefined,
true
);
+107 -19
View File
@@ -6,6 +6,37 @@ var KuromojiAnalyzer = require("kuroshiro-analyzer-kuromoji");
var kuroshiro = new Kuroshiro();
kuroshiro.init(new KuromojiAnalyzer());
var lang2flag = {
BG: '🇧🇬',
CS: '🇨🇿',
DA: '🇩🇰',
DE: '🇩🇪',
EL: '🇬🇷',
EN: '🇬🇧',
'EN-GB': '🇬🇧',
'EN-US': '🇺🇸',
ES: '🇪🇸',
ET: '🇪🇪',
FI: '🇫🇮',
FR: '🇫🇷',
HU: '🇭🇺',
IT: '🇮🇹',
JA: '🇯🇵',
LT: '🇱🇹',
LV: '🇱🇻',
NL: '🇳🇱',
PL: '🇵🇱',
PT: '🇵🇹',
'PT-PT': '🇵🇹',
'PT-BR': '🇧🇷',
RO: '🇷🇴',
RU: '🇷🇺',
SK: '🇸🇰',
SL: '🇸🇮',
SV: '🇸🇻',
ZH: '🇨🇳'
};
commands.push({
name: "toen",
@@ -15,7 +46,7 @@ commands.push({
{
type: "STRING",
name: "text",
description: "Text",
description: "Text to translate",
required: true
}
],
@@ -29,16 +60,65 @@ commands.push({
{
type: "STRING",
name: "text",
description: "Text",
description: "Text to translate",
required: true
}
],
exec: i => t(i, "JA")
});
commands.push({
name: "tolang",
description: "Translate text to any language",
global: true,
options: [
{
type: "STRING",
name: "lang",
description: "Language to translate to",
required: true,
choices: [
{ name: 'Bulgarian', value: 'BG' },
{ name: 'Czech', value: 'CS' },
{ name: 'Danish', value: 'DA' },
{ name: 'German', value: 'DE' },
{ name: 'Greek', value: 'EL' },
{ name: 'English (British)', value: 'EN-GB' },
{ name: 'English (American)', value: 'EN-US' },
{ name: 'Spanish', value: 'ES' },
{ name: 'Estonian', value: 'ET' },
{ name: 'Finnish', value: 'FI' },
{ name: 'French', value: 'FR' },
{ name: 'Hungarian', value: 'HU' },
{ name: 'Italian', value: 'IT' },
{ name: 'Japanese', value: 'JA' },
{ name: 'Lithuanian', value: 'LT' },
{ name: 'Latvian', value: 'LV' },
{ name: 'Dutch', value: 'NL' },
{ name: 'Polish', value: 'PL' },
// { name: 'Portuguese (all Portuguese varieties excluding Brazilian Portuguese)', value: 'PT-PT' },
{ name: 'Portuguese (Brazilian)', value: 'PT-BR' },
{ name: 'Romanian', value: 'RO' },
{ name: 'Russian', value: 'RU' },
{ name: 'Slovak', value: 'SK' },
{ name: 'Slovenian', value: 'SL' },
{ name: 'Swedish', value: 'SV' },
{ name: 'Chinese', value: 'ZH' }
]
},
{
type: "STRING",
name: "text",
description: "Text to translate",
required: true
}
],
exec: i => t(i, i.options.getString("lang"))
});
async function t(i, target_lang) {
var text = i.options.getString("text");
await i.deferReply();
try {
var translation = (await deepl({
text,
@@ -49,18 +129,24 @@ async function t(i, target_lang) {
} catch (error) {
return void await i.editReply(error.message);
}
if (translation.detected_source_language == "JA") {
try {
var input_romaji = await kuroshiro.convert(text, {to: "romaji", mode: "spaced"});
} catch (error) {}
}
if (target_lang == "JA") {
try {
var output_romaji = await kuroshiro.convert(translation.text, {to: "romaji", mode: "spaced"});
} catch (error) {}
}
let msg = `${text}${input_romaji ? `\n${input_romaji}` : ''}\n${translation.text}${output_romaji ? `\n${output_romaji}` : ''}`;
if (translation.detected_source_language == "JA") try {
var input_romaji = await kuroshiro.convert(text, {to: "romaji", mode: "spaced"});
} catch (error) {}
if (target_lang == "JA") try {
var output_romaji = await kuroshiro.convert(translation.text, {to: "romaji", mode: "spaced"});
} catch (error) {}
let input_flag = lang2flag[translation.detected_source_language] || `[${translation.detected_source_language}]`;
let output_flag = lang2flag[target_lang] || `[${target_lang}]`;
let msg = input_flag + ' ' + text;
if (input_romaji) msg += '\n' + input_flag + ' ' + input_romaji;
msg += '\n' + output_flag + ' ' + translation.text;
if (output_romaji) msg += '\n' + output_flag + ' ' + output_romaji;
await i.editReply(msg);
try {
var reverse_translation = (await deepl({
text: translation.text,
@@ -68,13 +154,15 @@ async function t(i, target_lang) {
free_api: true,
auth_key: config.deepl_auth_key
})).data.translations[0];
if (text.toLowerCase() != reverse_translation.text.toLowerCase()){
if (translation.detected_source_language == "JA") {
try {
var reverse_romaji = await kuroshiro.convert(reverse_translation.text, {to: "romaji", mode: "spaced"});
} catch (error) {}
}
if (normalize(text) != normalize(reverse_translation.text)){
if (translation.detected_source_language == "JA") try {
var reverse_romaji = await kuroshiro.convert(reverse_translation.text, {to: "romaji", mode: "spaced"});
} catch (error) {}
await i.editReply(`${msg}\n🔁 ${reverse_translation.text}${reverse_romaji ? `\n🔁 ${reverse_romaji}` : ''}`);
}
} catch(error) {}
}
function normalize(text) {
return text.toLowerCase()//.split('').filter(x => x.match(/[a-z0-9 ]/)).join('');
}
+2 -2
View File
@@ -5,7 +5,7 @@ client.once("ready", () => {
(function clock() {
var d = new Date();
for (let x of config.world_clock) {
let t = Intl.DateTimeFormat("en", {
let t = x.flag + ' ' + Intl.DateTimeFormat("en", {
timeZone: x.timezone,
hour: 'numeric',
//minute: 'numeric',
@@ -17,5 +17,5 @@ client.once("ready", () => {
}
d.setMinutes(60);
setTimeout(clock, d - Date.now());
})();
})();
});