This commit is contained in:
kekskurse 2024-03-04 03:11:29 +01:00
commit 603509210c
9 changed files with 355 additions and 0 deletions

4
.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
config.go
.idea
trelloBot
trello-bot-pi

2
Makefile Normal file
View file

@ -0,0 +1,2 @@
build-pi:
env GOOS=linux GOARCH=arm go build -o trello-bot-pi ./

20
Readme.md Normal file
View 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
View 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
View 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
View 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")
}
}

View 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
View 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
View 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
}