mirror of
https://github.com/ZeppelinBot/Zeppelin.git
synced 2025-03-16 14:11:50 +00:00
added join and leave voice channel triggers
This commit is contained in:
parent
8445c37f64
commit
03ead92c19
7 changed files with 207 additions and 1 deletions
|
@ -29,6 +29,7 @@ import {
|
||||||
RunAutomodOnThreadDelete,
|
RunAutomodOnThreadDelete,
|
||||||
RunAutomodOnThreadUpdate,
|
RunAutomodOnThreadUpdate,
|
||||||
} from "./events/runAutomodOnThreadEvents";
|
} from "./events/runAutomodOnThreadEvents";
|
||||||
|
import { RunAutomodOnVoiceStateUpdate } from "./events/runAutomodOnVoiceStateUpdate";
|
||||||
import { clearOldRecentNicknameChanges } from "./functions/clearOldNicknameChanges";
|
import { clearOldRecentNicknameChanges } from "./functions/clearOldNicknameChanges";
|
||||||
import { clearOldRecentActions } from "./functions/clearOldRecentActions";
|
import { clearOldRecentActions } from "./functions/clearOldRecentActions";
|
||||||
import { clearOldRecentSpam } from "./functions/clearOldRecentSpam";
|
import { clearOldRecentSpam } from "./functions/clearOldRecentSpam";
|
||||||
|
@ -207,7 +208,6 @@ export const AutomodPlugin = zeppelinGuildPlugin<AutomodPluginType>()({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
// prettier-ignore
|
|
||||||
events: [
|
events: [
|
||||||
RunAutomodOnJoinEvt,
|
RunAutomodOnJoinEvt,
|
||||||
RunAutomodOnMemberUpdate,
|
RunAutomodOnMemberUpdate,
|
||||||
|
@ -215,6 +215,7 @@ export const AutomodPlugin = zeppelinGuildPlugin<AutomodPluginType>()({
|
||||||
RunAutomodOnThreadCreate,
|
RunAutomodOnThreadCreate,
|
||||||
RunAutomodOnThreadDelete,
|
RunAutomodOnThreadDelete,
|
||||||
RunAutomodOnThreadUpdate
|
RunAutomodOnThreadUpdate
|
||||||
|
RunAutomodOnVoiceStateUpdate,
|
||||||
// Messages use message events from SavedMessages, see onLoad below
|
// Messages use message events from SavedMessages, see onLoad below
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
import { typedGuildEventListener } from "knub";
|
||||||
|
import { AutomodContext, AutomodPluginType } from "../types";
|
||||||
|
import { runAutomod } from "../functions/runAutomod";
|
||||||
|
import { noop } from "../../../utils";
|
||||||
|
|
||||||
|
export const RunAutomodOnVoiceStateUpdate = typedGuildEventListener<AutomodPluginType>()({
|
||||||
|
event: "voiceStateUpdate",
|
||||||
|
async listener({ pluginData, args: { newState, oldState } }) {
|
||||||
|
const oldChannel = newState.channel;
|
||||||
|
const { channel: newChannel, guild } = newState;
|
||||||
|
const timestamp = Date.now();
|
||||||
|
|
||||||
|
const member = newState.member ?? oldState.member ?? (await guild.members.fetch(newState.id).catch(noop));
|
||||||
|
if (!member) return;
|
||||||
|
|
||||||
|
if (!oldChannel && newChannel) {
|
||||||
|
const context: AutomodContext = {
|
||||||
|
member,
|
||||||
|
timestamp,
|
||||||
|
voiceChannel: {
|
||||||
|
joined: newChannel,
|
||||||
|
},
|
||||||
|
user: member.user,
|
||||||
|
};
|
||||||
|
|
||||||
|
pluginData.state.queue.add(() => {
|
||||||
|
runAutomod(pluginData, context);
|
||||||
|
});
|
||||||
|
} else if (oldChannel && !newChannel) {
|
||||||
|
const context: AutomodContext = {
|
||||||
|
member,
|
||||||
|
timestamp,
|
||||||
|
voiceChannel: {
|
||||||
|
left: oldChannel,
|
||||||
|
},
|
||||||
|
user: member.user,
|
||||||
|
};
|
||||||
|
|
||||||
|
pluginData.state.queue.add(() => {
|
||||||
|
runAutomod(pluginData, context);
|
||||||
|
});
|
||||||
|
} else if (oldChannel?.id && newChannel?.id && oldChannel.id === newChannel.id) {
|
||||||
|
const context: AutomodContext = {
|
||||||
|
member,
|
||||||
|
timestamp,
|
||||||
|
voiceChannel: {
|
||||||
|
left: oldChannel,
|
||||||
|
joined: newChannel,
|
||||||
|
},
|
||||||
|
user: member.user,
|
||||||
|
};
|
||||||
|
|
||||||
|
pluginData.state.queue.add(() => {
|
||||||
|
runAutomod(pluginData, context);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
|
@ -7,7 +7,9 @@ import { BanTrigger } from "./ban";
|
||||||
import { CharacterSpamTrigger } from "./characterSpam";
|
import { CharacterSpamTrigger } from "./characterSpam";
|
||||||
import { CounterTrigger } from "./counterTrigger";
|
import { CounterTrigger } from "./counterTrigger";
|
||||||
import { EmojiSpamTrigger } from "./emojiSpam";
|
import { EmojiSpamTrigger } from "./emojiSpam";
|
||||||
|
import { JoinVoiceChannelTrigger } from "./joinVoiceChannel";
|
||||||
import { KickTrigger } from "./kick";
|
import { KickTrigger } from "./kick";
|
||||||
|
import { LeaveVoiceChannelTrigger } from "./leaveVoiceChannel";
|
||||||
import { LineSpamTrigger } from "./lineSpam";
|
import { LineSpamTrigger } from "./lineSpam";
|
||||||
import { LinkSpamTrigger } from "./linkSpam";
|
import { LinkSpamTrigger } from "./linkSpam";
|
||||||
import { MatchAttachmentTypeTrigger } from "./matchAttachmentType";
|
import { MatchAttachmentTypeTrigger } from "./matchAttachmentType";
|
||||||
|
@ -21,6 +23,7 @@ import { MemberJoinSpamTrigger } from "./memberJoinSpam";
|
||||||
import { MemberLeaveTrigger } from "./memberLeave";
|
import { MemberLeaveTrigger } from "./memberLeave";
|
||||||
import { MentionSpamTrigger } from "./mentionSpam";
|
import { MentionSpamTrigger } from "./mentionSpam";
|
||||||
import { MessageSpamTrigger } from "./messageSpam";
|
import { MessageSpamTrigger } from "./messageSpam";
|
||||||
|
import { MoveVoiceChannelTrigger } from "./moveVoiceChannel";
|
||||||
import { MuteTrigger } from "./mute";
|
import { MuteTrigger } from "./mute";
|
||||||
import { NoteTrigger } from "./note";
|
import { NoteTrigger } from "./note";
|
||||||
import { RoleAddedTrigger } from "./roleAdded";
|
import { RoleAddedTrigger } from "./roleAdded";
|
||||||
|
@ -69,6 +72,10 @@ export const availableTriggers: Record<string, AutomodTriggerBlueprint<any, any>
|
||||||
ban: BanTrigger,
|
ban: BanTrigger,
|
||||||
unban: UnbanTrigger,
|
unban: UnbanTrigger,
|
||||||
|
|
||||||
|
join_voice_channel: JoinVoiceChannelTrigger,
|
||||||
|
leave_voice_channel: LeaveVoiceChannelTrigger,
|
||||||
|
move_voice_channel: MoveVoiceChannelTrigger,
|
||||||
|
|
||||||
antiraid_level: AntiraidLevelTrigger,
|
antiraid_level: AntiraidLevelTrigger,
|
||||||
|
|
||||||
thread_create: ThreadCreateTrigger,
|
thread_create: ThreadCreateTrigger,
|
||||||
|
@ -112,6 +119,10 @@ export const AvailableTriggers = t.type({
|
||||||
ban: BanTrigger.configType,
|
ban: BanTrigger.configType,
|
||||||
unban: UnbanTrigger.configType,
|
unban: UnbanTrigger.configType,
|
||||||
|
|
||||||
|
join_voice_channel: JoinVoiceChannelTrigger.configType,
|
||||||
|
leave_voice_channel: LeaveVoiceChannelTrigger.configType,
|
||||||
|
move_voice_channel: MoveVoiceChannelTrigger.configType,
|
||||||
|
|
||||||
antiraid_level: AntiraidLevelTrigger.configType,
|
antiraid_level: AntiraidLevelTrigger.configType,
|
||||||
|
|
||||||
thread_create: ThreadCreateTrigger.configType,
|
thread_create: ThreadCreateTrigger.configType,
|
||||||
|
|
37
backend/src/plugins/Automod/triggers/joinVoiceChannel.ts
Normal file
37
backend/src/plugins/Automod/triggers/joinVoiceChannel.ts
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import * as t from "io-ts";
|
||||||
|
import { automodTrigger } from "../helpers";
|
||||||
|
|
||||||
|
interface JoinVoiceChannelResult {
|
||||||
|
matchedChannelId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const JoinVoiceChannelTrigger = automodTrigger<JoinVoiceChannelResult>()({
|
||||||
|
configType: t.union([t.string, t.array(t.string)]),
|
||||||
|
|
||||||
|
defaultConfig: "",
|
||||||
|
|
||||||
|
async match({ triggerConfig, context }) {
|
||||||
|
if (!context.member || !context.voiceChannel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const triggerChannels = Array.isArray(triggerConfig) ? triggerConfig : [triggerConfig];
|
||||||
|
if (!triggerChannels.includes(context.voiceChannel.id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
extra: {
|
||||||
|
matchedChannelId: context.voiceChannel.id,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
renderMatchInformation({ matchResult, pluginData, contexts }) {
|
||||||
|
const channel = pluginData.guild.channels.get(matchResult.extra.matchedChannelId);
|
||||||
|
const channelName = channel?.name || "Unknown";
|
||||||
|
const member = contexts[0].member!;
|
||||||
|
const memberName = `**${member.user.username}#${member.user.discriminator}** (\`${member.id}\`)`;
|
||||||
|
return `${memberName} has joined the ${channelName} (\`${matchResult.extra.matchedChannelId}\`) voice channel`;
|
||||||
|
},
|
||||||
|
});
|
37
backend/src/plugins/Automod/triggers/leaveVoiceChannel.ts
Normal file
37
backend/src/plugins/Automod/triggers/leaveVoiceChannel.ts
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import * as t from "io-ts";
|
||||||
|
import { automodTrigger } from "../helpers";
|
||||||
|
|
||||||
|
interface LeaveVoiceChannelResult {
|
||||||
|
matchedChannelId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const LeaveVoiceChannelTrigger = automodTrigger<LeaveVoiceChannelResult>()({
|
||||||
|
configType: t.union([t.string, t.array(t.string)]),
|
||||||
|
|
||||||
|
defaultConfig: "",
|
||||||
|
|
||||||
|
async match({ triggerConfig, context }) {
|
||||||
|
if (!context.member || !context.voiceChannel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const triggerChannels = Array.isArray(triggerConfig) ? triggerConfig : [triggerConfig];
|
||||||
|
if (!triggerChannels.includes(context.voiceChannel.id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
extra: {
|
||||||
|
matchedChannelId: context.voiceChannel.id,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
renderMatchInformation({ matchResult, pluginData, contexts }) {
|
||||||
|
const channel = pluginData.guild.channels.get(matchResult.extra.matchedChannelId);
|
||||||
|
const channelName = channel?.name || "Unknown";
|
||||||
|
const member = contexts[0].member!;
|
||||||
|
const memberName = `**${member.user.username}#${member.user.discriminator}** (\`${member.id}\`)`;
|
||||||
|
return `${memberName} has left the ${channelName} (\`${matchResult.extra.matchedChannelId}\`) voice channel`;
|
||||||
|
},
|
||||||
|
});
|
58
backend/src/plugins/Automod/triggers/moveVoiceChannel.ts
Normal file
58
backend/src/plugins/Automod/triggers/moveVoiceChannel.ts
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
import * as t from "io-ts";
|
||||||
|
import { ChannelTypeStrings } from "../../../types";
|
||||||
|
import { automodTrigger } from "../helpers";
|
||||||
|
|
||||||
|
interface MoveVoiceChannelResult {
|
||||||
|
oldChannelId: string;
|
||||||
|
newChannelId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MoveVoiceChannelTrigger = automodTrigger<MoveVoiceChannelResult>()({
|
||||||
|
configType: t.type({
|
||||||
|
old_channel: t.union([t.string, t.array(t.string)]),
|
||||||
|
new_channel: t.union([t.string, t.array(t.string)]),
|
||||||
|
}),
|
||||||
|
|
||||||
|
defaultConfig: {},
|
||||||
|
|
||||||
|
async match({ triggerConfig, context }) {
|
||||||
|
const oldChannelId = context.voiceChannel?.left?.id;
|
||||||
|
const newChannelId = context.voiceChannel?.joined?.id;
|
||||||
|
|
||||||
|
if (!context.member || !oldChannelId || !newChannelId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const triggerOldChannels = Array.isArray(triggerConfig.old_channel)
|
||||||
|
? triggerConfig.old_channel
|
||||||
|
: [triggerConfig.old_channel];
|
||||||
|
|
||||||
|
const triggerNewChannels = Array.isArray(triggerConfig.new_channel)
|
||||||
|
? triggerConfig.new_channel
|
||||||
|
: [triggerConfig.new_channel];
|
||||||
|
|
||||||
|
if (!triggerOldChannels.includes(oldChannelId) || !triggerNewChannels.includes(newChannelId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
extra: {
|
||||||
|
oldChannelId,
|
||||||
|
newChannelId,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
renderMatchInformation({ matchResult, pluginData, contexts }) {
|
||||||
|
const { newChannelId, oldChannelId } = matchResult.extra;
|
||||||
|
const oldChannel = pluginData.guild.channels.resolve(oldChannelId);
|
||||||
|
const newChannel = pluginData.guild.channels.resolve(newChannelId);
|
||||||
|
const member = contexts[0].member!;
|
||||||
|
const memberName = `**${member.user.username}#${member.user.discriminator}** (\`${member.id}\`)`;
|
||||||
|
const oldChannelName = oldChannel?.name ?? "Unknown";
|
||||||
|
const newChannelName = newChannel?.name ?? "Unknown";
|
||||||
|
const oldChannelVoiceOrStage = oldChannel?.type === ChannelTypeStrings.STAGE ? "stage" : "voice";
|
||||||
|
const newChannelVoiceOrStage = newChannel?.type === ChannelTypeStrings.STAGE ? "stage" : "voice";
|
||||||
|
return `${memberName} has moved from the the ${oldChannelName} (\`${oldChannelId}\`) ${oldChannelVoiceOrStage} channel to the ${newChannelName} (\`${newChannelId}\`) ${newChannelVoiceOrStage} channel`;
|
||||||
|
},
|
||||||
|
});
|
|
@ -140,6 +140,10 @@ export interface AutomodContext {
|
||||||
unlocked?: ThreadChannel;
|
unlocked?: ThreadChannel;
|
||||||
};
|
};
|
||||||
channel?: TextChannel | ThreadChannel;
|
channel?: TextChannel | ThreadChannel;
|
||||||
|
voiceChannel?: {
|
||||||
|
joined?: VoiceChannel | StageChannel;
|
||||||
|
left?: VoiceChannel | StageChannel;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RecentAction {
|
export interface RecentAction {
|
||||||
|
|
Loading…
Add table
Reference in a new issue