drone-telegram/plugin.go
Bo-Yi Wu dc6dc4a444 Support send notification to commit author by check email.
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2016-11-04 09:38:21 +08:00

285 lines
5.2 KiB
Go

package main
import (
"errors"
"fmt"
"log"
"os"
"strconv"
"strings"
"github.com/appleboy/drone-facebook/template"
"gopkg.in/telegram-bot-api.v4"
)
type (
// Repo information.
Repo struct {
Owner string
Name string
}
// Build information.
Build struct {
Event string
Number int
Commit string
Message string
Branch string
Author string
Email string
Status string
Link string
Started float64
Finished float64
}
// Config for the plugin.
Config struct {
Token string
Debug bool
To []string
Message []string
Photo []string
Document []string
Sticker []string
Audio []string
Voice []string
Location []string
Video []string
Venue []string
Format string
}
// Plugin values.
Plugin struct {
Repo Repo
Build Build
Config Config
}
// Location format
Location struct {
Title string
Address string
Latitude float64
Longitude float64
}
)
func trimElement(keys []string) []string {
var newKeys []string
for _, value := range keys {
value = strings.Trim(value, " ")
if len(value) == 0 {
continue
}
newKeys = append(newKeys, value)
}
return newKeys
}
func fileExist(keys []string) []string {
var newKeys []string
for _, value := range keys {
if _, err := os.Stat(value); os.IsNotExist(err) {
continue
}
newKeys = append(newKeys, value)
}
return newKeys
}
func convertLocation(value string) (Location, bool) {
var latitude, longitude float64
var title, address string
var err error
values := trimElement(strings.Split(value, ","))
if len(values) < 2 {
return Location{}, true
}
if len(values) > 2 {
title = values[2]
}
if len(values) > 3 {
title = values[2]
address = values[3]
}
latitude, err = strconv.ParseFloat(values[0], 64)
if err != nil {
log.Println(err.Error())
return Location{}, true
}
longitude, err = strconv.ParseFloat(values[1], 64)
if err != nil {
log.Println(err.Error())
return Location{}, true
}
return Location{
Title: title,
Address: address,
Latitude: latitude,
Longitude: longitude,
}, false
}
func parseTo(value, authorEmail string) (int64, bool) {
ids := trimElement(strings.Split(value, ","))
if len(ids) > 1 {
if email := ids[1]; email != authorEmail {
return int64(0), false
}
}
id, err := strconv.ParseInt(ids[0], 10, 64)
if err != nil {
return int64(0), false
}
return id, true
}
// Exec executes the plugin.
func (p Plugin) Exec() error {
if len(p.Config.Token) == 0 || len(p.Config.To) == 0 {
log.Println("missing telegram token or user list")
return errors.New("missing telegram token or user list")
}
var message []string
if len(p.Config.Message) > 0 {
message = p.Config.Message
} else {
message = p.Message(p.Repo, p.Build)
}
bot, err := tgbotapi.NewBotAPI(p.Config.Token)
if err != nil {
log.Println("Initialize New Bot Error:", err.Error())
return err
}
bot.Debug = p.Config.Debug
photos := fileExist(trimElement(p.Config.Photo))
documents := fileExist(trimElement(p.Config.Document))
stickers := fileExist(trimElement(p.Config.Sticker))
audios := fileExist(trimElement(p.Config.Audio))
voices := fileExist(trimElement(p.Config.Voice))
videos := fileExist(trimElement(p.Config.Video))
locations := trimElement(p.Config.Location)
venues := trimElement(p.Config.Venue)
// send message.
for _, to := range p.Config.To {
user, enable := parseTo(to, p.Build.Email)
if !enable {
continue
}
for _, value := range trimElement(message) {
txt, err := template.RenderTrim(value, p)
if err != nil {
return err
}
msg := tgbotapi.NewMessage(user, txt)
msg.ParseMode = p.Config.Format
p.Send(bot, msg)
}
for _, value := range photos {
msg := tgbotapi.NewPhotoUpload(user, value)
p.Send(bot, msg)
}
for _, value := range documents {
msg := tgbotapi.NewDocumentUpload(user, value)
p.Send(bot, msg)
}
for _, value := range stickers {
msg := tgbotapi.NewStickerUpload(user, value)
p.Send(bot, msg)
}
for _, value := range audios {
msg := tgbotapi.NewAudioUpload(user, value)
msg.Title = "Audio Message."
p.Send(bot, msg)
}
for _, value := range voices {
msg := tgbotapi.NewVoiceUpload(user, value)
p.Send(bot, msg)
}
for _, value := range videos {
msg := tgbotapi.NewVideoUpload(user, value)
msg.Caption = "Video Message"
p.Send(bot, msg)
}
for _, value := range locations {
location, empty := convertLocation(value)
if empty == true {
continue
}
msg := tgbotapi.NewLocation(user, location.Latitude, location.Longitude)
p.Send(bot, msg)
}
for _, value := range venues {
location, empty := convertLocation(value)
if empty == true {
continue
}
msg := tgbotapi.NewVenue(user, location.Title, location.Address, location.Latitude, location.Longitude)
p.Send(bot, msg)
}
}
return nil
}
// Send bot message.
func (p Plugin) Send(bot *tgbotapi.BotAPI, msg tgbotapi.Chattable) {
_, err := bot.Send(msg)
if err != nil {
log.Println(err.Error())
}
}
// Message is plugin default message.
func (p Plugin) Message(repo Repo, build Build) []string {
return []string{fmt.Sprintf("[%s] <%s> (%s)『%s』by %s",
build.Status,
build.Link,
build.Branch,
build.Message,
build.Author,
)}
}