probably completed implementation of voicechannelbot
This commit is contained in:
parent
981fc2cb46
commit
16ee889aae
2 changed files with 397 additions and 0 deletions
99
cmd/tempbot/main.go
Normal file
99
cmd/tempbot/main.go
Normal file
|
@ -0,0 +1,99 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/disgoorg/disgo"
|
||||
"github.com/disgoorg/disgo/bot"
|
||||
"github.com/disgoorg/disgo/cache"
|
||||
"github.com/disgoorg/disgo/gateway"
|
||||
"github.com/disgoorg/log"
|
||||
"github.com/disgoorg/snowflake/v2"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
token = os.Getenv("disgo_token")
|
||||
registerGuildID = snowflake.GetEnv("disgo_guild_id")
|
||||
channelTempID snowflake.ID
|
||||
)
|
||||
|
||||
func main() {
|
||||
log.SetLevel(log.LevelInfo)
|
||||
log.Info("starting joinbot...")
|
||||
log.Info("disgo version: ", disgo.Version)
|
||||
|
||||
// intents needed GUILD_MESSAGES
|
||||
client, err := disgo.New(token,
|
||||
bot.WithGatewayConfigOpts(
|
||||
gateway.WithIntents(gateway.IntentsAll),
|
||||
),
|
||||
bot.WithCacheConfigOpts(
|
||||
cache.WithCacheFlags(
|
||||
cache.FlagsAll,
|
||||
),
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal("error while building disgo instance: ", err)
|
||||
return
|
||||
}
|
||||
|
||||
defer client.Close(context.TODO())
|
||||
|
||||
channels, err := client.Rest().GetGuildChannels(registerGuildID)
|
||||
for _, channel := range channels {
|
||||
switch channel.Name() {
|
||||
case "⌛-temp":
|
||||
channelTempID = channel.ID()
|
||||
}
|
||||
}
|
||||
if channelTempID == 0 {
|
||||
log.Fatal("couldn't find needed channel")
|
||||
}
|
||||
|
||||
// delete messages older then x min in channel
|
||||
|
||||
ticker := time.NewTicker(1 * time.Minute)
|
||||
quit := make(chan struct{})
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
messages, err := client.Rest().GetMessages(channelTempID, 0, 0, 0, 100)
|
||||
if err != nil {
|
||||
client.Logger().Error("error getting messages: ", err)
|
||||
}
|
||||
var messageIDs []snowflake.ID
|
||||
for _, message := range messages {
|
||||
if message.CreatedAt.Add(30 * time.Minute).Before(time.Now()) {
|
||||
messageIDs = append(messageIDs, message.ID)
|
||||
}
|
||||
}
|
||||
client.Logger().Debug("deleting messages: ", len(messageIDs))
|
||||
if len(messageIDs) == 1 {
|
||||
err = client.Rest().DeleteMessage(channelTempID, messageIDs[0])
|
||||
if err != nil {
|
||||
client.Logger().Error("error deleting messages: ", err)
|
||||
}
|
||||
}
|
||||
if len(messageIDs) > 1 {
|
||||
err = client.Rest().BulkDeleteMessages(channelTempID, messageIDs)
|
||||
if err != nil {
|
||||
client.Logger().Error("error deleting messages: ", err)
|
||||
}
|
||||
}
|
||||
case <-quit:
|
||||
ticker.Stop()
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
log.Infof("tempbot is now running. Press CTRL-C to exit.")
|
||||
s := make(chan os.Signal, 1)
|
||||
signal.Notify(s, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
|
||||
<-s
|
||||
}
|
298
cmd/voicechannelbot/main.go
Normal file
298
cmd/voicechannelbot/main.go
Normal file
|
@ -0,0 +1,298 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/disgoorg/disgo"
|
||||
"github.com/disgoorg/disgo/bot"
|
||||
"github.com/disgoorg/disgo/cache"
|
||||
"github.com/disgoorg/disgo/discord"
|
||||
"github.com/disgoorg/disgo/events"
|
||||
"github.com/disgoorg/disgo/gateway"
|
||||
"github.com/disgoorg/log"
|
||||
"github.com/disgoorg/snowflake/v2"
|
||||
"io"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
var (
|
||||
token = os.Getenv("disgo_token")
|
||||
registerGuildID = snowflake.GetEnv("disgo_guild_id")
|
||||
channelVoiceGroupID snowflake.ID
|
||||
channelVoiceLogID snowflake.ID
|
||||
channelVoicePrefix = "🔉 - "
|
||||
appleApi = "https://grow.rievo.page/applelist/initial.json"
|
||||
appleList []string
|
||||
)
|
||||
|
||||
type appleApiBody struct {
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
Version string `json:"version"`
|
||||
Body []string `json:"body"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
log.SetLevel(log.LevelInfo)
|
||||
log.Info("starting voicechannelbot...")
|
||||
log.Info("disgo version: ", disgo.Version)
|
||||
|
||||
err := loadAppleList()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
// intents needed
|
||||
client, err := disgo.New(token,
|
||||
bot.WithGatewayConfigOpts(
|
||||
gateway.WithIntents(gateway.IntentGuildVoiceStates),
|
||||
),
|
||||
bot.WithCacheConfigOpts(
|
||||
cache.WithCaches(
|
||||
cache.FlagChannels,
|
||||
cache.FlagVoiceStates,
|
||||
cache.FlagMembers,
|
||||
),
|
||||
),
|
||||
bot.WithEventListenerFunc(joinEvent),
|
||||
bot.WithEventListenerFunc(moveEvent),
|
||||
bot.WithEventListenerFunc(leaveEvent),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal("error while building disgo instance: ", err)
|
||||
return
|
||||
}
|
||||
|
||||
defer client.Close(context.TODO())
|
||||
|
||||
if err = client.OpenGateway(context.TODO()); err != nil {
|
||||
log.Fatal("error while connecting to gateway: ", err)
|
||||
}
|
||||
|
||||
channels, err := client.Rest().GetGuildChannels(registerGuildID)
|
||||
for _, channel := range channels {
|
||||
switch channel.Name() {
|
||||
case "🔊-talk":
|
||||
channelVoiceGroupID = channel.ID()
|
||||
case "📋-voice":
|
||||
channelVoiceLogID = channel.ID()
|
||||
}
|
||||
}
|
||||
if channelVoiceGroupID == 0 {
|
||||
log.Fatal("couldn't find needed channel")
|
||||
}
|
||||
|
||||
log.Infof("voicechannelbot is now running. Press CTRL-C to exit.")
|
||||
s := make(chan os.Signal, 1)
|
||||
signal.Notify(s, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
|
||||
<-s
|
||||
}
|
||||
|
||||
func loadAppleList() error {
|
||||
res, err := http.Get(appleApi)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
body, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var data appleApiBody
|
||||
err = json.Unmarshal(body, &data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
appleList = data.Body
|
||||
log.Debug("loaded apple list of lenght: ", len(appleList))
|
||||
return nil
|
||||
}
|
||||
|
||||
func sendNoMention(client bot.Client, msg, msgEdit string) {
|
||||
message, err := client.Rest().CreateMessage(channelVoiceLogID, discord.NewMessageCreateBuilder().
|
||||
SetContent(msg).Build())
|
||||
if err != nil {
|
||||
client.Logger().Error("unable to send channel message: ", err)
|
||||
return
|
||||
}
|
||||
_, err = client.Rest().UpdateMessage(channelVoiceLogID,
|
||||
message.ID,
|
||||
discord.NewMessageUpdateBuilder().ClearContent().SetContent(msgEdit).Build())
|
||||
if err != nil {
|
||||
client.Logger().Error("unable to update channel message: ", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func joinEvent(event *events.GuildVoiceJoin) {
|
||||
event.Client().Logger().Debug("joinEvent")
|
||||
channelId := *event.VoiceState.ChannelID
|
||||
channel, _ := event.Client().Rest().GetChannel(channelId)
|
||||
channelName := channel.Name()
|
||||
userName := event.Member.EffectiveName()
|
||||
userMention := event.Member.Mention()
|
||||
|
||||
message := fmt.Sprintf("**CHANNEL LOG:** %v joined %v", userName, channelName)
|
||||
messageEdit := fmt.Sprintf("**CHANNEL LOG:** %v joined %v", userMention, channelName)
|
||||
go sendNoMention(event.Client(), message, messageEdit)
|
||||
|
||||
updateVoiceChannels(event.Client(), false)
|
||||
}
|
||||
|
||||
func moveEvent(event *events.GuildVoiceMove) {
|
||||
if event.OldVoiceState.ChannelID.String() == event.VoiceState.ChannelID.String() {
|
||||
// no that's not a move event
|
||||
return
|
||||
}
|
||||
event.Client().Logger().Debug("moveEvent")
|
||||
channelOldId := *event.OldVoiceState.ChannelID
|
||||
channelOld, _ := event.Client().Rest().GetChannel(channelOldId)
|
||||
channelOldName := channelOld.Name()
|
||||
channelId := *event.VoiceState.ChannelID
|
||||
channel, _ := event.Client().Rest().GetChannel(channelId)
|
||||
channelName := channel.Name()
|
||||
userName := event.Member.EffectiveName()
|
||||
userMention := event.Member.Mention()
|
||||
|
||||
message := fmt.Sprintf("**CHANNEL LOG:** %v moved from %v to %v", userName, channelOldName, channelName)
|
||||
messageEdit := fmt.Sprintf("**CHANNEL LOG:** %v moved from %v to %v", userMention, channelOldName, channelName)
|
||||
go sendNoMention(event.Client(), message, messageEdit)
|
||||
|
||||
updateVoiceChannels(event.Client(), false)
|
||||
}
|
||||
|
||||
func leaveEvent(event *events.GuildVoiceLeave) {
|
||||
event.Client().Logger().Debug("leaveEvent")
|
||||
if event.OldVoiceState.ChannelID == nil {
|
||||
event.Client().Logger().Error("OldVoiceState.ChannelID missing")
|
||||
return
|
||||
}
|
||||
channelOldId := *event.OldVoiceState.ChannelID
|
||||
channelOld, _ := event.Client().Rest().GetChannel(channelOldId)
|
||||
channelOldName := channelOld.Name()
|
||||
userName := event.Member.EffectiveName()
|
||||
userMention := event.Member.Mention()
|
||||
|
||||
message := fmt.Sprintf("**CHANNEL LOG:** %v left %v", userName, channelOldName)
|
||||
messageEdit := fmt.Sprintf("**CHANNEL LOG:** %v left %v", userMention, channelOldName)
|
||||
go sendNoMention(event.Client(), message, messageEdit)
|
||||
|
||||
updateVoiceChannels(event.Client(), true)
|
||||
}
|
||||
|
||||
func getVoiceChannels(client bot.Client) (map[snowflake.ID]string, error) {
|
||||
allChannels, err := client.Rest().GetGuildChannels(registerGuildID)
|
||||
if err != nil {
|
||||
return nil, errors.New(fmt.Sprintf("error getting channels: %v", err.Error()))
|
||||
}
|
||||
voiceChannels := make(map[snowflake.ID]string)
|
||||
channelVoiceGroupIDStr := channelVoiceGroupID.String()
|
||||
for _, channel := range allChannels {
|
||||
if channel.Type() == discord.ChannelTypeGuildCategory {
|
||||
continue
|
||||
}
|
||||
parentIDStr := channel.ParentID().String()
|
||||
channelType := channel.Type()
|
||||
if parentIDStr == channelVoiceGroupIDStr && channelType == discord.ChannelTypeGuildVoice {
|
||||
voiceChannels[channel.ID()] = channel.Name()
|
||||
}
|
||||
}
|
||||
return voiceChannels, nil
|
||||
}
|
||||
|
||||
func getName(channels map[snowflake.ID]string) (string, error) {
|
||||
channelsReverse := make(map[string]snowflake.ID)
|
||||
for id, name := range channels {
|
||||
channelsReverse[name] = id
|
||||
}
|
||||
|
||||
appleListLen := len(appleList)
|
||||
for i := 0; i < appleListLen; i++ {
|
||||
randomIndex := rand.Intn(appleListLen)
|
||||
pick := appleList[randomIndex]
|
||||
newName := fmt.Sprintf("%v%v", channelVoicePrefix, pick)
|
||||
_, exists := channelsReverse[newName]
|
||||
if exists == false {
|
||||
return newName, nil
|
||||
}
|
||||
}
|
||||
return "", errors.New("could not find unused name")
|
||||
|
||||
}
|
||||
|
||||
func updateVoiceChannels(client bot.Client, deleteChannels bool) {
|
||||
|
||||
voiceChannels, err := getVoiceChannels(client)
|
||||
if err != nil {
|
||||
client.Logger().Error("error in getVoiceChannels: ", err)
|
||||
}
|
||||
voiceChannelsWithState := make(map[snowflake.ID]string)
|
||||
voiceChannelsEmpty := make(map[snowflake.ID]string)
|
||||
for key, val := range voiceChannels {
|
||||
voiceChannelsEmpty[key] = val
|
||||
}
|
||||
|
||||
client.Caches().VoiceStatesForEach(registerGuildID, func(state discord.VoiceState) {
|
||||
if state.ChannelID == nil {
|
||||
return
|
||||
}
|
||||
channelId := *state.ChannelID
|
||||
name, ok := voiceChannels[channelId]
|
||||
if !ok {
|
||||
// not channel of group
|
||||
return
|
||||
}
|
||||
voiceChannelsWithState[channelId] = name
|
||||
delete(voiceChannelsEmpty, channelId)
|
||||
})
|
||||
|
||||
if len(voiceChannels) == 2 && len(voiceChannelsWithState) == 0 {
|
||||
client.Logger().Debug("all channels are empty")
|
||||
return
|
||||
}
|
||||
|
||||
if len(voiceChannelsWithState) >= len(voiceChannels) {
|
||||
// if there are no empty voiceChannels create one
|
||||
client.Logger().Debug("new channel has to be created")
|
||||
name, err := getName(voiceChannels)
|
||||
if err != nil {
|
||||
client.Logger().Error("no empty channels")
|
||||
return
|
||||
}
|
||||
_, err = client.Rest().CreateGuildChannel(registerGuildID, discord.GuildVoiceChannelCreate{
|
||||
Name: name,
|
||||
UserLimit: 77,
|
||||
ParentID: channelVoiceGroupID,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if len(voiceChannels)-len(voiceChannelsWithState) > 1 && deleteChannels {
|
||||
// if there are more than one empty voiceChannels delete all but 1
|
||||
client.Logger().Debug("channel has to be deleted")
|
||||
client.Logger().Debug("empty channels: ", voiceChannelsEmpty)
|
||||
|
||||
for id, s := range voiceChannelsEmpty {
|
||||
// get the oldest channel and delete it
|
||||
client.Logger().Debug("deleting: ", s)
|
||||
err := client.Rest().DeleteChannel(id)
|
||||
if err != nil {
|
||||
client.Logger().Error("not able to delete: ", err)
|
||||
return
|
||||
}
|
||||
break
|
||||
}
|
||||
updateVoiceChannels(client, true)
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue