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

Add Filestack webhooks service #1542

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- [#1513](https://github.com/influxdata/telegraf/issues/1513): Add Ceph Cluster Performance Statistics
- [#1650](https://github.com/influxdata/telegraf/issues/1650): Ability to configure response_timeout in httpjson input.
- [#1685](https://github.com/influxdata/telegraf/issues/1685): Add additional redis metrics.
- [#1542](https://github.com/influxdata/telegraf/pull/1542): Add filestack webhook plugin.

### Bugfixes

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ Telegraf can also collect metrics via the following service plugins:
* [kafka_consumer](https://github.com/influxdata/telegraf/tree/master/plugins/inputs/kafka_consumer)
* [nats_consumer](https://github.com/influxdata/telegraf/tree/master/plugins/inputs/nats_consumer)
* [webhooks](https://github.com/influxdata/telegraf/tree/master/plugins/inputs/webhooks)
* [filestack](https://github.com/influxdata/telegraf/tree/master/plugins/inputs/webhooks/filestack)
* [github](https://github.com/influxdata/telegraf/tree/master/plugins/inputs/webhooks/github)
* [mandrill](https://github.com/influxdata/telegraf/tree/master/plugins/inputs/webhooks/mandrill)
* [rollbar](https://github.com/influxdata/telegraf/tree/master/plugins/inputs/webhooks/rollbar)
Expand Down
1 change: 1 addition & 0 deletions plugins/inputs/webhooks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ $ sudo service telegraf start

## Available webhooks

- [Filestack](filestack/)
- [Github](github/)
- [Mandrill](mandrill/)
- [Rollbar](rollbar/)
Expand Down
17 changes: 17 additions & 0 deletions plugins/inputs/webhooks/filestack/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Filestack webhook

You should configure your Filestack's Webhooks to point at the `webhooks` service. To do this go to `filestack.com/`, select your app and click `Credentials > Webhooks`. In the resulting page, set the `URL` to `http://<my_ip>:1619/filestack`, and click on `Add`.

## Events

See the [webhook doc](https://www.filestack.com/docs/webhooks).

*Limitations*: It stores all events except video conversions events.

All events for logs the original timestamp, the action and the id.

**Tags:**
* 'action' = `event.action` string

**Fields:**
* 'id' = `event.id` string
44 changes: 44 additions & 0 deletions plugins/inputs/webhooks/filestack/filestack_webhooks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package filestack

import (
"encoding/json"
"io/ioutil"
"log"
"net/http"
"time"

"github.com/gorilla/mux"
"github.com/influxdata/telegraf"
)

type FilestackWebhook struct {
Path string
acc telegraf.Accumulator
}

func (fs *FilestackWebhook) Register(router *mux.Router, acc telegraf.Accumulator) {
router.HandleFunc(fs.Path, fs.eventHandler).Methods("POST")

log.Printf("Started the webhooks_filestack on %s\n", fs.Path)
fs.acc = acc
}

func (fs *FilestackWebhook) eventHandler(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
body, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}

event := &FilestackEvent{}
err = json.Unmarshal(body, event)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}

fs.acc.AddFields("filestack_webhooks", event.Fields(), event.Tags(), time.Unix(event.TimeStamp, 0))

w.WriteHeader(http.StatusOK)
}
21 changes: 21 additions & 0 deletions plugins/inputs/webhooks/filestack/filestack_webhooks_events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package filestack

import "strconv"

type FilestackEvent struct {
Action string `json:"action"`
TimeStamp int64 `json:"timestamp"`
Id int `json:"id"`
}

func (fe *FilestackEvent) Tags() map[string]string {
return map[string]string{
"action": fe.Action,
}
}

func (fe *FilestackEvent) Fields() map[string]interface{} {
return map[string]interface{}{
"id": strconv.Itoa(fe.Id),
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package filestack

func DialogOpenJSON() string {
return `{
"action": "fp.dialog",
"timestamp": 1435584646,
"id": 102,
"text": {
"mimetypes": ["*/*"],
"iframe": false,
"language": "en",
"id": "1435584650723",
"mobile": false,
"app":{
"upsell": "false",
"apikey": "YOUR_API_KEY",
"customization":{
"saveas_subheader": "Save it down to your local device or onto the Cloud",
"folder_subheader": "Choose a folder to share with this application",
"open_subheader": "Choose from the files on your local device or the ones you have online",
"folder_header": "Select a folder",
"help_text": "",
"saveas_header": "Save your file",
"open_header": "Upload a file"
}
},
"dialogType": "open",
"auth": false,
"welcome_header": "Upload a file",
"welcome_subheader": "Choose from the files on your local device or the ones you have online",
"help_text": "",
"recent_path": "/",
"extensions": null,
"maxSize": 0,
"signature": null,
"policy": null,
"custom_providers": "imgur,cloudapp",
"intra": false
}
}`
}

func UploadJSON() string {
return `{
"action":"fp.upload",
"timestamp":1443444905,
"id":100946,
"text":{
"url":"https://www.filestackapi.com/api/file/WAunDTTqQfCNWwUUyf6n",
"client":"Facebook",
"type":"image/jpeg",
"filename":"1579337399020824.jpg",
"size":139154
}
}`
}

func VideoConversionJSON() string {
return `{
"status":"completed",
"message":"Done",
"data":{
"thumb":"https://cdn.filestackcontent.com/f1e8V88QDuxzOvtOAq1W",
"thumb100x100":"https://process.filestackapi.com/AhTgLagciQByzXpFGRI0Az/resize=w:100,h:100,f:crop/output=f:jpg,q:66/https://cdn.filestackcontent.com/f1e8V88QDuxzOvtOAq1W",
"thumb200x200":"https://process.filestackapi.com/AhTgLagciQByzXpFGRI0Az/resize=w:200,h:200,f:crop/output=f:jpg,q:66/https://cdn.filestackcontent.com/f1e8V88QDuxzOvtOAq1W",
"thumb300x300":"https://process.filestackapi.com/AhTgLagciQByzXpFGRI0Az/resize=w:300,h:300,f:crop/output=f:jpg,q:66/https://cdn.filestackcontent.com/f1e8V88QDuxzOvtOAq1W",
"url":"https://cdn.filestackcontent.com/VgvFVdvvTkml0WXPIoGn"
},
"metadata":{
"result":{
"audio_channels":2,
"audio_codec":"vorbis",
"audio_sample_rate":44100,
"created_at":"2015/12/21 20:45:19 +0000",
"duration":10587,
"encoding_progress":100,
"encoding_time":8,
"extname":".webm",
"file_size":293459,
"fps":24,
"height":260,
"mime_type":"video/webm",
"started_encoding_at":"2015/12/21 20:45:22 +0000",
"updated_at":"2015/12/21 20:45:32 +0000",
"video_bitrate":221,
"video_codec":"vp8",
"width":300
},
"source":{
"audio_bitrate":125,
"audio_channels":2,
"audio_codec":"aac",
"audio_sample_rate":44100,
"created_at":"2015/12/21 20:45:19 +0000",
"duration":10564,
"extname":".mp4",
"file_size":875797,
"fps":24,
"height":360,
"mime_type":"video/mp4",
"updated_at":"2015/12/21 20:45:32 +0000",
"video_bitrate":196,
"video_codec":"h264",
"width":480
}
},
"timestamp":"1453850583",
"uuid":"638311d89d2bc849563a674a45809b7c"
}`
}
74 changes: 74 additions & 0 deletions plugins/inputs/webhooks/filestack/filestack_webhooks_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package filestack

import (
"github.com/influxdata/telegraf/testutil"
"net/http"
"net/http/httptest"

"strings"
"testing"
)

func postWebhooks(md *FilestackWebhook, eventBody string) *httptest.ResponseRecorder {
req, _ := http.NewRequest("POST", "/filestack", strings.NewReader(eventBody))
w := httptest.NewRecorder()

md.eventHandler(w, req)

return w
}

func TestDialogEvent(t *testing.T) {
var acc testutil.Accumulator
fs := &FilestackWebhook{Path: "/filestack", acc: &acc}
resp := postWebhooks(fs, DialogOpenJSON())
if resp.Code != http.StatusOK {
t.Errorf("POST returned HTTP status code %v.\nExpected %v", resp.Code, http.StatusOK)
}

fields := map[string]interface{}{
"id": "102",
}

tags := map[string]string{
"action": "fp.dialog",
}

acc.AssertContainsTaggedFields(t, "filestack_webhooks", fields, tags)
}

func TestParseError(t *testing.T) {
fs := &FilestackWebhook{Path: "/filestack"}
resp := postWebhooks(fs, "")
if resp.Code != http.StatusBadRequest {
t.Errorf("POST returned HTTP status code %v.\nExpected %v", resp.Code, http.StatusBadRequest)
}
}

func TestUploadEvent(t *testing.T) {
var acc testutil.Accumulator
fs := &FilestackWebhook{Path: "/filestack", acc: &acc}
resp := postWebhooks(fs, UploadJSON())
if resp.Code != http.StatusOK {
t.Errorf("POST returned HTTP status code %v.\nExpected %v", resp.Code, http.StatusOK)
}

fields := map[string]interface{}{
"id": "100946",
}

tags := map[string]string{
"action": "fp.upload",
}

acc.AssertContainsTaggedFields(t, "filestack_webhooks", fields, tags)
}

func TestVideoConversionEvent(t *testing.T) {
var acc testutil.Accumulator
fs := &FilestackWebhook{Path: "/filestack", acc: &acc}
resp := postWebhooks(fs, VideoConversionJSON())
if resp.Code != http.StatusBadRequest {
t.Errorf("POST returned HTTP status code %v.\nExpected %v", resp.Code, http.StatusBadRequest)
}
}
11 changes: 8 additions & 3 deletions plugins/inputs/webhooks/webhooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/plugins/inputs"

"github.com/influxdata/telegraf/plugins/inputs/webhooks/filestack"
"github.com/influxdata/telegraf/plugins/inputs/webhooks/github"
"github.com/influxdata/telegraf/plugins/inputs/webhooks/mandrill"
"github.com/influxdata/telegraf/plugins/inputs/webhooks/rollbar"
Expand All @@ -26,9 +27,10 @@ func init() {
type Webhooks struct {
ServiceAddress string

Github *github.GithubWebhook
Mandrill *mandrill.MandrillWebhook
Rollbar *rollbar.RollbarWebhook
Github *github.GithubWebhook
Filestack *filestack.FilestackWebhook
Mandrill *mandrill.MandrillWebhook
Rollbar *rollbar.RollbarWebhook
}

func NewWebhooks() *Webhooks {
Expand All @@ -40,6 +42,9 @@ func (wb *Webhooks) SampleConfig() string {
## Address and port to host Webhook listener on
service_address = ":1619"

[inputs.webhooks.filestack]
path = "/filestack"

[inputs.webhooks.github]
path = "/github"

Expand Down