Skip to content

Instagram Alerts

Jerad Berhow edited this page Oct 10, 2026 · 3 revisions

Instagram Alerts

PariahBot shares every new Instagram post and reel from the accounts a server follows, in a dedicated channel of its own (separate from the Streamer-Alerts channel), optionally pinging a role.

Setup has two halves: credentials on the bot's host (once per bot, and the long part), then configuration in each Discord server (a minute).


How it works, and what that means for you

Instagram has no free public feed like YouTube's RSS, so the bot uses Meta's official Instagram Graph API, through a feature called Business Discovery:

  • The host connects one Instagram account of their own: a Business or Creator account, linked to a Facebook Page.
  • Through that account, the bot can read the recent posts of any public Business or Creator account, by username. Followed accounts don't need to do anything or know about the bot.
  • It checks each followed account every 10 minutes, with one API call per account, shared across every server that follows it.

What it can't follow:

  • Personal accounts, even public ones. Their owner can switch to a Creator or Business account for free in Instagram (Settings → Account type and tools).
  • Private and age-gated accounts.
  • Stories. Only feed posts and reels.

Part 1: credentials on the host

You end up with two values for hom.env:

Variable What it is
INSTAGRAM_ACCESS_TOKEN A System User access token from your Meta business portfolio. It never expires and never needs renewing.
INSTAGRAM_BUSINESS_ACCOUNT_ID The Instagram user ID of your own professional account, the one lookups run through. Not the Facebook Page ID.

It takes about 20 minutes the first time. Every step below exists because something failed without it, so don't skip any.

Why a System User token? Meta also hands out Page tokens tied to your personal Facebook login. Those never expire either, but their data access lapses after 90 days, and renewing it needs you to re-approve the app in a browser, which no script can do. A System User belongs to your business portfolio rather than to a person, so neither limit applies.

1. Prepare your Instagram account and Facebook Page

  1. Make your Instagram account professional. In the Instagram app: Settings → Account type and tools → Switch to professional account. Creator or Business both work.

  2. Link it to a Facebook Page you manage. Create a Page if you have none; it can be bare. Link it from the Page side, in any one of:

    • Instagram app: Edit profile → Page → Connect existing Page
    • Facebook: switch into the Page → Settings → Linked accounts → Instagram → Connect account
    • Meta Business Suite: Settings → Instagram accounts → Connect

    Linking the two in Meta's Accounts Center alone is not enough. The API only sees an Instagram account that's connected to the Page itself.

  3. Make sure you have a business portfolio at business.facebook.com/settings, containing the Page (Accounts → Pages) and the Instagram account (Accounts → Instagram accounts). Create one if you don't have one.

2. Create the Meta app

  1. Register as a developer at developers.facebook.com with the Facebook account that manages the Page.

  2. My Apps → Create app. Give it a name, e.g. PariahBot.

  3. Use case: choose Manage messaging & content on Instagram. If you're offered Other instead, choose it, then app type Business.

  4. Business: connect it to your business portfolio.

  5. In the app dashboard, open Use cases → Customize (on the Instagram use case) → API setup with Facebook login, or the Permissions list. Add each of these:

    • instagram_basic
    • instagram_manage_insights
    • pages_show_list
    • pages_read_engagement
    • business_management

    A permission that isn't added here won't appear anywhere later, including when generating the token. If one is missing from a list further on, come back here.

  6. Leave the app in Development mode. It works there for this, with no App Review, because the token belongs to your own business.

3. Create the System User and its token

  1. Add the app to the portfolio, if step 2 didn't: in Business Settings, Accounts → Apps → Add → Connect an app ID, and enter the app's App ID (from App settings → Basic in the app dashboard). A System User can't be created until the portfolio has an app.

  2. Users → System users → Add. Name it e.g. pariahbot, role Admin.

  3. With the System User selected, choose Assign assets and add all three, with full control:

    • Apps: your app
    • Pages: your Page
    • Instagram accounts: your Instagram account
  4. Choose Generate new token:

    • App: your app
    • Token expiration: Never
    • Permissions: the five from step 2

    Copy the token now. Meta won't show it again.

Assign the assets before generating the token. A token only covers what was assigned when it was made. If you assign something later, generate a new token.

4. Find your Instagram account ID

In a terminal, with your token:

TOKEN='your-system-user-token'
API='https://graph.facebook.com/v25.0'

curl -s "$API/me/accounts?fields=name,id,instagram_business_account&access_token=$TOKEN"

Find your Page in the output. Its instagram_business_account.id is your INSTAGRAM_BUSINESS_ACCOUNT_ID. The Page's own id is not it.

If instagram_business_account is missing, the Instagram account isn't linked to the Page from the Page side (step 1.2), or it isn't a professional account.

5. Check the token works

IG_ID='your-instagram-business-account-id'

# Expect "expires_at": 0 and "data_access_expires_at": 0
curl -s "$API/debug_token?input_token=$TOKEN&access_token=$TOKEN"

# Expect your own username
curl -s "$API/$IG_ID?fields=username&access_token=$TOKEN"

