mirror of
https://github.com/ZeppelinBot/Zeppelin.git
synced 2025-07-13 13:57:18 +00:00
Add command to list x recent messages from user
x defaults to 20 -f switch to show full message (trimmed to 50 characters by default)
This commit is contained in:
parent
7f75d6d8d3
commit
96c9e1f615
4 changed files with 98 additions and 0 deletions
|
@ -96,6 +96,17 @@ export class GuildSavedMessages extends BaseGuildRepository {
|
|||
.getMany();
|
||||
}
|
||||
|
||||
getLatestByUser(userId, limit = 20) {
|
||||
return this.messages
|
||||
.createQueryBuilder()
|
||||
.where("guild_id = :guild_id", { guild_id: this.guildId })
|
||||
.andWhere("user_id = :user_id", { user_id: userId })
|
||||
.andWhere("deleted_at IS NULL")
|
||||
.orderBy("id", "DESC")
|
||||
.limit(limit)
|
||||
.getMany();
|
||||
}
|
||||
|
||||
getUserMessagesByChannelAfterId(userId, channelId, afterId, limit?: number) {
|
||||
let query = this.messages
|
||||
.createQueryBuilder()
|
||||
|
|
|
@ -35,6 +35,7 @@ import { SnowflakeInfoCmd } from "./commands/SnowflakeInfoCmd";
|
|||
import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners";
|
||||
import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin";
|
||||
import { VcdisconnectCmd } from "./commands/VcdisconnectCmd";
|
||||
import { ShowMessagesCmd } from "./commands/ShowMessagesCmd";
|
||||
|
||||
const defaultOptions: PluginOptions<UtilityPluginType> = {
|
||||
config: {
|
||||
|
@ -48,6 +49,7 @@ const defaultOptions: PluginOptions<UtilityPluginType> = {
|
|||
can_channelinfo: false,
|
||||
can_messageinfo: false,
|
||||
can_userinfo: false,
|
||||
can_showmessage: false,
|
||||
can_snowflake: false,
|
||||
can_reload_guild: false,
|
||||
can_nickname: false,
|
||||
|
@ -77,6 +79,7 @@ const defaultOptions: PluginOptions<UtilityPluginType> = {
|
|||
can_channelinfo: true,
|
||||
can_messageinfo: true,
|
||||
can_userinfo: true,
|
||||
can_showmessage: true,
|
||||
can_snowflake: true,
|
||||
can_nickname: true,
|
||||
can_vcmove: true,
|
||||
|
@ -136,6 +139,7 @@ export const UtilityPlugin = zeppelinGuildPlugin<UtilityPluginType>()("utility",
|
|||
MessageInfoCmd,
|
||||
InfoCmd,
|
||||
SnowflakeInfoCmd,
|
||||
ShowMessagesCmd,
|
||||
],
|
||||
|
||||
onLoad(pluginData) {
|
||||
|
|
82
backend/src/plugins/Utility/commands/ShowMessagesCmd.ts
Normal file
82
backend/src/plugins/Utility/commands/ShowMessagesCmd.ts
Normal file
|
@ -0,0 +1,82 @@
|
|||
import { utilityCmd } from "../types";
|
||||
import { commandTypeHelpers as ct } from "../../../commandTypes";
|
||||
import { chunkMessageLines, convertMSToDelayString, EmbedWith } from "../../../utils";
|
||||
import { SavedMessage } from "../../../data/entities/SavedMessage";
|
||||
import moment from "moment";
|
||||
|
||||
export const ShowMessagesCmd = utilityCmd({
|
||||
trigger: ["show_messages", "messages", "recent_messages", "showmessages"],
|
||||
description: "Shows recent messages of a user",
|
||||
usage: "!show_messages 108552944961454080",
|
||||
permission: "can_showmessage",
|
||||
|
||||
signature: {
|
||||
user: ct.resolvedUser(),
|
||||
amount: ct.number({ required: false }),
|
||||
fullMessage: ct.switchOption({ shortcut: "f" }),
|
||||
},
|
||||
|
||||
async run({ message, args, pluginData }) {
|
||||
const latestMessages = (await pluginData.state.savedMessages.getLatestByUser(args.user.id, args.amount)).reverse();
|
||||
if (latestMessages.length === 0) {
|
||||
message.channel.createMessage(`No recent messages by user!`);
|
||||
return;
|
||||
}
|
||||
const messagesToChannelMap: Map<string, SavedMessage[]> = new Map();
|
||||
for (const msg of latestMessages) {
|
||||
if (messagesToChannelMap[msg.channel_id] == null) messagesToChannelMap[msg.channel_id] = [];
|
||||
messagesToChannelMap[msg.channel_id].push(msg);
|
||||
}
|
||||
|
||||
const embed: EmbedWith<"fields"> = {
|
||||
fields: [],
|
||||
};
|
||||
|
||||
let description = "";
|
||||
for (const channel in messagesToChannelMap) {
|
||||
const messages: SavedMessage[] = messagesToChannelMap[channel];
|
||||
description += `**Messages in <#${channel}>:**`;
|
||||
|
||||
for (const msg of messages) {
|
||||
// Trim preview down to 50 (47 with ...) characters as to not overflow chat (unless -f switch is set)
|
||||
const formattedContent =
|
||||
msg.data.content.length > 47 && !args.fullMessage
|
||||
? msg.data.content.substring(0, 47) + "..."
|
||||
: msg.data.content;
|
||||
// We remove milliseconds here as to not show 3 decimal points (which appears on convertMSToDelayString and humanizeDurationShort both)
|
||||
const timeAgo = convertMSToDelayString(
|
||||
moment()
|
||||
.milliseconds(0)
|
||||
.valueOf() -
|
||||
moment(msg.posted_at)
|
||||
.milliseconds(0)
|
||||
.valueOf(),
|
||||
);
|
||||
|
||||
description += `\n\`${formattedContent}\`, ${timeAgo} ago \[[Link](https://discord.com/channels/${msg.guild_id}/${msg.channel_id}/${msg.id})\]`;
|
||||
}
|
||||
description += `\n\n`;
|
||||
}
|
||||
|
||||
embed.author = {
|
||||
name: args.user.username + "#" + args.user.discriminator,
|
||||
icon_url: args.user.avatarURL,
|
||||
};
|
||||
|
||||
// Chunking to 1950 max length to accomodate footer and/or header
|
||||
const chunkedDescription = chunkMessageLines(description.trim(), 1950);
|
||||
for (let i = 0; i < chunkedDescription.length; i++) {
|
||||
embed.description = chunkedDescription[i];
|
||||
|
||||
// Only show author on top-most embed and footer on bottom-most embed to keep visual throughline
|
||||
if (i > 0) {
|
||||
embed.author = undefined;
|
||||
}
|
||||
if (i === chunkedDescription.length - 1) {
|
||||
embed.footer = { text: `Showing ${latestMessages.length} recent messages` };
|
||||
}
|
||||
|
||||
await message.channel.createMessage({ embed });
|
||||
}
|
||||
},
|
||||
});
|
|
@ -18,6 +18,7 @@ export const ConfigSchema = t.type({
|
|||
can_channelinfo: t.boolean,
|
||||
can_messageinfo: t.boolean,
|
||||
can_userinfo: t.boolean,
|
||||
can_showmessage: t.boolean,
|
||||
can_snowflake: t.boolean,
|
||||
can_reload_guild: t.boolean,
|
||||
can_nickname: t.boolean,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue