-
Notifications
You must be signed in to change notification settings - Fork 60
02. Timeline, Media & Pagination
Interactions with your timeline happen through the Timeline type, of which an instance can be accessed through insta.Timeline. The Timeline type represents the entire left tab in the Instagram app, and includes all posts and the tray at the top of the screen, which contains both stories and broadcasts (live streams).
...
tl := insta.Timeline
// Will only return non 0 if you called either insta.Login or insta.OpenApp
// Otherwise you will manually have to fetch posts, as detailed below
fmt.Printf("%d posts have been fetched already", len(tl.Items))The story circles at the top of your screen in the app are a collection of all story media items posted by that single user. This group is represented by the Reel struct in goinsta. To fetch the story groups, you can access them directly, or through the helper method:
// Direct access
stories := intsa.Timeline.Tray.Stories
// Helper method
stories := insta.Timeline.Stories()Likewise, if there are any broadcasts happening at the moment, they can be accessed directly or indirectly:
// Direct access of []Broadcast, with len == 0 if no one is currently live
live := insta.Timeline.Tray.Broadcasts
// Helper method
live := insta.Timeline.Broadcasts()While fetching more posts of the current feed will be discussed below in the pagination section, you can also check for new posts. In the app, this is called the pull_to_refresh (pulling up on the timeline), which will show you a new or updated timeline.
...
err := insta.Timeline.Refresh()By default, fetching more posts of any feed will append to the existing list of posts. The above method will clear the current list of posts, set the pull_to_fefresh flag, and fetch the first few items in the timeline. All of these can also be done manually if you for example wish to refresh without deleting the current items.
func (tl *Timeline) Refresh() error {
tl.ClearPosts()
tl.SetPullRefresh()
if !tl.Next() {
return tl.err
}
return nil
}As with most feeds or collections in goinsta, pagination happens through the Next() method. The return type is a bool, true means the request was successful, and false means that either all items have been fetched, or an error occurred during the request. If an error occurred, it can be retrieved using the Error() method. If the err returned is ErrNoMore, the resource has been exhausted.
for i:=0; tl.Next(); i++ {
if i == 5 {
break
}
fmt.Println("Fetched %d posts in last request", len(tl.NumResults))
}
if err := tl.Error(); err != nil && err != ErrNoMore {
...
}To fetch all items, you can leave out the index check. Be careful with this though, as if the resource you are paginating is practically never-ending you will get up making a massive amount of requests in a short amount of time, resulting in a temporary HTTP status 429 (too many requests), and risk your account getting flagged or even blocked. This can be useful if you want to fetch all user posts for example. It is also a good idea to implement a sleep timer in the loop, e.g. time.Sleep(3 * time.Second).
for tl.Next() {
fmt.Println("Fetched %d posts in last request", len(tl.NumResults))
}
if err := tl.Error(); err != nil && err != ErrNoMore {
...
}While the Timeline differs slightly from other post feeds, they use the same methods. If you get the feed from a user, it will be a FeedMedia instance, containing the following methods:
// Delete has not been implemented for all items,
// as you cannot delete all items.
func (media *FeedMedia) Delete() error
// Feed pagination will not return an error but a bool
// value. If it returns false, you can get the error with this method
func (media *FeedMedia) Error() error
// Used for pagination
func (media *FeedMedia) GetNextID() string
// FeedMedia.Items will always append new items to the existing
// list. Latest will return only the media fetched on the last call.
func (media *FeedMedia) Latest() []Item
// Next will paginate the resource if possible. Returns true if successful,
// and false if an error occurred, or if all media have been fetched.
func (media *FeedMedia) Next(params ...interface{}) bool
// If you want fine control over pagination, not needed for regular use
func (media *FeedMedia) SetID(id interface{})
// If you want to switch to a different user account
func (media *FeedMedia) SetInstagram(insta *Instagram)
// For some media items, only partial information will be fetched at first
// Sync() will fetch the rest if available. E.g. with highlights, it will only
// fetch the highlight groups, but not the media itself.
func (media *FeedMedia) Sync() error
// GetCommentInfo will fetch the item.CommentInfo; e.g. comment counts, and
// other comment information for the feed.Latest() items
func (media *FeedMedia) GetCommentInfo() errorAll media items, whether a timeline photo, video, story or IGTV, are all stored in the Item struct. This is aimed to a one size fits all solution as much as possible. As such, not all fields will be populated with every media item. You can check which fields are relevant for you by printing out the entire struct fmt.Printf("%+v\n", item), and reading through the struct.
The media struct also provides various methods that are useful for most media items.
// Double tap that post
err := post.Like()
// Undo that mistake
err := post.Unlike()
// Disclose your admiration
err := post.Comment("Absolutely fabulous!")
// Used for stories & highlights
err := post.Reply("So cute <3")
// Get rid of that shame
err := post.Delete()
// Collect all that thirst
// Returns a list of all hashtags used in a post caption
tags := post.Hashtags()
// Fetch list of fanboys
err := post.SyncLikers()
// Downloads will always be in the best possible quality
// Will not work for carousels, as they have multiple media items and this method only returns one byte slice.
// Use DownloadTo for a carousel, or iterate over the media items in a carousel manually.
mediaBytes, err := post.Download()
// Save it to a secret folder
// Folders can be created automagically
// If no file name is provided, one will be extracted from the media.
// File extension is not needed, and will be added automatically.
err := post.DownloadTo("/my/folder/")Other methods:
// Fetch the offensiveness score of a comment on a post.
// No need to call this manually, as item.Commen() will automatically call this
// before posting any comment
func (item *Item) CommentCheckOffensive(comment string) (*CommentOffensive, error)
// Convert the item.MediaType to a human readable string
func (item *Item) MediaToString() string
func (item *Item) PreviewComments() []Comment
func (item *Item) Save() error
func (item *Item) SaveTo(c *Collection) error
func (item *Item) StoryIsCloseFriends() bool
func (item *Item) SyncLikers() error
func (item *Item) TopLikers() []string
func (item *Item) Unsave() errorDisclaimer: 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.