Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
3091aece
Commit
3091aece
authored
Mar 28, 2018
by
Patrick Schuster
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add Google Hangouts Chat notifier.
parent
fdf7a4c4
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
268 additions
and
0 deletions
+268
-0
pkg/services/alerting/notifiers/googlechat.go
+215
-0
pkg/services/alerting/notifiers/googlechat_test.go
+53
-0
No files found.
pkg/services/alerting/notifiers/googlechat.go
0 → 100644
View file @
3091aece
package
notifiers
import
(
"encoding/json"
"fmt"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/log"
m
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/setting"
"time"
)
func
init
()
{
alerting
.
RegisterNotifier
(
&
alerting
.
NotifierPlugin
{
Type
:
"googlechat"
,
Name
:
"Google Hangouts Chat"
,
Description
:
"Sends notifications to Google Hangouts Chat via webhooks based on the official JSON message "
+
"format (https://developers.google.com/hangouts/chat/reference/message-formats/)."
,
Factory
:
NewGoogleChatNotifier
,
OptionsTemplate
:
`
<h3 class="page-heading">Google Hangouts Chat settings</h3>
<div class="gf-form max-width-30">
<span class="gf-form-label width-6">Url</span>
<input type="text" required class="gf-form-input max-width-30" ng-model="ctrl.model.settings.url" placeholder="Google Hangouts Chat incoming webhook url"></input>
</div>
`
,
})
}
func
NewGoogleChatNotifier
(
model
*
m
.
AlertNotification
)
(
alerting
.
Notifier
,
error
)
{
url
:=
model
.
Settings
.
Get
(
"url"
)
.
MustString
()
if
url
==
""
{
return
nil
,
alerting
.
ValidationError
{
Reason
:
"Could not find url property in settings"
}
}
return
&
GoogleChatNotifier
{
NotifierBase
:
NewNotifierBase
(
model
.
Id
,
model
.
IsDefault
,
model
.
Name
,
model
.
Type
,
model
.
Settings
),
Url
:
url
,
log
:
log
.
New
(
"alerting.notifier.googlechat"
),
},
nil
}
type
GoogleChatNotifier
struct
{
NotifierBase
Url
string
method
string
log
log
.
Logger
}
/**
Structs used to build a custom Google Hangouts Chat message card.
See: https://developers.google.com/hangouts/chat/reference/message-formats/cards
*/
type
outerStruct
struct
{
Cards
[]
card
`json:"cards"`
}
type
card
struct
{
Header
header
`json:"header"`
Sections
[]
section
`json:"sections"`
}
type
header
struct
{
Title
string
`json:"title"`
}
type
section
struct
{
Widgets
[]
widget
`json:"widgets"`
}
// "generic" widget used to add different types of widgets (buttonWidget, textParagraphWidget, imageWidget)
type
widget
interface
{
}
type
buttonWidget
struct
{
Buttons
[]
button
`json:"buttons"`
}
type
textParagraphWidget
struct
{
Text
text
`json:"textParagraph"`
}
type
text
struct
{
Text
string
`json:"text"`
}
type
imageWidget
struct
{
Image
image
`json:"image"`
}
type
image
struct
{
ImageUrl
string
`json:"imageUrl"`
}
type
button
struct
{
TextButton
textButton
`json:"textButton"`
}
type
textButton
struct
{
Text
string
`json:"text"`
OnClick
onClick
`json:"onClick"`
}
type
onClick
struct
{
OpenLink
openLink
`json:"openLink"`
}
type
openLink
struct
{
Url
string
`json:"url"`
}
func
(
this
*
GoogleChatNotifier
)
Notify
(
evalContext
*
alerting
.
EvalContext
)
error
{
this
.
log
.
Info
(
"Executing Google Chat notification"
)
headers
:=
map
[
string
]
string
{
"Content-Type"
:
"application/json; charset=UTF-8"
,
}
ruleUrl
,
err
:=
evalContext
.
GetRuleUrl
()
if
err
!=
nil
{
this
.
log
.
Error
(
"evalContext returned an invalid rule URL"
)
}
// add a text paragraph widget for the message
widgets
:=
[]
widget
{
textParagraphWidget
{
Text
:
text
{
Text
:
evalContext
.
Rule
.
Message
,
},
},
}
// add a text paragraph widget for the fields
var
fields
[]
textParagraphWidget
fieldLimitCount
:=
4
for
index
,
evt
:=
range
evalContext
.
EvalMatches
{
fields
=
append
(
fields
,
textParagraphWidget
{
Text
:
text
{
Text
:
"<i>"
+
evt
.
Metric
+
": "
+
fmt
.
Sprint
(
evt
.
Value
)
+
"</i>"
,
},
},
)
if
index
>
fieldLimitCount
{
break
}
}
widgets
=
append
(
widgets
,
fields
)
// if an image exists, add it as an image widget
if
evalContext
.
ImagePublicUrl
!=
""
{
widgets
=
append
(
widgets
,
imageWidget
{
Image
:
image
{
ImageUrl
:
evalContext
.
ImagePublicUrl
,
},
})
}
else
{
this
.
log
.
Info
(
"Could not retrieve a public image URL."
)
}
// add a button widget (link to Grafana)
widgets
=
append
(
widgets
,
buttonWidget
{
Buttons
:
[]
button
{
{
TextButton
:
textButton
{
Text
:
"OPEN IN GRAFANA"
,
OnClick
:
onClick
{
OpenLink
:
openLink
{
Url
:
ruleUrl
,
},
},
},
},
},
})
// add text paragraph widget for the build version and timestamp
widgets
=
append
(
widgets
,
textParagraphWidget
{
Text
:
text
{
Text
:
"Grafana v"
+
setting
.
BuildVersion
+
" | "
+
(
time
.
Now
())
.
Format
(
time
.
RFC822
),
},
})
// nest the required structs
res1D
:=
&
outerStruct
{
Cards
:
[]
card
{
{
Header
:
header
{
Title
:
evalContext
.
GetNotificationTitle
(),
},
Sections
:
[]
section
{
{
Widgets
:
widgets
,
},
},
},
},
}
body
,
_
:=
json
.
Marshal
(
res1D
)
cmd
:=
&
m
.
SendWebhookSync
{
Url
:
this
.
Url
,
HttpMethod
:
"POST"
,
HttpHeader
:
headers
,
Body
:
string
(
body
),
}
if
err
:=
bus
.
DispatchCtx
(
evalContext
.
Ctx
,
cmd
);
err
!=
nil
{
this
.
log
.
Error
(
"Failed to send Google Hangouts Chat alert"
,
"error"
,
err
,
"webhook"
,
this
.
Name
)
return
err
}
return
nil
}
pkg/services/alerting/notifiers/googlechat_test.go
0 → 100644
View file @
3091aece
package
notifiers
import
(
"testing"
"github.com/grafana/grafana/pkg/components/simplejson"
m
"github.com/grafana/grafana/pkg/models"
.
"github.com/smartystreets/goconvey/convey"
)
func
TestGoogleChatNotifier
(
t
*
testing
.
T
)
{
Convey
(
"Google Hangouts Chat notifier tests"
,
t
,
func
()
{
Convey
(
"Parsing alert notification from settings"
,
func
()
{
Convey
(
"empty settings should return error"
,
func
()
{
json
:=
`{ }`
settingsJSON
,
_
:=
simplejson
.
NewJson
([]
byte
(
json
))
model
:=
&
m
.
AlertNotification
{
Name
:
"ops"
,
Type
:
"googlechat"
,
Settings
:
settingsJSON
,
}
_
,
err
:=
NewGoogleChatNotifier
(
model
)
So
(
err
,
ShouldNotBeNil
)
})
Convey
(
"from settings"
,
func
()
{
json
:=
`
{
"url": "http://google.com"
}`
settingsJSON
,
_
:=
simplejson
.
NewJson
([]
byte
(
json
))
model
:=
&
m
.
AlertNotification
{
Name
:
"ops"
,
Type
:
"googlechat"
,
Settings
:
settingsJSON
,
}
not
,
err
:=
NewGoogleChatNotifier
(
model
)
webhookNotifier
:=
not
.
(
*
GoogleChatNotifier
)
So
(
err
,
ShouldBeNil
)
So
(
webhookNotifier
.
Name
,
ShouldEqual
,
"ops"
)
So
(
webhookNotifier
.
Type
,
ShouldEqual
,
"googlechat"
)
So
(
webhookNotifier
.
Url
,
ShouldEqual
,
"http://google.com"
)
})
})
})
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment