allow discord users to opt out of the bridge
This commit is contained in:
parent
800b9ed492
commit
8acd65159d
6 changed files with 100 additions and 7 deletions
|
@ -3,7 +3,7 @@
|
|||
import { client } from "./client";
|
||||
import { REST } from '@discordjs/rest';
|
||||
import { Routes } from 'discord-api-types/v9';
|
||||
import { BRIDGED_MESSAGES, BRIDGE_CONFIG, BRIDGE_REQUESTS, logger } from "..";
|
||||
import { BRIDGED_MESSAGES, BRIDGE_CONFIG, BRIDGE_REQUESTS, BRIDGE_USER_CONFIG, logger } from "..";
|
||||
import { MessageEmbed, TextChannel } from "discord.js";
|
||||
import { revoltFetchMessage, revoltFetchUser } from "../util";
|
||||
import { client as revoltClient } from "../revolt/client";
|
||||
|
@ -36,7 +36,20 @@ const COMMANDS: any[] = [
|
|||
name: 'help',
|
||||
description: 'Usage instructions',
|
||||
type: 1,
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'opt_out',
|
||||
description: 'Opt out of having your messages bridged',
|
||||
type: 1,
|
||||
options: [
|
||||
{
|
||||
name: 'opt_out',
|
||||
description: 'Whether you wish to opt out of having your messages bridged',
|
||||
optional: true,
|
||||
type: 5 // Boolean
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -168,6 +181,46 @@ client.on('interactionCreate', async interaction => {
|
|||
await interaction.reply({ embeds: [ embed ], ephemeral: true });
|
||||
break;
|
||||
|
||||
case 'opt_out':
|
||||
const optOut = interaction.options.getBoolean('opt_out', false);
|
||||
if (optOut == null) {
|
||||
const userConfig = await BRIDGE_USER_CONFIG.findOne({ id: interaction.user.id });
|
||||
if (userConfig?.optOut) {
|
||||
return await interaction.reply({
|
||||
ephemeral: true,
|
||||
content: 'You are currently **opted out** of message bridging. ' +
|
||||
'Users on Revolt **will not** see your username, avatar or message content.'
|
||||
});
|
||||
} else {
|
||||
return await interaction.reply({
|
||||
ephemeral: true,
|
||||
content: 'You are currently **not** opted out of message bridging. ' +
|
||||
'All your messages in a bridged channel will be sent to the associated Revolt channel.'
|
||||
});
|
||||
}
|
||||
} else {
|
||||
await BRIDGE_USER_CONFIG.update(
|
||||
{ id: interaction.user.id },
|
||||
{
|
||||
$setOnInsert: { id: interaction.user.id },
|
||||
$set: { optOut },
|
||||
},
|
||||
{ upsert: true }
|
||||
);
|
||||
|
||||
return await interaction.reply({
|
||||
ephemeral: true,
|
||||
content: `You have **opted ${optOut ? 'out of' : 'into'}** message bridging. `
|
||||
+ (
|
||||
optOut
|
||||
? 'Your username, avatar and message content will no longer be visible on Revolt.\n' +
|
||||
'Please note that some servers may be configured to automatically delete your messages.'
|
||||
: 'All your messages in a bridged channel will be sent to the associated Revolt channel.'
|
||||
),
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
default: await interaction.reply('Unknown subcommand');
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { BRIDGED_MESSAGES, BRIDGE_CONFIG, logger } from "..";
|
||||
import { BRIDGED_MESSAGES, BRIDGE_CONFIG, BRIDGE_USER_CONFIG, logger } from "..";
|
||||
import { client } from "./client";
|
||||
import { AUTUMN_URL, client as revoltClient } from "../revolt/client";
|
||||
import axios from 'axios';
|
||||
|
@ -27,6 +27,7 @@ client.on('messageDelete', async message => {
|
|||
]);
|
||||
|
||||
if (!bridgedMsg?.revolt) return logger.debug(`Discord: Message has not been bridged; ignoring deletion`);
|
||||
if (!bridgedMsg.ignore) return logger.debug(`Discord: Message marked as ignore`);
|
||||
if (!bridgeCfg?.revolt) return logger.debug(`Discord: No Revolt channel associated`);
|
||||
|
||||
const targetMsg = await revoltFetchMessage(bridgedMsg.revolt.messageId, revoltClient.channels.get(bridgeCfg.revolt));
|
||||
|
@ -51,6 +52,7 @@ client.on('messageUpdate', async (oldMsg, newMsg) => {
|
|||
]);
|
||||
|
||||
if (!bridgedMsg) return logger.debug(`Discord: Message has not been bridged; ignoring edit`);
|
||||
if (!bridgedMsg.ignore) return logger.debug(`Discord: Message marked as ignore`);
|
||||
if (!bridgeCfg?.revolt) return logger.debug(`Discord: No Revolt channel associated`);
|
||||
if (newMsg.webhookId && newMsg.webhookId == bridgeCfg.discordWebhook?.id) {
|
||||
return logger.debug(`Discord: Message was sent by bridge; ignoring edit`);
|
||||
|
@ -69,12 +71,13 @@ client.on('messageUpdate', async (oldMsg, newMsg) => {
|
|||
client.on('messageCreate', async message => {
|
||||
try {
|
||||
logger.debug(`[M] Discord: ${message.content}`);
|
||||
const [ bridgeCfg, bridgedReply ] = await Promise.all([
|
||||
const [ bridgeCfg, bridgedReply, userConfig ] = await Promise.all([
|
||||
BRIDGE_CONFIG.findOne({ discord: message.channelId }),
|
||||
(message.reference?.messageId
|
||||
? BRIDGED_MESSAGES.findOne({ "discord.messageId": message.reference.messageId })
|
||||
: undefined
|
||||
),
|
||||
BRIDGE_USER_CONFIG.findOne({ id: message.author.id }),
|
||||
]);
|
||||
|
||||
if (message.webhookId && bridgeCfg?.discordWebhook?.id == message.webhookId) {
|
||||
|
@ -98,6 +101,11 @@ client.on('messageCreate', async message => {
|
|||
}
|
||||
}
|
||||
|
||||
if (bridgeCfg.disallowIfOptedOut && userConfig?.optOut && message.deletable) {
|
||||
await message.delete();
|
||||
return;
|
||||
}
|
||||
|
||||
// Setting a known nonce allows us to ignore bridged
|
||||
// messages while still letting other AutoMod messages pass.
|
||||
const nonce = ulid();
|
||||
|
@ -105,7 +113,7 @@ client.on('messageCreate', async message => {
|
|||
await BRIDGED_MESSAGES.update(
|
||||
{ "discord.messageId": message.id },
|
||||
{
|
||||
$setOnInsert: {
|
||||
$setOnInsert: userConfig?.optOut ? {} : {
|
||||
origin: 'discord',
|
||||
discord: {
|
||||
messageId: message.id,
|
||||
|
@ -116,12 +124,32 @@ client.on('messageCreate', async message => {
|
|||
channels: {
|
||||
discord: message.channelId,
|
||||
revolt: bridgeCfg.revolt,
|
||||
}
|
||||
},
|
||||
ignore: userConfig?.optOut,
|
||||
}
|
||||
},
|
||||
{ upsert: true }
|
||||
);
|
||||
|
||||
if (userConfig?.optOut) {
|
||||
const msg = await channel.sendMessage({
|
||||
content: `$\\color{#565656}\\small{\\textsf{Message content redacted}}$`,
|
||||
masquerade: {
|
||||
name: 'AutoMod Bridge',
|
||||
},
|
||||
nonce: nonce,
|
||||
});
|
||||
|
||||
await BRIDGED_MESSAGES.update(
|
||||
{ "discord.messageId": message.id },
|
||||
{
|
||||
$set: { "revolt.messageId": msg._id },
|
||||
}
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const autumnUrls: string[] = [];
|
||||
|
||||
// todo: upload all attachments at once instead of sequentially
|
||||
|
|
|
@ -8,6 +8,7 @@ import BridgeConfig from './types/BridgeConfig';
|
|||
import BridgedMessage from './types/BridgedMessage';
|
||||
import BridgeRequest from './types/BridgeRequest';
|
||||
import DiscordBridgedEmoji from './types/DiscordBridgedEmoji';
|
||||
import BridgeUserConfig from './types/BridgeUserConfig';
|
||||
|
||||
config();
|
||||
|
||||
|
@ -17,6 +18,7 @@ const BRIDGED_MESSAGES: ICollection<BridgedMessage> = db.get('bridged_messages')
|
|||
const BRIDGE_CONFIG: ICollection<BridgeConfig> = db.get('bridge_config');
|
||||
const BRIDGE_REQUESTS: ICollection<BridgeRequest> = db.get('bridge_requests');
|
||||
const BRIDGED_EMOJIS: ICollection<DiscordBridgedEmoji> = db.get('bridged_emojis');
|
||||
const BRIDGE_USER_CONFIG: ICollection<BridgeUserConfig> = db.get('bridge_user_config');
|
||||
|
||||
for (const v of [ 'REVOLT_TOKEN', 'DISCORD_TOKEN', 'DB_STRING' ]) {
|
||||
if (!process.env[v]) {
|
||||
|
@ -33,4 +35,4 @@ for (const v of [ 'REVOLT_TOKEN', 'DISCORD_TOKEN', 'DB_STRING' ]) {
|
|||
]);
|
||||
})();
|
||||
|
||||
export { logger, db, BRIDGED_MESSAGES, BRIDGE_CONFIG, BRIDGE_REQUESTS, BRIDGED_EMOJIS }
|
||||
export { logger, db, BRIDGED_MESSAGES, BRIDGE_CONFIG, BRIDGE_REQUESTS, BRIDGED_EMOJIS, BRIDGE_USER_CONFIG }
|
||||
|
|
|
@ -10,4 +10,7 @@ export default class {
|
|||
id: string;
|
||||
token: string;
|
||||
}
|
||||
|
||||
// If true, messages by users who have opted out of bridging will be deleted.
|
||||
disallowIfOptedOut?: boolean;
|
||||
}
|
||||
|
|
5
bridge/src/types/BridgeUserConfig.ts
Normal file
5
bridge/src/types/BridgeUserConfig.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
export default class {
|
||||
platform: 'discord'; // Todo: Revolt users too?
|
||||
id: string;
|
||||
optOut?: boolean;
|
||||
}
|
|
@ -15,4 +15,6 @@ export default class {
|
|||
discord: string;
|
||||
revolt: string;
|
||||
}
|
||||
|
||||
ignore?: boolean;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue