Repository: appleboy/drone-telegram (go)

Issue:
Using datetime in custom template is broken
I have a custom message template like this one: `Build started at {{datetime build.started "2006-Jan-02T15:04:05Z" "GMT+2"}}`

This lets my pipeline fail since f529160 because the `datetime` [helper function](https://github.com/drone/drone-template-lib/blob/master/template/helpers.go#L62) expects the date to be a `float64`, but the plugin provides an `int64`.

Pull request:
Fix using datetime in custom template
Fixes #82

Baiscally reverts f52916076089568abe5294502042df001e43ce5d

Patch:
diff --git a/DOCS.md b/DOCS.md
index d5ea3f7..c0c6afa 100644
--- a/DOCS.md
+++ b/DOCS.md
@@ -149,6 +149,16 @@ Example configuration with a custom message template:
 +       {{/success}}
 ```
 
+Example configuration with a custom message template loaded from file:
+
+```diff
+  image: appleboy/drone-telegram
+  settings:
+    token: xxxxxxxxxx
+    to: telegram_user_id
++   message_file: message_file.tpl
+```
+
 ## Parameter Reference
 
 token
@@ -160,6 +170,9 @@ to
 message
 : overwrite the default message template
 
+message_file
+: overwrite the default message template with the contents of the specified file
+
 photo
 : local file path
 
diff --git a/README.md b/README.md
index 642dfd8..d2b986f 100644
--- a/README.md
+++ b/README.md
@@ -69,6 +69,7 @@ docker run --rm \
   -e PLUGIN_TOKEN=xxxxxxx \
   -e PLUGIN_TO=xxxxxxx \
   -e PLUGIN_MESSAGE=test \
+  -e PLUGIN_MESSAGE_FILE=testmessage.md \  
   -e PLUGIN_PHOTO=tests/github.png \
   -e PLUGIN_DOCUMENT=tests/gophercolor.png \
   -e PLUGIN_STICKER=tests/github-logo.png \
diff --git a/main.go b/main.go
index b048c44..3be25c2 100644
--- a/main.go
+++ b/main.go
@@ -36,6 +36,11 @@ func main() {
 			Usage:  "send telegram message",
 			EnvVar: "PLUGIN_MESSAGE,TELEGRAM_MESSAGE,INPUT_MESSAGE",
 		},
+		cli.StringFlag{
+			Name:   "message.file",
+			Usage:  "send telegram message from file",
+			EnvVar: "PLUGIN_MESSAGE_FILE,TELEGRAM_MESSAGE_FILE,INPUT_MESSAGE_FILE",
+		},
 		cli.StringSliceFlag{
 			Name:   "photo",
 			Usage:  "send photo message",
@@ -185,12 +190,12 @@ func main() {
 			Usage:  "pull request",
 			EnvVar: "DRONE_PULL_REQUEST",
 		},
-		cli.Int64Flag{
+		cli.Float64Flag{
 			Name:   "job.started",
 			Usage:  "job started",
 			EnvVar: "DRONE_BUILD_STARTED",
 		},
-		cli.Int64Flag{
+		cli.Float64Flag{
 			Name:   "job.finished",
 			Usage:  "job finished",
 			EnvVar: "DRONE_BUILD_FINISHED",
@@ -276,28 +281,29 @@ func run(c *cli.Context) error {
 			Event:    c.String("build.event"),
 			Status:   c.String("build.status"),
 			Link:     c.String("build.link"),
-			Started:  c.Int64("job.started"),
-			Finished: c.Int64("job.finished"),
+			Started:  c.Float64("job.started"),
+			Finished: c.Float64("job.finished"),
 			PR:       c.String("pull.request"),
 			DeployTo: c.String("deploy.to"),
 		},
 		Config: Config{
-			Token:      c.String("token"),
-			Debug:      c.Bool("debug"),
-			MatchEmail: c.Bool("match.email"),
-			WebPreview: c.Bool("webpage.preview"),
-			To:         c.StringSlice("to"),
-			Message:    c.StringSlice("message"),
-			Photo:      c.StringSlice("photo"),
-			Document:   c.StringSlice("document"),
-			Sticker:    c.StringSlice("sticker"),
-			Audio:      c.StringSlice("audio"),
-			Voice:      c.StringSlice("voice"),
-			Location:   c.StringSlice("location"),
-			Video:      c.StringSlice("video"),
-			Venue:      c.StringSlice("venue"),
-			Format:     c.String("format"),
-			GitHub:     c.Bool("github"),
+			Token:       c.String("token"),
+			Debug:       c.Bool("debug"),
+			MatchEmail:  c.Bool("match.email"),
+			WebPreview:  c.Bool("webpage.preview"),
+			To:          c.StringSlice("to"),
+			Message:     c.StringSlice("message"),
+			MessageFile: c.String("message.file"),
+			Photo:       c.StringSlice("photo"),
+			Document:    c.StringSlice("document"),
+			Sticker:     c.StringSlice("sticker"),
+			Audio:       c.StringSlice("audio"),
+			Voice:       c.StringSlice("voice"),
+			Location:    c.StringSlice("location"),
+			Video:       c.StringSlice("video"),
+			Venue:       c.StringSlice("venue"),
+			Format:      c.String("format"),
+			GitHub:      c.Bool("github"),
 		},
 	}
 
diff --git a/plugin.go b/plugin.go
index 60c21db..ad966af 100644
--- a/plugin.go
+++ b/plugin.go
@@ -1,9 +1,12 @@
 package main
 
 import (
+	"bufio"
 	"errors"
 	"fmt"
+	"io/ioutil"
 	"log"
+	"os"
 	"path/filepath"
 	"strconv"
 	"strings"
@@ -48,30 +51,31 @@ type (
 		Number   int
 		Status   string
 		Link     string
-		Started  int64
-		Finished int64
+		Started  float64
+		Finished float64
 		PR       string
 		DeployTo string
 	}
 
 	// Config for the plugin.
 	Config struct {
-		Token      string
-		Debug      bool
-		MatchEmail bool
-		WebPreview bool
-		To         []string
-		Message    []string
-		Photo      []string
-		Document   []string
-		Sticker    []string
-		Audio      []string
-		Voice      []string
-		Location   []string
-		Video      []string
-		Venue      []string
-		Format     string
-		GitHub     bool
+		Token       string
+		Debug       bool
+		MatchEmail  bool
+		WebPreview  bool
+		To          []string
+		Message     []string
+		MessageFile string
+		Photo       []string
+		Document    []string
+		Sticker     []string
+		Audio       []string
+		Voice       []string
+		Location    []string
+		Video       []string
+		Venue       []string
+		Format      string
+		GitHub      bool
 	}
 
 	// Plugin values.
@@ -184,6 +188,20 @@ func convertLocation(value string) (Location, bool) {
 	}, false
 }
 
+func loadTextFromFile(filename string) ([]string, error) {
+	f, err := os.Open(filename)
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+	r := bufio.NewReader(f)
+	content, err := ioutil.ReadAll(r)
+	if err != nil {
+		return nil, err
+	}
+	return []string{string(content)}, nil
+}
+
 func parseTo(to []string, authorEmail string, matchEmail bool) []int64 {
 	var emails []int64
 	var ids []int64
@@ -222,22 +240,26 @@ func parseTo(to []string, authorEmail string, matchEmail bool) []int64 {
 }
 
 // Exec executes the plugin.
-func (p Plugin) Exec() error {
-
+func (p Plugin) Exec() (err error) {
 	if len(p.Config.Token) == 0 || len(p.Config.To) == 0 {
 		return errors.New("missing telegram token or user list")
 	}
 
 	var message []string
-	if len(p.Config.Message) > 0 {
+	switch {
+	case len(p.Config.MessageFile) > 0:
+		message, err = loadTextFromFile(p.Config.MessageFile)
+		if err != nil {
+			return fmt.Errorf("error loading message file '%s': %v", p.Config.MessageFile, err)
+		}
+	case len(p.Config.Message) > 0:
 		message = p.Config.Message
-	} else {
+	default:
 		message = p.Message()
 	}
 
-	bot, err := tgbotapi.NewBotAPI(p.Config.Token)
-
-	if err != nil {
+	var bot *tgbotapi.BotAPI
+	if bot, err = tgbotapi.NewBotAPI(p.Config.Token); err != nil {
 		return err
 	}
 


Test patch:
diff --git a/plugin_test.go b/plugin_test.go
index 56d7684..23aeb3c 100644
--- a/plugin_test.go
+++ b/plugin_test.go
@@ -325,3 +325,32 @@ func TestHTMLMessage(t *testing.T) {
 	err := plugin.Exec()
 	assert.Nil(t, err)
 }
+
+func TestMessageFile(t *testing.T) {
+	plugin := Plugin{
+		Repo: Repo{
+			Name:      "go-hello",
+			Namespace: "appleboy",
+		},
+		Commit: Commit{
+			Sha:     "e7c4f0a63ceeb42a39ac7806f7b51f3f0d204fd2",
+			Author:  "Bo-Yi Wu",
+			Branch:  "master",
+			Message: "Freakin' macOS isn't fully case-sensitive..",
+		},
+		Build: Build{
+			Number: 101,
+			Status: "success",
+			Link:   "https://github.com/appleboy/go-hello",
+		},
+
+		Config: Config{
+			Token:       os.Getenv("TELEGRAM_TOKEN"),
+			To:          []string{os.Getenv("TELEGRAM_TO")},
+			MessageFile: "tests/.test.message",
+		},
+	}
+
+	err := plugin.Exec()
+	assert.Nil(t, err)
+}
diff --git a/tests/.test.message b/tests/.test.message
new file mode 100644
index 0000000..e7827a8
--- /dev/null
+++ b/tests/.test.message
@@ -0,0 +1,4 @@
+Sample message loaded from file.
+
+Commit msg:  {{commit.message}}
+