Django applications can receive PostPenguin webhooks and automatically create blog posts in your Django models.
๐ Quick Setup
1. Install Dependencies
pip install django djangorestframework requests2. Create Django App
python manage.py startapp blog3. Create Post Model
# blog/models.py
from django.db import models
import uuid
class Post(models.Model):
postpenguin_id = models.CharField(max_length=255, unique=True, blank=True)
title = models.CharField(max_length=500)
slug = models.SlugField(unique=True)
html = models.TextField()
meta_title = models.CharField(max_length=500, blank=True)
meta_description = models.TextField(blank=True)
featured_image = models.URLField(blank=True)
published_at = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-published_at']
def __str__(self):
return self.title
def save(self, *args, **kwargs):
if not self.postpenguin_id:
self.postpenguin_id = str(uuid.uuid4())
super().save(*args, **kwargs)
4. Create Webhook View
# blog/views.py
import hmac
import hashlib
import json
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from django.conf import settings
from .models import Post
@csrf_exempt
@require_POST
def postpenguin_webhook(request):
# Verify webhook signature (recommended)
signature = request.headers.get('X-PostPenguin-Signature')
webhook_secret = getattr(settings, 'POSTPENGUIN_WEBHOOK_SECRET', None)
if webhook_secret and signature:
payload = request.body
expected_signature = hmac.new(
webhook_secret.encode(),
payload,
hashlib.sha256
).hexdigest()
received_signature = signature.replace('sha256=', '')
if received_signature != expected_signature:
return JsonResponse({'error': 'Invalid signature'}, status=401)
try:
data = json.loads(request.body)
# Validate required fields
required_fields = ['title', 'slug', 'html']
for field in required_fields:
if field not in data:
return JsonResponse({'error': f'Missing required field: {field}'}, status=400)
# Create or update post
post, created = Post.objects.update_or_create(
postpenguin_id=data.get('postPenguinId', str(uuid.uuid4())),
defaults={
'title': data['title'],
'slug': data['slug'],
'html': data['html'],
'meta_title': data.get('meta_title', data['title']),
'meta_description': data.get('meta_description', ''),
'featured_image': data.get('featured_image', ''),
}
)
return JsonResponse({
'success': True,
'post_id': post.id,
'action': 'created' if created else 'updated',
'post_url': f'/posts/{post.slug}/' # Adjust URL pattern as needed
})
except json.JSONDecodeError:
return JsonResponse({'error': 'Invalid JSON'}, status=400)
except Exception as e:
return JsonResponse({'error': str(e)}, status=500)
5. Configure URLs
# blog/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('webhooks/postpenguin/', views.postpenguin_webhook, name='postpenguin_webhook'),
]
# main urls.py
from django.urls import path, include
urlpatterns = [
# ... other URLs ...
path('api/', include('blog.urls')),
]
6. Settings
# settings.py
POSTPENGUIN_WEBHOOK_SECRET = 'your-webhook-secret-here'
# Add to INSTALLED_APPS
INSTALLED_APPS = [
# ... other apps ...
'blog',
'rest_framework',
]
# Run migrations
python manage.py makemigrations blog
python manage.py migrate
7. Configure PostPenguin
When adding your site to PostPenguin:
- Webhook URL:
https://your-domain.com/api/webhooks/postpenguin/ - Secret Key: Same as
POSTPENGUIN_WEBHOOK_SECRET
๐งช Testing
Test Webhook
# Test the webhook endpoint
curl -X POST https://your-domain.com/api/webhooks/postpenguin/ \
-H "Content-Type: application/json" \
-d '{
"title": "Test Post from Django",
"slug": "test-post-django",
"html": "<p className="text-gray-700">This is a test post from Django.</p>",
"meta_title": "Test Post Title",
"meta_description": "Testing Django webhook integration",
"featured_image": "https://via.placeholder.com/800x400",
"status": "publish"
}'
Need Help?
Read our webhook documentation for technical details, or contact support for custom integrations.