Skip to content

01. Getting Started

David Brouwer edited this page Jan 24, 2022 · 2 revisions

Getting Started

Goinsta provides a programmatic interface to communicate with the Instagram API the Android APK uses. As such, it provides access to various singular endpoints, yet also methods that will perform a sequence of calls, just like the app will do. The Instagram.VisitProfile(user) method, for example, will perform a search for a user, register the result, load in the profile information, feed posts, stories, and highlights, and subsequently return the result.

Disclaimer: This code is in no way affiliated with, authorized, maintained, sponsored, or endorsed by Instagram or any of its affiliates or subsidiaries. This is an independent and unofficial API. Use at your own risk. It is prohibited to use this API to spam users or the platform in any way.

Login

All of the Instagram interactions happen through the Instagram struct.

import "github.com/Davincible/goinsta"

func main() {  
  insta := goinsta.New("<username>", "<password>")

  ...
}

The Instagram.New method will generate all necessary unique identifiers, and instantiate all child structs. The various child structs contain the more specific methods.

// Timeline provides access to your timeline
Timeline *Timeline
// Discover provides access to the discover/explore page
Discover *Discover
// Profiles provides methods for interaction with other user's profiles
Profiles *Profiles
// IGTV allows you to fetch the IGTV Discover page
IGTV *IGTV
// Account stores all personal data of the user and his/her options.
Account *Account
// Collections represents your collections with saved posts
Collections *Collections
// Searchbar provides methods to access IG's search functionalities
Searchbar *Search
// Activity provides access to Instagram notifications
Activity *Activity
// Inbox provides to Instagram's message/chat system
Inbox *Inbox
// Feed provides access to secondary feeds such as user's and hashtag's feeds
Feed *Feed
// Contacts provides address book sync/unsync methods
Contacts *Contacts
// Locations provide feed by location ID. To find location feeds by name use Searchbar
Locations *LocationInstance
// Challenge stores the challenge info if provided
Challenge *Challenge
// TwoFactorInfo enabled 2FA
TwoFactorInfo *TwoFactorInfo

With the Instagram instance created, valid authentication headers need to be fetched by logging in.

...

err := insta.Login()
if err != nil {
  ...
}

If you use 2FA, you will need to pass in the code:

...

err := insta.Login()
if err == goinsta.Err2FA {
  err2FA := insta.TwoFactorInfo.Login2FA(code)
  if err2FA != nil {
    ...
  }
} else if err != nil {
  ...
}

The Instagram.Login method will perform a sequence of calls imitating an app login. It will automatically fetch the first few posts on your timeline, stories, and discover page. After calling insta.Login(), you can access the first timeline posts by calling insta.Timeline

...

// All currently fetched timeline posts
posts := insta.Timeline.Items

// Slice of all currently fetched story groups (a group represents one user, one user can have multiple story items)
stories := insta.Timeline.Tray.Stories

// Like the first post
posts[0].Like()

// Select the first user in the tray, and reply to their first story
stories[0].Items[0].Reply("Happy Birthday!")

State Management

Instagram uses various extra headers, acting as cookies. Once you have obtained these headers through logging in, you can call the various API endpoints. Therefore it is important to write these values to disk at the end of every run so you don't have to log in every time you run a program (you also don't re-login in the app every day, you login once and you just use it). Goinsta provides various helper methods to make it easy to export the configuration.

As the header cookies change often, it is best practice to export the config at the end of every run. While it will likely still work if you don't, you would start off every run with the same old cookies.

...

// Export config as json to filepath
// Defer is used to export the config at every run
defer insta.Export(filepath)

// Export as json to an io.Writer interface
buf := new(bytes.Buffer)
err := insta.ExportIO(buf)

// Export as json to byte slice
buf, err := insta.ExportAsBytes()

// Export as base64 encoded json string
encoded, err := insta.ExportAsBase64String()

To subsequently import the config back into goinsta, you can use the Import counterpart of the method you used to export. E.g.:

insta, err := goinsta.Import(filepath)

By default, on every import goinsta will make one API call, fetch the user account info. This is useful if your account state changes in between runs (change of bio, name, profile pic etc.). If you want to import without making any API calls that is possible by passing true to any import function, this will set the dontSync flag to true, and use the account values stored in the config. This works best if you only plan on using an account with goinsta, and not manually, as then these values might change in between runs.

// Append true to skip initial sync
insta, err := goinsta.Import(filepath, true)

The Instagram.Login method will call the Instagram.OpenApp method to perform a post-login sequence, such as fetching the timeline posts, and unread DM's etc. The import method will not do this. After calling any import method, no media will be stored in the instance. It can be useful to manually call Instagram.OpenApp once a day or so, as it will also refresh some cookies. On the runs where you do not call the OpenApp() method, you will manually have to call the appropriate methods to fetch the media you need.

...

err := insta.OpenApp()
Clone this wiki locally