Skip to content

How the Simulator works ​

The model behind the code, on one page. Read it once, and the other pages read as detail.

The model in one picture ​

text
your code ─► AndroidIgpapi.install / launch / resume…   one call
                  │
                  ▼
        one app process on a virtual phone  ──► Instagram
                  │
                  ▼
        main(screen)  ──► screen handles ──► actions ──► the next screen
                  ▲
        otherwise (challenges) ┘            checkpoint() ──► your storage

Your code is ordinary JavaScript around one call. The call starts the Instagram Android app on a virtual phone, runs your main on it, and ends. Inside main you do what a person does, one screen at a time. When Instagram interrupts with a challenge, your otherwise branches answer it. To keep the account for the next run, you take a checkpoint() and store it.

One call is one app process ​

AndroidIgpapi.install, launch and the resume… entries each start an app process, run your main on it, and close it when main ends, by returning, by failing or by being interrupted. The screen handles you hold belong to that process and die with it. Do not use one after main returned. Keep the data you need: return it from main; the call resolves with it.

The virtual phone and seed ​

The phone is a virtual Android device: its identifiers, its screen, its language and its build. seed is a string of yours, and the same string always gives the same phone. Use one stable string per account (its username is a good one): Instagram then sees the account on the same phone every time, as it would for a person. Without a seed the phone is random, so a new run looks like a new phone. Changing a phone and keeping the session is what Bring an account from another system is for.

Screens and handles ​

What a person sees is a screen. Your program holds a handle to it: handle.data is what the screen shows, and its methods are the actions a person can take there. An action that opens another screen returns that screen's handle, and you continue with it (Work with screens). Everything a person can do on each screen is on the screen pages.

What the Simulator sends for you ​

You do not call the launch, the requests a screen sends when it opens, the telemetry or the pauses between requests. The Simulator sends them the way the app does, in the app's order. That is why you start with a launch and not with a request, and why a screen action looks like one tap: The app process says what goes out and when.

Effect, briefly ​

The code uses Effect for two reasons: a step can fail in ways you want to name, and a program is a value you can compose. To start you need three things: Effect.gen(function* () { … }) with yield* in front of every step; Effect.catchTags to answer an error by its tag; Effect.sleep to wait. An error of the Simulator is a typed error whose tag is its class name, so you answer IgLoginBadPasswordError by writing its name (Errors). Outside main you get a plain Promise.

Two ways in ​

  • The entries (AndroidIgpapi) are the recommended way. They start the process, give main the first screen, answer challenges with otherwise, and close the process.
  • The app layer (AndroidApp) is for a program that needs a request the screens do not offer, or that runs several programs over one process. It has no screens and no otherwise. See Compose the app layer yourself.

Android and iOS ​

The Android package is the one with the screens and the guides. The iOS package is implemented less exhaustively; its page says what it offers.

The pages of this site are the README files of the repository. The API reference is generated from the source.