commit
6f74571872
5 changed files with 263 additions and 5 deletions
4
Godeps/Godeps.json
generated
4
Godeps/Godeps.json
generated
|
@ -174,6 +174,10 @@
|
||||||
"Comment": "1.5.0-168-g2abea07",
|
"Comment": "1.5.0-168-g2abea07",
|
||||||
"Rev": "2abea075ec076abf0572d29bdb28ae7da64cfb7a"
|
"Rev": "2abea075ec076abf0572d29bdb28ae7da64cfb7a"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/stvp/flowdock",
|
||||||
|
"Rev": "50362abeabebf40b0f56a326d62f17e61a59302b"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "launchpad.net/goyaml",
|
"ImportPath": "launchpad.net/goyaml",
|
||||||
"Comment": "51",
|
"Comment": "51",
|
||||||
|
|
53
Godeps/_workspace/src/github.com/stvp/flowdock/README.md
generated
vendored
Normal file
53
Godeps/_workspace/src/github.com/stvp/flowdock/README.md
generated
vendored
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
flowdock
|
||||||
|
========
|
||||||
|
|
||||||
|
A Flowdock client for Golang. See the [Flowdock API docs][api_docs] for more
|
||||||
|
information on the individual attributes.
|
||||||
|
|
||||||
|
[Go API Documentation][godocs]
|
||||||
|
|
||||||
|
Examples
|
||||||
|
--------
|
||||||
|
|
||||||
|
You can set global defaults and use `flowdock.Inbox()` directly:
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"github.com/stvp/flowdock"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flowdock.Token = "732da505d0284d5b1d909b1a32426345"
|
||||||
|
flowdock.Source = "My Cool App"
|
||||||
|
flowdock.FromAddress = "cool@dudes.com"
|
||||||
|
// See API docs for more variables
|
||||||
|
|
||||||
|
go flowdock.Inbox("My subject", "My content goes here.")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Or you can create a `flowdock.Client` to use different Flowdock message
|
||||||
|
settings in the same app:
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"github.com/stvp/flowdock"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
client := flowdock.Client{
|
||||||
|
Token: "732da505d0284d5b1d909b1a32426345",
|
||||||
|
Source: "App A",
|
||||||
|
FromAddress: "email@stovepipestudios.com",
|
||||||
|
FromName: "Client A",
|
||||||
|
ReplyTo: "app_a@stovepipestudios.com",
|
||||||
|
Tags: []string{"app_a"},
|
||||||
|
}
|
||||||
|
|
||||||
|
go client.Inbox("Subject", "Content")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
[api_docs]: https://www.flowdock.com/api/team-inbox
|
||||||
|
[godocs]: http://godoc.org/github.com/stvp/flowdock
|
||||||
|
|
105
Godeps/_workspace/src/github.com/stvp/flowdock/flowdock.go
generated
vendored
Normal file
105
Godeps/_workspace/src/github.com/stvp/flowdock/flowdock.go
generated
vendored
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
package flowdock
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ENDPOINT = "https://api.flowdock.com/v1/messages/team_inbox/"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Required default client settings
|
||||||
|
Token = ""
|
||||||
|
Source = ""
|
||||||
|
FromAddress = ""
|
||||||
|
|
||||||
|
// Optional default client settings
|
||||||
|
FromName = ""
|
||||||
|
ReplyTo = ""
|
||||||
|
Project = ""
|
||||||
|
Link = ""
|
||||||
|
Tags = []string{}
|
||||||
|
)
|
||||||
|
|
||||||
|
type Client struct {
|
||||||
|
// Required
|
||||||
|
Token string
|
||||||
|
Source string
|
||||||
|
FromAddress string
|
||||||
|
Subject string
|
||||||
|
Content string
|
||||||
|
|
||||||
|
// Optional
|
||||||
|
FromName string
|
||||||
|
ReplyTo string
|
||||||
|
Project string
|
||||||
|
Link string
|
||||||
|
Tags []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) Inbox(subject, content string) error {
|
||||||
|
return send(c.Token, c.Source, c.FromAddress, subject, content, c.FromName, c.ReplyTo, c.Project, c.Link, c.Tags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Inbox(subject, content string) error {
|
||||||
|
return send(Token, Source, FromAddress, subject, content, FromName, ReplyTo, Project, Link, Tags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func send(token, source, fromAddress, subject, content, fromName, replyTo, project, link string, tags []string) error {
|
||||||
|
// Required validation
|
||||||
|
if len(token) == 0 {
|
||||||
|
return fmt.Errorf(`"Token" is required`)
|
||||||
|
}
|
||||||
|
if len(source) == 0 {
|
||||||
|
return fmt.Errorf(`"Source" is required`)
|
||||||
|
}
|
||||||
|
if len(fromAddress) == 0 {
|
||||||
|
return fmt.Errorf(`"FromAddress" is required`)
|
||||||
|
}
|
||||||
|
if len(subject) == 0 {
|
||||||
|
return fmt.Errorf(`"Subject" is required`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build payload
|
||||||
|
payload := map[string]interface{}{
|
||||||
|
"source": source,
|
||||||
|
"from_address": fromAddress,
|
||||||
|
"subject": subject,
|
||||||
|
"content": content,
|
||||||
|
}
|
||||||
|
if len(fromName) > 0 {
|
||||||
|
payload["from_name"] = fromName
|
||||||
|
}
|
||||||
|
if len(replyTo) > 0 {
|
||||||
|
payload["reply_to"] = replyTo
|
||||||
|
}
|
||||||
|
if len(project) > 0 {
|
||||||
|
payload["project"] = project
|
||||||
|
}
|
||||||
|
if len(link) > 0 {
|
||||||
|
payload["link"] = link
|
||||||
|
}
|
||||||
|
if len(tags) > 0 {
|
||||||
|
payload["tags"] = tags
|
||||||
|
}
|
||||||
|
jsonPayload, err := json.Marshal(payload)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send to Flowdock
|
||||||
|
resp, err := http.Post(ENDPOINT+token, "application/json", bytes.NewReader(jsonPayload))
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode == 200 {
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
bodyBytes, _ := ioutil.ReadAll(resp.Body)
|
||||||
|
return fmt.Errorf("Unexpected response from Flowdock: %s %s", resp.Status, string(bodyBytes))
|
||||||
|
}
|
||||||
|
}
|
90
pkg/plugin/notify/flowdock.go
Normal file
90
pkg/plugin/notify/flowdock.go
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
package notify
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"net/url"
|
||||||
|
"github.com/stvp/flowdock"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
flowdockStartedSubject = "Building %s (%s)"
|
||||||
|
flowdockSuccessSubject = "Build: %s (%s) is SUCCESS"
|
||||||
|
flowdockFailureSubject = "Build: %s (%s) is FAILED"
|
||||||
|
flowdockMessage = "<h2>%s </h2>\nBuild: %s <br/>\nResult: %s <br/>\nAuthor: %s <br/>Commit: <span class=\"commit-message\">%s</span> <br/>\nRepository Url: %s"
|
||||||
|
flowdockBuildOkEmail = "build+ok@flowdock.com"
|
||||||
|
flowdockBuildFailEmail = "build+fail@flowdock.com";
|
||||||
|
)
|
||||||
|
|
||||||
|
type Flowdock struct {
|
||||||
|
Token string `yaml:"token,omitempty"`
|
||||||
|
Source string `yaml:"source,omitempty"`
|
||||||
|
Tags string `yaml:"tags,omitempty"`
|
||||||
|
Started bool `yaml:"on_started,omitempty"`
|
||||||
|
Success bool `yaml:"on_success,omitempty"`
|
||||||
|
Failure bool `yaml:"on_failure,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Flowdock) Send(context *Context) error {
|
||||||
|
switch {
|
||||||
|
case context.Commit.Status == "Started" && f.Started:
|
||||||
|
return f.sendStarted(context)
|
||||||
|
case context.Commit.Status == "Success" && f.Success:
|
||||||
|
return f.sendSuccess(context)
|
||||||
|
case context.Commit.Status == "Failure" && f.Failure:
|
||||||
|
return f.sendFailure(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Flowdock) getBuildUrl(context *Context) string {
|
||||||
|
branchQuery := url.Values{}
|
||||||
|
if context.Commit.Branch != "" {
|
||||||
|
branchQuery.Set("branch", context.Commit.Branch)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%s/%s/commit/%s?%s", context.Host, context.Repo.Slug, context.Commit.Hash, branchQuery.Encode())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Flowdock) getRepoUrl(context *Context) string {
|
||||||
|
return fmt.Sprintf("%s/%s", context.Host, context.Repo.Slug)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Flowdock) getMessage(context *Context) string {
|
||||||
|
buildUrl := fmt.Sprintf("<a href=\"%s\"><span class=\"commit-sha\">%s</span></a>", f.getBuildUrl(context), context.Commit.HashShort())
|
||||||
|
return fmt.Sprintf(flowdockMessage, context.Repo.Name, buildUrl, context.Commit.Status, context.Commit.Author, context.Commit.Message, f.getRepoUrl(context))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Flowdock) sendStarted(context *Context) error {
|
||||||
|
fromAddress := context.Commit.Author
|
||||||
|
subject := fmt.Sprintf(flowdockStartedSubject, context.Repo.Name, context.Commit.Branch)
|
||||||
|
msg := f.getMessage(context)
|
||||||
|
tags := strings.Split(f.Tags, ",")
|
||||||
|
return f.send(fromAddress, subject, msg, tags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Flowdock) sendFailure(context *Context) error {
|
||||||
|
fromAddress := flowdockBuildFailEmail
|
||||||
|
tags := strings.Split(f.Tags, ",")
|
||||||
|
subject := fmt.Sprintf(flowdockFailureSubject, context.Repo.Name, context.Commit.Branch)
|
||||||
|
msg := f.getMessage(context)
|
||||||
|
return f.send(fromAddress, subject, msg, tags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Flowdock) sendSuccess(context *Context) error {
|
||||||
|
fromAddress := flowdockBuildOkEmail
|
||||||
|
tags := strings.Split(f.Tags, ",")
|
||||||
|
subject := fmt.Sprintf(flowdockSuccessSubject, context.Repo.Name, context.Commit.Branch)
|
||||||
|
msg := f.getMessage(context)
|
||||||
|
return f.send(fromAddress, subject, msg, tags)
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper function to send Flowdock requests
|
||||||
|
func (f *Flowdock) send(fromAddress, subject, message string, tags []string) error {
|
||||||
|
|
||||||
|
c := flowdock.Client{Token: f.Token, Source: f.Source, FromName: "drone.io", FromAddress: fromAddress, Tags: tags}
|
||||||
|
|
||||||
|
go c.Inbox(subject, message)
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -28,11 +28,12 @@ type Sender interface {
|
||||||
// for notifying a user, or group of users,
|
// for notifying a user, or group of users,
|
||||||
// when their Build has completed.
|
// when their Build has completed.
|
||||||
type Notification struct {
|
type Notification struct {
|
||||||
Email *Email `yaml:"email,omitempty"`
|
Email *Email `yaml:"email,omitempty"`
|
||||||
Webhook *Webhook `yaml:"webhook,omitempty"`
|
Webhook *Webhook `yaml:"webhook,omitempty"`
|
||||||
Hipchat *Hipchat `yaml:"hipchat,omitempty"`
|
Hipchat *Hipchat `yaml:"hipchat,omitempty"`
|
||||||
Irc *IRC `yaml:"irc,omitempty"`
|
Irc *IRC `yaml:"irc,omitempty"`
|
||||||
Slack *Slack `yaml:"slack,omitempty"`
|
Slack *Slack `yaml:"slack,omitempty"`
|
||||||
|
Flowdock *Flowdock `yaml:"flowdock,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Notification) Send(context *Context) error {
|
func (n *Notification) Send(context *Context) error {
|
||||||
|
@ -61,5 +62,10 @@ func (n *Notification) Send(context *Context) error {
|
||||||
n.Slack.Send(context)
|
n.Slack.Send(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// send flowdock notifications
|
||||||
|
if n.Flowdock != nil {
|
||||||
|
n.Flowdock.Send(context)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue