forked from Galactic/galactic-bot
Compare commits
1 Commits
main
...
rejoin-log
Author | SHA1 | Date | |
---|---|---|---|
|
f288293fd5 |
@ -332,6 +332,7 @@ export type InfractionArguments = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type AdditionalInfractionData = {
|
export type AdditionalInfractionData = {
|
||||||
|
track?: boolean;
|
||||||
muteType?: MuteType,
|
muteType?: MuteType,
|
||||||
roles?: Role[]
|
roles?: Role[]
|
||||||
roleIds?: Snowflake[],
|
roleIds?: Snowflake[],
|
||||||
|
10
@types/Events.d.ts
vendored
10
@types/Events.d.ts
vendored
@ -1,10 +1,17 @@
|
|||||||
import { Component } from '../src/client/interfaces/index.ts';
|
import { Component, Infraction } from '../src/client/interfaces/index.ts';
|
||||||
import { ClientEvents as CE, InvalidRequestWarningData, RateLimitData, ResponseLike } from 'discord.js';
|
import { ClientEvents as CE, InvalidRequestWarningData, RateLimitData, ResponseLike } from 'discord.js';
|
||||||
import { ExtendedGuildBan, ExtendedMessage } from './Client.ts';
|
import { ExtendedGuildBan, ExtendedMessage } from './Client.ts';
|
||||||
import { APIRequest } from '@discordjs/rest';
|
import { APIRequest } from '@discordjs/rest';
|
||||||
import { AutomodErrorProps, LinkFilterWarnProps, LogErrorProps, MissingPermsProps, UtilityErrorProps, WordWatcherErrorProps } from './Moderation.js';
|
import { AutomodErrorProps, LinkFilterWarnProps, LogErrorProps, MissingPermsProps, UtilityErrorProps, WordWatcherErrorProps } from './Moderation.js';
|
||||||
|
|
||||||
type ComponentUpdate = { component: Component, type: 'ENABLE' | 'DISABLE' | 'LOAD' | 'UNLOAD' | 'RELOAD' }
|
type ComponentUpdate = { component: Component, type: 'ENABLE' | 'DISABLE' | 'LOAD' | 'UNLOAD' | 'RELOAD' }
|
||||||
|
|
||||||
|
export type RejoinLogEntry = {
|
||||||
|
userId: string;
|
||||||
|
guildId: string;
|
||||||
|
caseId: string;
|
||||||
|
notify: string;
|
||||||
|
}
|
||||||
export interface ClientEvents extends CE {
|
export interface ClientEvents extends CE {
|
||||||
componentUpdate: [data: ComponentUpdate],
|
componentUpdate: [data: ComponentUpdate],
|
||||||
rateLimit: [rateLimitInfo: RateLimitData];
|
rateLimit: [rateLimitInfo: RateLimitData];
|
||||||
@ -20,4 +27,5 @@ export interface ClientEvents extends CE {
|
|||||||
utilityError: [UtilityErrorProps];
|
utilityError: [UtilityErrorProps];
|
||||||
linkFilterWarn: [LinkFilterWarnProps];
|
linkFilterWarn: [LinkFilterWarnProps];
|
||||||
filterMissingPermissions: [MissingPermsProps];
|
filterMissingPermissions: [MissingPermsProps];
|
||||||
|
infraction: [Infraction];
|
||||||
}
|
}
|
3
@types/Guild.d.ts
vendored
3
@types/Guild.d.ts
vendored
@ -21,6 +21,7 @@ import {
|
|||||||
PermissionSettings,
|
PermissionSettings,
|
||||||
ProtectionSettings,
|
ProtectionSettings,
|
||||||
RaidprotectionSettings,
|
RaidprotectionSettings,
|
||||||
|
RejoinSettings,
|
||||||
SelfroleSettings,
|
SelfroleSettings,
|
||||||
SilenceSettings,
|
SilenceSettings,
|
||||||
StaffSettings,
|
StaffSettings,
|
||||||
@ -63,6 +64,7 @@ export type GuildSettingTypes =
|
|||||||
| WordFilterSettings
|
| WordFilterSettings
|
||||||
| WordWatcherSettings
|
| WordWatcherSettings
|
||||||
| LocaleSettings
|
| LocaleSettings
|
||||||
|
| RejoinSettings
|
||||||
|
|
||||||
export type PartialGuildSettings = Partial<GuildSettings>
|
export type PartialGuildSettings = Partial<GuildSettings>
|
||||||
// {
|
// {
|
||||||
@ -101,6 +103,7 @@ export type GuildSettings = {
|
|||||||
invitefilter: InviteFilterSettings,
|
invitefilter: InviteFilterSettings,
|
||||||
mentionfilter: MentionFilterSettings,
|
mentionfilter: MentionFilterSettings,
|
||||||
raidprotection: RaidprotectionSettings,
|
raidprotection: RaidprotectionSettings,
|
||||||
|
rejoin: RejoinSettings
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PermissionSet = {
|
export type PermissionSet = {
|
||||||
|
@ -192,4 +192,9 @@ export type LocaleSettings = {
|
|||||||
|
|
||||||
export type RaidprotectionSettings = {
|
export type RaidprotectionSettings = {
|
||||||
//
|
//
|
||||||
|
} & Setting
|
||||||
|
|
||||||
|
export type RejoinSettings = {
|
||||||
|
channel: string | null,
|
||||||
|
message: string | null
|
||||||
} & Setting
|
} & Setting
|
@ -76,7 +76,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"mariadb": {
|
"mariadb": {
|
||||||
"load": false,
|
"load": true,
|
||||||
"tables": []
|
"tables": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -595,6 +595,11 @@ class DiscordClient extends Client
|
|||||||
return this.#storageManager.mongodb;
|
return this.#storageManager.mongodb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get mariadb ()
|
||||||
|
{
|
||||||
|
return this.#storageManager.mariadb;
|
||||||
|
}
|
||||||
|
|
||||||
get moderation ()
|
get moderation ()
|
||||||
{
|
{
|
||||||
return this.#moderationManager;
|
return this.#moderationManager;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { CommandParams } from '../../../../../@types/Client.js';
|
import { CommandOptionType, CommandParams } from '../../../../../@types/Client.js';
|
||||||
import DiscordClient from '../../../DiscordClient.js';
|
import DiscordClient from '../../../DiscordClient.js';
|
||||||
import { Kick } from '../../../infractions/index.js';
|
import { Kick } from '../../../infractions/index.js';
|
||||||
import { ModerationCommand } from '../../../interfaces/index.js';
|
import { ModerationCommand } from '../../../interfaces/index.js';
|
||||||
@ -13,7 +13,16 @@ class KickCommand extends ModerationCommand
|
|||||||
name: 'kick',
|
name: 'kick',
|
||||||
description: 'Kick people.',
|
description: 'Kick people.',
|
||||||
moduleName: 'moderation',
|
moduleName: 'moderation',
|
||||||
options: [],
|
options: [
|
||||||
|
{
|
||||||
|
name: 'track',
|
||||||
|
description: 'Whether to ping you if the user rejoins',
|
||||||
|
type: CommandOptionType.BOOLEAN,
|
||||||
|
flag: true,
|
||||||
|
valueOptional: true,
|
||||||
|
defaultValue: false
|
||||||
|
}
|
||||||
|
],
|
||||||
guildOnly: true,
|
guildOnly: true,
|
||||||
showUsage: true,
|
showUsage: true,
|
||||||
memberPermissions: [ 'KickMembers' ],
|
memberPermissions: [ 'KickMembers' ],
|
||||||
@ -21,11 +30,14 @@ class KickCommand extends ModerationCommand
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute (invoker: InvokerWrapper<true>, { users, ...args }: CommandParams)
|
async execute (invoker: InvokerWrapper<true>, { users, track, ...args }: CommandParams)
|
||||||
{
|
{
|
||||||
const wrappers = await Promise.all(users!.asUsers.map(user => invoker.guild.memberWrapper(user)));
|
const wrappers = await Promise.all(users!.asUsers.map(user => invoker.guild.memberWrapper(user)));
|
||||||
return this.client.moderation.handleInfraction(Kick, invoker, {
|
return this.client.moderation.handleInfraction(Kick, invoker, {
|
||||||
targets: wrappers.filter(Boolean) as MemberWrapper[],
|
targets: wrappers.filter(Boolean) as MemberWrapper[],
|
||||||
|
data: {
|
||||||
|
track: track?.asBool
|
||||||
|
},
|
||||||
args
|
args
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@ import { AttachmentData, MessageLogEntry } from '../../../../@types/Guild.js';
|
|||||||
import { stripIndents } from 'common-tags';
|
import { stripIndents } from 'common-tags';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { inspect } from 'util';
|
import { inspect } from 'util';
|
||||||
|
import Infraction from '../../interfaces/Infraction.js';
|
||||||
|
import { RejoinLogEntry } from '../../../../@types/Events.js';
|
||||||
|
|
||||||
/* eslint-disable no-labels */
|
/* eslint-disable no-labels */
|
||||||
const CONSTANTS: {
|
const CONSTANTS: {
|
||||||
@ -60,7 +62,9 @@ class GuildLogger extends Observer
|
|||||||
[ 'guildMemberUpdate', this.memberUpdate.bind(this) ],
|
[ 'guildMemberUpdate', this.memberUpdate.bind(this) ],
|
||||||
[ 'threadCreate', this.threadCreate.bind(this) ],
|
[ 'threadCreate', this.threadCreate.bind(this) ],
|
||||||
[ 'threadDelete', this.threadDelete.bind(this) ],
|
[ 'threadDelete', this.threadDelete.bind(this) ],
|
||||||
[ 'threadUpdate', this.threadUpdate.bind(this) ]
|
[ 'threadUpdate', this.threadUpdate.bind(this) ],
|
||||||
|
[ 'infraction', this.infraction.bind(this) ],
|
||||||
|
[ 'guildMemberAdd', this.rejoinTracking.bind(this) ],
|
||||||
];
|
];
|
||||||
|
|
||||||
if (!process.env.MODERATION_WEHBHOOK_ID || !process.env.MODERATION_WEHBHOOK_TOKEN)
|
if (!process.env.MODERATION_WEHBHOOK_ID || !process.env.MODERATION_WEHBHOOK_TOKEN)
|
||||||
@ -924,6 +928,60 @@ class GuildLogger extends Observer
|
|||||||
};
|
};
|
||||||
await logChannel.send({ embeds: [ embed ] });
|
await logChannel.send({ embeds: [ embed ] });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async infraction (inf: Infraction)
|
||||||
|
{
|
||||||
|
if (inf.type !== 'KICK')
|
||||||
|
return;
|
||||||
|
|
||||||
|
const { guild: wrapper } = inf;
|
||||||
|
const settings = await wrapper.settings();
|
||||||
|
const setting = settings.rejoin;
|
||||||
|
if (!setting.channel || !setting.enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!inf.targetId || !inf.guildId || !inf.id)
|
||||||
|
throw new Error('Missing ID for target, guild, infraction');
|
||||||
|
|
||||||
|
const notifyArray = [];
|
||||||
|
if (inf.data.track)
|
||||||
|
notifyArray.push(inf.executorId);
|
||||||
|
await this.client.mariadb.query('INSERT INTO `kickLog` (`userId`, `guildId`, `caseId`, `notify`) VALUES (?);', [[ inf.targetId, inf.guildId, inf.id, JSON.stringify(notifyArray) ]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
async rejoinTracking (member: ExtendedGuildMember)
|
||||||
|
{
|
||||||
|
const { guildWrapper: wrapper } = member;
|
||||||
|
const settings = await wrapper.settings();
|
||||||
|
const setting = settings.rejoin;
|
||||||
|
if (!setting.channel || !setting.enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const logChannel = await wrapper.resolveChannel<TextChannel>(setting.channel);
|
||||||
|
if (!logChannel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const missing = logChannel.permissionsFor(this.client.user!)?.missing([ 'ViewChannel', 'SendMessages' ]);
|
||||||
|
if (!missing || missing.length)
|
||||||
|
return this.client.emit('logError', { guild: wrapper, logger: 'rejoinLogger', reason: 'REJOINLOG_NO_PERMS', params: { missing: missing?.join(', ') ?? 'ALL' } });
|
||||||
|
|
||||||
|
const [ result ] = await this.client.mariadb.query('DELETE FROM `kickLog` WHERE `guildId` = ? AND `userId` = ? RETURNING *;', [ member.guild.id, member.id ]) as RejoinLogEntry[];
|
||||||
|
if (!result)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const infraction = await this.client.mongodb.infractions.findOne({ id: result.caseId });
|
||||||
|
|
||||||
|
let { message } = setting;
|
||||||
|
message = this._replaceTags(message!, member);
|
||||||
|
const notifyArray = JSON.parse(result.notify);
|
||||||
|
if (notifyArray.length > 0)
|
||||||
|
{
|
||||||
|
const notifyString = notifyArray.map((id: string) => `<@${id}>`).join(', ');
|
||||||
|
message = notifyString + '\n' + message;
|
||||||
|
}
|
||||||
|
message += (infraction ? `\n**Reason:** \`${infraction.reason}\`` : '') + `\n**Case:** \`${result.caseId.split(':')[1]}\``;
|
||||||
|
await this.client.rateLimiter.queueSend(logChannel, message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default GuildLogger;
|
export default GuildLogger;
|
83
src/client/components/settings/logging/Rejoin.ts
Normal file
83
src/client/components/settings/logging/Rejoin.ts
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
import { TextChannel } from 'discord.js';
|
||||||
|
import { CommandOptionType, CommandParams } from '../../../../../@types/Client.js';
|
||||||
|
import { RejoinSettings } from '../../../../../@types/Settings.js';
|
||||||
|
import DiscordClient from '../../../DiscordClient.js';
|
||||||
|
import Setting from '../../../interfaces/Setting.js';
|
||||||
|
import InvokerWrapper from '../../wrappers/InvokerWrapper.js';
|
||||||
|
import CommandError from '../../../interfaces/CommandError.js';
|
||||||
|
|
||||||
|
class Rejoin extends Setting
|
||||||
|
{
|
||||||
|
constructor (client: DiscordClient)
|
||||||
|
{
|
||||||
|
super(client, {
|
||||||
|
name: 'rejoin',
|
||||||
|
description: 'Configure if and where the bot will send a message when a kicked user rejoins the server',
|
||||||
|
display: 'Rejoin Logging',
|
||||||
|
moduleName: 'logging',
|
||||||
|
default: {
|
||||||
|
enabled: false,
|
||||||
|
channel: null,
|
||||||
|
message: 'The user **{mention}** ({id}) has rejoined the server after being kicked.',
|
||||||
|
},
|
||||||
|
definitions: {
|
||||||
|
enabled: 'BOOLEAN',
|
||||||
|
channel: 'GUILD_TEXT',
|
||||||
|
message: 'STRING'
|
||||||
|
},
|
||||||
|
commandOptions: [
|
||||||
|
{
|
||||||
|
name: 'enabled',
|
||||||
|
description: 'Toggle logging on or off',
|
||||||
|
type: CommandOptionType.BOOLEAN,
|
||||||
|
flag: true,
|
||||||
|
valueOptional: true,
|
||||||
|
defaultValue: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'channel',
|
||||||
|
description: 'Channel in which to output logs',
|
||||||
|
type: CommandOptionType.TEXT_CHANNEL
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'message',
|
||||||
|
description: 'Message to send when a user rejoins',
|
||||||
|
type: CommandOptionType.STRING
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async execute (invoker: InvokerWrapper, opts: CommandParams, setting: RejoinSettings)
|
||||||
|
{
|
||||||
|
const channel = opts.channel?.asChannel;
|
||||||
|
const message = opts.message?.asString;
|
||||||
|
|
||||||
|
const index = 'SETTING_SUCCESS_ALT';
|
||||||
|
|
||||||
|
if (opts.enabled)
|
||||||
|
setting.enabled = opts.enabled.asBool;
|
||||||
|
|
||||||
|
if (opts.channel)
|
||||||
|
{
|
||||||
|
if (!(channel instanceof TextChannel))
|
||||||
|
throw new CommandError(invoker, { index: 'ERR_INVALID_CHANNEL_TYPE' });
|
||||||
|
const perms = channel.permissionsFor(this.client.user!);
|
||||||
|
const missingPerms = perms?.missing([ 'ViewChannel', 'SendMessages' ]);
|
||||||
|
if (!missingPerms || missingPerms.length)
|
||||||
|
return {
|
||||||
|
error: true,
|
||||||
|
index: 'ERR_CHANNEL_PERMS',
|
||||||
|
params: { channel: channel.name, perms: missingPerms?.join(', ') ?? 'ALL' }
|
||||||
|
};
|
||||||
|
setting.channel = channel.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts.message)
|
||||||
|
setting.message = message ?? null;
|
||||||
|
|
||||||
|
return { index };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Rejoin;
|
@ -235,6 +235,8 @@ class Infraction
|
|||||||
if (this.#data.roles)
|
if (this.#data.roles)
|
||||||
delete this.#data.roles;
|
delete this.#data.roles;
|
||||||
|
|
||||||
|
this.client.emit('infraction', this);
|
||||||
|
|
||||||
return this.save();
|
return this.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ class MariaDBProvider extends Provider
|
|||||||
{
|
{
|
||||||
const result = await new Promise<T[] | FieldInfo[] | undefined>((resolve, reject) =>
|
const result = await new Promise<T[] | FieldInfo[] | undefined>((resolve, reject) =>
|
||||||
{
|
{
|
||||||
const q = connection.query({ timeout, sql: query }, [ values ], (err, results, fields) =>
|
const q = connection.query({ timeout, sql: query }, values, (err, results, fields) =>
|
||||||
{
|
{
|
||||||
if (err)
|
if (err)
|
||||||
reject(err);
|
reject(err);
|
||||||
|
@ -1,180 +1,185 @@
|
|||||||
// Message logs
|
// Message logs
|
||||||
[MSGLOG_DELETE_TITLE]
|
[MSGLOG_DELETE_TITLE]
|
||||||
{emoji_trash} {author}'s message was deleted in #{channel}
|
{emoji_trash} {author}'s message was deleted in #{channel}
|
||||||
|
|
||||||
[MSGLOG_NOCONTENT]
|
[MSGLOG_NOCONTENT]
|
||||||
**__NO TEXT CONTENT__**
|
**__NO TEXT CONTENT__**
|
||||||
|
|
||||||
[MSGLOG_REPLY]
|
[MSGLOG_REPLY]
|
||||||
Message was in reply to user {tag} ({id}):
|
Message was in reply to user {tag} ({id}):
|
||||||
|
|
||||||
[MSGLOG_REPLY_VALUE]
|
[MSGLOG_REPLY_VALUE]
|
||||||
**[Jump]({link})**
|
**[Jump]({link})**
|
||||||
{content}
|
{content}
|
||||||
|
|
||||||
[MSGLOG_REPLY_NOCONTENT]
|
[MSGLOG_REPLY_NOCONTENT]
|
||||||
**__Missing content.__**
|
**__Missing content.__**
|
||||||
|
|
||||||
[MSGLOG_FILTERED]
|
[MSGLOG_FILTERED]
|
||||||
The message was filtered:
|
The message was filtered:
|
||||||
|
|
||||||
[MSGLOG_FILTERED_VALUE_WORD]
|
[MSGLOG_FILTERED_VALUE_WORD]
|
||||||
Filter: **{matcher}**
|
Filter: **{matcher}**
|
||||||
Matched: **{match}**
|
Matched: **{match}**
|
||||||
|
|
||||||
[MSGLOG_FILTERED_VALUE_INVITE]
|
[MSGLOG_FILTERED_VALUE_INVITE]
|
||||||
Filter: **{matcher}**
|
Filter: **{matcher}**
|
||||||
Matched: **{match}**
|
Matched: **{match}**
|
||||||
|
|
||||||
[MSGLOG_FILTERED_VALUE_LINK]
|
[MSGLOG_FILTERED_VALUE_LINK]
|
||||||
Filter: **{matcher}**
|
Filter: **{matcher}**
|
||||||
Matched: **{match}**
|
Matched: **{match}**
|
||||||
|
|
||||||
[MSGLOG_FILTERED_VALUE_MENTION]
|
[MSGLOG_FILTERED_VALUE_MENTION]
|
||||||
Filter: **{filter}**
|
Filter: **{filter}**
|
||||||
Amount: **{amount}**
|
Amount: **{amount}**
|
||||||
|
|
||||||
[MSGLOG_FILTERED_VALUE_WORDWATCHER]
|
[MSGLOG_FILTERED_VALUE_WORDWATCHER]
|
||||||
Filter: **{filter}**
|
Filter: **{filter}**
|
||||||
Action: **{action}**
|
Action: **{action}**
|
||||||
|
|
||||||
[MSGLOG_FILTERED_SANCTIONED]
|
[MSGLOG_FILTERED_SANCTIONED]
|
||||||
__User was sanctioned.__ {emoji_hammer}
|
__User was sanctioned.__ {emoji_hammer}
|
||||||
|
|
||||||
[MSGLOG_DELETE_FOOTER]
|
[MSGLOG_DELETE_FOOTER]
|
||||||
Message ID: {msgID} | User ID: {userID}
|
Message ID: {msgID} | User ID: {userID}
|
||||||
|
|
||||||
[MSGLOG_EDIT_TITLE]
|
[MSGLOG_EDIT_TITLE]
|
||||||
{emoji_note} {author} edited their message in #{channel}
|
{emoji_note} {author} edited their message in #{channel}
|
||||||
|
|
||||||
[MSGLOG_EDIT_FOOTER]
|
[MSGLOG_EDIT_FOOTER]
|
||||||
Message ID: {msgID} | User ID: {userID}
|
Message ID: {msgID} | User ID: {userID}
|
||||||
|
|
||||||
[MSGLOG_EDIT_OLD]
|
[MSGLOG_EDIT_OLD]
|
||||||
Old message
|
Old message
|
||||||
|
|
||||||
[MSGLOG_EDIT_NEW]
|
[MSGLOG_EDIT_NEW]
|
||||||
New message
|
New message
|
||||||
|
|
||||||
[MSGLOG_EDIT_OLD_CUTOFF]
|
[MSGLOG_EDIT_OLD_CUTOFF]
|
||||||
The original message was cut off at 1024 characters.
|
The original message was cut off at 1024 characters.
|
||||||
|
|
||||||
[MSGLOG_EDIT_NEW_CUTOFF]
|
[MSGLOG_EDIT_NEW_CUTOFF]
|
||||||
The new message is cut off at 1024 characters.
|
The new message is cut off at 1024 characters.
|
||||||
|
|
||||||
[MSGLOG_EDIT_JUMP]
|
[MSGLOG_EDIT_JUMP]
|
||||||
**[Jump to message](https://discord.com/channels/{guild}/{channel}/{message})**
|
**[Jump to message](https://discord.com/channels/{guild}/{channel}/{message})**
|
||||||
|
|
||||||
[MSGLOG_PINNED_TITLE]
|
[MSGLOG_PINNED_TITLE]
|
||||||
{emoji_pin} {author}'s message was {pinned} in #{channel}
|
{emoji_pin} {author}'s message was {pinned} in #{channel}
|
||||||
|
|
||||||
[PIN_TOGGLE]
|
[PIN_TOGGLE]
|
||||||
switch({toggle}) {
|
switch({toggle}) {
|
||||||
case true:
|
case true:
|
||||||
'pinned';
|
'pinned';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
'unpinned';
|
'unpinned';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
[THREAD_SWITCH]
|
[THREAD_SWITCH]
|
||||||
switch('{type}') {
|
switch('{type}') {
|
||||||
case 'CREATE':
|
case 'CREATE':
|
||||||
'created';
|
'created';
|
||||||
break;
|
break;
|
||||||
case 'DELETE':
|
case 'DELETE':
|
||||||
'deleted';
|
'deleted';
|
||||||
break;
|
break;
|
||||||
case 'ARCHIVE':
|
case 'ARCHIVE':
|
||||||
'archived';
|
'archived';
|
||||||
break;
|
break;
|
||||||
case 'UNARCHIVE':
|
case 'UNARCHIVE':
|
||||||
'unarchived';
|
'unarchived';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MSGLOG_THREAD_TITLE]
|
[MSGLOG_THREAD_TITLE]
|
||||||
A thread was {action} in #{channel}
|
A thread was {action} in #{channel}
|
||||||
|
|
||||||
[MSGLOG_THREAD_DESC_DELETE]
|
[MSGLOG_THREAD_DESC_DELETE]
|
||||||
**Thread:** {name} ({id})
|
**Thread:** {name} ({id})
|
||||||
**Owner:** {owner}
|
**Owner:** {owner}
|
||||||
**Deleted by:** {actor}
|
**Deleted by:** {actor}
|
||||||
|
|
||||||
[MSGLOG_THREAD_DESC_CREATE]
|
[MSGLOG_THREAD_DESC_CREATE]
|
||||||
**Thread:** {name} <#{id}>
|
**Thread:** {name} <#{id}>
|
||||||
**Owner:** {owner}
|
**Owner:** {owner}
|
||||||
|
|
||||||
[MSGLOG_THREAD_DESC_ARCHIVE]
|
[MSGLOG_THREAD_DESC_ARCHIVE]
|
||||||
**Thread:** {name} <#{id}>
|
**Thread:** {name} <#{id}>
|
||||||
**Owner:** {owner}
|
**Owner:** {owner}
|
||||||
**Archived by:** {actor}
|
**Archived by:** {actor}
|
||||||
|
|
||||||
[MSGLOG_THREAD_DESC_UNARCHIVE]
|
[MSGLOG_THREAD_DESC_UNARCHIVE]
|
||||||
**Thread:** {name} <#{id}>
|
**Thread:** {name} <#{id}>
|
||||||
**Owner:** {owner}
|
**Owner:** {owner}
|
||||||
**Unarchived by:** {actor}
|
**Unarchived by:** {actor}
|
||||||
|
|
||||||
[MSGLOG_THREAD_FOOTER]
|
[MSGLOG_THREAD_FOOTER]
|
||||||
Channel ID: {channelId} • Thread ID: {threadId} • Owner ID: {ownerId}
|
Channel ID: {channelId} • Thread ID: {threadId} • Owner ID: {ownerId}
|
||||||
|
|
||||||
[MSGLOG_THREAD_LOCKED]
|
[MSGLOG_THREAD_LOCKED]
|
||||||
**Thread was locked**
|
**Thread was locked**
|
||||||
|
|
||||||
[MSGLOG_NO_PERMS]
|
[MSGLOG_NO_PERMS]
|
||||||
Bot missing permissions in message log channel
|
Bot missing permissions in message log channel
|
||||||
Missing: {missing}
|
Missing: {missing}
|
||||||
|
|
||||||
[MSGLOG_NO_HOOK]
|
[MSGLOG_NO_HOOK]
|
||||||
Webhook missing in message log channel.
|
Webhook missing in message log channel.
|
||||||
Reassign the message log channel to have the bot recreate the webhook.
|
Reassign the message log channel to have the bot recreate the webhook.
|
||||||
|
|
||||||
//Voice Logs
|
//Voice Logs
|
||||||
[VCLOG_JOIN]
|
[VCLOG_JOIN]
|
||||||
{nickname} **{tag}** ({id}) joined channel {emoji_voice-channel} **{newChannel}**.
|
{nickname} **{tag}** ({id}) joined channel {emoji_voice-channel} **{newChannel}**.
|
||||||
|
|
||||||
[VCLOG_SWITCH]
|
[VCLOG_SWITCH]
|
||||||
{nickname} **{tag}** ({id}) switched from {emoji_voice-channel} **{oldChannel}** to {emoji_voice-channel} **{newChannel}**.
|
{nickname} **{tag}** ({id}) switched from {emoji_voice-channel} **{oldChannel}** to {emoji_voice-channel} **{newChannel}**.
|
||||||
|
|
||||||
[VCLOG_LEAVE]
|
[VCLOG_LEAVE]
|
||||||
{nickname} **{tag}** ({id}) left channel {emoji_voice-channel} **{oldChannel}**
|
{nickname} **{tag}** ({id}) left channel {emoji_voice-channel} **{oldChannel}**
|
||||||
|
|
||||||
[VCLOG_NO_PERMS]
|
[VCLOG_NO_PERMS]
|
||||||
Bot missing permissions in voice join/leave log channel
|
Bot missing permissions in voice join/leave log channel
|
||||||
Missing: {missing}
|
Missing: {missing}
|
||||||
|
|
||||||
[MEMBERLOG_NO_PERMS]
|
[MEMBERLOG_NO_PERMS]
|
||||||
Bot missing permissions in member log channel
|
Bot missing permissions in member log channel
|
||||||
Missing: {missing}
|
Missing: {missing}
|
||||||
|
|
||||||
//Nickname Logs
|
//Nickname Logs
|
||||||
[NICKLOG_TITLE]
|
[NICKLOG_TITLE]
|
||||||
{user} updated their nickname
|
{user} updated their nickname
|
||||||
|
|
||||||
[NICKLOG_DESCRIPTION]
|
[NICKLOG_DESCRIPTION]
|
||||||
**Old nickname:** `{oldNick}`
|
**Old nickname:** `{oldNick}`
|
||||||
**New nickname:** `{newNick}`
|
**New nickname:** `{newNick}`
|
||||||
|
|
||||||
[NICKLOG_FOOTER]
|
[NICKLOG_FOOTER]
|
||||||
User ID: {id}
|
User ID: {id}
|
||||||
|
|
||||||
[NICKLOG_NO_PERMS]
|
[NICKLOG_NO_PERMS]
|
||||||
Bot missing permissions in nickname log channel
|
Bot missing permissions in nickname log channel
|
||||||
Missing: {missing}
|
Missing: {missing}
|
||||||
|
|
||||||
//Bulk Delete Logs
|
//Rejoin Tracking Logs
|
||||||
[BULK_DELETE_TITLE]
|
[REJOINLOG_NO_PERMS]
|
||||||
Bulk message delete log [{embedNr}] in **#{channel}**
|
Bot missing permissions in rejoin log channel
|
||||||
|
Missing: {missing}
|
||||||
[BULK_DELETE_FOOTER]
|
|
||||||
Showing messages {rangeStart}-{rangeEnd} of {total} messages
|
//Bulk Delete Logs
|
||||||
|
[BULK_DELETE_TITLE]
|
||||||
[BULK_DELETE_NO_CONTENT]
|
Bulk message delete log [{embedNr}] in **#{channel}**
|
||||||
No content.
|
|
||||||
|
[BULK_DELETE_FOOTER]
|
||||||
[BULK_DELETE_ATTACHMENTS]
|
Showing messages {rangeStart}-{rangeEnd} of {total} messages
|
||||||
Message attachments:
|
|
||||||
|
[BULK_DELETE_NO_CONTENT]
|
||||||
[BULK_DELETE_ATTACHMENTS_VALUE]
|
No content.
|
||||||
|
|
||||||
|
[BULK_DELETE_ATTACHMENTS]
|
||||||
|
Message attachments:
|
||||||
|
|
||||||
|
[BULK_DELETE_ATTACHMENTS_VALUE]
|
||||||
{links}
|
{links}
|
@ -1,44 +1,48 @@
|
|||||||
[SETTING_MESSAGES_HELP]
|
[SETTING_MESSAGES_HELP]
|
||||||
Configure message logging for your server.
|
Configure message logging for your server.
|
||||||
Message logging utilizes webhooks for bulk message deletions, so if you wish to log those, make sure the bot has the `ManageWebhooks` permission in the logging channel!
|
Message logging utilizes webhooks for bulk message deletions, so if you wish to log those, make sure the bot has the `ManageWebhooks` permission in the logging channel!
|
||||||
If you've given the permission retroactively, make sure to reconfigure the channel to ensure the bot creates the webhook.
|
If you've given the permission retroactively, make sure to reconfigure the channel to ensure the bot creates the webhook.
|
||||||
|
|
||||||
[SETTING_MEMBERS_HELP]
|
[SETTING_MEMBERS_HELP]
|
||||||
Configure member logging for your server.
|
Configure member logging for your server.
|
||||||
|
|
||||||
**Usable tags:**
|
**Usable tags:**
|
||||||
`{mention}` - mentions the user
|
`{mention}` - mentions the user
|
||||||
`{tag}` - username#discriminator
|
`{tag}` - username#discriminator
|
||||||
`{username}` - username
|
`{username}` - username
|
||||||
`{guildsize}` - member count of the server
|
`{guildsize}` - member count of the server
|
||||||
`{guildname}` - name of the server
|
`{guildname}` - name of the server
|
||||||
`{accage}` - age of the account
|
`{accage}` - age of the account
|
||||||
`{id}` - ID of the account
|
`{id}` - ID of the account
|
||||||
|
|
||||||
[SETTING_DMINFRACTION_HELP]
|
[SETTING_DMINFRACTION_HELP]
|
||||||
Configure if messages get sent to users after they're infracted.
|
Configure if messages get sent to users after they're infracted.
|
||||||
Setup custom messages and customize what infractions you want to send to the user.
|
Setup custom messages and customize what infractions you want to send to the user.
|
||||||
|
|
||||||
[SETTING_DMINFRACTION_VALID]
|
[SETTING_DMINFRACTION_VALID]
|
||||||
Valid choices are **{valid}**.
|
Valid choices are **{valid}**.
|
||||||
|
|
||||||
// Memberlogs
|
// Memberlogs
|
||||||
[SETTING_MEMBERLOG_JOIN]
|
[SETTING_MEMBERLOG_JOIN]
|
||||||
》 Join Message
|
》 Join Message
|
||||||
|
|
||||||
[SETTING_MEMBERLOG_LEAVE]
|
[SETTING_MEMBERLOG_LEAVE]
|
||||||
》 Leave Message
|
》 Leave Message
|
||||||
|
|
||||||
[SETTING_ERRORS_HELP]
|
[SETTING_ERRORS_HELP]
|
||||||
Log issues that arise due to configuration.
|
Log issues that arise due to configuration.
|
||||||
Most common outputs will be from automod.
|
Most common outputs will be from automod.
|
||||||
|
|
||||||
[SETTING_MODERATION_HELP]
|
[SETTING_MODERATION_HELP]
|
||||||
Define the channel to which moderation logs are sent.
|
Define the channel to which moderation logs are sent.
|
||||||
The setting also allows you to exclude/include types of actions from being logged in the channel.
|
The setting also allows you to exclude/include types of actions from being logged in the channel.
|
||||||
|
|
||||||
[SETTING_NICKNAMES_HELP]
|
[SETTING_NICKNAMES_HELP]
|
||||||
Configure member nickname logging for your server.
|
Configure member nickname logging for your server.
|
||||||
|
|
||||||
[SETTING_VOICE_HELP]
|
[SETTING_VOICE_HELP]
|
||||||
Configure logging of voice joins and leaves for your server.
|
Configure logging of voice joins and leaves for your server.
|
||||||
|
|
||||||
|
//Rejoin logs
|
||||||
|
[SETTING_REJOIN_HELP]
|
||||||
|
Configure if and where a message is sent when a user who has been kicked rejoins the server.
|
Loading…
Reference in New Issue
Block a user