fixed strapi webhook endpoint
This commit is contained in:
parent
4ccb65ba88
commit
2ff76ffda5
276
ADMINISTRATOR_GUIDE.md
Normal file
276
ADMINISTRATOR_GUIDE.md
Normal file
@ -0,0 +1,276 @@
|
||||
# Administrator Guide - Placebo.mk
|
||||
|
||||
## Overview
|
||||
Placebo.mk is a Macedonian news site with a sarcastic tone. This guide covers system administration, user management, and technical operations.
|
||||
|
||||
## System Architecture
|
||||
- **Frontend**: TanStack (React 19, Query, Router) + Vite + Tailwind CSS
|
||||
- **Backend**: NestJS + TypeORM + SQLite
|
||||
- **CMS**: Strapi for content management
|
||||
- **Database**: SQLite with TypeORM entities
|
||||
|
||||
## Environment Setup
|
||||
|
||||
### Backend Configuration
|
||||
```bash
|
||||
cd backend
|
||||
cp .env.example .env
|
||||
# Configure environment variables:
|
||||
# DATABASE_PATH=./data/app.db
|
||||
# PORT=3000
|
||||
# NODE_ENV=development
|
||||
npm install
|
||||
npm run start:dev
|
||||
```
|
||||
|
||||
### Frontend Configuration
|
||||
```bash
|
||||
cd frontend
|
||||
cp .env.example .env
|
||||
# Configure environment variables:
|
||||
# VITE_API_URL=http://localhost:3000
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### CMS (Strapi) Configuration
|
||||
```bash
|
||||
cd cms/cms
|
||||
cp .env.example .env
|
||||
# Configure Strapi environment variables:
|
||||
# DATABASE_CLIENT=sqlite
|
||||
# DATABASE_FILENAME=./data/app.db
|
||||
# API_TOKEN_SALT=
|
||||
# ADMIN_JWT_SECRET=
|
||||
npm run develop
|
||||
```
|
||||
|
||||
## Database Management
|
||||
|
||||
### Entities Overview
|
||||
- **Articles**: News articles with status (draft/published/archived)
|
||||
- **Authors**: Writer profiles with permissions
|
||||
- **Categories**: Hierarchical content organization
|
||||
- **Live Blogs**: Real-time event coverage
|
||||
- **Live Blog Updates**: Individual updates within live blogs
|
||||
|
||||
### Database Operations
|
||||
```bash
|
||||
# Run migrations (if implemented)
|
||||
npm run migration:run
|
||||
|
||||
# Check database schema
|
||||
npm run schema:sync
|
||||
|
||||
# Backup database
|
||||
cp backend/data/app.db backend/data/backup-$(date +%Y%m%d).db
|
||||
```
|
||||
|
||||
## User Management
|
||||
|
||||
### Author Management
|
||||
Authors are stored in the `authors` table with:
|
||||
- Basic profile (name, bio, avatar)
|
||||
- Unique slug for URLs
|
||||
- `isActive` flag for permissions
|
||||
- Relations to articles and live blogs
|
||||
|
||||
### CMS User Roles
|
||||
1. **Super Admin**: Full system access
|
||||
2. **Admin**: Content and user management
|
||||
3. **Editor**: Content creation and editing
|
||||
4. **Author**: Limited to assigned content
|
||||
|
||||
### Creating New Authors
|
||||
```sql
|
||||
INSERT INTO authors (id, name, slug, bio, avatar, isActive, createdAt, updatedAt)
|
||||
VALUES (
|
||||
uuid(),
|
||||
'Author Name',
|
||||
'author-slug',
|
||||
'Author bio',
|
||||
'avatar-url.jpg',
|
||||
true,
|
||||
datetime('now'),
|
||||
datetime('now')
|
||||
);
|
||||
```
|
||||
|
||||
## Content Management
|
||||
|
||||
### Article Workflow
|
||||
1. **Draft**: Initial creation phase
|
||||
2. **Published**: Publicly visible
|
||||
3. **Archived**: No longer public but retained
|
||||
|
||||
### Live Blog Management
|
||||
Live blogs support real-time updates:
|
||||
- **Draft**: Preparation phase
|
||||
- **Live**: Active event coverage
|
||||
- **Ended**: Coverage complete
|
||||
- **Archived**: Historical reference
|
||||
|
||||
## API Management
|
||||
|
||||
### Available Endpoints
|
||||
```
|
||||
GET /api/v1/articles # List articles
|
||||
GET /api/v1/articles/:id # Get single article
|
||||
GET /api/v1/articles/slug/:slug # Get article by slug
|
||||
POST /api/v1/articles # Create article
|
||||
PUT /api/v1/articles/:id # Update article
|
||||
DELETE /api/v1/articles/:id # Delete article
|
||||
|
||||
GET /api/v1/live-blogs # List live blogs
|
||||
GET /api/v1/live-blogs/:id # Get live blog
|
||||
POST /api/v1/live-blogs # Create live blog
|
||||
PUT /api/v1/live-blogs/:id # Update live blog
|
||||
|
||||
GET /api/v1/authors # List authors
|
||||
GET /api/v1/categories # List categories
|
||||
```
|
||||
|
||||
### API Authentication
|
||||
Configure JWT tokens for secure API access:
|
||||
```typescript
|
||||
// In .env
|
||||
JWT_SECRET=your-secret-key
|
||||
JWT_EXPIRES_IN=24h
|
||||
```
|
||||
|
||||
## CMS Administration
|
||||
|
||||
### Strapi Admin Panel
|
||||
Access at: `http://localhost:1337/admin`
|
||||
|
||||
### Content Types Configuration
|
||||
Articles support:
|
||||
- Rich text content
|
||||
- Multiple media files (images, files, videos, audio)
|
||||
- Featured images
|
||||
- Author attribution
|
||||
|
||||
### Media Management
|
||||
- Upload limits configured in Strapi settings
|
||||
- Image optimization handled automatically
|
||||
- File organization in `/uploads` directory
|
||||
|
||||
## Performance Monitoring
|
||||
|
||||
### Backend Monitoring
|
||||
```bash
|
||||
# Check application logs
|
||||
npm run start:prod
|
||||
|
||||
# Monitor performance
|
||||
npm run start:prod -- --inspect
|
||||
```
|
||||
|
||||
### Frontend Performance
|
||||
```bash
|
||||
# Build for production
|
||||
cd frontend
|
||||
npm run build
|
||||
|
||||
# Analyze bundle size
|
||||
npm run build:analyze
|
||||
```
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Authentication
|
||||
- Implement proper JWT handling
|
||||
- Use secure password hashing
|
||||
- Set appropriate CORS policies
|
||||
|
||||
### Data Protection
|
||||
- Regular database backups
|
||||
- Environment variable protection
|
||||
- Input validation and sanitization
|
||||
|
||||
### CMS Security
|
||||
- Regular Strapi updates
|
||||
- Role-based access control
|
||||
- Media file scanning
|
||||
|
||||
## Backup and Recovery
|
||||
|
||||
### Automated Backups
|
||||
```bash
|
||||
# Create backup script
|
||||
#!/bin/bash
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
mkdir -p backups
|
||||
cp backend/data/app.db backups/app_$DATE.db
|
||||
tar -czf backups/uploads_$DATE.tar.gz cms/cms/public/uploads/
|
||||
```
|
||||
|
||||
### Recovery Process
|
||||
1. Stop all services
|
||||
2. Restore database from backup
|
||||
3. Restore media files
|
||||
4. Restart services
|
||||
5. Verify functionality
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### Database Connection Errors
|
||||
```bash
|
||||
# Check database file exists
|
||||
ls -la backend/data/app.db
|
||||
|
||||
# Verify permissions
|
||||
chmod 664 backend/data/app.db
|
||||
```
|
||||
|
||||
#### Strapi Admin Access
|
||||
```bash
|
||||
# Reset admin password
|
||||
npm run strapi admin:reset-password
|
||||
```
|
||||
|
||||
#### Frontend Build Issues
|
||||
```bash
|
||||
# Clear cache
|
||||
rm -rf node_modules package-lock.json
|
||||
npm install
|
||||
|
||||
# Check environment variables
|
||||
cat .env
|
||||
```
|
||||
|
||||
## Maintenance Tasks
|
||||
|
||||
### Daily
|
||||
- Monitor system logs
|
||||
- Check backup completion
|
||||
- Review performance metrics
|
||||
|
||||
### Weekly
|
||||
- Update dependencies
|
||||
- Review content moderation queue
|
||||
- Security scan
|
||||
|
||||
### Monthly
|
||||
- Database maintenance
|
||||
- Archive old content
|
||||
- Performance optimization review
|
||||
|
||||
## Scaling Considerations
|
||||
|
||||
### Database Scaling
|
||||
- Consider PostgreSQL for high traffic
|
||||
- Implement read replicas
|
||||
- Optimize queries and indexes
|
||||
|
||||
### CDN Integration
|
||||
- Configure CDN for static assets
|
||||
- Optimize image delivery
|
||||
- Implement caching strategies
|
||||
|
||||
### Monitoring Setup
|
||||
- Application performance monitoring
|
||||
- Error tracking and alerting
|
||||
- User analytics and reporting
|
||||
314
PUBLISHER_GUIDE.md
Normal file
314
PUBLISHER_GUIDE.md
Normal file
@ -0,0 +1,314 @@
|
||||
# Publisher & Content Creator Guide - Placebo.mk
|
||||
|
||||
## Overview
|
||||
Placebo.mk is a Macedonian news site with a sarcastic tone. This guide covers content creation, publishing workflows, and best practices for writers and editors.
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Accessing the CMS
|
||||
1. Navigate to: `http://your-domain.com/admin`
|
||||
2. Log in with your credentials
|
||||
3. Select "Content Manager" from the sidebar
|
||||
|
||||
### Your Dashboard
|
||||
- **Content Manager**: Create and edit articles
|
||||
- **Media Library**: Upload and manage images/files
|
||||
- **Profile**: Update your author information
|
||||
|
||||
## Content Creation Workflow
|
||||
|
||||
### 1. Planning Your Article
|
||||
Before writing:
|
||||
- Choose a compelling headline
|
||||
- Research your topic thoroughly
|
||||
- Gather supporting images/media
|
||||
- Plan your article structure
|
||||
|
||||
### 2. Creating a New Article
|
||||
|
||||
#### Basic Article Setup
|
||||
1. Click **+ Create new entry** in Content Manager
|
||||
2. Select **Article** content type
|
||||
3. Fill in required fields:
|
||||
- **Title**: Catchy, SEO-friendly headline
|
||||
- **Author**: Your name (auto-populated)
|
||||
- **Content**: Main article body
|
||||
|
||||
#### Article Fields Explained
|
||||
- **Title**: Maximum 100 characters, include keywords
|
||||
- **Content**: Rich text editor with formatting options
|
||||
- **Media**: Upload images, videos, documents
|
||||
- **Featured Image**: Main article thumbnail
|
||||
- **Status**: Draft → Published → Archived
|
||||
|
||||
### 3. Writing Best Practices
|
||||
|
||||
#### Headline Guidelines
|
||||
- Use active voice and strong verbs
|
||||
- Include location if relevant (e.g., "Скопје:")
|
||||
- Keep under 100 characters
|
||||
- Ask questions or make bold statements
|
||||
|
||||
#### Content Structure
|
||||
```
|
||||
1. Lead Paragraph (2-3 sentences)
|
||||
- Who, what, where, when, why
|
||||
- Most important information first
|
||||
|
||||
2. Body Paragraphs (3-5 paragraphs)
|
||||
- Supporting details and quotes
|
||||
- Background information
|
||||
- Analysis and context
|
||||
|
||||
3. Conclusion (1-2 paragraphs)
|
||||
- Summary or call to action
|
||||
- Future implications
|
||||
```
|
||||
|
||||
#### Writing Style
|
||||
- **Tone**: Sarcastic but informative
|
||||
- **Language**: Macedonian with local context
|
||||
- **Length**: 300-800 words for news, 800-1500 for features
|
||||
- **Voice**: Conversational, engaging, slightly cynical
|
||||
|
||||
### 4. Media Integration
|
||||
|
||||
#### Adding Images
|
||||
1. Click **Media** field in article editor
|
||||
2. Click **Add new** or select from library
|
||||
3. Drag and drop or browse files
|
||||
4. Add alt text for accessibility
|
||||
5. Choose image size and alignment
|
||||
|
||||
#### Image Guidelines
|
||||
- **Featured Image**: 1200x630px minimum
|
||||
- **Inline Images**: 800px width maximum
|
||||
- **File Size**: Under 2MB per image
|
||||
- **Formats**: JPG, PNG, WebP
|
||||
|
||||
#### Video and Audio
|
||||
- Upload MP4 videos (under 100MB)
|
||||
- Embed YouTube/Vimeo links
|
||||
- Add MP3 audio files for interviews
|
||||
|
||||
## Publishing Workflow
|
||||
|
||||
### Article Status Management
|
||||
|
||||
#### Draft Status
|
||||
- Initial creation phase
|
||||
- Auto-saves every 30 seconds
|
||||
- Only visible to you and editors
|
||||
|
||||
#### Review Process
|
||||
1. Submit for review when ready
|
||||
2. Editor reviews content and style
|
||||
3. Request changes or approve
|
||||
4. Editor may edit directly
|
||||
|
||||
#### Published Status
|
||||
- Live on the website
|
||||
- Publicly accessible
|
||||
- Appears in category listings
|
||||
- Indexed by search engines
|
||||
|
||||
#### Archived Status
|
||||
- No longer public
|
||||
- Retained for reference
|
||||
- Can be republished if needed
|
||||
|
||||
### Publishing Best Practices
|
||||
|
||||
#### Before Publishing
|
||||
- [ ] Proofread for spelling/grammar
|
||||
- [ ] Check all facts and sources
|
||||
- [ ] Test all links
|
||||
- [ ] Optimize images for web
|
||||
- [ ] Add relevant tags
|
||||
- [ ] Set appropriate category
|
||||
|
||||
#### Publishing Schedule
|
||||
- **Breaking News**: Publish immediately
|
||||
- **Features**: Schedule for peak traffic (10:00-14:00)
|
||||
- **Analysis**: Publish by 17:00 for evening readers
|
||||
|
||||
## Live Blogging
|
||||
|
||||
### When to Use Live Blogs
|
||||
- Ongoing events (protests, sports, conferences)
|
||||
- Developing news stories
|
||||
- Election coverage
|
||||
- Emergency situations
|
||||
|
||||
### Creating a Live Blog
|
||||
1. Navigate to **Live Blogs** in Content Manager
|
||||
2. Click **+ Create new entry**
|
||||
3. Fill in basic information:
|
||||
- **Title**: Event name + "LIVE"
|
||||
- **Description**: Brief event summary
|
||||
- **Status**: Set to "Live" when ready
|
||||
|
||||
### Live Blog Updates
|
||||
Each update should include:
|
||||
- **Timestamp**: Auto-generated
|
||||
- **Content**: New information (1-3 sentences)
|
||||
- **Author**: Your attribution
|
||||
- **Media**: Relevant photos/videos
|
||||
|
||||
#### Update Guidelines
|
||||
- Keep updates concise and factual
|
||||
- Post major developments immediately
|
||||
- Use quotes when available
|
||||
- Add context for new followers
|
||||
- Pin important updates
|
||||
|
||||
## Content Categories
|
||||
|
||||
### Available Categories
|
||||
- **Политика**: Government, elections, policy
|
||||
- **Економија**: Business, markets, finance
|
||||
- **Друштво**: Social issues, culture, lifestyle
|
||||
- **Спорт**: Sports news and events
|
||||
- **Технологија**: Tech news and innovations
|
||||
- **Свет**: International news
|
||||
- **Култура**: Arts, entertainment, events
|
||||
|
||||
### Category Selection
|
||||
- Choose primary category carefully
|
||||
- Use tags for additional context
|
||||
- Consider audience interests
|
||||
- Follow editorial calendar
|
||||
|
||||
## SEO and Discoverability
|
||||
|
||||
### Title Optimization
|
||||
- Include primary keywords
|
||||
- Use location when relevant
|
||||
- Ask questions or make statements
|
||||
- Avoid clickbait (maintain credibility)
|
||||
|
||||
### Content SEO
|
||||
- Naturally include keywords
|
||||
- Use header tags (H2, H3)
|
||||
- Add internal links to related articles
|
||||
- Include external sources when relevant
|
||||
|
||||
### Meta Information
|
||||
- **Excerpt**: 150-character summary
|
||||
- **Featured Image**: Optimized for social sharing
|
||||
- **Tags**: 3-5 relevant keywords
|
||||
|
||||
## Author Profile Management
|
||||
|
||||
### Updating Your Profile
|
||||
1. Click **Profile** in sidebar
|
||||
2. Update information:
|
||||
- **Display Name**: Your byline name
|
||||
- **Bio**: 100-word professional summary
|
||||
- **Avatar**: Professional headshot
|
||||
- **Social Links**: Twitter, LinkedIn, etc.
|
||||
|
||||
### Author Best Practices
|
||||
- Maintain consistent voice across articles
|
||||
- Build expertise in specific topics
|
||||
- Engage with reader comments
|
||||
- Share published articles on social media
|
||||
|
||||
## Content Moderation
|
||||
|
||||
### Comment Policy
|
||||
- Comments are enabled on published articles
|
||||
- Inappropriate content is filtered automatically
|
||||
- Editors can approve/reject comments manually
|
||||
|
||||
### Handling Corrections
|
||||
1. Mark errors immediately
|
||||
2. Correct factual mistakes
|
||||
3. Add correction note at top
|
||||
4. Notify editor of significant changes
|
||||
|
||||
## Analytics and Performance
|
||||
|
||||
### Article Metrics
|
||||
- **Views**: Total page reads
|
||||
- **Engagement**: Time on page, scroll depth
|
||||
- **Shares**: Social media interactions
|
||||
- **Comments**: Reader engagement
|
||||
|
||||
### Improving Performance
|
||||
- Write compelling headlines
|
||||
- Use relevant, high-quality images
|
||||
- Publish at optimal times
|
||||
- Share on social media
|
||||
- Engage with reader comments
|
||||
|
||||
## Tools and Shortcuts
|
||||
|
||||
### Editor Shortcuts
|
||||
- **Ctrl+B**: Bold text
|
||||
- **Ctrl+I**: Italic text
|
||||
- **Ctrl+K**: Insert link
|
||||
- **Ctrl+Z**: Undo
|
||||
- **Ctrl+Y**: Redo
|
||||
|
||||
### Media Management
|
||||
- Drag and drop uploads
|
||||
- Bulk image optimization
|
||||
- Automatic alt text suggestions
|
||||
- Image cropping and resizing
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### Editor Not Saving
|
||||
- Check internet connection
|
||||
- Refresh page and try again
|
||||
- Contact administrator if persistent
|
||||
|
||||
#### Image Upload Errors
|
||||
- Verify file size under 2MB
|
||||
- Check file format (JPG, PNG, WebP)
|
||||
- Clear browser cache and retry
|
||||
|
||||
#### Publishing Problems
|
||||
- Ensure all required fields completed
|
||||
- Check article status permissions
|
||||
- Contact editor for approval
|
||||
|
||||
## Best Practices Summary
|
||||
|
||||
### Do's
|
||||
- Write factually accurate content
|
||||
- Use engaging, sarcastic tone appropriately
|
||||
- Include relevant, high-quality media
|
||||
- Proofread thoroughly before publishing
|
||||
- Engage with reader feedback
|
||||
- Follow ethical journalism standards
|
||||
|
||||
### Don'ts
|
||||
- Publish unverified information
|
||||
- Use excessive clickbait
|
||||
- Ignore reader comments
|
||||
- Publish without editor review
|
||||
- Violate copyright laws
|
||||
- Share confidential information
|
||||
|
||||
## Support and Resources
|
||||
|
||||
### Getting Help
|
||||
- **Editor**: Primary contact for content questions
|
||||
- **Administrator**: Technical support and system issues
|
||||
- **Style Guide**: Detailed writing and formatting guidelines
|
||||
|
||||
### Training Resources
|
||||
- CMS video tutorials
|
||||
- Writing style workshops
|
||||
- SEO best practices guide
|
||||
- Social media sharing strategies
|
||||
|
||||
### Community
|
||||
- Regular writer meetings
|
||||
- Content planning sessions
|
||||
- Feedback and improvement discussions
|
||||
- Collaboration opportunities
|
||||
@ -1,8 +1,8 @@
|
||||
import { Controller, Post, Body } from '@nestjs/common';
|
||||
import { Controller, Post, Body, Logger } from '@nestjs/common';
|
||||
import { StrapiService } from './strapi.service';
|
||||
|
||||
interface WebhookBody {
|
||||
event: 'entry.create' | 'entry.update' | 'entry.delete';
|
||||
event: 'entry.create' | 'entry.update' | 'entry.delete' | 'entry.publish';
|
||||
model: string;
|
||||
entry: {
|
||||
documentId: string;
|
||||
@ -11,17 +11,100 @@ interface WebhookBody {
|
||||
|
||||
@Controller('webhooks/strapi')
|
||||
export class StrapiController {
|
||||
private readonly logger = new Logger(StrapiController.name);
|
||||
|
||||
constructor(private readonly strapiService: StrapiService) {}
|
||||
|
||||
@Post('article')
|
||||
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, entry);
|
||||
await this.strapiService.handleWebhook(event, {
|
||||
documentId: entry.documentId,
|
||||
model,
|
||||
});
|
||||
return { message: 'Webhook processed successfully' };
|
||||
}
|
||||
|
||||
@Post('live-blog')
|
||||
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()
|
||||
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',
|
||||
];
|
||||
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',
|
||||
{ documentId, model },
|
||||
);
|
||||
return { message: 'Webhook processed successfully' };
|
||||
}
|
||||
|
||||
@ -31,18 +114,6 @@ export class StrapiController {
|
||||
return { message: 'Articles sync completed' };
|
||||
}
|
||||
|
||||
@Post('live-blog')
|
||||
async handleLiveBlogWebhook(@Body() body: WebhookBody) {
|
||||
const { event, model, entry } = body;
|
||||
|
||||
if (model !== 'live-blog') {
|
||||
return { message: 'Ignored: not a live blog' };
|
||||
}
|
||||
|
||||
await this.strapiService.handleWebhook(event, entry);
|
||||
return { message: 'Live blog webhook processed successfully' };
|
||||
}
|
||||
|
||||
@Post('sync/live-blogs')
|
||||
async syncAllLiveBlogs() {
|
||||
await this.strapiService.syncLiveBlogs();
|
||||
|
||||
@ -245,7 +245,7 @@ export class StrapiService {
|
||||
}
|
||||
|
||||
async handleWebhook(
|
||||
event: 'entry.create' | 'entry.update' | 'entry.delete',
|
||||
event: 'entry.create' | 'entry.update' | 'entry.delete' | 'entry.publish',
|
||||
data: { documentId: string; model?: string },
|
||||
): Promise<void> {
|
||||
this.logger.log(
|
||||
|
||||
@ -29,6 +29,16 @@
|
||||
},
|
||||
"author": {
|
||||
"type": "string"
|
||||
},
|
||||
"img": {
|
||||
"type": "media",
|
||||
"multiple": false,
|
||||
"allowedTypes": [
|
||||
"images",
|
||||
"files",
|
||||
"videos",
|
||||
"audios"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1
cms/cms/types/generated/contentTypes.d.ts
vendored
1
cms/cms/types/generated/contentTypes.d.ts
vendored
@ -446,6 +446,7 @@ export interface ApiArticleArticle extends Struct.CollectionTypeSchema {
|
||||
createdAt: Schema.Attribute.DateTime;
|
||||
createdBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||
Schema.Attribute.Private;
|
||||
img: Schema.Attribute.Media<'images' | 'files' | 'videos' | 'audios'>;
|
||||
locale: Schema.Attribute.String & Schema.Attribute.Private;
|
||||
localizations: Schema.Attribute.Relation<
|
||||
'oneToMany',
|
||||
|
||||
1
whliveblog.md
Normal file
1
whliveblog.md
Normal file
@ -0,0 +1 @@
|
||||
Live-blog webhooks work correctly: POST /api/v1/webhooks/strapi/live-blog
|
||||
Loading…
Reference in New Issue
Block a user