From 3e69ebd625c07ec586adc1cccd9f58f46810211d Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Sun, 30 Oct 2022 22:52:17 +0000 Subject: [PATCH] Working --- asana.go | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++ imap.go | 32 +++++++++++++++++---- imap2asana.go | 24 +++++++++++----- 3 files changed, 121 insertions(+), 12 deletions(-) create mode 100644 asana.go diff --git a/asana.go b/asana.go new file mode 100644 index 0000000..4de1821 --- /dev/null +++ b/asana.go @@ -0,0 +1,77 @@ +package main + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" + "os" +) + +type AsanaClient struct { + cli *http.Client + token string + workspace string + assignee string +} + +type addTaskRequest struct { + Data *addTaskRequestInt `json:"data"` +} + +type addTaskRequestInt struct { + Name string `json:"name"` + HtmlNotes string `json:"html_notes"` + Workspace string `json:"workspace"` + Assignee string `json:"assignee"` +} + +func NewAsanaClient() *AsanaClient { + return &AsanaClient{ + cli: &http.Client{}, + token: os.Getenv("ASANA_TOKEN"), + workspace: os.Getenv("ASANA_WORKSPACE"), + assignee: os.Getenv("ASANA_ASSIGNEE"), + } +} + +func (ac *AsanaClient) CreateTask(name string, notes string) error { + body := &addTaskRequest{ + Data: &addTaskRequestInt{ + Name: name, + HtmlNotes: notes, + Workspace: ac.workspace, + Assignee: ac.assignee, + }, + } + + js, err := json.Marshal(body) + if err != nil { + return err + } + + req, err := http.NewRequest("POST", "https://app.asana.com/api/1.0/tasks", bytes.NewReader(js)) + if err != nil { + return err + } + + ac.addAuth(req) + req.Header.Add("Content-Type", "application/json") + + resp, err := ac.cli.Do(req) + if err != nil { + return err + } + + if resp.StatusCode != 201 { + msg, _ := io.ReadAll(resp.Body) + return fmt.Errorf("%s: %s", resp.Status, msg) + } + + return nil +} + +func (ac *AsanaClient) addAuth(req *http.Request) { + req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", ac.token)) +} diff --git a/imap.go b/imap.go index 2823548..87c5fad 100644 --- a/imap.go +++ b/imap.go @@ -1,7 +1,9 @@ package main import ( + "fmt" "net/mail" + "strings" "github.com/emersion/go-imap" "github.com/emersion/go-imap/client" @@ -65,19 +67,32 @@ func (ic *ImapClient) Poll() ([]*Task, error) { return nil, err } + d, err := msg.Header.Date() + if err != nil { + return nil, err + } + ret = append(ret, &Task{ Name: msg.Header.Get("Subject"), + HtmlNotes: fmt.Sprintf( + "From: %s\nTo: %s\nDate: %s", + ic.escape(msg.Header.Get("From")), + ic.escape(msg.Header.Get("To")), + ic.escape(d.Local().Format("Monday, 2006-01-02 15h04 -0700")), + ), }) } - err = ic.Move(seqset, ic.toFolder) - if err != nil { - return nil, err - } - return ret, nil } +func (ic *ImapClient) Archive(num int) error { + seqset := &imap.SeqSet{} + seqset.AddRange(1, uint32(num)) + + return ic.Move(seqset, ic.toFolder) +} + func (ic *ImapClient) List(ref, name string) ([]*imap.MailboxInfo, error) { ch := make(chan *imap.MailboxInfo, 10) done := make(chan error) @@ -125,3 +140,10 @@ func (ic *ImapClient) Select(name string, readonly bool) (*imap.MailboxStatus, e func (ic *ImapClient) Move(seqset *imap.SeqSet, dest string) error { return ic.cli.Move(seqset, dest) } + +func (ic *ImapClient) escape(in string) string { + in = strings.ReplaceAll(in, "<", "<") + in = strings.ReplaceAll(in, ">", ">") + in = strings.ReplaceAll(in, `"`, """) + return in +} diff --git a/imap2asana.go b/imap2asana.go index 51ee156..e9bf4bd 100644 --- a/imap2asana.go +++ b/imap2asana.go @@ -1,7 +1,6 @@ package main import ( - "fmt" "log" "math/rand" "os" @@ -24,7 +23,9 @@ func main() { defer ic.Close() - err = Poll(ic) + ac := NewAsanaClient() + + err = Poll(ic, ac) if err != nil { log.Printf("%s", err) } @@ -32,7 +33,7 @@ func main() { for { time.Sleep(time.Duration(rand.Intn(60)) * time.Second) - err := Poll(ic) + err := Poll(ic, ac) if err != nil { log.Printf("%s", err) } @@ -44,15 +45,24 @@ type Task struct { HtmlNotes string } -func Poll(ic *ImapClient) error { +func Poll(ic *ImapClient, ac *AsanaClient) error { tasks, err := ic.Poll() if err != nil { return err } - for _, task := range tasks { - fmt.Printf("%#v\n", task) + if len(tasks) < 1 { + return nil } - return nil + for _, task := range tasks { + log.Printf("%s", task.Name) + + err = ac.CreateTask(task.Name, task.HtmlNotes) + if err != nil { + return err + } + } + + return ic.Archive(len(tasks)) }