1
0
Fork 0

Adding upstream version 1.34.4.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-05-24 07:26:29 +02:00
parent e393c3af3f
commit 4978089aab
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
4963 changed files with 677545 additions and 0 deletions

View file

@ -0,0 +1,22 @@
# Filestack webhook
You should configure your Filestack's Webhooks to point at the `webhooks`
service. To do this go to [filestack.com](https://www.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

View file

@ -0,0 +1,55 @@
package filestack
import (
"encoding/json"
"io"
"net/http"
"time"
"github.com/gorilla/mux"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/plugins/common/auth"
)
type Webhook struct {
Path string
acc telegraf.Accumulator
log telegraf.Logger
auth.BasicAuth
}
// Register registers the webhook with the provided router
func (fs *Webhook) Register(router *mux.Router, acc telegraf.Accumulator, log telegraf.Logger) {
router.HandleFunc(fs.Path, fs.eventHandler).Methods("POST")
fs.log = log
fs.log.Infof("Started the webhooks_filestack on %s", fs.Path)
fs.acc = acc
}
func (fs *Webhook) eventHandler(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
if !fs.Verify(r) {
w.WriteHeader(http.StatusUnauthorized)
return
}
body, err := io.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)
}

View file

@ -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),
}
}

View file

@ -0,0 +1,86 @@
package filestack
import (
"io"
"net/http"
"net/http/httptest"
"os"
"strings"
"testing"
"github.com/stretchr/testify/require"
"github.com/influxdata/telegraf/testutil"
)
func postWebhooks(t *testing.T, md *Webhook, eventBodyFile io.Reader) *httptest.ResponseRecorder {
req, err := http.NewRequest("POST", "/filestack", eventBodyFile)
require.NoError(t, err)
w := httptest.NewRecorder()
md.eventHandler(w, req)
return w
}
func TestDialogEvent(t *testing.T) {
var acc testutil.Accumulator
fs := &Webhook{Path: "/filestack", acc: &acc}
resp := postWebhooks(t, fs, getFile(t, "testdata/dialog_open.json"))
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 := &Webhook{Path: "/filestack"}
resp := postWebhooks(t, fs, strings.NewReader(""))
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 := &Webhook{Path: "/filestack", acc: &acc}
resp := postWebhooks(t, fs, getFile(t, "testdata/upload.json"))
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 := &Webhook{Path: "/filestack", acc: &acc}
resp := postWebhooks(t, fs, getFile(t, "testdata/video_conversion.json"))
if resp.Code != http.StatusBadRequest {
t.Errorf("POST returned HTTP status code %v.\nExpected %v", resp.Code, http.StatusBadRequest)
}
}
func getFile(t *testing.T, filePath string) io.Reader {
file, err := os.Open(filePath)
require.NoErrorf(t, err, "could not read from file %s", filePath)
return file
}

View file

@ -0,0 +1,39 @@
{
"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
}
}

View file

@ -0,0 +1,12 @@
{
"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
}
}

View file

@ -0,0 +1,51 @@
{
"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"
}