init
This commit is contained in:
commit
603509210c
9 changed files with 355 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
config.go
|
||||||
|
.idea
|
||||||
|
trelloBot
|
||||||
|
trello-bot-pi
|
2
Makefile
Normal file
2
Makefile
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
build-pi:
|
||||||
|
env GOOS=linux GOARCH=arm go build -o trello-bot-pi ./
|
20
Readme.md
Normal file
20
Readme.md
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# Trello Bot
|
||||||
|
Just some trello functions because i don't want to lean Automations....
|
||||||
|
|
||||||
|
# Functions
|
||||||
|
|
||||||
|
## reset-daily-tasks
|
||||||
|
Add a Label with the text "Daily" and a colome with the Text "ToDo", it will move all card with the label to thiw collume if run, so best run its every day ...
|
||||||
|
|
||||||
|
## remove-done-cards
|
||||||
|
Remove cards from the "Done" list which are older than 7 days
|
||||||
|
|
||||||
|
## move-backlog-card-with-date
|
||||||
|
Move all cards in the Backlog where the due date is in the past to the "ToDo" list and remove the due date
|
||||||
|
|
||||||
|
# Example Cron setup
|
||||||
|
```
|
||||||
|
*/5 * * * * /home/pi/trello-bot-pi move-backlog-card-with-date
|
||||||
|
0 5 * * * /home/pi/trello-bot-pi reset-daily-tasks
|
||||||
|
0 5 * * * /home/pi/trello-bot-pi remove-done-cards
|
||||||
|
```
|
20
go.mod
Normal file
20
go.mod
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
module trelloBot
|
||||||
|
|
||||||
|
go 1.22.0
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/adlio/trello v1.10.0
|
||||||
|
github.com/rs/zerolog v1.32.0
|
||||||
|
github.com/urfave/cli/v2 v2.27.1
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||||
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
|
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||||
|
golang.org/x/sys v0.12.0 // indirect
|
||||||
|
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e // indirect
|
||||||
|
)
|
29
go.sum
Normal file
29
go.sum
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
github.com/adlio/trello v1.10.0 h1:ia/rzoBwJJKr4IqnMlrU6n09CVqeyaahSkEVcV5/gPc=
|
||||||
|
github.com/adlio/trello v1.10.0/go.mod h1:I4Lti4jf2KxjTNgTqs5W3lLuE78QZZdYbbPnQQGwjOo=
|
||||||
|
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
|
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||||
|
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||||
|
github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0=
|
||||||
|
github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho=
|
||||||
|
github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
|
||||||
|
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
|
||||||
|
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||||
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
||||||
|
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s=
|
||||||
|
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
47
main.go
Normal file
47
main.go
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/adlio/trello"
|
||||||
|
_ "github.com/adlio/trello"
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
_ "github.com/urfave/cli/v2"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getTrelloClient() *trello.Client {
|
||||||
|
client := trello.NewClient(trelloAPIKey, trelloAPIToken)
|
||||||
|
return client
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
|
||||||
|
|
||||||
|
app := &cli.App{
|
||||||
|
Commands: []*cli.Command{
|
||||||
|
{
|
||||||
|
Name: "reset-daily-tasks",
|
||||||
|
Aliases: []string{"rd"},
|
||||||
|
Usage: "Reset all Task with a label \"Daily\" back to the list \"ToDo\"",
|
||||||
|
Action: resetDailyTasks,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "remove-done-cards",
|
||||||
|
Aliases: []string{"rm"},
|
||||||
|
Usage: "Reset all Cards in the list \"Done\"",
|
||||||
|
Action: removeDoneCArds,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "move-backlog-card-with-date",
|
||||||
|
//Aliases: []string{"rm"},
|
||||||
|
Usage: "Move all cards from \"Backlog\" to \"ToDo\" where the End Date is in the past and remove the duedate",
|
||||||
|
Action: moveBacklogCardWithDate,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := app.Run(os.Args); err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("Error running app")
|
||||||
|
}
|
||||||
|
}
|
81
move-backlog-card-with-date.go
Normal file
81
move-backlog-card-with-date.go
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/adlio/trello"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func moveBacklogCardWithDate(cCtx *cli.Context) error {
|
||||||
|
client := getTrelloClient()
|
||||||
|
board, err := client.GetBoard(trelloBordID, trello.Defaults())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cant get bord: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug().Interface("bord", board).Msg("get bord")
|
||||||
|
|
||||||
|
lists, err := board.GetLists(trello.Defaults())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cant get losts for board: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug().Interface("lists", lists).Msg("got lists")
|
||||||
|
|
||||||
|
var backlogList *trello.List
|
||||||
|
var todoList *trello.List
|
||||||
|
|
||||||
|
for _, list := range lists {
|
||||||
|
if list.Name == "Backlog" {
|
||||||
|
backlogList = list
|
||||||
|
}
|
||||||
|
if list.Name == "ToDo" {
|
||||||
|
todoList = list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if backlogList == nil {
|
||||||
|
return errors.New("cant find list with the text \"Backlog\"")
|
||||||
|
}
|
||||||
|
|
||||||
|
if todoList == nil {
|
||||||
|
return errors.New("cant find list with the text \"ToDo\"")
|
||||||
|
}
|
||||||
|
|
||||||
|
cards, err := backlogList.GetCards()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cant get card for Backlog list list: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, card := range cards {
|
||||||
|
log.Debug().Str("name", card.Name).Msg("Found card")
|
||||||
|
if card.Due == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if card.Due.Before(time.Now()) {
|
||||||
|
err = card.MoveToList(todoList.ID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cant move card to todo list: %w", err)
|
||||||
|
}
|
||||||
|
err = card.MoveToTopOfList()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cant move card to top of todo list: %w", err)
|
||||||
|
}
|
||||||
|
_, err = card.AddComment(fmt.Sprintf("Due Date %v in Backlog reached, moved to todo!", card.Due))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cant add comment to card: %w", err)
|
||||||
|
}
|
||||||
|
card.Due = nil
|
||||||
|
err = card.Update(trello.Arguments{"due": "null"})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cant update card to remove due date: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
62
remove-done-cards.go
Normal file
62
remove-done-cards.go
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/adlio/trello"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func removeDoneCArds(cCtx *cli.Context) error {
|
||||||
|
client := getTrelloClient()
|
||||||
|
board, err := client.GetBoard(trelloBordID, trello.Defaults())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cant get bord: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug().Interface("bord", board).Msg("get bord")
|
||||||
|
|
||||||
|
lists, err := board.GetLists(trello.Defaults())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cant get losts for board: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug().Interface("lists", lists).Msg("got lists")
|
||||||
|
|
||||||
|
var doneList *trello.List
|
||||||
|
|
||||||
|
for _, list := range lists {
|
||||||
|
if list.Name == "Done" {
|
||||||
|
doneList = list
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if doneList == nil {
|
||||||
|
return errors.New("cant find list with the text \"Done\"")
|
||||||
|
}
|
||||||
|
|
||||||
|
cards, err := doneList.GetCards()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cant get card for Done list: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, card := range cards {
|
||||||
|
log.Debug().Str("name", card.Name).Time("date of last activity", *card.DateLastActivity).Msg("Found card")
|
||||||
|
if !card.DateLastActivity.Before(time.Now().Add(-7 * 24 * time.Hour)) {
|
||||||
|
log.Debug().Msg("card not old enough,. keep")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
log.Info().Msg("card old enough, need to be deletet")
|
||||||
|
|
||||||
|
err := card.Delete()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cant delete card frome done list: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
90
reset-daily-tasks.go
Normal file
90
reset-daily-tasks.go
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/adlio/trello"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resetDailyTasks(cCtx *cli.Context) error {
|
||||||
|
client := getTrelloClient()
|
||||||
|
board, err := client.GetBoard(trelloBordID, trello.Defaults())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cant get bord: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug().Interface("bord", board).Msg("get bord")
|
||||||
|
|
||||||
|
labels, err := board.GetLabels()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cant get labels for bord: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug().Interface("labels", labels).Msg("got labels")
|
||||||
|
|
||||||
|
var dailyLabel *trello.Label
|
||||||
|
|
||||||
|
for _, l := range labels {
|
||||||
|
if l.Name == "Daily" {
|
||||||
|
dailyLabel = l
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if dailyLabel == nil {
|
||||||
|
return errors.New("cant find label with the name \"Daily\"")
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug().Interface("daily label", dailyLabel).Msg("got daily label")
|
||||||
|
|
||||||
|
lists, err := board.GetLists(trello.Defaults())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cant get losts for board: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug().Interface("lists", lists).Msg("got lists")
|
||||||
|
|
||||||
|
var todoList *trello.List
|
||||||
|
|
||||||
|
for _, list := range lists {
|
||||||
|
if list.Name == "ToDo" {
|
||||||
|
todoList = list
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if todoList == nil {
|
||||||
|
return errors.New("cant find list with the text \"ToDo\"")
|
||||||
|
}
|
||||||
|
|
||||||
|
cards, err := board.GetCards()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cant get cards for bord: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug().Int("number of cards", len(cards)).Msg("Get Cards")
|
||||||
|
|
||||||
|
for _, card := range cards {
|
||||||
|
foundLabel := false
|
||||||
|
for _, label := range card.Labels {
|
||||||
|
if label.ID == dailyLabel.ID {
|
||||||
|
foundLabel = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !foundLabel {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
err = card.MoveToList(todoList.ID, trello.Defaults())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cant move card to todo list: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
Reference in a new issue