mirror of
https://github.com/ZeppelinBot/Zeppelin.git
synced 2025-07-13 21: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();
|
.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) {
|
getUserMessagesByChannelAfterId(userId, channelId, afterId, limit?: number) {
|
||||||
let query = this.messages
|
let query = this.messages
|
||||||
.createQueryBuilder()
|
.createQueryBuilder()
|
||||||
|
|
|
@ -35,6 +35,7 @@ import { SnowflakeInfoCmd } from "./commands/SnowflakeInfoCmd";
|
||||||
import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners";
|
import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners";
|
||||||
import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin";
|
import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin";
|
||||||
import { VcdisconnectCmd } from "./commands/VcdisconnectCmd";
|
import { VcdisconnectCmd } from "./commands/VcdisconnectCmd";
|
||||||
|
import { ShowMessagesCmd } from "./commands/ShowMessagesCmd";
|
||||||
|
|
||||||
const defaultOptions: PluginOptions<UtilityPluginType> = {
|
const defaultOptions: PluginOptions<UtilityPluginType> = {
|
||||||
config: {
|
config: {
|
||||||
|
@ -48,6 +49,7 @@ const defaultOptions: PluginOptions<UtilityPluginType> = {
|
||||||
can_channelinfo: false,
|
can_channelinfo: false,
|
||||||
can_messageinfo: false,
|
can_messageinfo: false,
|
||||||
can_userinfo: false,
|
can_userinfo: false,
|
||||||
|
can_showmessage: false,
|
||||||
can_snowflake: false,
|
can_snowflake: false,
|
||||||
can_reload_guild: false,
|
can_reload_guild: false,
|
||||||
can_nickname: false,
|
can_nickname: false,
|
||||||
|
@ -77,6 +79,7 @@ const defaultOptions: PluginOptions<UtilityPluginType> = {
|
||||||
can_channelinfo: true,
|
can_channelinfo: true,
|
||||||
can_messageinfo: true,
|
can_messageinfo: true,
|
||||||
can_userinfo: true,
|
can_userinfo: true,
|
||||||
|
can_showmessage: true,
|
||||||
can_snowflake: true,
|
can_snowflake: true,
|
||||||
can_nickname: true,
|
can_nickname: true,
|
||||||
can_vcmove: true,
|
can_vcmove: true,
|
||||||
|
@ -136,6 +139,7 @@ export const UtilityPlugin = zeppelinGuildPlugin<UtilityPluginType>()("utility",
|
||||||
MessageInfoCmd,
|
MessageInfoCmd,
|
||||||
InfoCmd,
|
InfoCmd,
|
||||||
SnowflakeInfoCmd,
|
SnowflakeInfoCmd,
|
||||||
|
ShowMessagesCmd,
|
||||||
],
|
],
|
||||||
|
|
||||||
onLoad(pluginData) {
|
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_channelinfo: t.boolean,
|
||||||
can_messageinfo: t.boolean,
|
can_messageinfo: t.boolean,
|
||||||
can_userinfo: t.boolean,
|
can_userinfo: t.boolean,
|
||||||
|
can_showmessage: t.boolean,
|
||||||
can_snowflake: t.boolean,
|
can_snowflake: t.boolean,
|
||||||
can_reload_guild: t.boolean,
|
can_reload_guild: t.boolean,
|
||||||
can_nickname: t.boolean,
|
can_nickname: t.boolean,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue