```html

Integrating Instagram Graph API with AWS Lambda: Adding Social Media Context to Guest Photo Galleries

What We Built

We extended the guest photo gallery system at shipcaptaincrew.queenofsandwich.com/g/{event_id} to surface Instagram posts from the @sailjada account alongside user-uploaded charter photos. The integration lives in a dormant Lambda function (shipcaptaincrew, us-east-1, account 782785212866) that fetches media from Instagram's Graph API when credentials are provisioned.

This post covers the multi-step process to activate that integration: configuring the Facebook Developer app, obtaining long-lived access tokens, and deploying credentials to the Lambda environment.

Technical Architecture

Why Instagram Graph API, not Basic Display?

  • Graph API provides richer metadata (timestamps, captions, engagement metrics) and supports business/creator accounts — essential for correlating posts to event dates.
  • Basic Display is read-only and returns only recent media without filtering capabilities.
  • Messaging API is for DMs only; it will not grant the instagram_basic scope needed to read media.

The architecture follows a three-tier pattern:

  • Token Generation Layer: Facebook Graph API Explorer generates short-lived tokens; an exchange flow converts them to 60-day long-lived tokens.
  • Credential Storage: Long-lived tokens are stored as Lambda environment variables (IG_USER_ID, IG_ACCESS_TOKEN).
  • Media Fetch Layer: Lambda function queries Instagram Graph API at request time, filters by date/time window, and merges results into the response.

Step-by-Step Implementation

1. Add the Correct Product to Your Facebook App

Navigate to developers.facebook.com/apps, select the app (in this case, sailjada-social), and add Instagram Graph API as a product:

  • Left sidebar → Add Product
  • Search for Instagram
  • Select Instagram Graph API (not Basic Display, not Messaging)
  • Complete setup; the product will appear in your sidebar

Why this matters: Adding the wrong product (like Messaging) grants the wrong OAuth scopes and blocks access to media endpoints.

2. Verify @sailjada Account Status

Before proceeding, confirm:

  • @sailjada is a Business or Creator account (not Personal)
  • The account is linked to a Facebook Page (required for Graph API access)

If @sailjada is currently a Personal account, convert it via Instagram Settings → Account Type.

3. Connect the Instagram Account in the App Dashboard

Inside your sailjada-social app, navigate to Instagram Graph API → API setup with Instagram login, then click Add Instagram account and authenticate as @sailjada. This creates the linkage between the Facebook App and the Instagram account.

4. Generate a Short-Lived Access Token

Use the Facebook Graph API Explorer to mint an initial token:

  • Navigate to developers.facebook.com/tools/explorer
  • Select app: sailjada-social
  • From the token dropdown, generate a new Access Token
  • Select the Facebook Page linked to @sailjada
  • Requested scopes: instagram_basic, pages_show_list

This token is valid for ~2 hours and is used only for the next step.

5. Retrieve IG_USER_ID

With the short-lived token, query your Facebook Page to extract the Instagram Business Account ID:

curl -G https://graph.instagram.com/v18.0/{PAGE_ID} \
  -d fields=instagram_business_account \
  -d access_token={SHORT_LIVED_TOKEN}

Extract the id field from the instagram_business_account object. This is your IG_USER_ID.

6. Exchange for a Long-Lived Token

Short-lived tokens expire in hours. Exchange it for a 60-day long-lived token using your App ID and App Secret:

curl -G https://graph.instagram.com/access_token \
  -d grant_type=ig_refresh_access_token \
  -d access_token={SHORT_LIVED_TOKEN} \
  -d client_secret={APP_SECRET}

The returned access_token is your IG_ACCESS_TOKEN. Store this securely.

7. Deploy Credentials to Lambda

Update the shipcaptaincrew Lambda function (us-east-1) with environment variables:

aws lambda update-function-configuration \
  --function-name shipcaptaincrew \
  --region us-east-1 \
  --environment Variables="{IG_USER_ID={extracted_user_id},IG_ACCESS_TOKEN={long_lived_token}}"

The function code already contains conditional logic to skip Instagram integration if these variables are absent; provisioning them activates the feature.

8. Refresh Strategy

Long-lived tokens expire after 60 days. Implement a monthly refresh:

  • Manual: Re-run the exchange curl command (step 6) every 55 days and redeploy to Lambda.
  • Automated: Create an EventBridge rule triggering a Lambda that refreshes the token and updates environment variables. This requires additional IAM permissions for lambda:UpdateFunctionConfiguration.

For simplicity, manual refresh is acceptable for low-traffic integrations; automate if you prefer hands-off rotation.

Lambda Function Logic

The existing shipcaptaincrew function checks for environment variables at invocation time:

if IG_USER_ID and IG_ACCESS_TOKEN are set:
  query Instagram Graph API with date/time filters
  merge results into photo gallery response
else:
  return empty array (no Instagram posts)

The integration queries the /ig_hashtag_search or /ig_user_id/media endpoint with a timestamp filter to match posts from the event date, then combines them with guest-uploaded photos in the final response.

Key Decisions

  • Environment Variables over Secrets Manager: For a dormant feature, environment variables are simpler. If the function scales to dozens of integrations, migrate to AWS Secrets Manager for centralized rotation.
  • 60-Day Token Lifespan: Facebook's Graph API enforces this ceiling for business accounts. Monthly refresh is a safe cadence.
  • Request-Time Fetching: Instagram