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

  1. Create LinkedIn App:

  2. Configure Permissions: Add these required permissions to your app:

    • r_liteprofile - Read profile information
    • w_member_social - Post on behalf of user
    • w_organization_social - Post to company page
    • r_organization_social - Read company page info
  3. Set OAuth Redirect URL:

    https://your-site.azurestaticapps.net/api/linkedin-callback
    
  4. 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:

Bash
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

  1. Visit Admin Dashboard: Navigate to https://your-site.azurestaticapps.net/admin

  2. Click "Connect LinkedIn": This will initiate the OAuth flow

  3. 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 LinkedIn
  • state (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:

📋JSON
{
  "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):

📋JSON
{
  "blogSlug": "specific-post-slug",
  "forcePublish": false
}

Response Example:

📋JSON
{
  "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:

📋JSON
{
  "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:

📝YAML
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 .mdx files
  • Only processes blogs with published: true in 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 /admin and 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: true in frontmatter
  • Check: Blog file is in content/blog/ directory
  • Verify: File has .mdx extension

Debug Steps

  1. Check Connection Status:

    Bash
    curl https://your-site.com/api/linkedin-status
    
  2. View Publishing History:

    Bash
    curl https://your-site.com/api/blog-auto-publish
    
  3. Test Manual Publishing:

    Bash
    curl -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:

📝YAML
---
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:

🟨JavaScript
// 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:

Bash
# 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:

🎉 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! 🚀

Use Ctrl + / to navigate
Previous
First page
Next
Last page