unpublish fix

This commit is contained in:
echo 2026-02-01 13:57:16 +01:00
parent 0c2433cac6
commit acfbc80d1a
2 changed files with 99 additions and 27 deletions

View File

@ -2,7 +2,7 @@ import { Controller, Post, Body, Logger } from '@nestjs/common';
import { StrapiService } from './strapi.service';
interface WebhookBody {
event: 'entry.create' | 'entry.update' | 'entry.delete' | 'entry.publish';
event: 'entry.create' | 'entry.update' | 'entry.delete' | 'entry.publish' | 'entry.unpublish';
model: string;
entry: {
documentId: string;
@ -91,6 +91,7 @@ export class StrapiController {
'entry.update',
'entry.delete',
'entry.publish',
'entry.unpublish',
];
if (!validEvents.includes(event)) {
this.logger.warn(`Invalid event type: ${event}`);
@ -102,7 +103,8 @@ export class StrapiController {
| 'entry.create'
| 'entry.update'
| 'entry.delete'
| 'entry.publish',
| 'entry.publish'
| 'entry.unpublish',
{ documentId, model },
);
return { message: 'Webhook processed successfully' };

View File

@ -115,9 +115,12 @@ export class StrapiService {
}
}
async syncSingleArticle(strapiId: string): Promise<void> {
async syncSingleArticle(
strapiId: string,
event?: 'entry.create' | 'entry.update' | 'entry.delete' | 'entry.publish' | 'entry.unpublish',
): Promise<void> {
try {
this.logger.log(`Syncing single article from Strapi: ${strapiId}`);
this.logger.log(`Syncing single article from Strapi: ${strapiId}, event: ${event}`);
const response = await lastValueFrom(
this.httpService.get<StrapiResponse<StrapiArticle>>(
@ -129,14 +132,26 @@ export class StrapiService {
);
const strapiArticle = response.data.data;
// Determine status based on publishedAt and event type
let status: ArticleStatus;
if (event === 'entry.unpublish') {
// If it's an unpublish event, always mark as draft
status = ArticleStatus.DRAFT;
} else if (strapiArticle.publishedAt) {
// If publishedAt exists, it's published
status = ArticleStatus.PUBLISHED;
} else {
// Otherwise it's a draft
status = ArticleStatus.DRAFT;
}
const articleData: Partial<CreateArticleDto> = {
title: strapiArticle.title,
excerpt: strapiArticle.description,
content: strapiArticle.content,
slug: strapiArticle.slug,
status: strapiArticle.publishedAt
? ArticleStatus.PUBLISHED
: ArticleStatus.DRAFT,
status,
tags: [],
};
@ -144,8 +159,28 @@ export class StrapiService {
strapiArticle.documentId,
articleData,
);
this.logger.log(`Successfully synced article: ${strapiArticle.title}`);
} catch (error) {
this.logger.log(`Successfully synced article: ${strapiArticle.title} with status: ${status}`);
} catch (error: any) {
// If we get a 404 and it's an unpublish event, we can still mark it as draft
if (event === 'entry.unpublish' && error.response?.status === 404) {
this.logger.log(`Article ${strapiId} not found in Strapi, marking as draft based on unpublish event`);
// Try to update the article status to draft directly
try {
const articleData: Partial<CreateArticleDto> = {
status: ArticleStatus.DRAFT,
};
await this.articlesService.syncFromStrapi(strapiId, articleData);
this.logger.log(`Marked article ${strapiId} as draft based on unpublish event`);
} catch (syncError) {
this.logger.error(
`Failed to mark article ${strapiId} as draft:`,
syncError,
);
throw syncError;
}
} else {
this.logger.error(
`Failed to sync article ${strapiId} from Strapi`,
error,
@ -153,6 +188,7 @@ export class StrapiService {
throw error;
}
}
}
async syncLiveBlogs(): Promise<void> {
try {
@ -194,9 +230,12 @@ export class StrapiService {
}
}
async syncSingleLiveBlog(strapiId: string): Promise<void> {
async syncSingleLiveBlog(
strapiId: string,
event?: 'entry.create' | 'entry.update' | 'entry.delete' | 'entry.publish' | 'entry.unpublish',
): Promise<void> {
try {
this.logger.log(`Syncing single live blog from Strapi: ${strapiId}`);
this.logger.log(`Syncing single live blog from Strapi: ${strapiId}, event: ${event}`);
const response = await lastValueFrom(
this.httpService.get<StrapiResponse<StrapiLiveBlog>>(
@ -208,19 +247,49 @@ export class StrapiService {
);
const strapiLiveBlog = response.data.data;
// For live blogs, we use the status from Strapi directly
// but we might want to handle unpublish events differently
let status = this.mapStrapiStatusToLiveBlogStatus(strapiLiveBlog.status);
// If it's an unpublish event, set to draft
if (event === 'entry.unpublish') {
status = LiveBlogStatus.DRAFT;
}
const liveBlogData: Partial<CreateLiveBlogDto> = {
title: strapiLiveBlog.title,
description: strapiLiveBlog.description,
slug: strapiLiveBlog.slug,
status: this.mapStrapiStatusToLiveBlogStatus(strapiLiveBlog.status),
status,
};
await this.liveBlogService.syncFromStrapi(
strapiLiveBlog.documentId,
liveBlogData,
);
this.logger.log(`Successfully synced live blog: ${strapiLiveBlog.title}`);
} catch (error) {
this.logger.log(`Successfully synced live blog: ${strapiLiveBlog.title} with status: ${status}`);
} catch (error: any) {
// If we get a 404 and it's an unpublish event, we can still mark it as draft
if (event === 'entry.unpublish' && error.response?.status === 404) {
this.logger.log(`Live blog ${strapiId} not found in Strapi, marking as draft based on unpublish event`);
// Try to update the live blog status to draft directly
try {
const liveBlogData: Partial<CreateLiveBlogDto> = {
status: LiveBlogStatus.DRAFT,
};
await this.liveBlogService.syncFromStrapi(strapiId, liveBlogData);
this.logger.log(`Marked live blog ${strapiId} as draft based on unpublish event`);
} catch (syncError) {
this.logger.error(
`Failed to mark live blog ${strapiId} as draft:`,
syncError,
);
throw syncError;
}
} else {
this.logger.error(
`Failed to sync live blog ${strapiId} from Strapi`,
error,
@ -228,6 +297,7 @@ export class StrapiService {
throw error;
}
}
}
private mapStrapiStatusToLiveBlogStatus(status: string): LiveBlogStatus {
switch (status) {
@ -245,7 +315,7 @@ export class StrapiService {
}
async handleWebhook(
event: 'entry.create' | 'entry.update' | 'entry.delete' | 'entry.publish',
event: 'entry.create' | 'entry.update' | 'entry.delete' | 'entry.publish' | 'entry.unpublish',
data: { documentId: string; model?: string },
): Promise<void> {
this.logger.log(
@ -259,9 +329,9 @@ export class StrapiService {
// Route to appropriate sync method based on model
if (data.model === 'article') {
await this.syncSingleArticle(data.documentId);
await this.syncSingleArticle(data.documentId, event);
} else if (data.model === 'live-blog') {
await this.syncSingleLiveBlog(data.documentId);
await this.syncSingleLiveBlog(data.documentId, event);
} else {
this.logger.warn(`Unknown model type in webhook: ${data.model}`);
}