Appearance
Log in
A fresh install shows the login screen and nothing else: you log in from it with logIn({ username, password }), the way a person types them. The call does the whole job. It continues the same process through the app's launch and answers the next screen, so the program never runs the pre-login steps by hand. This page covers the password login, an account protected by two-factor authentication, and the accounts that use SMS or WhatsApp codes. For a program that also saves the session and uses the feed, read Your first program and A complete session.
Log in with a password
AndroidIgpapi.install starts a fresh install and hands main the login screen. logIn answers the feed for an ordinary account. The checkpoint of that feed is the session: save it (Keep a session) and a later program launches straight into the feed.
ts
import { AndroidIgpapi, FeedTimelineScreen } from '@igpapi/android';
import { Effect } from 'effect';
const username = process.env['IG_USERNAME'] ?? '';
const password = process.env['IG_PASSWORD'] ?? '';
// One call is one process: the login, and the checkpoint of the feed it reaches.
const checkpoint = await AndroidIgpapi.install({
seed: username,
main: home =>
Effect.gen(function* () {
const next = yield* home.logIn({ username, password });
// The two-factor and recovery answers come before the process holds a session.
if (!FeedTimelineScreen.is(next)) return undefined;
return yield* next.checkpoint(); // ScreenCheckpoint<'FeedTimeline'>
}),
});
if (checkpoint !== undefined) {
// The checkpoint's screen picks the launch's screen: the feed.
const entries = await AndroidIgpapi.launch({
checkpoint,
main: feed => Effect.succeed(FeedTimelineScreen.is(feed) ? feed.items.length : 0),
});
console.log(entries);
}A login that Instagram refuses is a typed failure of logIn (a wrong password is IgLoginBadPasswordError, a rejected login is LoginBloksRejectedError). Answer it with catchTag, as the complete session does (Errors).
Log in to an account with two-factor authentication
A fresh install's logIn answers only the screens its path reaches: the feed, LoginTwoFactorApproveFromAnotherDeviceScreen (the login waits for an approval on another device), LoginTwoFactorChooseMethodScreen (the picker of the ways to confirm), or AccountRecoveryEmailCodeScreen (the last-resort recovery code screen). Narrow the answer with the screen's own XxxScreen.is(screen).
A headless program computes the authenticator code itself: totpCodeOf(secret) takes the account's authenticator setup key and returns the six-digit code of this moment. The code rotates every 30 seconds, so compute it at the submit, never once at start-up.
What is the authenticator setup key and where do I get it
It is the base32 key Instagram shows when an authenticator app is set up on the account: "Can't scan the QR code? Copy this key", a string such as JBSWY3DPEHPK3PXP. It is not the six-digit code; the code is computed from it.
- For an account you control, Turn on the authenticator app makes the program its own authenticator: it generates a new key, enables the app with it, and you store the key.
- For an account whose authenticator app is already set up, you need the key from the day it was set up.
- The account's owner must keep a copy: the key is the second factor, so losing it locks the owner out of the account's authenticator method.
- Keep the key where the program can read it at run time, apart from the password unless the program is the account's only user (Account safety and pacing).
The program below handles each answer of a protected account. It reads the key from IG_TOTP_SECRET.
ts
import {
AndroidIgpapi,
FeedTimelineScreen,
LoginTwoFactorApproveFromAnotherDeviceScreen,
LoginTwoFactorChooseMethodScreen,
totpCodeOf,
} from '@igpapi/android';
import { Effect } from 'effect';
const username = process.env['IG_USERNAME'] ?? '';
const password = process.env['IG_PASSWORD'] ?? '';
// The account's authenticator setup key, from your secret store.
const totpSecret = process.env['IG_TOTP_SECRET'] ?? '';
/** How many approval polls a headless program waits for an approval on another device. */
const APPROVAL_POLLS = 8;
const outcome = await AndroidIgpapi.install({
seed: username,
main: home =>
Effect.gen(function* () {
const next = yield* home.logIn({ username, password });
// The login continues the process itself: the feed, the approval screen, the method picker
// (when the server's default is another method), or the last-resort recovery code screen.
if (LoginTwoFactorApproveFromAnotherDeviceScreen.is(next)) {
// The caller owns the pace; a headless program bounds the wait instead of polling forever.
let check = yield* next.checkApproval();
for (let poll = 0; check.status === 'still-waiting' && poll < APPROVAL_POLLS; poll += 1) {
yield* Effect.sleep('7500 millis'); // the app polls about every 7.5 s
check = yield* next.checkApproval();
}
// Past the bound nobody approved: the outcome says so, and the caller decides.
if (check.status === 'still-waiting') return { _tag: 'NotApproved' as const };
// The launch leaves the feed or its splash on top; only the feed has entries.
return { _tag: 'LoggedIn' as const, entries: FeedTimelineScreen.is(check) ? check.items.length : 0 };
}
if (LoginTwoFactorChooseMethodScreen.is(next)) {
// The server's default is another method: choose the authenticator app.
const codeScreen = yield* next.chooseAuthenticationApp();
// `submitCode` sends the code and continues the process into the launch; its result is the feed.
const done = yield* codeScreen.submitCode(totpCodeOf(totpSecret));
return { _tag: 'LoggedIn' as const, entries: done.items.length };
}
if (!FeedTimelineScreen.is(next)) return { _tag: 'RecoveryRequired' as const };
return { _tag: 'LoggedIn' as const, entries: next.items.length };
}),
});
console.log(outcome);Each two-factor screen, its actions and its errors are on the two-factor page.
Accounts that use SMS or WhatsApp codes
The two-factor screens act on the authenticator app and on an approval on another device. LoginTwoFactorChooseMethodScreen.data.offeredMethods shows the other methods the account has, but SMS and WhatsApp codes have no action on these screens. Use one of these:
- Turn on the authenticator app for the account (Turn on the authenticator app) and log in as above.
- Finish the login with the effects of the app layer: Two-factor without the screens (SMS, WhatsApp).