Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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 plugins/webhooks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const plugins = [
options: {
// Add here the subcribers you will define
subscriptions: ["product.created", "product.updated"],
secretKey:"Your-webhook-secret"
},
},
];
Expand Down
32 changes: 24 additions & 8 deletions plugins/webhooks/src/modules/webhooks/service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { MedusaError, MedusaService } from "@medusajs/framework/utils";
import { Webhook } from "./models/webhooks";
import { LoaderOptions, Logger } from "@medusajs/framework/types";
import { WebhookModel } from "../../common";
import type { LoaderOptions, Logger } from "@medusajs/framework/types";
import type{ WebhookModel } from "../../common";
import Crypto from "node:crypto";


export type WebhookSendResponse = {
event_type: string;
Expand All @@ -23,32 +25,46 @@ type ConstructorParams = {
logger: Logger;
};

type WebhookOptions = LoaderOptions & { subscriptions: string[] & { secretKey: string } };
Copy link

Copilot AI May 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type definition for WebhookOptions seems off; combining subscriptions as string[] with an embedded secretKey is confusing. Consider separating secretKey from subscriptions, e.g., 'LoaderOptions & { secretKey: string, subscriptions: string[] }'.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

old



class WebhooksService extends MedusaService({
Webhook,
}) {
public subscriptions: string[] = [];
private logger: Logger;

private options: WebhookOptions;
constructor(
container: ConstructorParams,
options: LoaderOptions & { subscriptions: string[] }
options: WebhookOptions
) {
super(container, options);
this.options = options;
this.subscriptions = options.subscriptions;
this.logger = container.logger;
}

createHmacSignature(payload: Record<string, unknown>) {
return Crypto
.createHmac("sha256", this.options.secretKey)
.update(JSON.stringify(payload))
.digest("hex");
}

public async send(
subscription: WebhookModel,
payload: any
payload: Record<string, unknown>
): Promise<WebhookSendResponse> {
const { event_type, target_url } = subscription;



try {
const response = await fetch(target_url, {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-webhook-signature": this.createHmacSignature(payload),
},
body: JSON.stringify(payload),
});
Expand All @@ -69,8 +85,8 @@ class WebhooksService extends MedusaService({
}
}

public async sendWebhooksEvents(webhooks: WebhookModel[], payload: any) {
console.log("webhooks", webhooks);
public async sendWebhooksEvents(webhooks: WebhookModel[], payload: Record<string, unknown>) {

const results = (await Promise.allSettled(
webhooks?.map((webhook) => this.send(webhook, payload))
)) as PromiseFulfilledResult<WebhookSendResponse>[];
Expand Down Expand Up @@ -124,7 +140,7 @@ class WebhooksService extends MedusaService({
private onSendError(
err: WebhookSendResponseError,
subscription: WebhookModel,
payload: any
payload: Record<string, unknown>
): WebhookSendResponse {
this.logger.error(
"Error sending webhook",
Expand Down