Skip to content

Commit

Permalink
refactor(notifiers): enhancing typing & subclass relation
Browse files Browse the repository at this point in the history
  • Loading branch information
fraxken committed Apr 12, 2024
1 parent a2745e8 commit 4d33200
Show file tree
Hide file tree
Showing 12 changed files with 195 additions and 132 deletions.
12 changes: 11 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 15 additions & 7 deletions src/discord/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// Import Third-party Dependencies
import { ExecuteWebhookOptions, WebhookNotifier } from "@sigyn/notifiers";
import { WebhookNotifierOptions, WebhookNotifier } from "@sigyn/notifiers";

// CONSTANTS
const kWebhookUsername = "Sigyn Agent";
const kAvatarUrl = "https://user-images.githubusercontent.com/39910767/261796970-1c07ee01-30e4-464c-b9f9-903b93f84ff3.png";

// https://gist.github.com/thomasbnt/b6f455e2c7d743b796917fa3c205f812
const kEmbedColor = {
critical: 15548997,
Expand All @@ -12,21 +13,23 @@ const kEmbedColor = {
info: 16777215
};

class DiscordNotifier extends WebhookNotifier {
class DiscordNotifier extends WebhookNotifier<any> {
contentTemplateOptions() {
return {
transform: ({ key, value }) => (key === "lokiUrl" ? value : `**${value === undefined ? "unknown" : value}**`),
ignoreMissing: true
};
}

async formatWebhook(): Promise<any> {
async formatWebhookBody(): Promise<any> {
if (this.data.ruleConfig?.logql) {
this.data.ruleConfig.logql = this.#formatLogQL(this.data.ruleConfig.logql);
}

const title = await this.formatTitle();
const content = await this.formatContent();
const [title, content] = await Promise.all([
this.formatTitle(),
this.formatContent()
]);

return {
embeds: [{
Expand All @@ -44,8 +47,13 @@ class DiscordNotifier extends WebhookNotifier {
}
}

export function execute(options: ExecuteWebhookOptions) {
export async function execute(
options: WebhookNotifierOptions
) {
const notifier = new DiscordNotifier(options);
const body = await notifier.formatWebhookBody();

return notifier.execute();
return notifier.execute(
body
);
}
8 changes: 6 additions & 2 deletions src/discord/test/execute.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ describe("executeWebhook()", () => {
data: {
counter: 10,
severity: "error",
label: { foo: "bar" }
label: { foo: "bar" },
labelCount: 0,
labelMatchCount: 0
},
template: { title: "foo", content: [] }
});
Expand All @@ -56,7 +58,9 @@ describe("executeWebhook()", () => {
data: {
counter: 10,
severity: "error",
label: { foo: "bar" }
label: { foo: "bar" },
labelCount: 0,
labelMatchCount: 0
},
template: { title: "foo", content: [] }
}), {
Expand Down
103 changes: 58 additions & 45 deletions src/notifiers/docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,46 +7,46 @@
## Webhook

Create a class that extends from `WebhookNotifier` to build a Webhook notifier.
Create a class that extends from `WebhookNotifier<T>` to build a Webhook notifier.

```ts
import { ExecuteWebhookOptions, WebhookNotifier } from "@sigyn/notifiers";
import { WebhookNotifierOptions, WebhookNotifier } from "@sigyn/notifiers";

class MyAwesomeWebhookNotifier extends WebhookNotifier {
async formatWebhook(): Promise<any> {
const title = await this.formatTitle();
const content = await this.formatContent();
interface MyAwesomeFormat {
title: string,
content: string
}

class MyAwesomeWebhookNotifier extends WebhookNotifier<MyAwesomeFormat> {
async formatWebhookBody(): Promise<MyAwesomeFormat> {
const [title, content] = await Promise.all([
this.formatTitle(),
this.formatContent()
]);

return {
title,
content.join("\n")
content: content.join("\n")
}
}
}

export function execute(options: ExecuteWebhookOptions) {
export function execute(
options: WebhookNotifierOptions
) {
const notifier = new MyAwesomeWebhookNotifier(options);
const body = await notifier.formatWebhookBody();

return notifier.execute();
return notifier.execute(
body
);
}
```

The only required method to implement is `formatWebhook()`.
This method return the Webhook body.
```ts
async execute() {
const body = await this.formatWebhook();

return httpie.post<string>(this.webhookUrl, {
body,
headers: this.#headers
});
}
```
You can use `formatTitle()` & `formatContent()` to get title & content formatted with template data. Theses functions uses `@sigyn/morphix` and you can customise the options of boths:

```ts
class MyAwesomeWebhookNotifier extends WebhookNotifier {
class MyAwesomeWebhookNotifier extends WebhookNotifier<MyAwesomeFormat> {
contentTemplateOptions() {
return {
transform: ({ value }) => (value === undefined ? "unknown" : value),
Expand All @@ -61,13 +61,15 @@ class MyAwesomeWebhookNotifier extends WebhookNotifier {
}
}

async formatWebhook(): Promise<any> {
const title = await this.formatTitle();
const content = await this.formatContent();
async formatWebhookBody(): Promise<MyAwesomeFormat> {
const [title, content] = await Promise.all([
this.formatTitle(),
this.formatContent()
]);

return {
title,
content.join("\n")
content: content.join("\n")
}
}
}
Expand All @@ -77,6 +79,7 @@ class MyAwesomeWebhookNotifier extends WebhookNotifier {
> The `contentTemplateOptions` & `titleTemplateOptions` above are the default values.
By default, `showSeverityEmoji` is truthy: this option add an emoji before the title depending the alert **severity**.

```ts
const kSeverityEmoji = {
critical: "💥",
Expand All @@ -85,27 +88,33 @@ const kSeverityEmoji = {
info: "📢"
};
```

You can do `this.showSeverityEmoji = false` to disable this behavior.

```ts
async formatWebhook(): Promise<any> {
this.showSeverityEmoji = false;

const title = await this.formatTitle();
const content = await this.formatContent();
const [title, content] = await Promise.all([
this.formatTitle(),
this.formatContent()
]);

return {
title,
content.join("\n")
content: content.join("\n")
}
}
```

You can also disable it in the constructor

```ts
class MyAwesomeWebhookNotifier extends WebhookNotifier {
// directly set the property to false
showSeverityEmoji = false;

constructor(options: ExecuteWebhookOptions) {
constructor(options: WebhookNotifierOptions) {
super(options);
// or
this.showSeverityEmoji = false;
Expand All @@ -121,21 +130,25 @@ You can see implementation examples with our notifiers:
## Interfaces

```ts
interface ExecuteWebhookOptions {
webhookUrl: string;
data: ExecuteWebhookData;
template: SigynInitializedTemplate;
export interface WebhookNotifierOptions {
webhookUrl: string;
data: WebhookData;
template: SigynInitializedTemplate;
}
interface ExecuteWebhookData {
ruleConfig?: NotifierFormattedSigynRule;
counter?: number;
severity: "critical" | "error" | "warning" | "info";
label?: Record<string, string>;
lokiUrl?: string;
agentFailure?: {
errors: string;
rules: string;
};
rules?: string;

export interface WebhookData {
ruleConfig?: NotifierFormattedSigynRule;
counter?: number;
severity: "critical" | "error" | "warning" | "info";
label?: Record<string, string>;
lokiUrl?: string;
agentFailure?: {
errors: string;
rules: string;
}
rules?: string;
labelCount: number;
labelMatchCount: number;
labelMatchPercent?: number;
}
```
30 changes: 1 addition & 29 deletions src/notifiers/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,2 @@
// Import Third-party Dependencies
import { NotifierFormattedSigynRule, SigynInitializedTemplate } from "@sigyn/config";

// Import Internal Dependencies
import { WebhookNotifier } from "./webhook";

export { WebhookNotifier };

export interface ExecuteWebhookOptions {
webhookUrl: string;
data: ExecuteWebhookData;
template: SigynInitializedTemplate;
}

export interface ExecuteWebhookData {
ruleConfig?: NotifierFormattedSigynRule;
counter?: number;
severity: "critical" | "error" | "warning" | "info";
label?: Record<string, string>;
lokiUrl?: string;
agentFailure?: {
errors: string;
rules: string;
}
rules?: string;
labelCount: number;
labelMatchCount: number;
labelMatchPercent?: number;
}

export * from "./webhook.js";
Loading

0 comments on commit 4d33200

Please sign in to comment.