LinkedIn Integration
Complete guide to LinkedIn OAuth integration and automatic blog publishing for your portfolio site
🔗 LinkedIn Integration Guide
The Portfolio API includes a comprehensive LinkedIn integration system that allows you to automatically publish blog posts to your LinkedIn company page. This integration uses OAuth 2.0 for secure authentication and provides both automated and manual publishing options.
🎯 Features
OAuth 2.0 Authentication
- Secure LinkedIn app integration
- Token management with automatic refresh
- Company page access permissions
- State-based CSRF protection
Automatic Blog Publishing
- GitHub Actions integration for deployment-triggered publishing
- Smart duplicate prevention
- Rich post formatting with hashtags and links
- Batch processing of multiple blog posts
Admin Dashboard
- Real-time connection status monitoring
- Manual publishing controls
- Publishing history and statistics
- Token expiry management
API Integration
- RESTful endpoints for all LinkedIn operations
- Comprehensive error handling and logging
- Rate limiting and security features
- OpenAPI 3.0 documentation
🚀 Quick Start
1. LinkedIn App Setup
-
Create LinkedIn App:
- Go to LinkedIn Developer Console
- Click "Create App"
- Fill in your app details and select your company page
-
Configure Permissions: Add these required permissions to your app:
r_liteprofile- Read profile informationw_member_social- Post on behalf of userw_organization_social- Post to company pager_organization_social- Read company page info
-
Set OAuth Redirect URL:
https://your-site.azurestaticapps.net/api/linkedin-callback -
Get Credentials:
- Copy your Client ID and Client Secret
- Note your Company Page ID from the URL
2. Environment Configuration
Add these variables to your Azure Static Web Apps configuration:
LINKEDIN_CLIENT_ID=your_linkedin_app_client_id
LINKEDIN_CLIENT_SECRET=your_linkedin_app_client_secret
LINKEDIN_COMPANY_ID=your_company_page_numeric_id
LINKEDIN_REDIRECT_URI=https://your-site.azurestaticapps.net/api/linkedin-callback
LINKEDIN_JWT_SECRET=generate_secure_random_string
AUTO_PUBLISH_SECRET=generate_webhook_secret
3. Connect Your Account
-
Visit Admin Dashboard: Navigate to
https://your-site.azurestaticapps.net/admin -
Click "Connect LinkedIn": This will initiate the OAuth flow
-
Complete Authorization:
- You'll be redirected to LinkedIn
- Grant the requested permissions
- You'll be redirected back with connection status
4. Test Auto-Publishing
Create a test blog post with published: true in the frontmatter and deploy your site. The GitHub Action will automatically publish it to LinkedIn.
📖 API Endpoints
Authentication Flow
GET /api/linkedin-auth
Initiates the LinkedIn OAuth 2.0 authorization flow.
Response: Redirects to LinkedIn authorization page
GET /api/linkedin-callback
Handles the OAuth callback after user authorization.
Parameters:
code(required) - Authorization code from LinkedInstate(required) - State parameter for CSRF protection
Response: Redirects to admin dashboard with connection status
Status and Management
GET /api/linkedin-status
Returns current LinkedIn connection status and profile information.
Response Example:
{
"connected": true,
"expired": false,
"canRefresh": true,
"expiresAt": "2024-04-15T10:30:00Z",
"profile": {
"firstName": "John",
"lastName": "Doe",
"id": "abc123xyz"
},
"companyId": "12345678"
}
Publishing Endpoints
POST /api/blog-auto-publish
Automatically scans for and publishes new blog posts.
Authentication: Requires Authorization: Bearer AUTO_PUBLISH_SECRET
Request Body (optional):
{
"blogSlug": "specific-post-slug",
"forcePublish": false
}
Response Example:
{
"success": true,
"message": "Processed 3 blogs",
"published": 2,
"errors": 0,
"results": [
{
"slug": "new-blog-post",
"published": true,
"linkedInUrl": "https://www.linkedin.com/feed/update/urn:li:share:123456",
"title": "My New Blog Post"
}
]
}
POST /api/linkedin-publish
Publishes a single blog post to LinkedIn.
Authentication: Requires Authorization: Bearer INTERNAL_API_KEY
Request Body:
{
"title": "Blog Post Title",
"content": "Blog post description or excerpt",
"url": "https://your-site.com/blog/post-slug",
"tags": ["tech", "programming", "webdev"],
"imageUrl": "https://your-site.com/images/post-cover.jpg"
}
🤖 GitHub Actions Integration
The integration includes a GitHub Action that automatically publishes new blog posts after successful deployment:
Workflow Configuration
The LinkedIn auto-publish workflow is triggered after successful Azure Static Web Apps deployment:
name: LinkedIn Auto-Publish Blog Posts
on:
workflow_run:
workflows: ["Azure Static Web Apps CI/CD"]
types: [completed]
workflow_dispatch:
jobs:
auto-publish:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- name: Auto-publish new blogs to LinkedIn
run: |
curl -X POST \
-H "Authorization: Bearer ${{ secrets.AUTO_PUBLISH_SECRET }}" \
-H "Content-Type: application/json" \
-d '{}' \
"${{ vars.SITE_URL || 'https://journey.thakurganeshsingh.com' }}/api/blog-auto-publish"
Required Secrets
Add to your GitHub repository secrets:
AUTO_PUBLISH_SECRET- Same value as your environment variable
Optional Variables
Add to your GitHub repository variables:
SITE_URL- Your production site URL (defaults to journey.thakurganeshsingh.com)
🎨 Admin Dashboard
The admin dashboard at /admin provides a complete interface for managing LinkedIn integration:
Connection Management
- Connection Status: Real-time display of authentication state
- Profile Information: Shows connected LinkedIn profile details
- Token Expiry: Displays when tokens need renewal
- One-Click Connect: Easy OAuth flow initiation
Publishing Controls
- Publish All New Blogs: Batch publish unpublished content
- Publishing History: View count of published posts
- Manual Triggers: Force republish specific posts
- Status Monitoring: Real-time feedback on publishing operations
Security Features
- Token Validation: Automatic token health checks
- Error Reporting: Clear error messages and recovery steps
- Rate Limit Monitoring: LinkedIn API usage tracking
🔒 Security Features
OAuth 2.0 Security
- State parameter verification (CSRF protection)
- Secure token storage using JWT encryption
- Automatic token refresh handling
- Authorization scope validation
API Security
- Bearer token authentication for all endpoints
- Request origin validation
- Rate limiting per endpoint
- Input sanitization and validation
Data Protection
- No sensitive data in logs
- Encrypted token storage
- Secure cookie handling
- Profile information sanitization
📊 Publishing Logic
Blog Detection
- Scans
content/blog/directory for.mdxfiles - Only processes blogs with
published: truein frontmatter - Extracts title, description, tags, and featured images
- Validates content before publishing
Duplicate Prevention
- Maintains a record of published blog slugs
- Prevents accidental republishing
- Supports force republish for updates
- Tracks publishing history
Content Formatting
- Rich LinkedIn post formatting
- Automatic hashtag generation from blog tags
- Includes blog URL and call-to-action
- Supports featured images and media
Error Handling
- Comprehensive error logging
- Retry logic for transient failures
- Detailed error reporting in responses
- Graceful fallback for LinkedIn API issues
🛠️ Troubleshooting
Common Issues
"LinkedIn not authenticated"
- Solution: Visit
/adminand click "Connect LinkedIn" - Check: LinkedIn app permissions are correctly configured
- Verify: Redirect URL matches your site domain
"Token expired"
- Solution: The system should auto-refresh, but you can reconnect manually
- Check: Your LinkedIn app has refresh token permissions
- Verify: Token storage is working correctly
"Rate limit exceeded"
- Solution: Wait for the rate limit to reset (24 hours)
- Check: You're not exceeding LinkedIn's posting limits
- Consider: Reducing publishing frequency
"Blog not found or not published"
- Solution: Ensure blog has
published: truein frontmatter - Check: Blog file is in
content/blog/directory - Verify: File has
.mdxextension
Debug Steps
-
Check Connection Status:
⚡Bashcurl https://your-site.com/api/linkedin-status -
View Publishing History:
⚡Bashcurl https://your-site.com/api/blog-auto-publish -
Test Manual Publishing:
⚡Bashcurl -X POST \ -H "Authorization: Bearer YOUR_SECRET" \ -H "Content-Type: application/json" \ -d '{"blogSlug": "test-post", "forcePublish": true}' \ https://your-site.com/api/blog-auto-publish
🚀 Advanced Usage
Custom Publishing Logic
You can customize the publishing behavior by modifying the blog frontmatter:
---
title: "My Blog Post"
description: "Post description"
published: true
linkedin:
publish: true
tags: ["custom", "tags", "override"]
message: "Custom LinkedIn message"
---
Webhook Integration
Set up webhooks to trigger publishing from external systems:
// Custom webhook trigger
const response = await fetch('/api/blog-auto-publish', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_AUTO_PUBLISH_SECRET',
'Content-Type': 'application/json'
},
body: JSON.stringify({
blogSlug: 'my-new-post',
forcePublish: false
})
})
Multi-Environment Setup
Configure different environments with separate LinkedIn apps:
# Development
LINKEDIN_REDIRECT_URI=http://localhost:3000/api/linkedin-callback
# Staging
LINKEDIN_REDIRECT_URI=https://staging.yoursite.com/api/linkedin-callback
# Production
LINKEDIN_REDIRECT_URI=https://yoursite.com/api/linkedin-callback
📞 Support
For help with LinkedIn integration:
- Documentation: Review this guide and the API documentation
- Admin Dashboard: Use
/adminfor connection status and troubleshooting - GitHub Issues: Report bugs at Portfolio API Issues
- Email Support: thakurg785@thakurganeshsingh.com
🎉 Success!
Once configured, your LinkedIn integration will:
- ✅ Automatically publish new blog posts when you deploy
- ✅ Format posts with rich content and hashtags
- ✅ Prevent duplicate publishing
- ✅ Provide admin dashboard for monitoring
- ✅ Handle authentication and token refresh
- ✅ Scale with your content publishing needs
Happy blogging! 🚀