package controller import ( "context" "fmt" "os" "ticket-pimp/internal/domain" "ticket-pimp/internal/storage/db" "time" "github.com/bwmarrin/discordgo" "github.com/jackc/pgx/v5/pgtype" ) // WriteTaskToDB /* Makes an SQL query to create new tasks row from domain.Task entity - Creator field: telegram nickname or Discord's Mention(); - Creator link (tg ID) in telegram case; - Description from telegram/discord message bodies; */ func (wc *WorkflowController) WriteTaskToDB(t *domain.Task) (*domain.Task, error) { dbtask, err := wc.q.InsertTask(context.TODO(), db.InsertTaskParams{ Creator: pgtype.Text{String: t.Creator, Valid: true}, CreatorLink: pgtype.Text{ String: t.CreatorLink, Valid: true, }, Description: pgtype.Text{ String: t.Description, Valid: true, }, }) if err != nil { return nil, fmt.Errorf("unable to create task at the db: %v", err) } // ------------------------------------------------------------------------------------ task := newConvertable(&dbtask).ExtractDomain() return task, nil } // InitTask /* Runs the following: - Use WriteTaskToDB method to make a new task row in the db; - init new discord bot instance; - Possible errors: - db record couldn't be created; - bot couldn't be inited; - bot session couldn't be started; - thread couldn't be started; - first task message couldn't be edited; */ func (wc *WorkflowController) InitTask(t *domain.Task) (*domain.Task, error) { task, err := wc.WriteTaskToDB(t) if err != nil { return nil, fmt.Errorf("unable to create task at the db: %v", err) } // Инициализируем новый клиент дискорда // [ ] Нездоровое получение параметров клиента из os.. var ( token = os.Getenv("DISCORD_TOKEN") forumChannelID = os.Getenv("TASKS_CHANNEL") ) s, err := discordgo.New("Bot " + token) if err != nil { return task, fmt.Errorf("unable to create discord session: %v", err) } if err := s.Open(); err != nil { return task, fmt.Errorf("cannot open the session: %v", err) } msg := discordgo.MessageSend{ Content: task.DiscordMessage(domain.NewTaskState()), Components: []discordgo.MessageComponent{ discordgo.ActionsRow{ Components: []discordgo.MessageComponent{ discordgo.Button{ Label: "Start", Style: discordgo.SuccessButton, Disabled: false, CustomID: "task_start", }, discordgo.Button{ Label: "Close", Style: discordgo.DangerButton, Disabled: true, CustomID: "task_close", }, }, }, }, } th, err := s.ForumThreadStartComplex( forumChannelID, &discordgo.ThreadStart{ Name: fmt.Sprintf("Task ID: %d, by %s", task.ID, task.Creator), }, &msg, ) if err != nil { return task, fmt.Errorf("unable to update channel: %v", err) } err = wc.UpdateTasksMessageID(context.TODO(), th.ID, task.ID) if err != nil { return task, fmt.Errorf("unable to set discord message to task: %v", err) } return task, nil } func (wc *WorkflowController) UpdateTasksMessageID(ctx context.Context, msgID string, taskID int32) error { err := wc.q.UpdateTaskWithMessageID(context.TODO(), db.UpdateTaskWithMessageIDParams{ Messageid: pgtype.Text{String: msgID, Valid: true}, ID: taskID, }) return err } func (wc *WorkflowController) UpdateTask(id string, opt int, user string) (*TaskConvertable, error) { var ( err error dbtask db.Task ) switch opt { case 0: dbtask, err = wc.q.StartTask(context.TODO(), db.StartTaskParams{ UpdatedAt: pgtype.Timestamptz{Time: time.Now(), InfinityModifier: 0, Valid: true}, Assignee: pgtype.Text{String: user, Valid: true}, Messageid: pgtype.Text{String: id, Valid: true}, }) return &TaskConvertable{&dbtask}, err case 1: dbtask, err = wc.q.CloseTask(context.TODO(), db.CloseTaskParams{ DeletedAt: pgtype.Timestamptz{Time: time.Now(), InfinityModifier: 0, Valid: true}, Assignee: pgtype.Text{String: user, Valid: true}, Messageid: pgtype.Text{String: id, Valid: true}, }) return &TaskConvertable{&dbtask}, err } return &TaskConvertable{&dbtask}, nil }