mirror of
https://github.com/Luzifer/discord-community.git
synced 2024-11-08 15:10:02 +00:00
95 lines
2.3 KiB
Go
95 lines
2.3 KiB
Go
|
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
|
||
|
}
|
||
|
}
|
||
|
}
|