Skip to main content

Instagram Graph API

Specs

https://docs.google.com/document/d/1hdt7MpnNAfQjzvLoYfooLiMxrt1QnSiWX6MR02HbfG4/edit

DB tables structure

There 3 tables

alt_text

With following structure

alt_text

Table “Instagram_installs” - stores tokens and corresponding instagram account data.

ColumnDescription
instagram_accountStores instagram account name string, e.g. “trees” for account https://www.instagram.com/trees/
instagram_business_account_idInsta account id connected to user selected FB page
first_verify_email_sent_atTracks the datetime of the first email which is sent when (currently) 10 days are left before token expiration. Note: this field is reset to when the user reconnects instagram account.
second_verify_email_sent_atTracks the datetime of the second which is sent when the token already expired. Note: this field is reset when the user reconnects instagram account.

Table “Instagram_apps” - Stores 1-to-Many connections between instagram tokens and apps. Multiple apps will use the same token if they connect to the same instagram account.

Table “Instagram_hashtags” - Acts as a lookup cache to obtain Instagram Graph API “hashtag_id” by hashtag name to preserve API limits.

alt_text

E.g. when user searches hashtag “food”, and there's no corresponding data in this table then API request is made to Graph API and the result “hashtag_id” is stored in table

alt_text

Obtaining token flow

Users connect instagram accounts by selecting the connected FB page.

alt_text

alt_text

alt_text

alt_text

alt_text

Then an XHR request is made to “instagram#oauth” to obtain a long term token. E.g. request https://www.powr.io/instagram/oauth?token=...&appId=28049484&user=3263780&app_type=socialFeed contains “token” which is short token (expiration ~2 hours) and which server exchanges with long token (expiration 90 days) using FB Graph API endpoint:

alt_text

If all scopes and connected FB page are correct, then “instagram#oauth” responses

alt_text

Then immediately client makes request to “instagram#index” to get instagram data, e.g.

https://www.powr.io/instagram?app_id=28049484&following=powr_io&page_name=powr_io&username_or_hashtag=@&instagram_username=powr_io&is_settings=true. Which returns data in following structure

alt_text

On client side the server response data is handled by

   getResultsFromPowrServer() function (/powr/app/javascript/helpers/socialfeed/instagram.js) 

Sending token refresh emails

If token is close to expire or already expired then emails are sent by “**codeinstagram_graph_api_refresh_tokenscode” rake task in “/powr/lib/tasks/scheduler.rake” file which is run (currently) once a day:

alt_text

alt_text

Action button in the email contains an oauth link of the form **"https://www.facebook.com/v9.0/dialog/oauth?client_id=#{client_id}&redirect_uri=#{redirect_uri}&scope=instagram_basic,pages_read_engagement"

Where “redirect_uri” is also handled by “instagram#oauth”, but instead of a short token, the code param is sent.

https://www.powr.io/users/oauth/?code=.....

Migration flow for apps that were created previously before Graph API integration

  • Migration is applied only for “social feed” and it’s aliases
  • Rollout “instagram_graph_api_migrate_apps” controls user accounts which will see migration flow
  • For apps that are 1) not new (i.e. app.backup_content present) and 2) were saved Graph API enabled, then attribute APP_MODEL.attributes.instagram_graph_api_migrated_at is set to “never”.
  • APP_MODEL.attributes.instagram_graph_api_migrated_at is used to determine if migration was already performed and whether to show upgrade banner.

alt_text

  • After the user Connects instagram account by clicking “Continue with Facebook”, then following items are migrated to Graph API mode 1) all hashtags 2) connected instagram username. Other instagram accounts are still served by non Graph API mode (i.e. from powr-outlet), because Graph API allows fetching data only of connected accounts. In this example only “#food” and “@powr_io” will be migrated.

alt_text

  • Also after successful migration the attributeAPP_MODEL.attributes.instagram_graph_api_migrated_at will be changed from “never” to the current date.
  • Not migrated instagram accounts still needs to load correctly, so its required to determine which instagram account should be served from “powr-outlet”, and which from Graph API. To determine this we store the not migrated instagram accounts in APP_MODEL.atreibutes.instagramNotMigratedFeeds array. (@natgeo, @apple, @trees in this case). And once a user Connects one of these accounts to Graph API, then this account is removed from APP_MODEL.atreibutes.instagramNotMigratedFeeds.