diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index ee605ec..a294efb 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -13,6 +13,7 @@ plugins/Postcoder/* @richbenwell plugins/RDAP/* @richbenwell plugins/RSS/* @clarkd plugins/Rootly/* @noorulkhan-n +plugins/SendGrid/* @richbenwell plugins/Spotify/* @jame2O plugins/Steam/* @kmichalski0 plugins/SumoLogic/* @richpeters diff --git a/plugins/SendGrid/v1/README.md b/plugins/SendGrid/v1/README.md new file mode 100644 index 0000000..5d54ad8 --- /dev/null +++ b/plugins/SendGrid/v1/README.md @@ -0,0 +1,19 @@ +## Overview + +A plugin for Twilio SendGrid, a popular SMTP server. + +The plugin provides email send stats and unsubscribes, allowing software and marketing teams to report on email performance. + +## Setup + +Authentication is via API key. + +Create an API key in https://app.sendgrid.com/settings/api_keys + +Select 'Custom Access' and configure the following permissions: +- Stats (read-only) +- Suppressions (read-only) + +## Known limitations + +Account credits cannot be monitored using this plugin. Although an API endpoint is available, it seems to require an API key with full admin access. \ No newline at end of file diff --git a/plugins/SendGrid/v1/dataStreams/allClientStats.json b/plugins/SendGrid/v1/dataStreams/allClientStats.json new file mode 100644 index 0000000..1122092 --- /dev/null +++ b/plugins/SendGrid/v1/dataStreams/allClientStats.json @@ -0,0 +1,66 @@ +{ + "name": "allClientStats", + "displayName": "All Client Stats", + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "paging": { + "mode": "none" + }, + "expandInnerObjects": true, + "endpointPath": "/clients/stats", + "getArgs": [ + { + "key": "start_date", + "value": "{{timeframe.start.substring(0,10)}}" + }, + { + "key": "aggregated_by", + "value": "day" + }, + { + "key": "limit", + "value": "100" + }, + { + "key": "end_date", + "value": "{{timeframe.end.substring(0,10)}}" + } + ], + "postRequestScript": "script1-post.js", + "headers": [] + }, + "metadata": [ + { + "shape": [ + "date", + { + "timeZone": "Etc/UTC" + } + ], + "name": "date" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "metrics.opens" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "metrics.unique_opens" + }, + { + "pattern": ".*" + } + ], + "timeframes": true +} \ No newline at end of file diff --git a/plugins/SendGrid/v1/dataStreams/blocks.json b/plugins/SendGrid/v1/dataStreams/blocks.json new file mode 100644 index 0000000..6e539d9 --- /dev/null +++ b/plugins/SendGrid/v1/dataStreams/blocks.json @@ -0,0 +1,44 @@ +{ + "name": "blocks", + "displayName": "Blocks", + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "paging": { + "mode": "none" + }, + "expandInnerObjects": true, + "endpointPath": "/suppression/blocks", + "getArgs": [ + { + "key": "start_time", + "value": "{{timeframe.unixStart}}" + }, + { + "key": "end_time", + "value": "{{timeframe.unixEnd}}" + }, + { + "key": "limit", + "value": "500" + } + ], + "pathToData": "", + "headers": [] + }, + "metadata": [ + { + "shape": [ + "date", + { + "timeZone": "Etc/UTC" + } + ], + "name": "created" + }, + { + "pattern": ".*" + } + ], + "timeframes": true +} \ No newline at end of file diff --git a/plugins/SendGrid/v1/dataStreams/bounces.json b/plugins/SendGrid/v1/dataStreams/bounces.json new file mode 100644 index 0000000..e6e5176 --- /dev/null +++ b/plugins/SendGrid/v1/dataStreams/bounces.json @@ -0,0 +1,44 @@ +{ + "name": "bounces", + "displayName": "Bounces", + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "paging": { + "mode": "none" + }, + "expandInnerObjects": true, + "endpointPath": "/suppression/bounces", + "getArgs": [ + { + "key": "start_time", + "value": "{{timeframe.unixStart}}" + }, + { + "key": "end_time", + "value": "{{timeframe.unixEnd}}" + }, + { + "key": "limit", + "value": "500" + } + ], + "pathToData": "", + "headers": [] + }, + "metadata": [ + { + "shape": [ + "date", + { + "timeZone": "Etc/UTC" + } + ], + "name": "created" + }, + { + "pattern": ".*" + } + ], + "timeframes": true +} \ No newline at end of file diff --git a/plugins/SendGrid/v1/dataStreams/browserStats.json b/plugins/SendGrid/v1/dataStreams/browserStats.json new file mode 100644 index 0000000..5359fe4 --- /dev/null +++ b/plugins/SendGrid/v1/dataStreams/browserStats.json @@ -0,0 +1,96 @@ +{ + "name": "browserStats", + "displayName": "Browser Stats", + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "paging": { + "mode": "none" + }, + "expandInnerObjects": true, + "endpointPath": "/browsers/stats", + "getArgs": [ + { + "key": "start_date", + "value": "{{timeframe.start.substring(0,10)}}" + }, + { + "key": "end_date", + "value": "{{timeframe.end.substring(0,10)}}" + }, + { + "key": "aggregated_by", + "value": "{{aggregated_by}}" + }, + { + "key": "limit", + "value": "1000" + } + ], + "postRequestScript": "script1-post.js", + "headers": [] + }, + "ui": [ + { + "name": "aggregated_by", + "type": "autocomplete", + "label": "Aggregate by", + "validation": { + "required": true + }, + "allowCustomValues": false, + "isMulti": false, + "defaultValue": "day", + "data": { + "source": "fixed", + "values": [ + { + "value": "day", + "label": "Day" + }, + { + "value": "week", + "label": "Week" + }, + { + "value": "month", + "label": "Month" + } + ] + } + } + ], + "metadata": [ + { + "shape": [ + "date", + { + "timeZone": "Etc/UTC" + } + ], + "name": "date" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "metrics.clicks" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "metrics.unique_clicks" + }, + { + "pattern": ".*" + } + ], + "timeframes": true +} \ No newline at end of file diff --git a/plugins/SendGrid/v1/dataStreams/clientTypeStats.json b/plugins/SendGrid/v1/dataStreams/clientTypeStats.json new file mode 100644 index 0000000..975cf10 --- /dev/null +++ b/plugins/SendGrid/v1/dataStreams/clientTypeStats.json @@ -0,0 +1,96 @@ +{ + "name": "clientTypeStats", + "displayName": "Client Type Stats", + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "paging": { + "mode": "none" + }, + "expandInnerObjects": true, + "endpointPath": "/clients/desktop/stats", + "getArgs": [ + { + "key": "start_date", + "value": "{{timeframe.start.substring(0,10)}}" + }, + { + "key": "end_date", + "value": "{{timeframe.end.substring(0,10)}}" + }, + { + "key": "aggregated_by", + "value": "{{aggregated_by}}" + }, + { + "key": "limit", + "value": "1000" + } + ], + "postRequestScript": "script1-post.js", + "headers": [] + }, + "ui": [ + { + "name": "aggregated_by", + "type": "autocomplete", + "label": "Aggregate by", + "validation": { + "required": true + }, + "allowCustomValues": false, + "isMulti": false, + "defaultValue": "day", + "data": { + "source": "fixed", + "values": [ + { + "value": "day", + "label": "Day" + }, + { + "value": "week", + "label": "Week" + }, + { + "value": "month", + "label": "Month" + } + ] + } + } + ], + "metadata": [ + { + "shape": [ + "date", + { + "timeZone": "Etc/UTC" + } + ], + "name": "date" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "metrics.opens" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "metrics.unique_opens" + }, + { + "pattern": ".*" + } + ], + "timeframes": true +} \ No newline at end of file diff --git a/plugins/SendGrid/v1/dataStreams/devicesStats.json b/plugins/SendGrid/v1/dataStreams/devicesStats.json new file mode 100644 index 0000000..774bbb3 --- /dev/null +++ b/plugins/SendGrid/v1/dataStreams/devicesStats.json @@ -0,0 +1,96 @@ +{ + "name": "devicesStats", + "displayName": "Devices Stats", + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "paging": { + "mode": "none" + }, + "expandInnerObjects": true, + "endpointPath": "/devices/stats", + "getArgs": [ + { + "key": "start_date", + "value": "{{timeframe.start.substring(0,10)}}" + }, + { + "key": "end_date", + "value": "{{timeframe.end.substring(0,10)}}" + }, + { + "key": "aggregated_by", + "value": "{{aggregated_by}}" + }, + { + "key": "limit", + "value": "1000" + } + ], + "postRequestScript": "script1-post.js", + "headers": [] + }, + "ui": [ + { + "name": "aggregated_by", + "type": "autocomplete", + "label": "Aggregate by", + "validation": { + "required": true + }, + "allowCustomValues": false, + "isMulti": false, + "defaultValue": "day", + "data": { + "source": "fixed", + "values": [ + { + "value": "day", + "label": "Day" + }, + { + "value": "week", + "label": "Week" + }, + { + "value": "month", + "label": "Month" + } + ] + } + } + ], + "metadata": [ + { + "shape": [ + "date", + { + "timeZone": "Etc/UTC" + } + ], + "name": "date" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "metrics.opens" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "metrics.unique_opens" + }, + { + "pattern": ".*" + } + ], + "timeframes": true +} \ No newline at end of file diff --git a/plugins/SendGrid/v1/dataStreams/globalStats.json b/plugins/SendGrid/v1/dataStreams/globalStats.json new file mode 100644 index 0000000..209556a --- /dev/null +++ b/plugins/SendGrid/v1/dataStreams/globalStats.json @@ -0,0 +1,221 @@ +{ + "name": "globalStats", + "displayName": "Global Stats", + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "paging": { + "mode": "none" + }, + "expandInnerObjects": true, + "endpointPath": "/stats", + "getArgs": [ + { + "key": "start_date", + "value": "{{timeframe.start.substring(0,10)}}" + }, + { + "key": "end_date", + "value": "{{timeframe.end.substring(0,10)}}" + }, + { + "key": "aggregated_by", + "value": "{{aggregated_by}}" + }, + { + "key": "limit", + "value": "1000" + } + ], + "headers": [] + }, + "ui": [ + { + "name": "aggregated_by", + "type": "autocomplete", + "label": "Aggregate by", + "validation": { + "required": true + }, + "allowCustomValues": false, + "isMulti": false, + "defaultValue": "day", + "data": { + "source": "fixed", + "values": [ + { + "value": "day", + "label": "Day" + }, + { + "value": "week", + "label": "Week" + }, + { + "value": "month", + "label": "Month" + } + ] + } + } + ], + "metadata": [ + { + "shape": [ + "date", + { + "timeZone": "Etc/UTC" + } + ], + "name": "date" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "stats.0.metrics.blocks" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "stats.0.metrics.bounce_drops" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "stats.0.metrics.bounces" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "stats.0.metrics.clicks" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "stats.0.metrics.deferred" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "stats.0.metrics.delivered" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "stats.0.metrics.invalid_emails" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "stats.0.metrics.opens" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "stats.0.metrics.processed" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "stats.0.metrics.requests" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "stats.0.metrics.spam_report_drops" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "stats.0.metrics.spam_reports" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "stats.0.metrics.unique_clicks" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "stats.0.metrics.unique_opens" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "stats.0.metrics.unsubscribe_drops" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "stats.0.metrics.unsubscribes" + }, + { + "pattern": ".*" + } + ], + "timeframes": true +} \ No newline at end of file diff --git a/plugins/SendGrid/v1/dataStreams/globalUnsubscribes.json b/plugins/SendGrid/v1/dataStreams/globalUnsubscribes.json new file mode 100644 index 0000000..361c389 --- /dev/null +++ b/plugins/SendGrid/v1/dataStreams/globalUnsubscribes.json @@ -0,0 +1,44 @@ +{ + "name": "globalUnsubscribes", + "displayName": "Global Unsubscribes", + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "paging": { + "mode": "none" + }, + "expandInnerObjects": true, + "endpointPath": "/suppression/unsubscribes", + "getArgs": [ + { + "key": "start_time", + "value": "{{timeframe.unixStart}}" + }, + { + "key": "end_time", + "value": "{{timeframe.unixEnd}}" + }, + { + "key": "limit", + "value": "500" + } + ], + "pathToData": "", + "headers": [] + }, + "metadata": [ + { + "shape": [ + "date", + { + "timeZone": "Etc/UTC" + } + ], + "name": "created" + }, + { + "pattern": ".*" + } + ], + "timeframes": true +} \ No newline at end of file diff --git a/plugins/SendGrid/v1/dataStreams/groupUnsubscribes.json b/plugins/SendGrid/v1/dataStreams/groupUnsubscribes.json new file mode 100644 index 0000000..eda9ae4 --- /dev/null +++ b/plugins/SendGrid/v1/dataStreams/groupUnsubscribes.json @@ -0,0 +1,52 @@ +{ + "name": "groupUnsubscribes", + "displayName": "Group Unsubscribes", + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "paging": { + "mode": "none" + }, + "expandInnerObjects": true, + "endpointPath": "/asm/suppressions", + "getArgs": [ + { + "key": "start_time", + "value": "{{timeframe.unixStart}}" + }, + { + "key": "end_time", + "value": "{{timeframe.unixEnd}}" + } + ], + "pathToData": "", + "headers": [] + }, + "metadata": [ + { + "shape": [ + "date", + { + "timeZone": "Etc/UTC" + } + ], + "name": "created_at" + }, + { + "name": "email", + "shape": "string" + }, + { + "name": "group_name", + "shape": "string" + }, + { + "name": "group_id", + "shape": "string" + }, + { + "pattern": ".*" + } + ], + "timeframes": true +} \ No newline at end of file diff --git a/plugins/SendGrid/v1/dataStreams/invalidEmails.json b/plugins/SendGrid/v1/dataStreams/invalidEmails.json new file mode 100644 index 0000000..6310dd0 --- /dev/null +++ b/plugins/SendGrid/v1/dataStreams/invalidEmails.json @@ -0,0 +1,44 @@ +{ + "name": "invalidEmails", + "displayName": "Invalid Emails", + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "paging": { + "mode": "none" + }, + "expandInnerObjects": true, + "endpointPath": "/suppression/invalid_emails", + "getArgs": [ + { + "key": "start_time", + "value": "{{timeframe.unixStart}}" + }, + { + "key": "end_time", + "value": "{{timeframe.unixEnd}}" + }, + { + "key": "limit", + "value": "500" + } + ], + "pathToData": "", + "headers": [] + }, + "metadata": [ + { + "shape": [ + "date", + { + "timeZone": "Etc/UTC" + } + ], + "name": "created" + }, + { + "pattern": ".*" + } + ], + "timeframes": true +} \ No newline at end of file diff --git a/plugins/SendGrid/v1/dataStreams/mailboxProviderStats.json b/plugins/SendGrid/v1/dataStreams/mailboxProviderStats.json new file mode 100644 index 0000000..b7aab42 --- /dev/null +++ b/plugins/SendGrid/v1/dataStreams/mailboxProviderStats.json @@ -0,0 +1,186 @@ +{ + "name": "mailboxProviderStats", + "displayName": "Mailbox Provider Stats", + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "paging": { + "mode": "none" + }, + "expandInnerObjects": true, + "endpointPath": "/mailbox_providers/stats", + "getArgs": [ + { + "key": "start_date", + "value": "{{timeframe.start.substring(0,10)}}" + }, + { + "key": "end_date", + "value": "{{timeframe.end.substring(0,10)}}" + }, + { + "key": "aggregated_by", + "value": "{{aggregated_by}}" + }, + { + "key": "limit", + "value": "1000" + } + ], + "postRequestScript": "script1-post.js", + "headers": [] + }, + "ui": [ + { + "name": "aggregated_by", + "type": "autocomplete", + "label": "Aggregate by", + "validation": { + "required": true + }, + "allowCustomValues": false, + "isMulti": false, + "defaultValue": "day", + "data": { + "source": "fixed", + "values": [ + { + "value": "day", + "label": "Day" + }, + { + "value": "week", + "label": "Week" + }, + { + "value": "month", + "label": "Month" + } + ] + } + } + ], + "metadata": [ + { + "shape": [ + "date", + { + "timeZone": "Etc/UTC" + } + ], + "name": "date" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "metrics.opens" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "metrics.unique_opens" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "metrics.blocks" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "metrics.bounces" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "metrics.clicks" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "metrics.deferred" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "metrics.delivered" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "metrics.drops" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "metrics.processed" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "metrics.requests" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "metrics.spam_reports" + }, + { + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ], + "name": "metrics.unique_clicks" + }, + { + "pattern": ".*" + } + ], + "timeframes": true +} \ No newline at end of file diff --git a/plugins/SendGrid/v1/dataStreams/scripts/script1-post.js b/plugins/SendGrid/v1/dataStreams/scripts/script1-post.js new file mode 100644 index 0000000..3c4b2d6 --- /dev/null +++ b/plugins/SendGrid/v1/dataStreams/scripts/script1-post.js @@ -0,0 +1,3 @@ +result = _.flatMap(data, ({ date, stats }) => + _.map(stats, stat => ({ date, ...stat})) +); \ No newline at end of file diff --git a/plugins/SendGrid/v1/dataStreams/spamReports.json b/plugins/SendGrid/v1/dataStreams/spamReports.json new file mode 100644 index 0000000..9811789 --- /dev/null +++ b/plugins/SendGrid/v1/dataStreams/spamReports.json @@ -0,0 +1,44 @@ +{ + "name": "spamReports", + "displayName": "Spam Reports", + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "paging": { + "mode": "none" + }, + "expandInnerObjects": true, + "endpointPath": "/suppression/spam_reports", + "getArgs": [ + { + "key": "start_time", + "value": "{{timeframe.unixStart}}" + }, + { + "key": "end_time", + "value": "{{timeframe.unixEnd}}" + }, + { + "key": "limit", + "value": "500" + } + ], + "pathToData": "", + "headers": [] + }, + "metadata": [ + { + "shape": [ + "date", + { + "timeZone": "Etc/UTC" + } + ], + "name": "created" + }, + { + "pattern": ".*" + } + ], + "timeframes": true +} \ No newline at end of file diff --git a/plugins/SendGrid/v1/defaultContent/SendGrid/emailClientInsights.dash.json b/plugins/SendGrid/v1/defaultContent/SendGrid/emailClientInsights.dash.json new file mode 100644 index 0000000..309f085 --- /dev/null +++ b/plugins/SendGrid/v1/defaultContent/SendGrid/emailClientInsights.dash.json @@ -0,0 +1,347 @@ +{ + "name": "Email Client Insights", + "schemaVersion": "1.4", + "dashboard": { + "_type": "layout/grid", + "contents": [ + { + "static": false, + "w": 2, + "moved": false, + "h": 3, + "x": 0, + "y": 0, + "i": "78f8a742-94b5-4496-a581-3c3088a6bf39", + "z": 0, + "config": { + "dataStream": { + "name": "allClientStats", + "filter": { + "multiOperation": "and", + "filters": [] + }, + "id": "{{dataStreams.allClientStats}}", + "sort": { + "top": 10, + "by": [ + [ + "metrics.opens_sum", + "desc" + ] + ] + }, + "group": { + "by": [ + [ + "name", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "metrics.opens" + ] + } + ] + }, + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "All Client Stats", + "visualisation": { + "type": "data-stream-donut-chart", + "config": { + "data-stream-donut-chart": { + "valueColumn": "metrics.opens_sum", + "hideCenterValue": true, + "showValuesAsPercentage": true, + "legendPosition": "auto", + "legendMode": "inline", + "labelColumn": "name_uniqueValues" + } + } + } + } + }, + { + "static": false, + "w": 2, + "moved": false, + "h": 3, + "x": 2, + "y": 0, + "i": "141fb5aa-78a2-4015-a95c-0914fb91b51b", + "z": 0, + "config": { + "dataStream": { + "name": "browserStats", + "filter": { + "multiOperation": "and", + "filters": [] + }, + "dataSourceConfig": { + "aggregated_by": "day" + }, + "id": "{{dataStreams.browserStats}}", + "sort": { + "top": 10, + "by": [ + [ + "metrics.unique_clicks_sum", + "desc" + ] + ] + }, + "group": { + "by": [ + [ + "name", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "metrics.unique_clicks" + ] + } + ] + }, + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "Browsers", + "visualisation": { + "type": "data-stream-donut-chart", + "config": { + "data-stream-donut-chart": { + "valueColumn": "metrics.unique_clicks_sum", + "hideCenterValue": true, + "showValuesAsPercentage": true, + "legendPosition": "auto", + "legendMode": "inline", + "labelColumn": "name_uniqueValues" + } + } + } + } + }, + { + "static": false, + "w": 2, + "moved": false, + "h": 3, + "x": 0, + "y": 3, + "i": "6bd1165a-02cd-4588-af17-21ab79c73031", + "z": 0, + "config": { + "dataStream": { + "name": "clientTypeStats", + "dataSourceConfig": { + "aggregated_by": "day" + }, + "id": "{{dataStreams.clientTypeStats}}", + "sort": { + "top": 10, + "by": [ + [ + "metrics.opens_sum", + "desc" + ] + ] + }, + "group": { + "by": [ + [ + "name", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "metrics.opens" + ] + } + ] + }, + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "Desktop Apps", + "visualisation": { + "type": "data-stream-donut-chart", + "config": { + "data-stream-donut-chart": { + "valueColumn": "metrics.opens_sum", + "hideCenterValue": true, + "showValuesAsPercentage": true, + "legendPosition": "auto", + "legendMode": "inline", + "labelColumn": "name_uniqueValues" + } + } + } + } + }, + { + "static": false, + "w": 2, + "moved": false, + "h": 3, + "x": 2, + "y": 3, + "i": "263b2e69-e6a5-452a-88d2-32024c45761d", + "z": 0, + "config": { + "dataStream": { + "name": "devicesStats", + "filter": { + "multiOperation": "and", + "filters": [ + { + "column": "name", + "operation": "notequals", + "value": "Other" + } + ] + }, + "dataSourceConfig": { + "aggregated_by": "day" + }, + "id": "{{dataStreams.devicesStats}}", + "sort": { + "top": 10, + "by": [ + [ + "metrics.unique_opens_sum", + "desc" + ] + ] + }, + "group": { + "by": [ + [ + "name", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "metrics.unique_opens" + ] + } + ] + }, + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "Excluding 'other'", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "Devices", + "visualisation": { + "type": "data-stream-donut-chart", + "config": { + "data-stream-donut-chart": { + "valueColumn": "metrics.unique_opens_sum", + "hideCenterValue": true, + "showValuesAsPercentage": true, + "legendPosition": "auto", + "legendMode": "inline", + "labelColumn": "name_uniqueValues" + } + } + } + } + }, + { + "static": false, + "w": 2, + "moved": false, + "h": 3, + "x": 0, + "y": 6, + "i": "e93a232f-3108-435e-a2c0-89eb33cf259f", + "z": 0, + "config": { + "dataStream": { + "name": "mailboxProviderStats", + "dataSourceConfig": { + "aggregated_by": "day" + }, + "id": "{{dataStreams.mailboxProviderStats}}", + "sort": { + "top": 10, + "by": [ + [ + "metrics.delivered_sum", + "desc" + ] + ] + }, + "group": { + "by": [ + [ + "name", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "metrics.delivered" + ] + } + ] + }, + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "Mailbox Provider", + "visualisation": { + "type": "data-stream-donut-chart", + "config": { + "data-stream-donut-chart": { + "valueColumn": "metrics.delivered_sum", + "hideCenterValue": true, + "showValuesAsPercentage": true, + "legendPosition": "auto", + "legendMode": "inline", + "labelColumn": "name_uniqueValues" + } + } + } + } + } + ], + "version": 50, + "columns": 4 + }, + "timeframe": "last30days" +} \ No newline at end of file diff --git a/plugins/SendGrid/v1/defaultContent/SendGrid/engagement.dash.json b/plugins/SendGrid/v1/defaultContent/SendGrid/engagement.dash.json new file mode 100644 index 0000000..0202c9b --- /dev/null +++ b/plugins/SendGrid/v1/defaultContent/SendGrid/engagement.dash.json @@ -0,0 +1,87 @@ +{ + "name": "Engagement", + "schemaVersion": "1.4", + "dashboard": { + "_type": "layout/grid", + "contents": [ + { + "static": false, + "w": 4, + "moved": false, + "h": 3, + "x": 0, + "y": 0, + "i": "8bd02931-3ac3-4f37-a67b-95a18a426a87", + "z": 0, + "config": { + "dataStream": { + "name": "globalStats", + "id": "{{dataStreams.globalStats}}", + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "Positive Engagement", + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "showLegend": true, + "legendPosition": "bottom", + "xAxisColumn": "date", + "yAxisColumn": [ + "stats.0.metrics.delivered", + "stats.0.metrics.unique_clicks", + "stats.0.metrics.unique_opens" + ] + } + } + } + } + }, + { + "static": false, + "w": 4, + "moved": false, + "h": 3, + "x": 0, + "y": 3, + "i": "23c80f70-0c71-484b-b148-2f071b84a9a9", + "z": 0, + "config": { + "dataStream": { + "name": "globalStats", + "id": "{{dataStreams.globalStats}}", + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "Negative Engagement", + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "showLegend": true, + "legendPosition": "bottom", + "xAxisColumn": "date", + "yAxisColumn": [ + "stats.0.metrics.spam_reports", + "stats.0.metrics.unsubscribes" + ] + } + } + } + } + } + ], + "version": 132, + "columns": 4 + }, + "timeframe": "last30days" +} \ No newline at end of file diff --git a/plugins/SendGrid/v1/defaultContent/SendGrid/manifest.json b/plugins/SendGrid/v1/defaultContent/SendGrid/manifest.json new file mode 100644 index 0000000..1a69e1c --- /dev/null +++ b/plugins/SendGrid/v1/defaultContent/SendGrid/manifest.json @@ -0,0 +1,20 @@ +{ + "items": [ + { + "name": "engagement", + "type": "dashboard" + }, + { + "name": "nonDelivery", + "type": "dashboard" + }, + { + "name": "unsubscribes", + "type": "dashboard" + }, + { + "name": "emailClientInsights", + "type": "dashboard" + } + ] +} \ No newline at end of file diff --git a/plugins/SendGrid/v1/defaultContent/SendGrid/nonDelivery.dash.json b/plugins/SendGrid/v1/defaultContent/SendGrid/nonDelivery.dash.json new file mode 100644 index 0000000..f13c898 --- /dev/null +++ b/plugins/SendGrid/v1/defaultContent/SendGrid/nonDelivery.dash.json @@ -0,0 +1,561 @@ +{ + "name": "Non-delivery", + "schemaVersion": "1.4", + "dashboard": { + "_type": "layout/grid", + "contents": [ + { + "static": false, + "w": 1, + "moved": false, + "h": 2, + "x": 0, + "y": 0, + "i": "ab81dcb5-821b-42b1-aae4-c8cd7ab0d0f9", + "z": 0, + "config": { + "dataStream": { + "name": "globalStats", + "id": "{{dataStreams.globalStats}}", + "group": { + "by": [ + [ + "date", + "byYear" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "stats.0.metrics.bounce_drops" + ] + }, + { + "type": "sum", + "names": [ + "stats.0.metrics.unsubscribe_drops" + ] + }, + { + "type": "sum", + "names": [ + "stats.0.metrics.invalid_emails" + ] + }, + { + "type": "sum", + "names": [ + "stats.0.metrics.spam_report_drops" + ] + }, + { + "type": "sum", + "names": [ + "stats.0.metrics.delivered" + ] + } + ] + }, + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "Delivered", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "comparisonColumn": "none", + "label": "delivered", + "manualSize": 50, + "value": "stats.0.metrics.delivered_sum" + } + } + } + } + }, + { + "static": false, + "w": 1, + "moved": false, + "h": 2, + "x": 2, + "y": 0, + "i": "57da2bd4-ef2c-4844-8479-fed6b91104b0", + "z": 0, + "config": { + "dataStream": { + "name": "globalStats", + "id": "{{dataStreams.globalStats}}", + "group": { + "by": [ + [ + "date", + "byYear" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "stats.0.metrics.bounce_drops" + ] + }, + { + "type": "sum", + "names": [ + "stats.0.metrics.unsubscribe_drops" + ] + }, + { + "type": "sum", + "names": [ + "stats.0.metrics.invalid_emails" + ] + }, + { + "type": "sum", + "names": [ + "stats.0.metrics.spam_report_drops" + ] + }, + { + "type": "sum", + "names": [ + "stats.0.metrics.delivered" + ] + } + ] + }, + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "Undelivered – Spam", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "comparisonColumn": "none", + "label": "undelivered – spam", + "manualSize": 50, + "value": "stats.0.metrics.spam_report_drops_sum" + } + } + } + } + }, + { + "static": false, + "w": 1, + "moved": false, + "h": 2, + "x": 3, + "y": 0, + "i": "7a321574-77bd-464a-8231-10ff322683ae", + "z": 0, + "config": { + "dataStream": { + "name": "globalStats", + "id": "{{dataStreams.globalStats}}", + "group": { + "by": [ + [ + "date", + "byYear" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "stats.0.metrics.bounce_drops" + ] + }, + { + "type": "sum", + "names": [ + "stats.0.metrics.unsubscribe_drops" + ] + }, + { + "type": "sum", + "names": [ + "stats.0.metrics.invalid_emails" + ] + }, + { + "type": "sum", + "names": [ + "stats.0.metrics.spam_report_drops" + ] + }, + { + "type": "sum", + "names": [ + "stats.0.metrics.delivered" + ] + } + ] + }, + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "Undelivered – Unsubscribed", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "comparisonColumn": "none", + "label": "undelivered – unsubscribed", + "manualSize": 50, + "value": "stats.0.metrics.unsubscribe_drops_sum" + } + } + } + } + }, + { + "static": false, + "w": 1, + "moved": false, + "h": 2, + "x": 4, + "y": 0, + "i": "6bc15a69-d4fd-4457-b79f-4454981050be", + "z": 0, + "config": { + "dataStream": { + "name": "globalStats", + "id": "{{dataStreams.globalStats}}", + "group": { + "by": [ + [ + "date", + "byYear" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "stats.0.metrics.bounce_drops" + ] + }, + { + "type": "sum", + "names": [ + "stats.0.metrics.unsubscribe_drops" + ] + }, + { + "type": "sum", + "names": [ + "stats.0.metrics.invalid_emails" + ] + }, + { + "type": "sum", + "names": [ + "stats.0.metrics.spam_report_drops" + ] + }, + { + "type": "sum", + "names": [ + "stats.0.metrics.delivered" + ] + } + ] + }, + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "Undelivered – Invalid", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "comparisonColumn": "none", + "label": "undelivered – invalid email", + "manualSize": 50, + "value": "stats.0.metrics.invalid_emails_sum" + } + } + } + } + }, + { + "static": false, + "w": 1, + "moved": false, + "h": 2, + "x": 1, + "y": 0, + "i": "1c6c3e7d-e7d1-48f5-baaf-8a232e60bb28", + "z": 0, + "config": { + "dataStream": { + "name": "globalStats", + "id": "{{dataStreams.globalStats}}", + "group": { + "by": [ + [ + "date", + "byYear" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "stats.0.metrics.bounce_drops" + ] + }, + { + "type": "sum", + "names": [ + "stats.0.metrics.unsubscribe_drops" + ] + }, + { + "type": "sum", + "names": [ + "stats.0.metrics.invalid_emails" + ] + }, + { + "type": "sum", + "names": [ + "stats.0.metrics.spam_report_drops" + ] + }, + { + "type": "sum", + "names": [ + "stats.0.metrics.delivered" + ] + } + ] + }, + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "Undelivered – Bounce", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "comparisonColumn": "none", + "label": "undelivered – bounce", + "manualSize": 50, + "value": "stats.0.metrics.bounce_drops_sum" + } + } + } + } + }, + { + "static": false, + "w": 5, + "moved": false, + "h": 2, + "x": 0, + "y": 2, + "i": "4df41a49-6816-4f92-9c02-a36f848834a1", + "z": 0, + "config": { + "dataStream": { + "name": "bounces", + "id": "{{dataStreams.bounces}}", + "sort": { + "by": [ + [ + "email_uniqueValues", + "asc" + ] + ] + }, + "group": { + "by": [ + [ + "email", + "uniqueValues" + ], + [ + "reason", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "count" + } + ] + }, + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "New Bounces", + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "columnOrder": [ + "created", + "email", + "reason" + ], + "hiddenColumns": [ + "status" + ] + } + } + } + } + }, + { + "static": false, + "w": 5, + "moved": false, + "h": 2, + "x": 0, + "y": 4, + "i": "d9ad9b18-3861-4135-bdc9-37ba1f9098ba", + "z": 0, + "config": { + "dataStream": { + "name": "blocks", + "id": "{{dataStreams.blocks}}", + "sort": { + "by": [ + [ + "email_uniqueValues", + "asc" + ] + ] + }, + "group": { + "by": [ + [ + "email", + "uniqueValues" + ], + [ + "reason", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "count" + } + ] + }, + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "New Blocks", + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "columnOrder": [ + "created", + "email", + "reason" + ], + "hiddenColumns": [ + "status" + ] + } + } + } + } + }, + { + "static": false, + "w": 5, + "moved": false, + "h": 2, + "x": 0, + "y": 6, + "i": "afe0d592-c2d9-48bf-a75b-d0773946fb49", + "z": 0, + "config": { + "dataStream": { + "name": "invalidEmails", + "id": "{{dataStreams.invalidEmails}}", + "group": { + "by": [ + [ + "email", + "uniqueValues" + ], + [ + "reason", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "count" + } + ] + }, + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "New Invalid Emails", + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "columnOrder": [ + "created", + "email", + "reason" + ], + "hiddenColumns": [] + } + } + } + } + } + ], + "version": 221, + "columns": 5 + }, + "timeframe": "last30days" +} \ No newline at end of file diff --git a/plugins/SendGrid/v1/defaultContent/SendGrid/unsubscribes.dash.json b/plugins/SendGrid/v1/defaultContent/SendGrid/unsubscribes.dash.json new file mode 100644 index 0000000..aea80d4 --- /dev/null +++ b/plugins/SendGrid/v1/defaultContent/SendGrid/unsubscribes.dash.json @@ -0,0 +1,85 @@ +{ + "name": "Unsubscribes", + "schemaVersion": "1.4", + "dashboard": { + "_type": "layout/grid", + "contents": [ + { + "static": false, + "w": 4, + "moved": false, + "h": 3, + "x": 0, + "y": 0, + "i": "eb477b90-a930-4d26-8315-d8e893dd089a", + "z": 0, + "config": { + "dataStream": { + "name": "globalUnsubscribes", + "id": "{{dataStreams.globalUnsubscribes}}", + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "Global Unsubscribes", + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "columnOrder": [ + "created", + "email" + ], + "hiddenColumns": [] + } + } + } + } + }, + { + "static": false, + "w": 4, + "moved": false, + "h": 3, + "x": 0, + "y": 3, + "i": "17b47de5-1278-4e2f-ad51-2971e0499368", + "z": 0, + "config": { + "dataStream": { + "name": "groupUnsubscribes", + "id": "{{dataStreams.groupUnsubscribes}}", + "pluginConfigId": "{{configId}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "title": "Group Unsubscribes", + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "columnOrder": [ + "created_at", + "group_name", + "email" + ], + "hiddenColumns": [ + "group_id" + ] + } + } + } + } + } + ], + "version": 8, + "columns": 4 + }, + "timeframe": "last30days" +} \ No newline at end of file diff --git a/plugins/SendGrid/v1/defaultContent/manifest.json b/plugins/SendGrid/v1/defaultContent/manifest.json new file mode 100644 index 0000000..19575eb --- /dev/null +++ b/plugins/SendGrid/v1/defaultContent/manifest.json @@ -0,0 +1,8 @@ +{ + "items": [ + { + "name": "SendGrid", + "type": "folder" + } + ] +} \ No newline at end of file diff --git a/plugins/SendGrid/v1/defaultContent/scopes.json b/plugins/SendGrid/v1/defaultContent/scopes.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/plugins/SendGrid/v1/defaultContent/scopes.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/plugins/SendGrid/v1/icon.png b/plugins/SendGrid/v1/icon.png new file mode 100644 index 0000000..0d32241 Binary files /dev/null and b/plugins/SendGrid/v1/icon.png differ diff --git a/plugins/SendGrid/v1/metadata.json b/plugins/SendGrid/v1/metadata.json new file mode 100644 index 0000000..05b10a2 --- /dev/null +++ b/plugins/SendGrid/v1/metadata.json @@ -0,0 +1,42 @@ +{ + "name": "sendgrid", + "displayName": "Twilio SendGrid", + "version": "1.0.0", + "author": { + "name": "@agoodthing.org.uk", + "type": "community" + }, + "description": "Query email send statistics from Twilio SendGrid.", + "category": "Utility", + "type": "cloud", + "schemaVersion": "2.0", + "base": { + "plugin": "WebAPI", + "majorVersion": "1", + "config": { + "headers": [ + { + "value": "Bearer {{apiKey}}", + "key": "Authorization" + } + ], + "baseUrl": "https://api.{{region === 'eu' ? 'eu.' : ''}}sendgrid.com/v3" + } + }, + "links": [ + { + "category": "documentation", + "url": "https://github.com/squaredup/plugins/blob/main/plugins/SendGrid/v1/README.md", + "label": "Help adding this plugin" + }, + { + "category": "source", + "url": "https://github.com/squaredup/plugins/tree/main/plugins/SendGrid/v1", + "label": "Repository" + } + ], + "screenshots": [ + "https://github.com/squaredup/plugins/blob/main/plugins/SendGrid/v1/screenshots/sendgrid-stats-client.png", + "https://github.com/squaredup/plugins/blob/main/plugins/SendGrid/v1/screenshots/sendgrid-stats-engagement.png" + ] +} \ No newline at end of file diff --git a/plugins/SendGrid/v1/screenshots/sendgrid-stats-client.png b/plugins/SendGrid/v1/screenshots/sendgrid-stats-client.png new file mode 100644 index 0000000..83ecf13 Binary files /dev/null and b/plugins/SendGrid/v1/screenshots/sendgrid-stats-client.png differ diff --git a/plugins/SendGrid/v1/screenshots/sendgrid-stats-engagement.png b/plugins/SendGrid/v1/screenshots/sendgrid-stats-engagement.png new file mode 100644 index 0000000..a42bcdf Binary files /dev/null and b/plugins/SendGrid/v1/screenshots/sendgrid-stats-engagement.png differ diff --git a/plugins/SendGrid/v1/ui.json b/plugins/SendGrid/v1/ui.json new file mode 100644 index 0000000..41be29d --- /dev/null +++ b/plugins/SendGrid/v1/ui.json @@ -0,0 +1,36 @@ +[ + { + "help": "The API key must have read-only permissions to Stats and/or Suppressions", + "label": "API Key", + "name": "apiKey", + "placeholder": "Enter the SendGrid API key", + "type": "password", + "validation": { + "required": true + } + }, + { + "name": "region", + "type": "autocomplete", + "label": "SendGrid Account Region", + "validation": { + "required": true + }, + "allowCustomValues": false, + "isMulti": false, + "defaultValue": "global", + "data": { + "source": "fixed", + "values": [ + { + "value": "global", + "label": "Global" + }, + { + "value": "eu", + "label": "EU" + } + ] + } + } +]