Huge refactoring:
- removed deprecated methods from controller; - moved handlers to a separate files; - create initiation handler; - moved farmer tasks to coda!
This commit is contained in:
parent
a9ff088af9
commit
ec5d95586c
|
|
@ -1,15 +1,11 @@
|
|||
package controller
|
||||
|
||||
import (
|
||||
"encoding/csv"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"sync"
|
||||
"ticket-pimp/internal/domain"
|
||||
"ticket-pimp/internal/services"
|
||||
|
||||
"github.com/imroc/req/v3"
|
||||
)
|
||||
|
||||
type WorkflowController struct {
|
||||
|
|
@ -38,96 +34,6 @@ func NewWorkflowController(
|
|||
|
||||
type IWorkflowController interface {
|
||||
Workflow(name string) (string, error)
|
||||
|
||||
NewTask(summ, desc, c, cLink string) *Task
|
||||
CreateTask(t *Task) (*Task, error)
|
||||
|
||||
ThrowConversions(f io.ReadCloser, appID string, token string) *domain.ConversionLog
|
||||
}
|
||||
|
||||
func (wc *WorkflowController) ThrowConversions(f io.ReadCloser, appID string, token string) *domain.ConversionLog {
|
||||
c := req.C().
|
||||
SetBaseURL("https://graph.facebook.com/v15.0/").
|
||||
DevMode()
|
||||
|
||||
const currency = "USD"
|
||||
|
||||
r := csv.NewReader(f)
|
||||
|
||||
conversionLog := domain.ConversionLog{}
|
||||
|
||||
for {
|
||||
record, err := r.Read()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
advertiser := strings.Split(record[0], ";")[0]
|
||||
|
||||
params := map[string]string{
|
||||
"advertiser_id": advertiser,
|
||||
"event": "CUSTOM_APP_EVENTS",
|
||||
"application_tracking_enabled": "1",
|
||||
"advertiser_tracking_enabled": "1",
|
||||
"custom_events": `[{"_eventName":"fb_mobile_purchase"}]`,
|
||||
}
|
||||
|
||||
res, _ := c.R().
|
||||
SetQueryString(token).
|
||||
SetQueryParams(params).
|
||||
Post(appID + "/activities")
|
||||
|
||||
if res.Err != nil {
|
||||
conversionLog.Advertiser = append(conversionLog.Advertiser, advertiser)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return &conversionLog
|
||||
}
|
||||
|
||||
type Task struct {
|
||||
Summary string
|
||||
Description string
|
||||
Creator string
|
||||
CreatorLink string
|
||||
|
||||
Key string
|
||||
URL string
|
||||
}
|
||||
|
||||
func (wc *WorkflowController) NewTask(summ, desc, c, cLink string) *Task {
|
||||
return &Task{
|
||||
Summary: summ,
|
||||
Description: desc,
|
||||
Creator: c,
|
||||
CreatorLink: cLink,
|
||||
}
|
||||
}
|
||||
|
||||
func (wc *WorkflowController) CreateTask(t *Task) (*Task, error) {
|
||||
|
||||
yt := wc.additionalYT
|
||||
|
||||
projectID, err := yt.GetProjectIDByName("E")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
t.Description += fmt.Sprintf("\n\n Created by: [%s](%s)", t.Creator, t.CreatorLink)
|
||||
|
||||
issue, err := yt.CreateIssue(projectID, t.Creator+" | "+t.Summary, t.Description)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
t.Key = issue.Key
|
||||
t.URL = fmt.Sprintf("https://mobmarlerino.youtrack.cloud/issue/%s", issue.Key)
|
||||
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func (wc *WorkflowController) Workflow(name string) (string, error) {
|
||||
|
|
@ -192,7 +98,7 @@ func (wc *WorkflowController) Workflow(name string) (string, error) {
|
|||
cloudResult = cloud.PrivateURL
|
||||
}
|
||||
|
||||
wc.iCoda.CreateApp(domain.CodaIssue{
|
||||
wc.iCoda.CreateApp(domain.CodaApplication{
|
||||
ID: issue.Key,
|
||||
Summary: strings.TrimSpace(name),
|
||||
Git: gitResult,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/mr-linch/go-tg"
|
||||
"github.com/mr-linch/go-tg/tgb"
|
||||
)
|
||||
|
||||
func (h *Handler) DevelopmentTaskHandler(ctx context.Context, mu *tgb.MessageUpdate) error {
|
||||
|
||||
str := strings.Replace(mu.Text, "/new", "", 1)
|
||||
|
||||
if str == "" {
|
||||
return errors.New("empty command provided")
|
||||
}
|
||||
|
||||
issueKeyStr, err := h.workflow.Workflow(str)
|
||||
|
||||
if err != nil {
|
||||
answer := errorAnswer(err.Error())
|
||||
h.LogMessage(ctx, mu, answer)
|
||||
return mu.Answer(answer).ParseMode(tg.HTML).DoVoid(ctx)
|
||||
}
|
||||
|
||||
answer := newTicketAnswer(issueKeyStr)
|
||||
h.LogMessage(ctx, mu, answer)
|
||||
return mu.Answer(answer).ParseMode(tg.HTML).DoVoid(ctx)
|
||||
}
|
||||
|
||||
func newTicketAnswer(name string) string {
|
||||
return tg.HTML.Text(
|
||||
tg.HTML.Line(
|
||||
"🤘 Ticket ",
|
||||
tg.HTML.Link(name, fmt.Sprintf("https://marlerino.youtrack.cloud/issue/%s", name)),
|
||||
"has been created!",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"ticket-pimp/internal/domain"
|
||||
|
||||
"github.com/mr-linch/go-tg"
|
||||
"github.com/mr-linch/go-tg/tgb"
|
||||
)
|
||||
|
||||
func (h *Handler) FarmTaskHandler(ctx context.Context, mu *tgb.MessageUpdate) error {
|
||||
|
||||
msgID := mu.Message.ID
|
||||
|
||||
taskText := strings.TrimSpace(strings.Replace(mu.Text, "/task", "", 1))
|
||||
|
||||
var summaryTail string
|
||||
|
||||
sentances := strings.Split(taskText, "\n")
|
||||
if len(sentances) < 2 {
|
||||
words := strings.Split(taskText, " ")
|
||||
if len(words) > 2 {
|
||||
summaryTail = strings.Join(words[0:2], " ")
|
||||
} else {
|
||||
summaryTail = strings.Join(words, " ")
|
||||
}
|
||||
} else {
|
||||
summaryTail = sentances[0]
|
||||
}
|
||||
|
||||
t := domain.NewTask(
|
||||
summaryTail,
|
||||
taskText,
|
||||
mu.From.Username.PeerID(),
|
||||
mu.Chat.ID.PeerID(),
|
||||
)
|
||||
|
||||
id, err := h.coda.CreateTask(t.Summary, t.Description, t.Creator, t.CreatorLink)
|
||||
if err != nil {
|
||||
answer := errorAnswer(err.Error())
|
||||
h.LogMessage(ctx, mu, answer)
|
||||
return mu.Answer(answer).ParseMode(tg.HTML).DoVoid(ctx)
|
||||
}
|
||||
if id == "" {
|
||||
answer := errorAnswer("task wasn't created")
|
||||
h.LogMessage(ctx, mu, answer)
|
||||
return mu.Answer(answer).ParseMode(tg.HTML).DoVoid(ctx)
|
||||
}
|
||||
|
||||
err = mu.Answer(fmt.Sprintf("Задача с id: %s была создана, жду ссылку", id)).DoVoid(ctx)
|
||||
if err != nil {
|
||||
log.Println("бот не смог ответить про создание задачи")
|
||||
}
|
||||
|
||||
url, err := h.coda.GetRowLink(id)
|
||||
if err != nil {
|
||||
answer := err.Error()
|
||||
h.LogMessage(ctx, mu, answer)
|
||||
return err
|
||||
}
|
||||
t.URL = url
|
||||
|
||||
answer := tg.HTML.Text(
|
||||
tg.HTML.Line(tg.HTML.Link("🤘 Задача", t.URL), "была создана!"))
|
||||
h.LogMessage(ctx, mu, answer)
|
||||
return mu.Answer(answer).
|
||||
ReplyToMessageID(msgID).ParseMode(tg.HTML).DisableWebPagePreview(true).DoVoid(ctx)
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/mr-linch/go-tg"
|
||||
"github.com/mr-linch/go-tg/tgb"
|
||||
)
|
||||
|
||||
func (h *Handler) NewFolderHandler(ctx context.Context, mu *tgb.MessageUpdate) error {
|
||||
|
||||
str := strings.Replace(mu.Text, "/folder", "", 1)
|
||||
|
||||
if str == "" {
|
||||
return errors.New("empty command provided")
|
||||
}
|
||||
|
||||
cloud, err := h.cloud.CreateFolder(str)
|
||||
|
||||
if err != nil {
|
||||
answer := errorAnswer(err.Error())
|
||||
h.LogMessage(ctx, mu, answer)
|
||||
return mu.Answer(answer).ParseMode(tg.HTML).DoVoid(ctx)
|
||||
}
|
||||
|
||||
answer := tg.HTML.Text(
|
||||
tg.HTML.Line(
|
||||
"✨ Shiny folder",
|
||||
tg.HTML.Link(cloud.Title, cloud.PrivateURL),
|
||||
"has been created!",
|
||||
),
|
||||
)
|
||||
|
||||
h.LogMessage(ctx, mu, answer)
|
||||
return mu.Answer(answer).
|
||||
ParseMode(tg.HTML).
|
||||
DoVoid(ctx)
|
||||
}
|
||||
|
||||
func errorAnswer(errorMsg string) string {
|
||||
return tg.HTML.Text(
|
||||
tg.HTML.Line(
|
||||
tg.HTML.Italic(errorMsg),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"ticket-pimp/internal/domain"
|
||||
|
||||
"github.com/mr-linch/go-tg"
|
||||
"github.com/mr-linch/go-tg/tgb"
|
||||
)
|
||||
|
||||
type git struct {
|
||||
name string
|
||||
url string
|
||||
|
||||
git string
|
||||
ssh string
|
||||
}
|
||||
|
||||
func newGit(domain *domain.Git) *git {
|
||||
return &git{
|
||||
name: domain.Name,
|
||||
url: domain.HtmlUrl,
|
||||
git: domain.CloneUrl,
|
||||
ssh: fmt.Sprintf("ssh://%s/%s.git", domain.SshUrl, domain.FullName),
|
||||
}
|
||||
}
|
||||
|
||||
// FYI: Telegram doesn't renders this hyperlink, if the url is localhost 🤷♂️
|
||||
func (g *git) PrepareAnswer() string {
|
||||
return tg.HTML.Text(
|
||||
tg.HTML.Line(
|
||||
"Repo ",
|
||||
tg.HTML.Link(g.name, g.url),
|
||||
"has been created!",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
func (h *Handler) NewRepoHandler(ctx context.Context, mu *tgb.MessageUpdate) error {
|
||||
|
||||
str := strings.Replace(mu.Text, "/repo", "", 1)
|
||||
|
||||
if str == "" {
|
||||
return errors.New("empty command provided")
|
||||
}
|
||||
|
||||
var g *domain.Git
|
||||
|
||||
g, err := h.git.CreateRepo(str)
|
||||
|
||||
if err != nil {
|
||||
return mu.Answer(errorAnswer(err.Error())).ParseMode(tg.HTML).DoVoid(ctx)
|
||||
}
|
||||
|
||||
resp := newGit(g).PrepareAnswer()
|
||||
h.LogMessage(ctx, mu, resp)
|
||||
|
||||
return mu.Answer(resp).ParseMode(tg.HTML).DoVoid(ctx)
|
||||
}
|
||||
|
|
@ -1,23 +1,15 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"ticket-pimp/bot/controller"
|
||||
"ticket-pimp/internal/domain"
|
||||
"ticket-pimp/internal/services"
|
||||
|
||||
"github.com/mr-linch/go-tg"
|
||||
"github.com/mr-linch/go-tg/tgb"
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
workflow controller.IWorkflowController
|
||||
git services.IGit
|
||||
cloud services.ICloud
|
||||
coda services.ICoda
|
||||
}
|
||||
|
||||
func NewHandler(
|
||||
|
|
@ -32,202 +24,6 @@ func NewHandler(
|
|||
workflow: controller.NewWorkflowController(git, cloud, devyt, farmyt, coda),
|
||||
git: git,
|
||||
cloud: cloud,
|
||||
coda: coda,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) PingHandler(ctx context.Context, mu *tgb.MessageUpdate) error {
|
||||
|
||||
return mu.Answer("pong").DoVoid(ctx)
|
||||
}
|
||||
|
||||
type git struct {
|
||||
name string
|
||||
url string
|
||||
|
||||
git string
|
||||
ssh string
|
||||
}
|
||||
|
||||
func newGit(domain *domain.Git) *git {
|
||||
return &git{
|
||||
name: domain.Name,
|
||||
url: domain.HtmlUrl,
|
||||
git: domain.CloneUrl,
|
||||
ssh: fmt.Sprintf("ssh://%s/%s.git", domain.SshUrl, domain.FullName),
|
||||
}
|
||||
}
|
||||
|
||||
// FYI: Telegram doesn't renders this hyperlink, if the url is localhost 🤷♂️
|
||||
func (g *git) PrepareAnswer() string {
|
||||
return tg.HTML.Text(
|
||||
tg.HTML.Line(
|
||||
"Repo ",
|
||||
tg.HTML.Link(g.name, g.url),
|
||||
"has been created!",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
func (h *Handler) NewRepoHandler(ctx context.Context, mu *tgb.MessageUpdate) error {
|
||||
|
||||
str := strings.Replace(mu.Text, "/repo", "", 1)
|
||||
|
||||
if str == "" {
|
||||
return errors.New("empty command provided")
|
||||
}
|
||||
|
||||
var g *domain.Git
|
||||
|
||||
g, err := h.git.CreateRepo(str)
|
||||
|
||||
if err != nil {
|
||||
return mu.Answer(errorAnswer(err.Error())).ParseMode(tg.HTML).DoVoid(ctx)
|
||||
}
|
||||
|
||||
resp := newGit(g).PrepareAnswer()
|
||||
|
||||
return mu.Answer(resp).ParseMode(tg.HTML).DoVoid(ctx)
|
||||
}
|
||||
|
||||
func (h *Handler) NewFolderHandler(ctx context.Context, mu *tgb.MessageUpdate) error {
|
||||
|
||||
str := strings.Replace(mu.Text, "/folder", "", 1)
|
||||
|
||||
if str == "" {
|
||||
return errors.New("empty command provided")
|
||||
}
|
||||
|
||||
cloud, err := h.cloud.CreateFolder(str)
|
||||
|
||||
if err != nil {
|
||||
return mu.Answer(errorAnswer(err.Error())).ParseMode(tg.HTML).DoVoid(ctx)
|
||||
}
|
||||
|
||||
answer := tg.HTML.Text(
|
||||
tg.HTML.Line(
|
||||
"✨ Shiny folder",
|
||||
tg.HTML.Link(cloud.Title, cloud.PrivateURL),
|
||||
"has been created!",
|
||||
),
|
||||
)
|
||||
|
||||
return mu.Answer(answer).
|
||||
ParseMode(tg.HTML).
|
||||
DoVoid(ctx)
|
||||
}
|
||||
|
||||
func errorAnswer(errorMsg string) string {
|
||||
return tg.HTML.Text(
|
||||
tg.HTML.Line(
|
||||
tg.HTML.Italic(errorMsg),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
func (h *Handler) DevelopmentTaskHandler(ctx context.Context, mu *tgb.MessageUpdate) error {
|
||||
|
||||
str := strings.Replace(mu.Text, "/new", "", 1)
|
||||
|
||||
if str == "" {
|
||||
return errors.New("empty command provided")
|
||||
}
|
||||
|
||||
issueKeyStr, err := h.workflow.Workflow(str)
|
||||
|
||||
if err != nil {
|
||||
return mu.Answer(errorAnswer(err.Error())).ParseMode(tg.HTML).DoVoid(ctx)
|
||||
}
|
||||
|
||||
return mu.Answer(newTicketAnswer(issueKeyStr)).ParseMode(tg.HTML).DoVoid(ctx)
|
||||
}
|
||||
|
||||
func newTicketAnswer(name string) string {
|
||||
return tg.HTML.Text(
|
||||
tg.HTML.Line(
|
||||
"🤘 Ticket ",
|
||||
tg.HTML.Link(name, fmt.Sprintf("https://marlerino.youtrack.cloud/issue/%s", name)),
|
||||
"has been created!",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
func (h *Handler) FarmTaskHandler(ctx context.Context, mu *tgb.MessageUpdate) error {
|
||||
|
||||
taskText := strings.TrimSpace(strings.Replace(mu.Text, "/task", "", 1))
|
||||
words := strings.Split(taskText, " ")
|
||||
|
||||
var summaryTail string
|
||||
if len(words) > 3 {
|
||||
summaryTail = strings.Join(words[0:3], " ")
|
||||
} else {
|
||||
summaryTail = strings.Join(words, " ")
|
||||
}
|
||||
|
||||
task := h.workflow.NewTask(
|
||||
summaryTail,
|
||||
taskText,
|
||||
mu.From.Username.PeerID(),
|
||||
mu.From.Username.Link(),
|
||||
)
|
||||
|
||||
createdTicket, err := h.workflow.CreateTask(task)
|
||||
if err != nil {
|
||||
return mu.Answer(errorAnswer(err.Error())).ParseMode(tg.HTML).DoVoid(ctx)
|
||||
}
|
||||
|
||||
return mu.Answer(tg.HTML.Text(
|
||||
tg.HTML.Line(
|
||||
"🤘 Задача",
|
||||
tg.HTML.Link(createdTicket.Key, createdTicket.URL),
|
||||
"была создана!",
|
||||
),
|
||||
)).ParseMode(tg.HTML).DoVoid(ctx)
|
||||
}
|
||||
|
||||
func (h *Handler) NewConversion(ctx context.Context, mu *tgb.MessageUpdate) error {
|
||||
msg := strings.TrimSpace(strings.Replace(mu.Caption, "/conversion", "", 1))
|
||||
|
||||
appID, token := normalizeToken(msg)
|
||||
|
||||
fid := mu.Update.Message.Document.FileID
|
||||
|
||||
client := mu.Client
|
||||
|
||||
file, err := client.GetFile(fid).Do(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := client.Download(ctx, file.FilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
l := h.workflow.ThrowConversions(f, appID, token)
|
||||
|
||||
if len(l.Advertiser) != 0 {
|
||||
return mu.Answer(tg.HTML.Text(
|
||||
"Неуспешные запросы:",
|
||||
tg.HTML.Code(strings.Join(l.Advertiser, ", ")),
|
||||
)).ParseMode(tg.HTML).DoVoid(ctx)
|
||||
}
|
||||
|
||||
return mu.Answer(tg.HTML.Text(
|
||||
"Конверсии отправлены",
|
||||
)).ParseMode(tg.HTML).DoVoid(ctx)
|
||||
}
|
||||
|
||||
func normalizeToken(msg string) (string, string) {
|
||||
msg = strings.TrimSpace(msg)
|
||||
|
||||
args := strings.Split(msg, "|")
|
||||
|
||||
if len(args) != 2 {
|
||||
log.Print(len(args))
|
||||
return "", ""
|
||||
}
|
||||
|
||||
return args[0], args[0] + "|" + args[1]
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/mr-linch/go-tg"
|
||||
"github.com/mr-linch/go-tg/tgb"
|
||||
)
|
||||
|
||||
func (h *Handler) LogMessage(ctx context.Context, mu *tgb.MessageUpdate, msg string) error {
|
||||
|
||||
env := os.Getenv("TGSPAM")
|
||||
id, err := strconv.ParseInt(env, 10, 64)
|
||||
if err == nil {
|
||||
log.Println("fatal while parsing chatID")
|
||||
}
|
||||
|
||||
msg += " <i>from:</i>" + string(mu.From.Username)
|
||||
|
||||
return mu.Client.SendMessage(tg.ChatID(id), msg).ParseMode(tg.HTML).DoVoid(ctx)
|
||||
}
|
||||
|
||||
func (h *Handler) Init(ctx context.Context, mu *tgb.MessageUpdate) error {
|
||||
msgID := mu.Message.ID
|
||||
peer := mu.Chat.ID.PeerID()
|
||||
|
||||
if mu.From.ID == 2532580 {
|
||||
os.Setenv("TGSPAM", peer)
|
||||
answer := fmt.Sprintf("<i>this chat (%s) is now a logger chat</i>", peer)
|
||||
return mu.Answer(answer).ReplyToMessageID(msgID).ParseMode(tg.HTML).DoVoid(ctx)
|
||||
}
|
||||
|
||||
answer := "я тебя не знаю, уходи"
|
||||
return mu.Answer(answer).ReplyToMessageID(msgID).ParseMode(tg.HTML).DoVoid(ctx)
|
||||
|
||||
}
|
||||
|
||||
func (h *Handler) PingHandler(ctx context.Context, mu *tgb.MessageUpdate) error {
|
||||
h.LogMessage(ctx, mu, "pong")
|
||||
return mu.Answer("pong").DoVoid(ctx)
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ import (
|
|||
|
||||
func main() {
|
||||
log.Print("started")
|
||||
env("dev.env")
|
||||
env("develop.env")
|
||||
ctx := context.Background()
|
||||
|
||||
ctx, cancel := signal.NotifyContext(ctx, os.Interrupt, os.Kill, syscall.SIGTERM)
|
||||
|
|
@ -80,12 +80,12 @@ func runBot(ctx context.Context) error {
|
|||
)
|
||||
|
||||
router := tgb.NewRouter().
|
||||
Message(h.DevelopmentTaskHandler, tgb.TextHasPrefix("/new")).
|
||||
Message(h.Init, tgb.Command("init")).
|
||||
Message(h.PingHandler, tgb.Command("ping")).
|
||||
Message(h.DevelopmentTaskHandler, tgb.TextHasPrefix("/new")).
|
||||
Message(h.NewRepoHandler, tgb.TextHasPrefix("/repo")).
|
||||
Message(h.NewFolderHandler, tgb.TextHasPrefix("/folder")).
|
||||
Message(h.FarmTaskHandler, tgb.TextHasPrefix("/task")).
|
||||
Message(h.NewConversion, tgb.TextHasPrefix("/conversion"))
|
||||
Message(h.FarmTaskHandler, tgb.TextHasPrefix("/task"))
|
||||
|
||||
return tgb.NewPoller(
|
||||
router,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ type Folder struct {
|
|||
PrivateURL string // http://domain/apps/files/?dir=/temp/k OR http://domain/f/3333
|
||||
}
|
||||
|
||||
type CodaIssue struct {
|
||||
type CodaApplication struct {
|
||||
ID string `json:"id"`
|
||||
Summary string `json:"summary"`
|
||||
URL string `json:"url"`
|
||||
|
|
@ -17,6 +17,57 @@ type CodaIssue struct {
|
|||
Folder string `json:"folder"`
|
||||
}
|
||||
|
||||
type Insert struct {
|
||||
Rows []Row `json:"rows"`
|
||||
}
|
||||
|
||||
func NewTaskRequest() *Insert {
|
||||
return &Insert{}
|
||||
}
|
||||
|
||||
type Row struct {
|
||||
Cells []Cell `json:"cells"`
|
||||
}
|
||||
|
||||
func (req *Insert) NewRow() *Row {
|
||||
row := Row{}
|
||||
i := len(req.Rows)
|
||||
req.Rows = append(req.Rows, row)
|
||||
return &req.Rows[i]
|
||||
}
|
||||
|
||||
type Cell struct {
|
||||
Column string `json:"column"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
func (r *Row) NewCell(col string, value string) *Row {
|
||||
cell := Cell{
|
||||
Column: col,
|
||||
Value: value,
|
||||
}
|
||||
r.Cells = append(r.Cells, cell)
|
||||
return r
|
||||
}
|
||||
|
||||
type Task struct {
|
||||
Summary string
|
||||
Description string
|
||||
Creator string
|
||||
CreatorLink string
|
||||
|
||||
URL string
|
||||
}
|
||||
|
||||
func NewTask(summ, desc, c, cLink string) *Task {
|
||||
return &Task{
|
||||
Summary: summ,
|
||||
Description: desc,
|
||||
Creator: c,
|
||||
CreatorLink: cLink,
|
||||
}
|
||||
}
|
||||
|
||||
type ConversionLog struct {
|
||||
Advertiser []string
|
||||
}
|
||||
|
|
@ -31,11 +82,6 @@ type Git struct {
|
|||
SshUrl string `json:"ssh_url"` // ?!
|
||||
}
|
||||
|
||||
type Task struct {
|
||||
Description string
|
||||
URL string
|
||||
}
|
||||
|
||||
type Project struct {
|
||||
ID string `json:"id"`
|
||||
ShortName string `json:"shortName"`
|
||||
|
|
|
|||
|
|
@ -14,14 +14,20 @@ func NewClient() *CommonClient {
|
|||
return &CommonClient{req.C().
|
||||
OnAfterResponse(func(client *req.Client, resp *req.Response) error {
|
||||
if resp.Err != nil {
|
||||
if dump := resp.Dump(); dump != "" {
|
||||
resp.Err = fmt.Errorf("%s\nraw content:\n%s", resp.Err.Error(), resp.Dump())
|
||||
if resp.String() != "" {
|
||||
resp.Err = fmt.Errorf("%s\nraw content:\n%s", resp.Err.Error(), resp.String())
|
||||
} else {
|
||||
resp.Err = fmt.Errorf("bad request")
|
||||
}
|
||||
return nil // Skip the following logic if there is an underlying error.
|
||||
return nil
|
||||
}
|
||||
|
||||
if !resp.IsSuccessState() {
|
||||
resp.Err = fmt.Errorf("bad response, raw content:\n%s", resp.Dump())
|
||||
if resp.String() != "" {
|
||||
resp.Err = fmt.Errorf("bad response, raw content:\n%s", resp.String())
|
||||
} else {
|
||||
resp.Err = fmt.Errorf("bad response")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import (
|
|||
"log"
|
||||
"ticket-pimp/internal/domain"
|
||||
"time"
|
||||
|
||||
"github.com/imroc/req/v3"
|
||||
)
|
||||
|
||||
type Coda struct {
|
||||
|
|
@ -13,13 +15,15 @@ type Coda struct {
|
|||
|
||||
type ICoda interface {
|
||||
ListDocs()
|
||||
CreateApp(task domain.CodaIssue)
|
||||
CreateApp(task domain.CodaApplication)
|
||||
CreateTask(title string, desc string, creatorName string, creatorID string) (string, error)
|
||||
GetRowLink(id string) (string, error)
|
||||
}
|
||||
|
||||
func NewCodaClient(token string) *Coda {
|
||||
|
||||
client := NewClient().
|
||||
SetTimeout(5 * time.Second).
|
||||
SetTimeout(15 * time.Second).
|
||||
SetCommonBearerAuthToken(token).
|
||||
SetBaseURL("https://coda.io/apis/v1")
|
||||
|
||||
|
|
@ -35,8 +39,6 @@ func (c *Coda) ListDocs() {
|
|||
const tableID = "grid-obBN3tWdeh"
|
||||
const docID = "Ic3IZpQ3Wk"
|
||||
|
||||
//var i []RespObj
|
||||
|
||||
resp, _ := c.R().
|
||||
SetQueryParam("tableTypes", "table").
|
||||
//SetSuccessResult(&i).
|
||||
|
|
@ -50,7 +52,7 @@ func (c *Coda) ListDocs() {
|
|||
log.Print(resp)
|
||||
}
|
||||
|
||||
func (c *Coda) CreateApp(task domain.CodaIssue) {
|
||||
func (c *Coda) CreateApp(task domain.CodaApplication) {
|
||||
resp, _ := c.R().
|
||||
SetBody(task).
|
||||
SetContentType("application/json").
|
||||
|
|
@ -58,3 +60,65 @@ func (c *Coda) CreateApp(task domain.CodaIssue) {
|
|||
|
||||
fmt.Print(resp)
|
||||
}
|
||||
|
||||
func (c *Coda) CreateTask(title string, desc string, creatorName string, creatorID string) (string, error) {
|
||||
const (
|
||||
docID = "vceN8BewiU"
|
||||
tableID = "grid-GPdeq96hUq"
|
||||
)
|
||||
|
||||
request := domain.NewTaskRequest()
|
||||
request.
|
||||
NewRow().
|
||||
NewCell("c-rvWipOfkxr", title).
|
||||
NewCell("c-fLsUoIqQG9", creatorName).
|
||||
NewCell("c-psmWFHIoKl", creatorID).
|
||||
NewCell("c-ASsOsB1hzH", desc)
|
||||
|
||||
type TaskURL struct {
|
||||
ID []string `json:"addedRowIds"`
|
||||
}
|
||||
|
||||
tasks := TaskURL{}
|
||||
|
||||
_, err := c.R().
|
||||
SetContentType("application/json").
|
||||
SetQueryParam("disableParsing", "true").
|
||||
SetBodyJsonMarshal(&request).
|
||||
SetSuccessResult(&tasks).
|
||||
Post("/docs/" + docID + "/tables/" + tableID + "/rows")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return tasks.ID[0], nil
|
||||
}
|
||||
|
||||
func (c *Coda) GetRowLink(id string) (string, error) {
|
||||
const (
|
||||
docID = "vceN8BewiU"
|
||||
tableID = "grid-GPdeq96hUq"
|
||||
)
|
||||
type RowResponse struct {
|
||||
Link string `json:"browserLink"`
|
||||
}
|
||||
rowResponse := RowResponse{}
|
||||
resp, err := c.R().
|
||||
SetRetryCount(20).
|
||||
SetRetryBackoffInterval(1*time.Second, 5*time.Second).
|
||||
SetSuccessResult(&rowResponse).
|
||||
AddRetryHook(func(resp *req.Response, err error) {
|
||||
req := resp.Request.RawRequest
|
||||
fmt.Println("Retry request:", req.Method, req.URL)
|
||||
fmt.Println("Retry to retrieve row")
|
||||
}).
|
||||
AddRetryCondition(func(resp *req.Response, err error) bool {
|
||||
log.Println(resp.String())
|
||||
return err != nil || resp.StatusCode == 404
|
||||
}).
|
||||
Get("/docs/" + docID + "/tables/" + tableID + "/rows/" + id)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
_ = resp
|
||||
return rowResponse.Link, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
package storage
|
||||
|
||||
import "ticket-pimp/internal/domain"
|
||||
|
||||
type TaskRepository interface {
|
||||
GetOrCreate(tg string) *domain.TgUser
|
||||
}
|
||||
Loading…
Reference in New Issue