162 lines
4.0 KiB
Go
162 lines
4.0 KiB
Go
package discord
|
||
|
||
import (
|
||
"errors"
|
||
"fmt"
|
||
"log"
|
||
"os"
|
||
"os/signal"
|
||
"ticket-pimp/client/discord/router"
|
||
"ticket-pimp/internal/controller"
|
||
"ticket-pimp/internal/domain"
|
||
|
||
"github.com/bwmarrin/discordgo"
|
||
)
|
||
|
||
func initBotWith(token string) *discordgo.Session {
|
||
discord, err := discordgo.New("Bot " + token)
|
||
if err != nil {
|
||
log.Fatalf("unable to create discord session: %v", err)
|
||
}
|
||
|
||
return discord
|
||
}
|
||
|
||
type DiscordOptions struct {
|
||
Config *domain.Config
|
||
Controller *controller.WorkflowController
|
||
}
|
||
|
||
func checkPrivateMessaging(s *discordgo.Session, i *discordgo.InteractionCreate) error {
|
||
// Моментальный ответ для избежания столкновения с протуханием токена
|
||
initialResponse := discordgo.InteractionResponse{
|
||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||
Data: &discordgo.InteractionResponseData{
|
||
Flags: discordgo.MessageFlagsEphemeral,
|
||
Content: "👩🍳 Cooking your query..",
|
||
},
|
||
}
|
||
|
||
s.InteractionRespond(i.Interaction, &initialResponse)
|
||
|
||
dchan, err := s.Channel(i.ChannelID)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
if dchan.Type == discordgo.ChannelTypeDM {
|
||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||
Data: &discordgo.InteractionResponseData{
|
||
Content: "Yo, fella! I'm not working in private!",
|
||
},
|
||
})
|
||
return errors.New("no private messages! lol")
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
func Run(conf domain.Config, opts DiscordOptions) error {
|
||
token := conf.Discord.Token
|
||
|
||
s := initBotWith(token)
|
||
|
||
router := router.InitRouter(*opts.Controller, &conf.Discord, &conf.Telegram)
|
||
|
||
commandHandlers := map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){}
|
||
for _, handler := range router.Commands {
|
||
commandHandlers[handler.Command.Name] = handler.Handler
|
||
}
|
||
|
||
componentsHandlers := map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){
|
||
"task_start": router.Components[0].Handler,
|
||
"task_close": router.Components[0].Handler,
|
||
}
|
||
|
||
s.AddHandler(router.ListenPosts)
|
||
|
||
s.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||
err := checkPrivateMessaging(s, i)
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
switch i.Type {
|
||
case discordgo.InteractionApplicationCommand:
|
||
if h, ok := commandHandlers[i.ApplicationCommandData().Name]; ok {
|
||
h(s, i)
|
||
}
|
||
case discordgo.InteractionMessageComponent:
|
||
if h, ok := componentsHandlers[i.MessageComponentData().CustomID]; ok {
|
||
h(s, i)
|
||
}
|
||
}
|
||
})
|
||
|
||
if err := s.Open(); err != nil {
|
||
return fmt.Errorf("cannot open the session: %v", err)
|
||
}
|
||
|
||
// UPDATE FORUM IF NEEDED:
|
||
|
||
forum, err := s.Channel(conf.Discord.IsTaskForum)
|
||
if err != nil {
|
||
log.Print(err)
|
||
}
|
||
|
||
tagsAvailable := []discordgo.ForumTag{
|
||
{
|
||
Name: "В работе",
|
||
Moderated: true,
|
||
EmojiName: "👩🍳",
|
||
},
|
||
{
|
||
Name: "Готово",
|
||
Moderated: true,
|
||
EmojiName: "✅",
|
||
},
|
||
}
|
||
dchan, err := s.ChannelEditComplex(forum.ID, &discordgo.ChannelEdit{
|
||
AvailableTags: &tagsAvailable,
|
||
})
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
|
||
log.Printf("Channel %s with ID %s propagated by tags:", dchan.Name, dchan.ID)
|
||
for _, t := range dchan.AvailableTags {
|
||
log.Printf("N: %s, ID: %s", t.Name, t.ID)
|
||
}
|
||
|
||
log.Println("Adding commands...")
|
||
var cmds []*discordgo.ApplicationCommand
|
||
var logString []string
|
||
for _, h := range router.Commands {
|
||
cmd, err := s.ApplicationCommandCreate(s.State.User.ID, "", &h.Command)
|
||
if err != nil {
|
||
log.Panicf("Cannot create '%v' command: %v", h.Command.Name, err)
|
||
}
|
||
cmds = append(cmds, cmd)
|
||
logString = append(logString, cmd.Name)
|
||
}
|
||
|
||
log.Println("Following commands added:")
|
||
log.Println(logString)
|
||
|
||
defer s.Close()
|
||
stop := make(chan os.Signal, 1)
|
||
signal.Notify(stop, os.Interrupt)
|
||
<-stop
|
||
log.Println("Graceful shutdown")
|
||
|
||
log.Println("Removing commands...")
|
||
for _, h := range cmds {
|
||
err := s.ApplicationCommandDelete(s.State.User.ID, "", h.ID)
|
||
if err != nil {
|
||
log.Panicf("Cannot delete '%v' command: %v", h.Name, err)
|
||
}
|
||
}
|
||
return nil
|
||
}
|