package command import ( "fmt" "strconv" "strings" "github.com/mattermost/mattermost/server/public/model" "github.com/mattermost/mattermost/server/public/pluginapi" "github.com/fmartingr/mattermost-plugin-cleanup-channel/server/autocleanup" ) const ( cleanupCommandTrigger = "cleanup-channel" autoCleanupCommandTrigger = "auto-cleanup-channel" ) type AutoCleanupStore interface { Get(channelID string) (*autocleanup.Config, error) Set(channelID string, offsetDays int) error Delete(channelID string) error } type Handler struct { client *pluginapi.Client cleanup func(userID, channelID string) (int, error) autoCleanupStore AutoCleanupStore } type Command interface { Handle(args *model.CommandArgs) (*model.CommandResponse, error) } func NewCommandHandler(client *pluginapi.Client, autoCleanupStore AutoCleanupStore, cleanup func(userID, channelID string) (int, error)) Command { registerCommand(client, cleanupCommandTrigger, "Remove all messages from the current channel (system admins only)") registerCommand(client, autoCleanupCommandTrigger, "Configure automatic message cleanup for the current channel (system admins only)") return &Handler{ client: client, cleanup: cleanup, autoCleanupStore: autoCleanupStore, } } func registerCommand(client *pluginapi.Client, trigger, description string) { err := client.SlashCommand.Register(&model.Command{ Trigger: trigger, AutoComplete: false, AutoCompleteDesc: description, }) if err != nil { client.Log.Error("Failed to register command", "trigger", trigger, "error", err) } } func (c *Handler) Handle(args *model.CommandArgs) (*model.CommandResponse, error) { fields := strings.Fields(args.Command) if len(fields) == 0 { return ephemeralResponse("Empty command"), nil } trigger := strings.TrimPrefix(fields[0], "/") switch trigger { case cleanupCommandTrigger: return c.handleCleanup(args) case autoCleanupCommandTrigger: return c.handleAutoCleanup(args, fields[1:]) default: return ephemeralResponse(fmt.Sprintf("Unknown command: %s", args.Command)), nil } } func (c *Handler) handleCleanup(args *model.CommandArgs) (*model.CommandResponse, error) { if !c.client.User.HasPermissionTo(args.UserId, model.PermissionManageSystem) { return ephemeralResponse("This command is only available to system administrators."), nil } deleted, err := c.cleanup(args.UserId, args.ChannelId) if err != nil { c.client.Log.Error("Failed to cleanup channel via slash command", "channel_id", args.ChannelId, "error", err) return ephemeralResponse("Failed to remove messages from this channel."), nil } return ephemeralResponse(fmt.Sprintf("Removed %d message(s) from this channel.", deleted)), nil } func (c *Handler) handleAutoCleanup(args *model.CommandArgs, params []string) (*model.CommandResponse, error) { if !c.client.User.HasPermissionTo(args.UserId, model.PermissionManageSystem) { return ephemeralResponse("This command is only available to system administrators."), nil } if len(params) == 0 { config, err := c.autoCleanupStore.Get(args.ChannelId) if err != nil { c.client.Log.Error("Failed to get auto cleanup config", "channel_id", args.ChannelId, "error", err) return ephemeralResponse("Failed to get automatic cleanup settings for this channel."), nil } if config == nil { return ephemeralResponse("Automatic cleanup is not configured for this channel."), nil } return ephemeralResponse(fmt.Sprintf( "Automatic cleanup is enabled for this channel. Messages older than %d day(s) are removed daily.", config.OffsetDays, )), nil } switch strings.ToLower(params[0]) { case "off", "disable", "disabled": if err := c.autoCleanupStore.Delete(args.ChannelId); err != nil { c.client.Log.Error("Failed to disable auto cleanup", "channel_id", args.ChannelId, "error", err) return ephemeralResponse("Failed to disable automatic cleanup for this channel."), nil } return ephemeralResponse("Automatic cleanup has been disabled for this channel."), nil default: offsetDays, err := strconv.Atoi(params[0]) if err != nil || offsetDays <= 0 { return ephemeralResponse("Usage: /auto-cleanup-channel [days|off]. Example: /auto-cleanup-channel 30"), nil } if err := c.autoCleanupStore.Set(args.ChannelId, offsetDays); err != nil { c.client.Log.Error("Failed to set auto cleanup config", "channel_id", args.ChannelId, "error", err) return ephemeralResponse("Failed to configure automatic cleanup for this channel."), nil } return ephemeralResponse(fmt.Sprintf( "Automatic cleanup enabled. Messages older than %d day(s) will be removed daily from this channel.", offsetDays, )), nil } } func ephemeralResponse(text string) *model.CommandResponse { return &model.CommandResponse{ ResponseType: model.CommandResponseTypeEphemeral, Text: text, } }