143 lines
4.0 KiB
TypeScript
143 lines
4.0 KiB
TypeScript
import { Controller, Post, Body, Logger } from '@nestjs/common';
|
|
import { StrapiService } from './strapi.service';
|
|
import { Public } from './auth/public.decorator';
|
|
|
|
interface WebhookBody {
|
|
event:
|
|
| 'entry.create'
|
|
| 'entry.update'
|
|
| 'entry.delete'
|
|
| 'entry.publish'
|
|
| 'entry.unpublish';
|
|
model: string;
|
|
entry: {
|
|
documentId: string;
|
|
};
|
|
}
|
|
|
|
@Controller('webhooks/strapi')
|
|
export class StrapiController {
|
|
private readonly logger = new Logger(StrapiController.name);
|
|
|
|
constructor(private readonly strapiService: StrapiService) {}
|
|
|
|
@Post('article')
|
|
@Public()
|
|
async handleArticleWebhook(@Body() body: WebhookBody) {
|
|
this.logger.log(`Received article webhook: ${JSON.stringify(body)}`);
|
|
const { event, model, entry } = body;
|
|
|
|
if (model !== 'article') {
|
|
this.logger.warn(`Ignored: not an article, model: ${model}`);
|
|
return { message: 'Ignored: not an article' };
|
|
}
|
|
|
|
await this.strapiService.handleWebhook(event, {
|
|
documentId: entry.documentId,
|
|
model,
|
|
});
|
|
return { message: 'Webhook processed successfully' };
|
|
}
|
|
|
|
@Post('live-blog')
|
|
@Public()
|
|
async handleLiveBlogWebhook(@Body() body: WebhookBody) {
|
|
this.logger.log(`Received live-blog webhook: ${JSON.stringify(body)}`);
|
|
const { event, model, entry } = body;
|
|
|
|
if (model !== 'live-blog') {
|
|
this.logger.warn(`Ignored: not a live blog, model: ${model}`);
|
|
return { message: 'Ignored: not a live blog' };
|
|
}
|
|
|
|
await this.strapiService.handleWebhook(event, {
|
|
documentId: entry.documentId,
|
|
model,
|
|
});
|
|
return { message: 'Live blog webhook processed successfully' };
|
|
}
|
|
|
|
@Post()
|
|
@Public()
|
|
async handleGenericWebhook(@Body() body: unknown) {
|
|
this.logger.log(`Received generic webhook: ${JSON.stringify(body)}`);
|
|
|
|
// Type guard to check if body is an object
|
|
if (typeof body !== 'object' || body === null) {
|
|
this.logger.warn(`Invalid webhook payload: ${JSON.stringify(body)}`);
|
|
return { message: 'Invalid payload' };
|
|
}
|
|
|
|
const bodyObj = body as Record<string, unknown>;
|
|
|
|
// Try to extract event and model from different possible payload structures
|
|
const event = (bodyObj.event || bodyObj.type) as string;
|
|
const model = (bodyObj.model || bodyObj.contentType) as string;
|
|
const entry = bodyObj.entry || bodyObj.data || bodyObj;
|
|
|
|
if (!event || !model) {
|
|
this.logger.warn(
|
|
`Cannot process webhook: missing event or model. Payload: ${JSON.stringify(body)}`,
|
|
);
|
|
return { message: 'Cannot process: missing event or model' };
|
|
}
|
|
|
|
const entryObj = entry as Record<string, unknown>;
|
|
const documentId = (entryObj.documentId ||
|
|
entryObj.id ||
|
|
(entryObj.document as Record<string, unknown>)?.id) as string;
|
|
|
|
if (!documentId) {
|
|
this.logger.warn(
|
|
`Cannot process webhook: missing documentId. Payload: ${JSON.stringify(body)}`,
|
|
);
|
|
return { message: 'Cannot process: missing documentId' };
|
|
}
|
|
|
|
// Validate event type
|
|
const validEvents = [
|
|
'entry.create',
|
|
'entry.update',
|
|
'entry.delete',
|
|
'entry.publish',
|
|
'entry.unpublish',
|
|
];
|
|
if (!validEvents.includes(event)) {
|
|
this.logger.warn(`Invalid event type: ${event}`);
|
|
return { message: 'Invalid event type' };
|
|
}
|
|
|
|
await this.strapiService.handleWebhook(
|
|
event as
|
|
| 'entry.create'
|
|
| 'entry.update'
|
|
| 'entry.delete'
|
|
| 'entry.publish'
|
|
| 'entry.unpublish',
|
|
{ documentId, model },
|
|
);
|
|
return { message: 'Webhook processed successfully' };
|
|
}
|
|
|
|
@Post('sync/all')
|
|
async syncAllArticles() {
|
|
await this.strapiService.syncArticles();
|
|
return { message: 'Articles sync completed' };
|
|
}
|
|
|
|
@Post('sync/live-blogs')
|
|
async syncAllLiveBlogs() {
|
|
await this.strapiService.syncLiveBlogs();
|
|
return { message: 'Live blogs sync completed' };
|
|
}
|
|
|
|
@Post('sync/everything')
|
|
async syncEverything() {
|
|
await Promise.all([
|
|
this.strapiService.syncArticles(),
|
|
this.strapiService.syncLiveBlogs(),
|
|
]);
|
|
return { message: 'Full sync completed' };
|
|
}
|
|
}
|