Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added notification support for discord #157

Merged
merged 24 commits into from
Oct 10, 2019
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f891a4b
added notification support for discord
wryonik Jun 9, 2019
1edf4d8
removed changes from go.sum
wryonik Jun 9, 2019
fedfd99
changed discord icon
wryonik Jun 10, 2019
812cdc0
tried to improve notification structure
wryonik Jun 14, 2019
eed16a0
tried to implement interface for notifier
wryonik Jun 15, 2019
4c1f818
tried to implement interface for notifier. Some errors are still ther…
wryonik Jun 15, 2019
3ee5816
tried to implement interface for notifier. Some errors are still ther…
wryonik Jun 15, 2019
e946b1f
solved some errors. Some remains with sending payload
wryonik Jun 18, 2019
7e19304
enumeration of notification providers
wryonik Jun 19, 2019
7dea82c
completed notification for discord
wryonik Jun 20, 2019
5fae9bf
completed notification for discord
wryonik Jun 20, 2019
e7b4349
removed changes from go.sum
wryonik Jun 20, 2019
4a840a4
Review changes fixed
wryonik Aug 3, 2019
c485521
Merge branch 'master' into added_more_notification_channels
wryonik Aug 3, 2019
2603ae6
Formatting errors fixed
wryonik Aug 3, 2019
4b5eb5e
Changed notification functions such that now both the notification fo…
wryonik Aug 4, 2019
e34c8b3
Minor review changes
wryonik Aug 5, 2019
c7b7ac6
Minor review changes
wryonik Aug 26, 2019
d13953b
Minor changes
wryonik Sep 1, 2019
681cead
Review changes fixed
wryonik Sep 25, 2019
d091dbf
Removed discord test server link from example.config.toml
wryonik Sep 27, 2019
6215179
Some changes fixed
wryonik Oct 9, 2019
ee0bbdb
Minor changes fixes
wryonik Oct 10, 2019
6e5fd76
Documentation update
wryonik Oct 10, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type BeastConfig struct {
GitRemote GitRemote `toml:"remote"`
JWTSecret string `toml:"jwt_secret"`
SlackWebHookURL string `toml:"slack_webhook"`
DiscordWebHookURL string `toml:"disocrd_webhook"`
TickerFrequency int `toml:"ticker_frequency"`
}

Expand Down
57 changes: 57 additions & 0 deletions pkg/notify/discord.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package notify

import (
"fmt"
"time"

"github.com/sdslabs/beastv4/core/config"
log "github.com/sirupsen/logrus"
)

type DiscordNotificationProvider struct {
DiscordWebHookURL string
}

func SendNotificationToDiscord(nType NotificationType, msg string) error {
if config.Cfg.DiscordWebHookURL == "" {
log.Warnf("No discord webhook url provided in beast config, cannot send notification.")
return fmt.Errorf("No webhook URL in beast config.")
}

discordNotifier := NewNotifier(config.Cfg.DiscordWebHookURL)
discordNotifier.PostPayload = PostPayload{
wryonik marked this conversation as resolved.
Show resolved Hide resolved
Username: "Beast",
IconUrl: "https://i.ibb.co/sjC5dRY/beast-eye-39371.png",
Channel: "#beast",
}

nAttachment := Attachment{
AuthorName: "Beast Notifier",
AuthorLink: "https://backdoor.sdslabs.co",
Footer: "Beast Discord API",
FooterIcon: "https://discordapp.com/assets/e05ead6e6ebc08df9291738d0aa6986d.png",
Timestamp: time.Now().Unix(),
Text: msg,
}

switch nType {
case Success:
nAttachment.Color = SuccessColor
nAttachment.Title = "Beast Deployment Success"
break
case Error:
nAttachment.Color = ErrorColor
nAttachment.Title = "Beast Deployment Error"
break
}

discordNotifier.PostPayload.Attachments = []Attachment{nAttachment}
err := discordNotifier.SendNotification()
if err != nil {
log.Errorf("Error while sending notification to discord : %s", err)
return fmt.Errorf("NOTIFICATION_SEND_ERROR: %s", err)
}

log.Infof("Notfication sent to discord.")
return nil
}
123 changes: 123 additions & 0 deletions pkg/notify/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package notify

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

type Attachment struct {
Fallback string `json:"fallback,omitempty"`
Color NotificationColor `json:"color,omitempty"`
PreText string `json:"pretext,omitempty"`
AuthorName string `json:"author_name,omitempty"`
AuthorLink string `json:"author_link,omitempty"`
AuthorIcon string `json:"author_icon,omitempty"`
Title string `json:"title,omitempty"`
TitleLink string `json:"title_link,omitempty"`
Text string `json:"text,omitempty"`
ImageUrl string `json:"image_url,omitempty"`
Footer string `json:"footer,omitempty"`
FooterIcon string `json:"footer_icon,omitempty"`
Timestamp int64 `json:"ts,omitempty"`
MarkdownIn []string `json:"mrkdwn_in,omitempty"`
CallbackID string `json:"callback_id,omitempty"`
ThumbnailUrl string `json:"thumb_url,omitempty"`
}

type PostPayload 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"`
Attachments []Attachment `json:"attachments,omitempty"`
Markdown bool `json:"mrkdwn,omitempty"`
}

type ProviderType struct {
Slack SlackNotificationProvider
Discord DiscordNotificationProvider
}

type Notifier interface {
SendNotification() error
PostPayload
wryonik marked this conversation as resolved.
Show resolved Hide resolved
}

func NewNotifier(providerType ProviderType) Notifier {
if providerType == ProviderType.Slack {
return &SlackNotificationProvider{
SlackWebHookURL: SlackWebHookURL,
}
} else if providerType == ProviderType.Discord {
return &DiscordNotificationProvider{
DiscordWebHookURL: SlackWebHookURL + "/slack",
}
}
return nil
}

