3
0
Fork 0
mirror of https://github.com/ZeppelinBot/Zeppelin.git synced 2025-03-16 14:11:50 +00:00

Add permission checks and alerts to Automod 'reply' action

This commit is contained in:
Dragory 2021-04-11 14:13:25 +03:00
parent c5cab69f98
commit e6461d541d
No known key found for this signature in database
GPG key ID: 5F387BA66DF8AAC1

View file

@ -9,10 +9,13 @@ import {
tMessageContent, tMessageContent,
tNullable, tNullable,
unique, unique,
verboseChannelMention,
} from "../../../utils"; } from "../../../utils";
import { TextChannel } from "eris"; import { AdvancedMessageContent, Constants, MessageContent, TextChannel, User } from "eris";
import { AutomodContext } from "../types"; import { AutomodContext } from "../types";
import { renderTemplate } from "../../../templateFormatter"; import { renderTemplate } from "../../../templateFormatter";
import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions";
import { LogType } from "../../../data/LogType";
export const ReplyAction = automodAction({ export const ReplyAction = automodAction({
configType: t.union([ configType: t.union([
@ -25,7 +28,7 @@ export const ReplyAction = automodAction({
defaultConfig: {}, defaultConfig: {},
async apply({ pluginData, contexts, actionConfig }) { async apply({ pluginData, contexts, actionConfig, ruleName }) {
const contextsWithTextChannels = contexts const contextsWithTextChannels = contexts
.filter(c => c.message?.channel_id) .filter(c => c.message?.channel_id)
.filter(c => pluginData.guild.channels.get(c.message!.channel_id) instanceof TextChannel); .filter(c => pluginData.guild.channels.get(c.message!.channel_id) instanceof TextChannel);
@ -40,7 +43,7 @@ export const ReplyAction = automodAction({
}, new Map()); }, new Map());
for (const [channelId, _contexts] of contextsByChannelId.entries()) { for (const [channelId, _contexts] of contextsByChannelId.entries()) {
const users = unique(Array.from(new Set(_contexts.map(c => c.user).filter(Boolean)))); const users = unique(Array.from(new Set(_contexts.map(c => c.user).filter(Boolean)))) as User[];
const user = users[0]; const user = users[0];
const renderReplyText = async str => const renderReplyText = async str =>
@ -50,10 +53,37 @@ export const ReplyAction = automodAction({
const formatted = const formatted =
typeof actionConfig === "string" typeof actionConfig === "string"
? await renderReplyText(actionConfig) ? await renderReplyText(actionConfig)
: await renderRecursively(actionConfig.text, renderReplyText); : ((await renderRecursively(actionConfig.text, renderReplyText)) as AdvancedMessageContent);
if (formatted) { if (formatted) {
const channel = pluginData.guild.channels.get(channelId) as TextChannel; const channel = pluginData.guild.channels.get(channelId) as TextChannel;
// Check for basic Send Messages and View Channel permissions
if (
!hasDiscordPermissions(
channel.permissionsOf(pluginData.client.user.id),
Constants.Permissions.sendMessages | Constants.Permissions.readMessages,
)
) {
pluginData.state.logs.log(LogType.BOT_ALERT, {
body: `Missing permissions to reply in ${verboseChannelMention(channel)} in Automod rule \`${ruleName}\``,
});
continue;
}
// If the message is an embed, check for embed permissions
if (
typeof formatted !== "string" &&
!hasDiscordPermissions(channel.permissionsOf(pluginData.client.user.id), Constants.Permissions.embedLinks)
) {
pluginData.state.logs.log(LogType.BOT_ALERT, {
body: `Missing permissions to reply **with an embed** in ${verboseChannelMention(
channel,
)} in Automod rule \`${ruleName}\``,
});
continue;
}
const replyMsg = await channel.createMessage(formatted); const replyMsg = await channel.createMessage(formatted);
if (typeof actionConfig === "object" && actionConfig.auto_delete) { if (typeof actionConfig === "object" && actionConfig.auto_delete) {