# Expect {"business_discovery":{"username":"nasa",...}} — proves other accounts can be read
curl -s "$API/$IG_ID?fields=business_discovery.username(nasa){username,media_count}&access_token=$TOKEN"
The same checks in PowerShell
$token = 'your-system-user-token'
$igId  = 'your-instagram-business-account-id'
$api   = 'https://graph.facebook.com/v25.0'

(Invoke-RestMethod "$api/debug_token?input_token=$token&access_token=$token").data |
	Select-Object is_valid, expires_at, data_access_expires_at, type | Format-List
Invoke-RestMethod "$api/$igId`?fields=username&access_token=$token" | ConvertTo-Json
Invoke-RestMethod "$api/$igId`?fields=business_discovery.username(nasa){username,media_count}&access_token=$token" | ConvertTo-Json

Pipe each result through ConvertTo-Json, as above. Otherwise PowerShell prints later results in the first one's table, and they show up as blank lines.

Result Meaning
expires_at and data_access_expires_at are both 0 The token never needs renewing
(#10) Application does not have permission for this action A permission is missing from the app (step 2.5) or the token (step 3.4), or the Page and Instagram account aren't assigned to the System User (step 3.3). Fix it and generate a new token
(#100) Unsupported get request IG_ID is empty or wrong. It must be the instagram_business_account.id, not the Page ID

The token's per-permission target lists (granular_scopes) being empty is normal for a System User: its access comes from the assigned assets instead.

6. Add them to hom.env and restart

INSTAGRAM_ACCESS_TOKEN=your-system-user-token
INSTAGRAM_BUSINESS_ACCOUNT_ID=your-instagram-business-account-id
sudo systemctl restart pariahbot.service
sudo journalctl -u pariahbot.service -n 30

When it's working, the startup log has no InstagramAlerts: … not set — Instagram alerts are disabled. line.

The token is a secret. Treat it like the bot token: keep it in hom.env only, and never paste it into an issue, PR, commit or chat. If it leaks, choose Revoke tokens on the System User, then generate a new one.


Part 2: set up a server

All of these are staff commands, for mods and admins. See Server Configuration.

1. Choose the channel

/instagram channel channel:#instagram ping_role:@Insta-Notify
  • ping_role is optional, and is the only thing a post ever pings. Mentions inside captions never ping anyone.
  • The bot checks up front that it can View Channel, Send Messages and Embed Links there, and refuses with the fix if not.
  • If the ping role isn't mentionable, the reply warns you. Turn on Allow anyone to @mention this role, or give the bot Mention Everyone.

Custom message (optional)

By default an alert's text is just the ping role. Set your own message, and the role is still pinged:

/instagram message text:New from {name}! {title} {role}

Which posts as:

New from @someaccount! Behind the scenes from today @Insta-Notify

Placeholder Becomes
{name} The account, as @username
{title} The first line of the caption, up to 200 characters
{url} The link
{platform} Instagram
{role} The ping role's mention
  • Where the ping goes: where you put {role}. Without it, the ping goes at the start. With no ping role set, the message posts without a ping.
  • Only the ping role ever notifies anyone. @everyone, @here or other mentions in your message show as text but don't ping.
  • A misspelt placeholder like {titel} is refused, with the list of valid ones.
  • The reply shows a preview with sample values, so you can check it.
  • /instagram clear-message goes back to just the ping. /instagram list shows the current message. /instagram disable keeps it.
  • Up to 1,000 characters.

2. Follow accounts

/instagram add account:nasa
/instagram add account:https://www.instagram.com/natgeo/

account accepts a username, @username or instagram.com/<username> link. A link to a post or reel won't work. The bot looks the account up straight away, so a typo, or a personal account, fails immediately with an explanation.

3. Check it

/instagram list

This shows the channel, the ping role, whether Instagram is set up on the host, and every followed account with the date it was added.


What gets announced

What Feed posts (photos, videos, carousels) and reels
When Within about 10 minutes of being posted
Looks like The account's name and picture, the caption (cut to 500 characters), the image or video cover, and a View on Instagram button

Each post is announced once, even across restarts. If several posts arrive between checks, they post in order, oldest first.

Never announced:

  • Anything posted before the account was added. Adding an account doesn't flood the channel with its history.
  • Posts more than 7 days old, for example after the bot has been offline for a while.
  • Stories.

Managing the list

Command Effect
/instagram remove account:<pick> Stop following an account. Start typing and pick from the suggestions, or type the username.
/instagram disable Stop posting in this server. The list is kept, and /instagram channel turns it back on.

Limits

  • API calls: one per followed account every 10 minutes, across the whole bot, so 6 an hour per account. If Meta's rate limit is ever hit, the log says so, and posts from the last 7 days catch up once it resets.
  • No image on some videos. Instagram withholds the media for videos with licensed music, so those alerts post without an image.
  • A renamed account has to be re-added. Business Discovery only looks accounts up by username. If someone else takes over the old name, the bot notices the account ID doesn't match and logs it rather than posting a stranger's posts.
  • Graph API version. The bot uses v25.0. Meta retires a version about two years after release, and the code has to be updated before then.

Testing it

  1. Point /instagram channel at a private test channel with no ping role.
  2. Run /instagram add account:<your own account>.
  3. Post something on that account. It should appear within about 10 minutes.
  4. Restart the bot, and check it isn't posted a second time.

If nothing posts, see Troubleshooting.

Clone this wiki locally