From 4ea884433d6bee60a851471b7802794f14b3c438 Mon Sep 17 00:00:00 2001 From: cryptic-ai Date: Mon, 29 Nov 2021 20:27:04 -0500 Subject: [PATCH 1/4] new prometheus provider --- src/provider/Prometheus.ts | 81 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/provider/Prometheus.ts diff --git a/src/provider/Prometheus.ts b/src/provider/Prometheus.ts new file mode 100644 index 0000000..bc35e52 --- /dev/null +++ b/src/provider/Prometheus.ts @@ -0,0 +1,81 @@ +import { Embed, EmbedField, EmbedAuthor } from '../model/DiscordApi' +import { TypeParseProvder } from './BaseProvider' + +export class Prometheus extends TypeParseProvder { + private embed: Embed + constructor() { + super() + this.setEmbedColor(0x205081) + this.embed = {} + } + + public preParse(): void { + this.headers = ['x-skyhook-event'] + // Prometheus does not have a type, so we set our own. + this.headers['x-skyhook-event'] = 'fire' + } + + public getName(): string { + return 'Prometheus' + } + + public getType(): string | null { + // Prometheus does not have a type, so we set our own. + return this.headers['x-skyhook-event'] + } + + public knownTypes(): string[] { + return ['fire'] + } + + /** + * There is no event type for this provider. Creating a single + * method to handle all events. + */ + public async fire(): Promise { + // Set Embed Author + this.embed.author = this.extractAuthor() + + // Set Embed Title + this.embed.title = this.body.groupLabels?.alertname + + this.embed.url = this.body.externalURL + + // Set Embed Fields + this.embed.fields = this.extractAlertDescriptions() + + this.addEmbed(this.embed) + } + + private extractAuthor(): EmbedAuthor { + return { + name: 'Prometheus Alert', + icon_url: 'https://avatars.githubusercontent.com/u/3380462?s=200&v=4', + } + } + + private extractAlertDescriptions(): EmbedField[] { + const fieldArray: EmbedField[] = [] + + // As per https://discord.com/developers/docs/resources/channel#embed-limits-limits + // Embed fields are limited to 25 fields. + + if (this.body.alerts) { + for (let i = 0; i < Math.min(this.body.alerts.length, 25); i++) { + // Get current Alert + const alert = this.body.alerts[i] + + // Push alert to fieldArray + fieldArray.push({ + name: alert.labels.alertname, + value: alert.annotations.description, + inline: false, + }) + } + + return fieldArray + } else { + return [] + } + } +} \ No newline at end of file From 5cad47b70e81792b9c4011b77c25f89817880737 Mon Sep 17 00:00:00 2001 From: cryptic-ai Date: Mon, 29 Nov 2021 20:27:43 -0500 Subject: [PATCH 2/4] add prometheus to index, added tests --- src/index.ts | 2 ++ test/prometheus/prometheus-spec.ts | 10 ++++++++ test/prometheus/prometheus.json | 37 ++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 test/prometheus/prometheus-spec.ts create mode 100644 test/prometheus/prometheus.json diff --git a/src/index.ts b/src/index.ts index 087ac82..5231d71 100644 --- a/src/index.ts +++ b/src/index.ts @@ -29,6 +29,7 @@ import { Unity } from './provider/Unity' import { UptimeRobot } from './provider/UptimeRobot' import { VSTS } from './provider/VSTS' import { Type } from './util/TSUtility' +import { Prometheus } from './provider/Prometheus' dotenv.config() @@ -58,6 +59,7 @@ const providers: Type[] = [ NewRelic, Patreon, Pingdom, + Prometheus, Rollbar, Travis, Trello, diff --git a/test/prometheus/prometheus-spec.ts b/test/prometheus/prometheus-spec.ts new file mode 100644 index 0000000..7c5ef2d --- /dev/null +++ b/test/prometheus/prometheus-spec.ts @@ -0,0 +1,10 @@ +import { expect } from 'chai' +import { Tester } from '../Tester' +import { Prometheus } from '../../src/provider/Prometheus' + +describe('/POST prometheus', () => { + it('fires when called', async () => { + const res = await Tester.test(new Prometheus(), 'prometheus.json') + expect(res).to.not.be.null + }) +}) \ No newline at end of file diff --git a/test/prometheus/prometheus.json b/test/prometheus/prometheus.json new file mode 100644 index 0000000..319ab89 --- /dev/null +++ b/test/prometheus/prometheus.json @@ -0,0 +1,37 @@ +{ + "receiver": "webhook", + "status": "firing", + "alerts": [ + { + "status": "firing", + "labels": { + "alertname": "API Latency", + "dc": "eu-west-1", + "instance": "localhost:9090", + "job": "prometheus24" + }, + "annotations": { + "description": "API has a latency of greater than 200ms" + }, + "startsAt": "2018-08-03T09:52:26.739266876+02:00", + "endsAt": "0001-01-01T00:00:00Z", + "generatorURL": "http://example.com:9090/graph?g0.expr=go_memstats_alloc_bytes+%3E+0\u0026g0.tab=1" + } + ], + "groupLabels": { + "alertname": "API Latency", + "job": "prometheus24" + }, + "commonLabels": { + "alertname": "Test", + "dc": "eu-west-1", + "instance": "localhost:9090", + "job": "prometheus24" + }, + "commonAnnotations": { + "description": "some description" + }, + "externalURL": "http://example.com:9093", + "version": "4", + "groupKey": "{}:{alertname=\"Test\", job=\"prometheus24\"}" +} \ No newline at end of file From eaf9977677655a955eeb95d878f6b2faf705caa4 Mon Sep 17 00:00:00 2001 From: cryptic-ai Date: Mon, 29 Nov 2021 20:42:56 -0500 Subject: [PATCH 3/4] Added prometheus to readme --- README.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a1cb443..c29c81c 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,32 @@ # skyhook + Parses webhooks and forwards them in the proper format to Discord. [![Discord](https://discordapp.com/api/guilds/303595820345851905/widget.png)](https://discord.gg/js7wD7p) ## Setup + You can use the [site](https://skyhookapi.com/) to create the right webhook link. If you want to manually do it, here are the steps: + 1. Create a webhook in Discord (Server Settings -> Webhooks -> Create Webhook) 2. Copy the webhook url 3. Turn the Discord webhook url into a skyhook webhook url like so: + ``` Replace discordapp.com in url with skyhookapi.com https://discordapp.com/api/webhooks/firstPartOfWebhook/secondPartOfWebhook -> https://skyhookapi.com/api/webhooks/firstPartOfWebhook/secondPartOfWebhook ``` + 4. Add the provider you want to the end of the url: + ``` https://skyhookapi.com/api/webhooks/firstPartOfWebhook/secondPartOfWebhook/providerGoesHere ``` + ## Supported Providers + - [AppVeyor](https://www.appveyor.com/docs/notifications/#webhook-payload-default) - `/appveyor` - [Basecamp 3](https://github.com/basecamp/bc3-api/blob/master/sections/webhooks.md) - `/basecamp` - [BitBucket](https://confluence.atlassian.com/bitbucket/manage-webhooks-735643732.html) - `/bitbucket` @@ -34,6 +42,7 @@ https://skyhookapi.com/api/webhooks/firstPartOfWebhook/secondPartOfWebhook/provi - [NewRelic](https://docs.newrelic.com/docs/alerts/new-relic-alerts/managing-notification-channels/customize-your-webhook-payload) - `/newrelic` - [Patreon](https://www.patreon.com/platform/documentation/webhooks) - `/patreon` - [Pingdom](https://www.pingdom.com/resources/webhooks) - `/pingdom` +- [Prometheus](https://prometheus.io/docs/alerting/latest/configuration/#webhook_config) - `/prometheus` - [Rollbar](https://docs.rollbar.com/docs/webhooks) - `/rollbar` - [Travis](https://docs.travis-ci.com/user/notifications/#Webhooks-Delivery-Format) - `/travis` - [Trello](https://developers.trello.com/apis/webhooks) - `/trello` @@ -45,38 +54,50 @@ If you want support for a new provider, just create a pull request and add it! Alternatively, a new provider can also be requested by creating an [issue](https://github.com/Commit451/skyhook/issues). ## Contributing + If you wish to contribute, follow our [contributing guide](CONTRIBUTING.md). ### Creating a Provider + If you want to create a new provider please follow the examples shown at our small [documentation](docs/CreateNewProvider.md). ## Testing Locally + To build: + ``` npm run build ``` + To run server (after building): + ``` npm start ``` + To run tests: + ``` npm test ``` Through Docker: + ``` docker run -it --rm -p 8080:8080 commit451/skyhook ``` ## Deploying + - [Docker](docs/docker) - [Google Cloud](docs/gcloud) ## Thanks + Special thanks to all our amazing contributors. skyhookapi.com is hosted for free for you, so if you feel so inclined, [buy a coffee!](https://ko-fi.com/jawnnypoo) ## License + skyhook is available under the MIT license. See the LICENSE file for more info. -\ ゜o゜)ノ +\ ゜ o ゜)ノ From 768f50ef8fffbe5fe30020849fde0e934c3d47f5 Mon Sep 17 00:00:00 2001 From: cryptic-ai Date: Tue, 30 Nov 2021 10:10:20 -0500 Subject: [PATCH 4/4] changed to DirectParseProvider Changed to the direct parse provider per PR review comments. Removed the getType, knownTypes, and preParse methods. --- src/provider/Prometheus.ts | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/src/provider/Prometheus.ts b/src/provider/Prometheus.ts index bc35e52..12c949f 100644 --- a/src/provider/Prometheus.ts +++ b/src/provider/Prometheus.ts @@ -1,7 +1,7 @@ import { Embed, EmbedField, EmbedAuthor } from '../model/DiscordApi' -import { TypeParseProvder } from './BaseProvider' +import { DirectParseProvider } from './BaseProvider' -export class Prometheus extends TypeParseProvder { +export class Prometheus extends DirectParseProvider { private embed: Embed constructor() { super() @@ -9,30 +9,15 @@ export class Prometheus extends TypeParseProvder { this.embed = {} } - public preParse(): void { - this.headers = ['x-skyhook-event'] - // Prometheus does not have a type, so we set our own. - this.headers['x-skyhook-event'] = 'fire' - } - public getName(): string { return 'Prometheus' } - public getType(): string | null { - // Prometheus does not have a type, so we set our own. - return this.headers['x-skyhook-event'] - } - - public knownTypes(): string[] { - return ['fire'] - } - /** * There is no event type for this provider. Creating a single * method to handle all events. */ - public async fire(): Promise { + public async parseData(): Promise { // Set Embed Author this.embed.author = this.extractAuthor()