From 8dc637e41ee4df834ae99bda17b6ab5f11be74f8 Mon Sep 17 00:00:00 2001 From: Knut Ahlers Date: Sat, 31 Jul 2021 00:54:28 +0200 Subject: [PATCH] Add clearchannel module Signed-off-by: Knut Ahlers --- mod_clearChannel.go | 94 +++++++++++++++++++++++++++++++++++++++++++++ wiki/Home.md | 10 +++++ 2 files changed, 104 insertions(+) create mode 100644 mod_clearChannel.go diff --git a/mod_clearChannel.go b/mod_clearChannel.go new file mode 100644 index 0000000..19ca4a6 --- /dev/null +++ b/mod_clearChannel.go @@ -0,0 +1,94 @@ +package main + +import ( + "sort" + "strconv" + "time" + + "github.com/bwmarrin/discordgo" + "github.com/pkg/errors" + "github.com/robfig/cron/v3" + log "github.com/sirupsen/logrus" +) + +/* + * @module clearchannel + * @module_desc Cleans up old messages from a channel (for example announcement channel) which are older than the retention time + */ + +func init() { + RegisterModule("clearchannel", func() module { return &modClearChannel{} }) +} + +type modClearChannel struct { + attrs moduleAttributeStore + discord *discordgo.Session +} + +func (m *modClearChannel) Initialize(crontab *cron.Cron, discord *discordgo.Session, attrs moduleAttributeStore) error { + m.attrs = attrs + m.discord = discord + + if err := attrs.Expect( + "discord_channel_id", + "retention", + ); err != nil { + return errors.Wrap(err, "validating attributes") + } + + // @attr cron optional string "0 * * * *" When to execute the cleaner + if _, err := crontab.AddFunc(attrs.MustString("cron", ptrString("0 * * * *")), m.cronClearChannel); err != nil { + return errors.Wrap(err, "adding cron function") + } + + return nil +} + +func (m modClearChannel) cronClearChannel() { + var ( + after = "0" + + // @attr discord_channel_id required string "" ID of the Discord channel to clean up + channelID = m.attrs.MustString("discord_channel_id", nil) + // @attr retention required duration "" How long to keep messages in this channel + retention = m.attrs.MustDuration("retention", nil) + ) + + for { + msgs, err := m.discord.ChannelMessages(channelID, 100, "", after, "") + if err != nil { + log.WithError(err).Error("Unable to fetch announcement channel messages") + return + } + + sort.Slice(msgs, func(i, j int) bool { + iu, _ := strconv.ParseUint(msgs[i].ID, 10, 64) + ju, _ := strconv.ParseUint(msgs[j].ID, 10, 64) + return iu < ju + }) + + if len(msgs) == 0 { + break + } + + for _, msg := range msgs { + mt, err := msg.Timestamp.Parse() + if err != nil { + log.WithField("msg_id", msg.ID).WithError(err).Error("Unable to parse message timestamp") + break + } + + if time.Since(mt) < retention { + // We got to the first message within the retention time, we can end now + break + } + + if err = m.discord.ChannelMessageDelete(channelID, msg.ID); err != nil { + log.WithError(err).Error("Unable to delete messages") + return + } + + after = msg.ID + } + } +} diff --git a/wiki/Home.md b/wiki/Home.md index 0c3a9f7..da911a7 100644 --- a/wiki/Home.md +++ b/wiki/Home.md @@ -16,6 +16,16 @@ module_configs: # Modules +## Type: `clearchannel` + +Cleans up old messages from a channel (for example announcement channel) which are older than the retention time + +| Attribute | Req. | Type | Default Value | Description | +| --------- | :--: | ---- | ------------- | ----------- | +| `discord_channel_id` | ✅ | string | | ID of the Discord channel to clean up | +| `retention` | ✅ | duration | | How long to keep messages in this channel | +| `cron` | | string | `0 * * * *` | When to execute the cleaner | + ## Type: `liveposting` Announces stream live status based on Discord streaming status