src/shared/utils/webhook/webhook.service.ts
Service for handling webhooks in the application.
Methods |
constructor(httpService: HttpService, sessionService: SessionService, sessionLogger: SessionLoggerService)
|
||||||||||||
|
Constructor for WebhookService.
Parameters :
|
| sendWebhook | ||||||
sendWebhook(values: literal type)
|
||||||
|
Sends a webhook with the optional provided credentials, return the response data.
Parameters :
Returns :
any
|
| Async sendWebhookNotification | ||||||||||||
sendWebhookNotification(session: Session, logContext: SessionLogContext, notification: Notification)
|
||||||||||||
|
Sends a webhook notification for a session.
Parameters :
Returns :
any
|
import { HttpService } from "@nestjs/axios";
import { Injectable } from "@nestjs/common";
import { firstValueFrom } from "rxjs";
import {
Notification,
Session,
} from "../../../session/entities/session.entity";
import { SessionService } from "../../../session/session.service";
import { SessionLoggerService } from "../logger/session-logger.service";
import { SessionLogContext } from "../logger/session-logger-context";
import { WebhookConfig } from "./webhook.dto";
/**
* Response from a webhook to receive credentials.
*/
export class WebhookResponse {
[key: string]: Record<string, any>;
}
/**
* Service for handling webhooks in the application.
*/
@Injectable()
export class WebhookService {
/**
* Constructor for WebhookService.
* @param httpService
* @param sessionService
* @param sessionLogger
*/
constructor(
private httpService: HttpService,
private sessionService: SessionService,
private sessionLogger: SessionLoggerService,
) {}
/**
* Sends a webhook with the optional provided credentials, return the response data.
*/
sendWebhook(values: {
webhook: WebhookConfig;
logContext: SessionLogContext;
session: Session;
credentials?: any[];
expectResponse: boolean;
}) {
const headers: Record<string, string> = {};
if (values.webhook.auth && values.webhook.auth.type === "apiKey") {
headers[values.webhook.auth.config.headerName] =
values.webhook.auth.config.value;
}
this.sessionLogger.logSession(values.logContext, "Sending webhook", {
webhookUrl: values.webhook.url,
authType: values.webhook.auth?.type || "none",
});
return firstValueFrom(
this.httpService.post(
values.webhook.url,
{
credentials: values.credentials,
session: values.session.id,
},
{
headers,
},
),
).then(
async (webhookResponse) => {
this.sessionLogger.logSession(
values.logContext,
"Webhook sent successfully",
{
responseStatus: webhookResponse.status,
hasResponseData: !!webhookResponse.data,
},
);
//check if a redirect URI is passed, we either expect a redirect or claims, but never both.
if (webhookResponse.data?.redirectUri) {
//TODO: do we need to do something with it?
} else if (webhookResponse.data && values.expectResponse) {
//TODO: update this for presentation during issuance
//session.credentialPayload!.credentialClaims!["id"].claims = webhookResponse.data;
//store received webhook response
await this.sessionService.add(values.session.id, {
credentialPayload: values.session.credentialPayload,
});
}
return webhookResponse.data;
},
(err) => {
this.sessionLogger.logSessionError(
values.logContext,
err,
"Error sending webhook",
{
webhookUrl: values.webhook.url,
},
);
throw new Error(`Error sending webhook: ${err.message || err}`);
},
);
}
/**
* Sends a webhook notification for a session.
* @param session
* @param logContext
* @param notification
*/
async sendWebhookNotification(
session: Session,
logContext: SessionLogContext,
notification: Notification,
) {
const headers: Record<string, string> = {};
const webhook = session.notifyWebhook!;
if (webhook.auth && webhook.auth.type === "apiKey") {
headers[webhook.auth.config.headerName] = webhook.auth.config.value;
}
this.sessionLogger.logSession(
logContext,
"Sending webhook notification",
{
webhookUrl: webhook.url,
authType: webhook.auth?.type || "none",
},
);
await firstValueFrom(
this.httpService.post(
webhook.url,
{
notification,
session: session.id,
},
{
headers,
},
),
).then(
(webhookResponse) => {
//TODO: update notification status based on response
this.sessionLogger.logSession(
logContext,
"Webhook notification sent successfully",
{
responseStatus: webhookResponse.status,
hasResponseData: !!webhookResponse.data,
},
);
},
(err) => {
this.sessionLogger.logSessionError(
logContext,
err,
"Error sending webhook",
{
webhookUrl: webhook.url,
},
);
throw new Error(`Error sending webhook: ${err.message || err}`);
},
);
}
}