add "не начат" tag to tags preset

This commit is contained in:
naudachu 2023-11-24 14:55:11 +05:00
parent 4c6ed95819
commit b9614e4c45
1 changed files with 213 additions and 134 deletions

View File

@ -20,99 +20,102 @@ var (
projectRepo string = "project_repo" projectRepo string = "project_repo"
buildRepo string = "build_repo" buildRepo string = "build_repo"
nameOption string = "repo_name" nameOption string = "repo_name"
) tagsPreset = [3]discordgo.ForumTag{
{
var tags = []discordgo.ForumTag{ Name: "В работе",
{ Moderated: true,
Name: "В работе", EmojiName: "👩‍🍳",
Moderated: true,
EmojiName: "👩‍🍳",
},
{
Name: "Готово",
Moderated: true,
EmojiName: "✅",
},
}
var commands = []discordgo.ApplicationCommand{
{
Name: "ping",
Description: "pongs in a reply",
},
{
Name: "init_project",
Description: "Connect project with Coda ID",
Options: []*discordgo.ApplicationCommandOption{
{
Type: discordgo.ApplicationCommandOptionString,
Name: "key",
Description: "Project's key from Coda.io",
Required: true,
MinLength: &minLength,
},
}, },
}, {
{ Name: "Готово",
Name: "project", Moderated: true,
Description: "Create new development ticket", EmojiName: "✅",
Options: []*discordgo.ApplicationCommandOption{
{
Type: discordgo.ApplicationCommandOptionString,
Name: "project_name",
Description: "Temporary project name",
Required: true,
MinLength: &minLength,
},
}, },
}, {
{ Name: "Не начат",
Name: "info", Moderated: true,
Description: "Get project's info", EmojiName: "🚧",
}, },
{ }
Name: "repo", commands = []discordgo.ApplicationCommand{
Description: "Creates repository of selected type. Name used for projects channels only", {
Options: []*discordgo.ApplicationCommandOption{ Name: "ping",
{ Description: "pongs in a reply",
Type: discordgo.ApplicationCommandOptionString, },
Name: repoType, {
Description: "The type of repo", Name: "init_project",
Required: true, Description: "Connect project with Coda ID",
Choices: []*discordgo.ApplicationCommandOptionChoice{ Options: []*discordgo.ApplicationCommandOption{
{ {
Name: "Unity project repo", Type: discordgo.ApplicationCommandOptionString,
Value: projectRepo, Name: "key",
}, Description: "Project's key from Coda.io",
{ Required: true,
Name: "XCode build repo", MinLength: &minLength,
Value: buildRepo,
},
}, },
}, },
{ },
Type: discordgo.ApplicationCommandOptionString, {
Name: nameOption, Name: "project",
Description: "Type the repository's name", Description: "Create new development ticket",
Required: false, Options: []*discordgo.ApplicationCommandOption{
MinLength: &minLength, {
Type: discordgo.ApplicationCommandOptionString,
Name: "project_name",
Description: "Temporary project name",
Required: true,
MinLength: &minLength,
},
}, },
}, },
}, {
{ Name: "info",
Name: "folder", Description: "Get project's info",
Description: "Command for cloud folder creation", },
Options: []*discordgo.ApplicationCommandOption{ {
{ Name: "repo",
Type: discordgo.ApplicationCommandOptionString, Description: "Creates repository of selected type. Name used for projects channels only",
Name: nameOption, Options: []*discordgo.ApplicationCommandOption{
Description: "Type the folder's name", {
Required: false, Type: discordgo.ApplicationCommandOptionString,
MinLength: &minLength, Name: repoType,
Description: "The type of repo",
Required: true,
Choices: []*discordgo.ApplicationCommandOptionChoice{
{
Name: "Unity project repo",
Value: projectRepo,
},
{
Name: "XCode build repo",
Value: buildRepo,
},
},
},
{
Type: discordgo.ApplicationCommandOptionString,
Name: nameOption,
Description: "Type the repository's name",
Required: false,
MinLength: &minLength,
},
}, },
}, },
}, {
} Name: "folder",
Description: "Command for cloud folder creation",
Options: []*discordgo.ApplicationCommandOption{
{
Type: discordgo.ApplicationCommandOptionString,
Name: nameOption,
Description: "Type the folder's name",
Required: false,
MinLength: &minLength,
},
},
},
}
)
func initBotWith(token string) *discordgo.Session { func initBotWith(token string) *discordgo.Session {
discord, err := discordgo.New("Bot " + token) discord, err := discordgo.New("Bot " + token)
@ -128,87 +131,122 @@ type DiscordOptions struct {
Controller *controller.WorkflowController Controller *controller.WorkflowController
} }
func Run(conf domain.Config, opts DiscordOptions) error { // Моментальный ответ для избежания столкновения с протуханием токена
func initialResponse(s *discordgo.Session, i *discordgo.InteractionCreate) {
s := initBotWith(conf.Discord.Token) initialResponse := discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Flags: discordgo.MessageFlagsEphemeral,
Content: "👩‍🍳 Cooking your query..",
},
}
h := discord_handler.New( s.InteractionRespond(i.Interaction, &initialResponse)
opts.Controller, }
&conf.Discord,
services.NewDummyClient(conf.Telegram),
tags,
)
commandHandlers := map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){} // Определяем канал и реджектим запрос, если пишут в лс:
func isRejected(s *discordgo.Session, i *discordgo.InteractionCreate) bool {
for _, cmd := range commands { dchan, err := s.Channel(i.ChannelID)
var f func(s *discordgo.Session, i *discordgo.InteractionCreate) if err != nil {
return true
}
switch cmd.Name { 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 true
}
return false
}
func route(s *discordgo.Session, i *discordgo.InteractionCreate, h discord_handler.Handler) {
initialResponse(s, i)
if isRejected(s, i) {
return
}
// Определяем тип взаимодействия и хэндлим правильной функцией:
switch i.Type {
case discordgo.InteractionApplicationCommand:
cmd := i.ApplicationCommandData().Name
switch cmd {
case "ping": case "ping":
f = h.Ping h.Ping(s, i)
case "project": case "project":
f = h.CreateTicket h.CreateProject(s, i)
case "info": case "info":
f = h.ProjectInfo h.ProjectInfo(s, i)
case "repo": case "repo":
f = h.CreateGit h.CreateGit(s, i)
case "folder": case "folder":
f = h.CreateFolder h.CreateFolder(s, i)
case "init_project": case "init_project":
f = h.InitChannelAsProject h.InitChannelAsProject(s, i)
} }
commandHandlers[cmd.Name] = f case discordgo.InteractionMessageComponent:
} c := i.MessageComponentData().CustomID
switch c {
componentsHandlers := map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){ case "task_start":
"task_start": h.HandleTaskButtons, h.HandleTaskButtons(s, i)
"task_close": h.HandleTaskButtons, case "task_close":
} h.HandleTaskButtons(s, i)
s.AddHandler(h.ListenPosts)
s.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) {
h.AllInteractions(s, i)
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: func updateForum(conf *domain.Config, s *discordgo.Session) ([]discordgo.ForumTag, error) {
log.Println("Updating forum chan...")
// Get tasks channel instance:
forum, err := s.Channel(conf.Discord.IsTaskForum) forum, err := s.Channel(conf.Discord.IsTaskForum)
if err != nil { if err != nil {
log.Print(err) return nil, err
}
// Map all pre-set tags
var tagsMap = map[string]discordgo.ForumTag{}
for _, t := range forum.AvailableTags {
tagsMap[t.Name] = t
}
// Result tags array
tags := forum.AvailableTags
// Check if preset tag exists into current channel
for i := 0; i < len(tagsPreset); i++ {
_, ok := tagsMap[tagsPreset[i].Name]
if !ok {
tags = append(tags, tagsPreset[i])
}
} }
dchan, err := s.ChannelEditComplex(forum.ID, &discordgo.ChannelEdit{ dchan, err := s.ChannelEditComplex(forum.ID, &discordgo.ChannelEdit{
AvailableTags: &tags, AvailableTags: &tags,
}) })
if err != nil { if err != nil {
log.Fatal(err) return nil, err
} }
log.Printf("Channel %s with ID %s propagated by tags:", dchan.Name, dchan.ID) log.Printf("Channel %s with ID %s propagated by tags:", dchan.Name, dchan.ID)
for _, t := range dchan.AvailableTags { for _, t := range dchan.AvailableTags {
log.Printf("N: %s, ID: %s", t.Name, t.ID) fmt.Printf("N: %s, ID: %s", t.Name, t.ID)
} }
return dchan.AvailableTags, nil
}
func commandRegistration(s *discordgo.Session, commands []discordgo.ApplicationCommand) []*discordgo.ApplicationCommand {
log.Println("Adding commands...") log.Println("Adding commands...")
var cmds []*discordgo.ApplicationCommand var cmds []*discordgo.ApplicationCommand
for _, cmd := range commands { for _, cmd := range commands {
cmd, err := s.ApplicationCommandCreate(s.State.User.ID, "", &cmd) cmd, err := s.ApplicationCommandCreate(s.State.User.ID, "", &cmd)
if err != nil { if err != nil {
@ -217,7 +255,48 @@ func Run(conf domain.Config, opts DiscordOptions) error {
cmds = append(cmds, cmd) cmds = append(cmds, cmd)
log.Println(cmd.Name + " command added") log.Println(cmd.Name + " command added")
} }
return cmds
}
func Run(conf *domain.Config, opts DiscordOptions) error {
// bot init
s := initBotWith(conf.Discord.Token)
// Init new handler
h := discord_handler.New(
opts.Controller,
&conf.Discord,
services.NewDummyClient(conf.Telegram),
)
// Add posts listener
s.AddHandler(h.ListenPosts)
// Add interactions handlers
s.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) {
route(s, i, *h)
})
// session opening
if err := s.Open(); err != nil {
return fmt.Errorf("cannot open the session: %v", err)
}
// Forum update
tags, err := updateForum(conf, s)
if err != nil {
log.Println(err.Error())
}
//Update handler with tags:
h.SetAvailableTags(tags)
// commands registration
cmds := commandRegistration(s, commands)
// gracefull shutdown
defer s.Close() defer s.Close()
stop := make(chan os.Signal, 1) stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt) signal.Notify(stop, os.Interrupt)