Skip to content

Commit

Permalink
Add slack webhook lib
Browse files Browse the repository at this point in the history
  • Loading branch information
anthonycorbacho committed Feb 15, 2019
1 parent 729cd96 commit 04260db
Show file tree
Hide file tree
Showing 8 changed files with 272 additions and 1 deletion.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Emacs
# IDE
*~
\#*\#
.\#*
.idea
17 changes: 17 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2019 The Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package slack allows application to seamlessly send Slack Message by using the Incoming Webhooks API from Slack.
//
package slack
29 changes: 29 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2019 The Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package slack

// Slack errors.
const (
ErrSerializeMessage = Error("couldn't serialise Slack Message")
ErrCreateRequest = Error("couldn't create the request")
ErrSendingRequest = Error("couldn't send Slack Message")
)

// Error represents a Slack error.
type Error string

// Error returns the error message.
func (e Error) Error() string {
return string(e)
}
37 changes: 37 additions & 0 deletions exemple_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2019 The Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package slack_test

import (
"fmt"

"github.com/anthonycorbacho/slack-webhook"
)

func ExemplBasic() {
hookURL := "<slack_hook_url>"

attachment1 := slack.Attachment{}
attachment1.AddField(slack.Field{Title: "Field test", Value: "Field value"})

msg := slack.Message{
Text: "This is a slack message content",
Attachments: []slack.Attachment{attachment1},
}
err := slack.Send(hookURL, msg)
if err != nil {
fmt.Printf("failed to send message: %v\n", err)
}
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module github.com/anthonycorbacho/slack-webhook
Empty file added go.sum
Empty file.
119 changes: 119 additions & 0 deletions slack.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// Copyright 2019 The Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package slack

import (
"bytes"
"crypto/tls"
"encoding/json"
"fmt"
"net/http"
)

// Send send message (Payload) to the given slack hook URL.
func Send(hookURL string, message Message) error {
bts, err := json.Marshal(message)
if err != nil {
return ErrSerializeMessage
}

tr := &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}

client := &http.Client{Transport: tr}
req, err := http.NewRequest("POST", hookURL, bytes.NewReader(bts))
if err != nil {
return ErrCreateRequest
}

res, err := client.Do(req)
if err != nil {
return ErrSendingRequest
}
defer res.Body.Close()

if res.StatusCode >= 400 {
return fmt.Errorf("error sending slack message. Status: %v", res.StatusCode)
}

return nil
}

// Message contains the slack message.
type Message struct {
Parse string `json:"parse,omitempty"`
Username string `json:"username,omitempty"`
IconUrl string `json:"icon_url,omitempty"`
IconEmoji string `json:"icon_emoji,omitempty"`
Channel string `json:"channel,omitempty"`
Text string `json:"text,omitempty"`
LinkNames string `json:"link_names,omitempty"`
Attachments []Attachment `json:"attachments,omitempty"`
UnfurlLinks bool `json:"unfurl_links,omitempty"`
UnfurlMedia bool `json:"unfurl_media,omitempty"`
Markdown bool `json:"mrkdwn,omitempty"`
}

// Attachment let you add more context to a message, making them more useful and effective.
// See https://api.slack.com/docs/message-attachments
type Attachment struct {
Fallback *string `json:"fallback"`
Color *string `json:"color"`
PreText *string `json:"pretext"`
AuthorName *string `json:"author_name"`
AuthorLink *string `json:"author_link"`
AuthorIcon *string `json:"author_icon"`
Title *string `json:"title"`
TitleLink *string `json:"title_link"`
Text *string `json:"text"`
ImageUrl *string `json:"image_url"`
Fields []*Field `json:"fields"`
Footer *string `json:"footer"`
FooterIcon *string `json:"footer_icon"`
Timestamp *int64 `json:"ts"`
MarkdownIn *[]string `json:"mrkdwn_in"`
Actions []*Action `json:"actions"`
CallbackID *string `json:"callback_id"`
ThumbnailUrl *string `json:"thumb_url"`
}

// AddField appends a new field to the Attachment
func (attachment *Attachment) AddField(field Field) *Attachment {
attachment.Fields = append(attachment.Fields, &field)
return attachment
}

// AddAction appends a new Action to the Attachment
func (attachment *Attachment) AddAction(action Action) *Attachment {
attachment.Actions = append(attachment.Actions, &action)
return attachment
}

// Field is defined as a dictionary with key-value pairs.
type Field struct {
Title string `json:"title"`
Value string `json:"value"`
Short bool `json:"short"`
}

// Action make message interactive
type Action struct {
Type string `json:"type"`
Text string `json:"text"`
Url string `json:"url"`
Style string `json:"style"`
}
67 changes: 67 additions & 0 deletions slack_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright 2019 The Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package slack

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"
)

func handler() http.Handler {
r := http.NewServeMux()
r.HandleFunc("/services", testHandler)
return r
}

func testHandler(w http.ResponseWriter, r *http.Request) {
body := r.Body
if body == nil {
http.Error(w, "missing value", http.StatusBadRequest)
return
}
defer body.Close()

var msg Message

b, _ := ioutil.ReadAll(r.Body)
err := json.Unmarshal(b, &msg)
if err != nil {
http.Error(w, "cannot unmarshal body", http.StatusBadRequest)
return
}
}

func Test_slack(t *testing.T) {
srv := httptest.NewServer(handler())
defer srv.Close()

slackURL := fmt.Sprintf("%s/services", srv.URL)

attachment1 := Attachment{}
attachment1.AddField(Field{Title: "Field", Value: "Field test value"})

msg := Message{
Text: "the is a slack test massage",
Attachments: []Attachment{attachment1},
}

err := Send(slackURL, msg)
if err != nil {
t.Error(err)
}
}

0 comments on commit 04260db

Please sign in to comment.