diff --git a/.planning/phases/03-reviewer-account/03-02-FACEBOOK-TOKEN-HANDOFF.md b/.planning/phases/03-reviewer-account/03-02-FACEBOOK-TOKEN-HANDOFF.md new file mode 100644 index 0000000..13bc4d4 --- /dev/null +++ b/.planning/phases/03-reviewer-account/03-02-FACEBOOK-TOKEN-HANDOFF.md @@ -0,0 +1,120 @@ +# Handoff: Generate + Deploy Long-Lived Facebook/Instagram Token + +**For:** Claude Cowork (browser session) +**Goal:** Replace the expired Facebook/Instagram env token in K8s with a long-lived Page token +**Blocker:** Claude.ai MCP Directory form #18 cannot be checked until Facebook + Instagram API calls return success + +--- + +## Current state + +- `https://hermes.squaremcp.com/api/facebook/page` returns: + > Error validating access token: Session has expired on Friday, 12-Jun-26 08:00:00 PDT +- `https://hermes.squaremcp.com/api/instagram/profile` returns the same error +- The env vars `FACEBOOK_DEFAULT_ACCESS_TOKEN` and `INSTAGRAM_DEFAULT_ACCESS_TOKEN` are set in `hermes-k8s.yaml` but the token is dead +- `INSTAGRAM_DEFAULT_BUSINESS_ACCOUNT_ID` is already correct: `17841422623735880` +- `FACEBOOK_DEFAULT_PAGE_ID` is already correct: `1152192567968569` + +--- + +## Step 1: Get a short-lived User Token + +1. Open [Facebook Developer Console → Graph API Explorer](https://developers.facebook.com/tools/explorer/) +2. Select app: `squaremcp` +3. Click **Generate Access Token** +4. Grant these permissions: + - `pages_show_list` + - `pages_read_engagement` + - `pages_manage_posts` + - `instagram_basic` + - `instagram_content_publish` +5. Copy the User Token (starts with `EAAY...`) + +--- + +## Step 2: Exchange for a long-lived User Token + +In Graph API Explorer, run: + +``` +GET /oauth/access_token + ?grant_type=fb_exchange_token + &client_id= + &client_secret= + &fb_exchange_token= +``` + +Copy the `access_token` from the response. This is the **long-lived User Token**. + +--- + +## Step 3: Get the long-lived Page Token + Instagram Business Account ID + +In Graph API Explorer, run with the long-lived User Token: + +``` +GET /me/accounts?fields=id,name,access_token,instagram_business_account{username,id} +``` + +From the response, copy: +- `data[0].access_token` for the page named **"Squaremcp"** → this is the new `FACEBOOK_DEFAULT_ACCESS_TOKEN` and `INSTAGRAM_DEFAULT_ACCESS_TOKEN` +- `data[0].instagram_business_account.id` → confirm it is `17841422623735880` + +--- + +## Step 4: Test the new token + +Run these in a terminal and confirm they return page/profile info, not an error: + +```bash +TOKEN="" +curl -s "https://graph.facebook.com/v22.0/1152192567968569?fields=id,name,category,about,fan_count,followers_count,link&access_token=$TOKEN" | python3 -m json.tool +curl -s "https://graph.facebook.com/v22.0/17841422623735880?fields=username,name,followers_count,follows_count,media_count&access_token=$TOKEN" | python3 -m json.tool +``` + +--- + +## Step 5: Deploy to K8s + +Paste the new token into the terminal and run: + +```bash +NEW_TOKEN="" +ssh -p 2222 garfield@23.120.207.35 "microk8s kubectl set env deployment/hermes-mcp -n fetcherpay \ + FACEBOOK_DEFAULT_ACCESS_TOKEN='$NEW_TOKEN' \ + INSTAGRAM_DEFAULT_ACCESS_TOKEN='$NEW_TOKEN' && \ + microk8s kubectl rollout restart deployment/hermes-mcp -n fetcherpay && \ + microk8s kubectl rollout status deployment/hermes-mcp -n fetcherpay" +``` + +If SSH is unavailable from the browser environment, give the token to kimi-cli instead. + +--- + +## Step 6: Verify through SquareMCP API + +```bash +API_KEY="fdb6fb01bb7f4c50a9ab329c7287b81c" + +echo "=== Facebook ===" +curl -s -H "x-api-key: $API_KEY" "https://hermes.squaremcp.com/api/facebook/page" | python3 -m json.tool + +echo "=== Instagram ===" +curl -s -H "x-api-key: $API_KEY" "https://hermes.squaremcp.com/api/instagram/profile" | python3 -m json.tool +``` + +Both must return actual data (not an error) before checking box #18 on the Claude.ai form. + +--- + +## Step 7: Update hermes-k8s.yaml + +If kimi-cli is handling deploy, also ask it to update `hermes-k8s.yaml` placeholders with the new token so the manifest stays in sync. + +--- + +## Notes + +- The Page token from a long-lived User token should not expire on a fixed schedule. +- If the token expires again, the root cause is using a short-lived User Token in Step 1. Make sure to do Step 2 exchange. +- Do not commit the token to git. It lives in `hermes-k8s.yaml` (which is `.gitignore`d) and in K8s env vars only.