155 lines
4.0 KiB
Go
155 lines
4.0 KiB
Go
package controller
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"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)
|
||
}
|
||
|
||
s, err := discordgo.New("Bot " + wc.conf.Discord.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(
|
||
wc.conf.Discord.IsTaskForum,
|
||
&discordgo.ThreadStart{
|
||
Name: fmt.Sprintf("Task ID: %d, by %s", task.ID, task.Creator),
|
||
AppliedTags: []string{"Не начат"},
|
||
},
|
||
&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
|
||
}
|
||
|
||
// UpdateTask
|
||
/*
|
||
- updates task by message Id
|
||
- with an action:
|
||
0 for 'in progress' state;
|
||
1 for 'done' state;
|
||
- and assignee..
|
||
*/
|
||
func (wc *WorkflowController) UpdateTask(messageId string, opt int, assignee 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: assignee, Valid: true},
|
||
Messageid: pgtype.Text{String: messageId, 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: assignee, Valid: true},
|
||
Messageid: pgtype.Text{String: messageId, Valid: true},
|
||
})
|
||
return &TaskConvertable{&dbtask}, err
|
||
}
|
||
|
||
return &TaskConvertable{&dbtask}, nil
|
||
}
|