Files
InnkeeperBot/autoCreate.go
Matte23 bd2fe73102
All checks were successful
Build artifact / build (push) Successful in 22s
Build artifact / release (push) Has been skipped
chore: Objectify managed guilds
2024-07-11 12:44:30 +02:00

171 lines
5.2 KiB
Go

// InnkeeperBot, a bot to create and manage custom channels
// Copyright (C) 2020-2021 Matteo Schiff
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package main
import (
"github.com/bwmarrin/discordgo"
)
type AutoGuild struct {
id string
newChannelEndpoint *discordgo.Channel
createdChannels map[string][]string
}
var managedGuilds = make(map[string]*AutoGuild)
const CATEGORY_NAME = "Gaming🎮"
const DEFAULT_CHANNEL_NAME = "Stanza"
func initChannels(s *discordgo.Session, guildID string) {
var guild AutoGuild
guild.id = guildID
guild.createdChannels = make(map[string][]string)
log.Debugf("Preparing guild %s for automatic channel management", guildID)
category := searchChannel(s, guildID, CATEGORY_NAME, "")
if category == nil {
log.Errorf("Cannot find category %s in guild %s", CATEGORY_NAME, guildID)
return
}
deleteAllChannelsUnderCategory(s, guildID, category.ID)
guild.createNewChannelEndpoint(s, category.ID)
managedGuilds[guildID] = &guild
}
func (guild *AutoGuild) createNewChannelEndpoint(s *discordgo.Session, channelParent string) {
newChannelData := discordgo.GuildChannelCreateData{
Name: "Crea nuovo canale",
Type: discordgo.ChannelTypeGuildVoice,
ParentID: channelParent}
var err error
guild.newChannelEndpoint, err = s.GuildChannelCreateComplex(guild.id, newChannelData)
if err != nil {
log.Errorf("Cannot create channel with name %s in guild %s. This guild is in a corrupted state", newChannelData.Name, guild.id)
return
}
log.Debugf("Created channel with name %s in guild %s", newChannelData.Name, guild.id)
}
func (guild *AutoGuild) createNewChannel(s *discordgo.Session, channelID string, userID string) {
category := searchChannel(s, guild.id, CATEGORY_NAME, "")
if category == nil {
log.Errorf("Cannot find category %s in guild %s", CATEGORY_NAME, guild.id)
return
}
channelName := guild.getActivity(s.State, userID)
editChannelData := discordgo.ChannelEdit{Name: channelName}
_, err := s.ChannelEdit(channelID, &editChannelData)
if err != nil {
log.Errorf("Cannot rename channel %s with new name %s in guild %s", channelID, channelName, guild.id)
return
}
guild.createdChannels[channelID] = []string{userID}
log.Debugf("Renamed channel %s to %s in guild %s", channelID, channelName, guild.id)
guild.createNewChannelEndpoint(s, category.ID)
}
func (guild *AutoGuild) removeUserFromChannels(s *discordgo.Session, userID string) {
for channelID, channel := range guild.createdChannels {
index := contains(channel, userID)
if index != -1 {
if len(channel) == 1 {
// If this user was the only one left in the channel, delete the channel
_, err := s.ChannelDelete(channelID)
if err != nil {
log.Errorf("Cannot delete channel %s in guild %s", channelID, guild.id)
} else {
log.Debugf("Channel %s deleted in guild %s", channelID, guild.id)
delete(guild.createdChannels, channelID)
}
} else {
// Otherwise update the channel name and remove user from the list
guild.createdChannels[channelID] = remove(channel, index)
guild.updateChannelName(s, channelID)
}
}
}
}
func (guild *AutoGuild) trackUserJoinManagedChannel(s *discordgo.Session, channelID string, userID string) {
guild.createdChannels[channelID] = append(guild.createdChannels[channelID], userID)
guild.updateChannelName(s, channelID)
}
func (guild *AutoGuild) updateChannelName(s *discordgo.Session, channelID string) {
programs := make(map[string]int)
for _, userID := range guild.createdChannels[channelID] {
programs[guild.getActivity(s.State, userID)] += 1
}
max := -1
name := DEFAULT_CHANNEL_NAME
for program, count := range programs {
if program != DEFAULT_CHANNEL_NAME && count > max {
max = count
name = program
}
}
channel, err := s.Channel(channelID)
if err != nil {
log.Errorf("Channel %s not found in guild %s", channelID, guild.id)
return
}
oldName := channel.Name
if oldName == name {
return
}
editChannelData := discordgo.ChannelEdit{Name: name}
_, err = s.ChannelEdit(channelID, &editChannelData)
if err != nil {
log.Errorf("Cannot rename channel %s with new name %s in guild %s", channelID, name, guild.id)
}
log.Debugf("Renamed channel %s from %s to %s in guild %s", channelID, oldName, name, guild.id)
}
func (guild *AutoGuild) getActivity(st *discordgo.State, userID string) string {
presence, err := st.Presence(guild.id, userID)
if err != nil || len(presence.Activities) == 0 {
return DEFAULT_CHANNEL_NAME
}
for _, activity := range presence.Activities {
if activity.Name != "Hang Status" {
return activity.Name
}
}
return DEFAULT_CHANNEL_NAME
}