Appearance
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 storageYour 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, givemainthe first screen, answer challenges withotherwise, 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 nootherwise. 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.