# Meta (Facebook & Instagram) API Setup Guide

This guide provides step-by-step instructions for setting up Meta Graph API integration for managing Facebook Pages and Instagram Business accounts.

---

## Table of Contents

1. [Overview](#overview)
2. [Prerequisites](#prerequisites)
3. [Meta for Developers Setup](#meta-for-developers-setup)
4. [Environment Configuration](#environment-configuration)
5. [OAuth Redirect URI Configuration](#oauth-redirect-uri-configuration)
6. [Permissions & Scopes](#permissions--scopes)
7. [Webhook Configuration](#webhook-configuration)
8. [Development vs Production](#development-vs-production)
9. [Troubleshooting](#troubleshooting)

---

## Overview

**API Version:** Graph API v24.0
**Base URL:** `https://graph.facebook.com/v24.0`
**Auth URL:** `https://www.facebook.com/v24.0/dialog/oauth`

### Features Supported
- **Facebook Pages:**
  - Fetch page posts
  - Read comments on posts
  - Reply to comments as the Page

- **Instagram Business:**
  - Fetch Instagram media posts
  - Read comments on posts
  - Reply to comments (with nesting limitations)

### How It Works
1. User authenticates with Facebook
2. App discovers all Facebook Pages the user manages
3. For each Page, app also discovers linked Instagram Business accounts
4. Page Access Tokens are permanent (don't expire if app is active)

---

## Prerequisites

- A Facebook account with admin access to at least one Facebook Page
- An Instagram Business Account linked to your Facebook Page
- Access to [Meta for Developers](https://developers.facebook.com/)
- HTTPS-enabled server for production

### Linking Instagram to Facebook Page

1. Go to your Facebook Page settings
2. Navigate to **Instagram** → **Connect Account**
3. Log in to your Instagram Business account
4. Authorize the connection

---

## Meta for Developers Setup

### Step 1: Create a Meta App

1. Navigate to [Meta for Developers](https://developers.facebook.com/apps/)
2. Click **"Create App"**
3. Select **"Business"** as the app type
4. Fill in the details:
   - **App Name:** Your application name (e.g., "PX360 Social Manager")
   - **App Contact Email:** Your contact email
   - **Business Account:** Select your business (if applicable)
5. Click **"Create App"**
6. Complete security verification if prompted

### Step 2: Configure Basic Settings

1. Go to **"Settings"** → **"Basic"**
2. Fill in required fields:
   - **Privacy Policy URL:** Your privacy policy URL
   - **User Data Deletion:** Provide deletion instructions or URL
   - **Category:** Select "Business Tools"
3. Add **App Domains** (your application's domain)
4. Click **"Save Changes"**

### Step 3: Add Facebook Login Product

1. Go to **"Add Products"** (left sidebar)
2. Find **"Facebook Login"** and click **"Set Up"**
3. Select **"Web"** as platform
4. Enter your site URL
5. Configure OAuth settings (see Redirect URI section below)

### Step 4: Get App Credentials

1. Go to **"Settings"** → **"Basic"**
2. Copy the following:
   - **App ID** → This is your `META_APP_ID`
   - **App Secret** → Click "Show" → This is your `META_APP_SECRET`

> ⚠️ **Important:** Never expose your App Secret in client-side code.

---

## Environment Configuration

### Django Settings (settings.py)

```python
# Meta (Facebook/Instagram) API Configuration
META_APP_ID = 'your_app_id_here'
META_APP_SECRET = 'your_app_secret_here'
META_REDIRECT_URI = 'https://yourdomain.com/social/callback/META/'
META_WEBHOOK_VERIFY_TOKEN = 'your_random_secret_string_here'
```

### Environment Variables (.env)

```env
META_APP_ID=your_app_id_here
META_APP_SECRET=your_app_secret_here
META_REDIRECT_URI=https://yourdomain.com/social/callback/META/
META_WEBHOOK_VERIFY_TOKEN=your_random_secret_string_here
```

---

## OAuth Redirect URI Configuration

### In Meta Developer Portal

1. Go to **"Facebook Login"** → **"Settings"**
2. Under **"Valid OAuth Redirect URIs"**, add:
   - Development: `http://127.0.0.1:8000/social/callback/META/`
   - Production: `https://yourdomain.com/social/callback/META/`
3. Click **"Save Changes"**

### Development vs Production URIs

| Environment | Redirect URI |
|-------------|--------------|
| Development | `http://127.0.0.1:8000/social/callback/META/` |
| Production | `https://yourdomain.com/social/callback/META/` |

> ⚠️ **Note:** Meta accepts HTTP for localhost but requires HTTPS for production.

---

## Permissions & Scopes

The application requests the following OAuth scopes:

| Scope | Description | Required |
|-------|-------------|----------|
| `pages_manage_engagement` | Reply to comments | ✅ Yes |
| `pages_read_engagement` | Read comments and reactions | ✅ Yes |
| `pages_show_list` | Discover pages and get tokens | ✅ Yes |
| `pages_read_user_content` | Read user-generated content | ✅ Yes |
| `instagram_basic` | Basic Instagram info | ✅ Yes |
| `instagram_manage_comments` | Manage Instagram comments | ✅ Yes |
| `public_profile` | Basic user profile | ✅ Yes |

### Code Reference

```python
# apps/social/utils/meta.py
BASE_GRAPH_URL = "https://graph.facebook.com/v24.0"
BASE_AUTH_URL = "https://www.facebook.com/v24.0"

META_SCOPES = [
    "pages_manage_engagement",
    "pages_read_engagement",
    "pages_show_list",
    "pages_read_user_content",
    "instagram_basic",
    "instagram_manage_comments",
    "public_profile",
]
```

### App Review Requirements

Some permissions require Meta's App Review:

1. Go to **"App Review"** → **"Permissions and Features"**
2. Request permissions that require review
3. Submit detailed use case and screencast
4. Typical use case explanation:
   > "This application helps businesses manage their social media presence by allowing them to read and respond to comments on their Facebook Pages and Instagram Business accounts from a centralized dashboard."

---

## Webhook Configuration

Webhooks allow real-time notifications for new comments.

### Step 1: Create Webhook Endpoint

Your application needs an endpoint to receive webhook events:

```
POST /social/webhooks/meta/
```

### Step 2: Configure Webhook in Meta Portal

1. Go to **"Webhooks"** in your app dashboard
2. Click **"Add Subscription"**
3. Enter your callback URL:
   ```
   https://yourdomain.com/social/webhooks/meta/
   ```
4. Enter your verify token (from `META_WEBHOOK_VERIFY_TOKEN`)
5. Click **"Verify and Save"**

### Step 3: Subscribe to Events

1. After verification, select subscriptions:
   - **Page Events:** `feed`, `comments`
   - **Instagram Events:** `comments`, `mentions`

### Step 4: Subscribe Individual Pages

For each Page, subscribe to webhook events:

```python
# Done automatically during account connection
from apps.social.services.meta import MetaService

MetaService.subscribe_webhook(page_id, page_access_token)
```

### Webhook Verification Handler

```python
def verify_webhook(request):
    mode = request.GET.get('hub.mode')
    challenge = request.GET.get('hub.challenge')
    verify_token = request.GET.get('hub.verify_token')
    
    if mode == 'subscribe' and verify_token == settings.META_WEBHOOK_VERIFY_TOKEN:
        return HttpResponse(challenge, status=200)
    return HttpResponse(status=403)
```

---

## Development vs Production

### Development Setup

| Setting | Value |
|---------|-------|
| `META_REDIRECT_URI` | `http://127.0.0.1:8000/social/callback/META/` |
| Protocol | HTTP allowed for localhost |
| App Mode | Development |
| App Review | Not required for testing |
| Test Users | Add yourself and team members |

### Production Setup

| Setting | Value |
|---------|-------|
| `META_REDIRECT_URI` | `https://yourdomain.com/social/callback/META/` |
| Protocol | **HTTPS required** |
| App Mode | Live |
| App Review | Required for sensitive permissions |
| Rate Limits | Higher limits for approved apps |

### Using ngrok for Local Webhooks

```bash
# Install ngrok
npm install -g ngrok

# Create tunnel
ngrok http 8000

# Use ngrok URL for webhook
# Example: https://abc123.ngrok.io/social/webhooks/meta/
```

---

## Troubleshooting

### Common Error: "Error Validating Verification Code"

**Cause:** Redirect URI mismatch.

**Solution:**
1. Check exact URL in Facebook Login → Settings → Valid OAuth Redirect URIs
2. Ensure trailing slashes match
3. Verify protocol (http vs https)

---

### Common Error: "Permission Error (Code 200)"

**Cause:** Missing permissions or user doesn't have page access.

**Solution:**
1. Verify all required scopes are requested
2. Ensure user has Page Admin role
3. Check if permission needs App Review approval

---

### Common Error: "Invalid OAuth Access Token (Code 190)"

**Cause:** Token expired or invalid.

**Solution:**
1. Page tokens should be permanent, but user tokens expire
2. User may need to re-authenticate
3. Check if app is in Development mode and user is a test user

---

### Common Error: "Unsupported Post Request (Code 100)"

**Cause:** Trying to reply to a reply on Instagram (nested replies not supported).

**Solution:**
- Instagram only supports 1 level of comment nesting
- You can reply to a top-level comment, but cannot reply to a reply
- The application handles this gracefully

---

### Common Error: "Non-Existent Field 'name' (Instagram)"

**Cause:** Instagram comments use `username`, not `name` for author.

**Solution:**
- The application dynamically selects fields based on platform
- This is handled automatically in the code

---

### Common Error: "Rate Limit (Code 4, 17, 32)"

**Cause:** Too many API requests.

**Solution:**
- Application implements automatic retry with delay
- Wait for rate limit to reset (usually 1 hour)
- Reduce polling frequency

---

### Common Error: "Page Not Found (Code 404)"

**Cause:** Page doesn't exist or user doesn't have access.

**Solution:**
1. Verify page exists and is published
2. Ensure user has Page Admin/Editor role
3. Check page ID is correct

---

## API Rate Limits

| Resource | Rate Limit |
|----------|------------|
| Graph API Calls | 200 calls/hour per user per app |
| Page-level Calls | Higher limits for page tokens |
| Webhook Events | Unlimited |

The application implements rate limiting to stay within bounds.

---

## Facebook vs Instagram ID Detection

The application automatically detects platform based on ID format:

```python
# Instagram IDs typically start with 17 or 18
if str(comment_id).startswith('17') and str(comment_id).isdigit():
    platform = 'IG'
elif '_' in str(comment_id):
    platform = 'FB'  # Facebook IDs often contain underscore
```

---

## Page Access Token Lifecycle

| Token Type | Lifetime | Notes |
|------------|----------|-------|
| User Access Token | ~60 days | Short-lived, can be exchanged |
| Page Access Token | **Permanent** | Doesn't expire if app remains active |
| Instagram Token | Same as Page | Uses Page token for access |

> ✅ **Good News:** Page tokens are permanent. Once a user connects their account, the integration continues working indefinitely.

---

## Verification

After setup, verify the integration:

### For Facebook:
1. Navigate to `/social/` in your application
2. Click "Connect Facebook/Instagram"
3. Authorize with Facebook
4. Select your Facebook Page
5. Verify posts are fetched
6. Test replying to a comment

### For Instagram:
1. After connecting Facebook, Instagram accounts are auto-discovered
2. Verify Instagram Business account appears in account list
3. Check if Instagram media is fetched
4. Test replying to an Instagram comment

### Testing in Django Shell

```python
from apps.social.services.meta import MetaService
from apps.social.models import SocialAccount

# Test Facebook
fb_account = SocialAccount.objects.filter(platform='FB').first()
posts = MetaService.fetch_posts(fb_account.platform_id, fb_account.access_token, 'FB')
print(f"Found {len(posts)} FB posts")

# Test Instagram
ig_account = SocialAccount.objects.filter(platform='IG').first()
if ig_account:
    media = MetaService.fetch_posts(ig_account.platform_id, ig_account.access_token, 'IG')
    print(f"Found {len(media)} IG media posts")
```

---

## Support Resources

- [Meta Graph API Documentation](https://developers.facebook.com/docs/graph-api/)
- [Facebook Login Guide](https://developers.facebook.com/docs/facebook-login/)
- [Instagram Graph API](https://developers.facebook.com/docs/instagram-api/)
- [Webhooks Documentation](https://developers.facebook.com/docs/graph-api/webhooks/)
- [Meta Bug Tracker](https://developers.facebook.com/support/bugs/)

---

*Last Updated: February 2026*
*API Version: Meta Graph API v24.0*