ticket-pimp/discord/handler/handler.go

319 lines
8.2 KiB
Go

package handler
import (
"context"
"fmt"
"log"
"ticket-pimp/internal/controller"
"ticket-pimp/internal/domain"
"github.com/bwmarrin/discordgo"
)
type router struct {
Routes []route
controller controller.WorkflowController
}
// Подключение роутов к Discord боту
func InitRouter(wc controller.WorkflowController) *router {
var r router
r.Routes = append(
r.Routes,
// r.CreateRepoHandler(3),
r.CreateFolderHandler(3),
r.Ping(),
// r.CreateTicketHandler(3),
)
r.controller = wc
return &r
}
type route struct {
Command discordgo.ApplicationCommand
Handler func(s *discordgo.Session, i *discordgo.InteractionCreate)
}
func (h *router) Ping() route {
return route{
Command: discordgo.ApplicationCommand{
Name: "ping",
Description: "pongs in a reply",
},
Handler: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
log.Println("ok, I'm here..")
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseDeferredMessageUpdate,
Data: &discordgo.InteractionResponseData{
Content: "`pong`",
Title: "Pong reply",
},
})
},
}
}
func (h *router) CreateFolderHandler(nameMinLenght int) route {
const (
nameOption string = "folder_name"
)
return route{
Command: discordgo.ApplicationCommand{
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: &nameMinLenght,
},
},
},
Handler: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
var result string
resp := discordgo.InteractionResponse{
Type: discordgo.InteractionResponseUpdateMessage,
Data: &discordgo.InteractionResponseData{
Content: "Folder is going to be created..",
},
}
err := s.InteractionRespond(i.Interaction, &resp)
if err != nil {
log.Println(err)
return
}
options := i.ApplicationCommandData().Options
optionMap := make(map[string]*discordgo.ApplicationCommandInteractionDataOption, len(options))
for _, opt := range options {
optionMap[opt.Name] = opt
}
var str string = ""
project, err := h.controller.GetProjectByChannelID(context.TODO(), i.ChannelID)
if err != nil {
result = fmt.Sprintf("unable to retrieve project from db, error: %v", err)
} else {
if project == nil {
if option, ok := optionMap[nameOption]; ok {
str = option.StringValue()
} else {
str = ""
}
} else {
str = project.ShortName
}
if str == "" {
result = "Ты, либо в проекте директорию создавай, либо имя напиши, блет!"
} else {
f, err := h.controller.ICloud.CreateFolder(str)
if err != nil {
result = fmt.Sprintf("error while cloud folder creation: %v", err)
} else {
result = fmt.Sprint(f.PrivateURL)
}
}
}
// resp = discordgo.InteractionResponse{
// // Ignore type for now, they will be discussed in "responses"
// Type: discordgo.InteractionResponseUpdateMessage,
// Data: &discordgo.InteractionResponseData{
// Content: result,
// Title: "📂 Folder was created",
// },
// }
webhookEdit := discordgo.WebhookEdit{
Content: &result,
}
s.InteractionResponseEdit(i.Interaction, &webhookEdit)
// discerr := s.InteractionRespond(i.Interaction, &resp)
// if discerr != nil {
// log.Println(discerr)
// }
},
}
}
func (h *router) CreateRepoHandler(repoNameMinLength int) route {
const (
projectRepo = "project_repo"
buildRepo = "build_repo"
)
return route{
Command: discordgo.ApplicationCommand{
Name: "repo",
Description: "Command for repository creation",
Options: []*discordgo.ApplicationCommandOption{
{
Type: discordgo.ApplicationCommandOptionString,
Name: "repo_type",
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: "repo_name",
Description: "Type the repository's name",
Required: false,
MinLength: &repoNameMinLength,
},
},
},
Handler: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
var result string
// Access options in the order provided by the user.
options := i.ApplicationCommandData().Options
// Or convert the slice into a map
optionMap := make(map[string]*discordgo.ApplicationCommandInteractionDataOption, len(options))
for _, opt := range options {
optionMap[opt.Name] = opt
}
var str string = ""
project, err := h.controller.GetProjectByChannelID(context.TODO(), i.ChannelID)
if err != nil {
result = fmt.Sprintf("unable to retrieve project from db, error: %v", err)
} else {
var suffix string
if option, ok := optionMap["repo_type"]; ok {
switch option.Value {
case projectRepo:
suffix = ""
case buildRepo:
suffix = "-build"
}
}
if project == nil {
if option, ok := optionMap["repo_name"]; ok {
str = option.StringValue()
} else {
str = ""
}
} else {
str = project.ShortName
}
if str == "" {
result = "Ты, либо в проекте репо создавай, либо имя напиши, блет!"
} else {
str = str + suffix
// var g *domain.Git
g, err := h.controller.IGit.CreateRepo(str)
if err != nil {
result = fmt.Sprintf("error while repo creation: %v", err)
} else {
result = "🚀 " + g.HtmlUrl + " was created"
}
}
}
resp := &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: result,
},
}
s.InteractionRespond(i.Interaction, resp)
},
}
}
func (h *router) CreateTicketHandler(repoNameMinLength int) route {
return route{
Command: discordgo.ApplicationCommand{
Name: "project",
Description: "Create new development ticket",
Options: []*discordgo.ApplicationCommandOption{
{
Type: discordgo.ApplicationCommandOptionString,
Name: "project_name",
Description: "Temporary project name",
Required: true,
MinLength: &repoNameMinLength,
},
},
},
Handler: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
var result string
// Access options in the order provided by the user.
options := i.ApplicationCommandData().Options
// Or convert the slice into a map
optionMap := make(map[string]*discordgo.ApplicationCommandInteractionDataOption, len(options))
for _, opt := range options {
optionMap[opt.Name] = opt
}
if option, ok := optionMap["project_name"]; ok {
dchan, err := s.GuildChannelCreate(i.GuildID, option.StringValue(), discordgo.ChannelTypeGuildText)
if err != nil {
result = fmt.Sprintf("chan creation problem: %v\n", err)
} else {
p, err := h.controller.ProjectCreate(context.TODO(), domain.Project{
ChannelID: dchan.ID,
})
if err != nil {
result = fmt.Sprintf("unable to create project: %v\n", err)
} else {
edit := discordgo.ChannelEdit{
Name: p.ShortName,
ParentID: "1150719794853716028",
}
dchan, err = s.ChannelEdit(dchan.ID, &edit)
if err != nil {
result = fmt.Sprintf("channel created, but unable to edit: %v\n", err)
} else {
_, err = s.ChannelMessageSend(dchan.ID, "Hello!")
if err != nil {
log.Printf("message send problem: %v\n", err)
}
result = dchan.ID
}
}
}
}
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
// Ignore type for now, they will be discussed in "responses"
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: result,
},
})
},
}
}