func (s *SlackNotificationProvider) SendNotification() error {
if notifier.WebHookURL == "" {
return fmt.Errorf("Need a WebHookURL to send notification.")
}

if notifier.PostPayload.Channel == "" || notifier.PostPayload.Username == "" {
return fmt.Errorf("Username and Channel required to send the notification.")
}

payload, err := json.Marshal(notifier.PostPayload)
if err != nil {
return fmt.Errorf("Error while converting payload to JSON : %s", err)
}

payloadReader := bytes.NewReader(payload)
req, err := http.NewRequest("POST", notifier.WebHookURL, payloadReader)
if err != nil {
return fmt.Errorf("Error while connecting to webhook url host : %s", err)
}

req.Header.Set("Content-Type", "application/json")
client := http.Client{}
_, err = client.Do(req)

if err != nil {
return fmt.Errorf("Error while posting payload for notification : %s", err)
}

return nil
}

func (d *DiscordNotificationProvider) SendNotification() error {
if notifier.WebHookURL == "" {
return fmt.Errorf("Need a WebHookURL to send notification.")
}

if notifier.PostPayload.Channel == "" || notifier.PostPayload.Username == "" {
return fmt.Errorf("Username and Channel required to send the notification.")
}

payload, err := json.Marshal(notifier.PostPayload)
if err != nil {
return fmt.Errorf("Error while converting payload to JSON : %s", err)
}

payloadReader := bytes.NewReader(payload)
req, err := http.NewRequest("POST", notifier.WebHookURL, payloadReader)
if err != nil {
return fmt.Errorf("Error while connecting to webhook url host : %s", err)
}

req.Header.Set("Content-Type", "application/json")
client := http.Client{}
_, err = client.Do(req)

if err != nil {
return fmt.Errorf("Error while posting payload for notification : %s", err)
}

return nil
}
81 changes: 5 additions & 76 deletions pkg/notify/slack.go
Original file line number Diff line number Diff line change
@@ -1,86 +1,15 @@
package notify

import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"time"

"github.com/sdslabs/beastv4/core/config"
log "github.com/sirupsen/logrus"
)

type Attachment struct {
Fallback string `json:"fallback,omitempty"`
Color NotificationColor `json:"color,omitempty"`
PreText string `json:"pretext,omitempty"`
AuthorName string `json:"author_name,omitempty"`
AuthorLink string `json:"author_link,omitempty"`
AuthorIcon string `json:"author_icon,omitempty"`
Title string `json:"title,omitempty"`
TitleLink string `json:"title_link,omitempty"`
Text string `json:"text,omitempty"`
ImageUrl string `json:"image_url,omitempty"`
Footer string `json:"footer,omitempty"`
FooterIcon string `json:"footer_icon,omitempty"`
Timestamp int64 `json:"ts,omitempty"`
MarkdownIn []string `json:"mrkdwn_in,omitempty"`
CallbackID string `json:"callback_id,omitempty"`
ThumbnailUrl string `json:"thumb_url,omitempty"`
}

type SlackPostPayload 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"`
Attachments []Attachment `json:"attachments,omitempty"`
Markdown bool `json:"mrkdwn,omitempty"`
}

type SlackNotifier struct {
WebHookURL string
SlackPostPayload SlackPostPayload
}

func NewSlackNotifier(webhookUrl string) *SlackNotifier {
return &SlackNotifier{
WebHookURL: webhookUrl,
}
}

func (notifier *SlackNotifier) SendNotification() error {
if notifier.WebHookURL == "" {
return fmt.Errorf("Need a WebHookURL to send notification.")
}

if notifier.SlackPostPayload.Channel == "" || notifier.SlackPostPayload.Username == "" {
return fmt.Errorf("Username and Channel required to send the notification.")
}

payload, err := json.Marshal(notifier.SlackPostPayload)
if err != nil {
return fmt.Errorf("Error while converting payload to JSON : %s", err)
}

payloadReader := bytes.NewReader(payload)
req, err := http.NewRequest("POST", notifier.WebHookURL, payloadReader)
if err != nil {
return fmt.Errorf("Error while connecting to webhook url host : %s", err)
}

req.Header.Set("Content-Type", "application/json")
client := http.Client{}
_, err = client.Do(req)

if err != nil {
return fmt.Errorf("Error while posting payload for notification : %s", err)
}

return nil
type SlackNotificationProvider struct {
SlackWebHookURL string
}

func SendNotificationToSlack(nType NotificationType, msg string) error {
Expand All @@ -89,8 +18,8 @@ func SendNotificationToSlack(nType NotificationType, msg string) error {
return fmt.Errorf("No webhook URL in beast config.")
}

slackNotifier := NewSlackNotifier(config.Cfg.SlackWebHookURL)
slackNotifier.SlackPostPayload = SlackPostPayload{
slackNotifier := NewNotifier(config.Cfg.SlackWebHookURL)
slackNotifier.PostPayload = PostPayload{
wryonik marked this conversation as resolved.
Show resolved Hide resolved
Username: "Beast",
IconUrl: "https://i.ibb.co/sjC5dRY/beast-eye-39371.png",
Channel: "#beast",
Expand All @@ -116,7 +45,7 @@ func SendNotificationToSlack(nType NotificationType, msg string) error {
break
}

slackNotifier.SlackPostPayload.Attachments = []Attachment{nAttachment}
slackNotifier.PostPayload.Attachments = []Attachment{nAttachment}
err := slackNotifier.SendNotification()
if err != nil {
log.Errorf("Error while sending notification to slack : %s", err)
Expand Down