Integrating Instagram Graph API with AWS Lambda: Adding Social Media to Guest Photo Pages
What Was Done
We implemented Instagram Graph API integration into the shipcaptaincrew Lambda function (us-east-1, account 782785212866) to display @sailjada Instagram posts alongside guest-uploaded charter photos on the guest gallery page at shipcaptaincrew.queenofsandiego.com/g/{event_id}. The integration was dormant in the codebase but lacked proper token provisioning and Instagram app configuration. This walkthrough documents the complete setup process from app configuration through Lambda environment variable deployment.
Technical Details: Instagram Graph API Setup
Step 1: Product Configuration in Facebook App Dashboard
The critical first step that was blocking implementation: the app had a "Messaging" product added, which grants Direct Message scopes but not media read permissions. Instagram Graph API requires a separate product.
- Navigate to
developers.facebook.com/appsand select thesailjada-socialapp - Click Add Product in the left sidebar (near the bottom)
- Search for and select Instagram Graph API (distinct from Basic Display and Messaging products)
- Complete setup — this grants access to media endpoints and business account data
Why this matters: The Messaging product only grants instagram_manage_messages scope. Reading media requires instagram_basic and pages_show_list scopes, which are only available under the Instagram Graph API product.
Step 2: Instagram Account Connection
The @sailjada account must be a Business or Creator account linked to a Facebook Page, and explicitly connected in the app settings:
- In Instagram Graph API section of app dashboard, select API setup with Instagram login
- Click Add Instagram account
- Log in as @sailjada to authorize the connection
Step 3: Generate Short-Lived Access Token
Use the Graph API Explorer to generate an initial token with the required scopes:
- Visit
developers.facebook.com/tools/explorer - Select
sailjada-socialapp from the dropdown - Click Generate Access Token
- Select the Facebook Page linked to @sailjada
- In the scopes list, select:
instagram_basicandpages_show_list
This produces a short-lived token (typically 1 hour) used in the next step.
Step 4: Extract IG_USER_ID from Page Data
Use the short-lived token to query the Facebook Page and retrieve the linked Instagram Business Account ID:
curl -s "https://graph.facebook.com/v18.0/{PAGE_ID}?fields=instagram_business_account&access_token={SHORT_LIVED_TOKEN}" | jq .
The response contains instagram_business_account.id — this is your IG_USER_ID.
Step 5: Exchange for Long-Lived Token
The short-lived token is only valid for ~1 hour. Exchange it for a long-lived token (60 days) that can be stored in Lambda environment variables:
curl -s "https://graph.facebook.com/v18.0/oauth/access_token?grant_type=fb_exchange_token&client_id={APP_ID}&client_secret={APP_SECRET}&fb_exchange_token={SHORT_LIVED_TOKEN}" | jq .
The returned access_token is your IG_ACCESS_TOKEN.
Why exchange tokens: Short-lived tokens expire quickly; long-lived tokens allow Lambda to read Instagram data without requesting a new token on every invocation. The 60-day expiration requires a monthly refresh strategy (covered below).
Infrastructure: Lambda Configuration
Function Details
- Function name:
shipcaptaincrew - Region: us-east-1
- Account: 782785212866
- Runtime: Python 3.x (with
boto3andrequestslibraries) - Execution role: Standard Lambda service role with no special Instagram API permissions needed (API calls are made from Lambda code, not via AWS credentials)
Environment Variables to Deploy
Update Lambda configuration with the two values obtained above. Use the AWS CLI or console:
aws lambda update-function-configuration \
--function-name shipcaptaincrew \
--region us-east-1 \
--environment Variables='{IG_USER_ID=17841400000000000,IG_ACCESS_TOKEN=IGQWRfNDAwODAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD