-
Notifications
You must be signed in to change notification settings - Fork 58
07. Uploads
In goinsta, all uploads are done through a single method, the Instagram.Upload method provides access to all upload functionality. Currently, these uploads listed below are supported. If you are missing something please let me know. One limitation is that all images have to be jpeg, and all videos have to be mp4 formatted, as there is no format conversion build-in. If you want to do this programmatically, you can achieve this with ffmpeg.
- Photo Post
- Video Post
- Carousel/Album Post (supporting mixed photo & video uploads, up to 10 items)
- Story Photo
- Story Video
- Story Video Sequence
There are some additional optional attributes that can be used as upload setting.
// Option flags, set to true disable
MuteAudio bool
DisableComments bool
DisableLikeViewCount bool
DisableSubtitles boolThe upload method is pretty straightforward. It takes a single argument, an instance of UploadOptions, which specifies all settings used for the upload. The primary file ingestion is done through the File attribute, which takes any io.Reader interface, such as an HTTP response body, or a file descriptor. It can either be an image or a video, and depending on the file type the right upload will be performed automagically.
// Get Random Photo
resp, err := http.Get("https://picsum.photos/1400/1400")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
// Upload Photo
item, err := insta.Upload(
&goinsta.UploadOptions{
File: resp.Body,
Caption: "awesome! :) #41",
},
)User & Location Tags
In regular Instagram posts, you can tag users on arbitrary positions in the photo, and add a location tag. This functionality is supported through the Location and UserTags attributes of the upload options. The location takes a Location instance, and UserTags takes a []UserTag. The UserTag is comprised of a User instance, and an optional Position: [2]float64. The position coordinates need to be between 0.0 and 1.0, and determine the relative position. If they are not set, a random position will be used. For video posts, the position does not matter and will always be set to (0, 0), regardless. An extra check is added to make sure they are never exactly 0 or 1, as there is some margin. They need to be larger than ~0.012, and smaller than ~0.95. The tags do not work with story posts, that feature has not been implemented currently, as those tags are a little more elaborate. Tags will also be ignored in IGTV posts, as they have no tags.
// Get Random Photo
resp, err := http.Get("https://picsum.photos/1400/1400")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
// Get Location Instance
results, err := insta.Searchbar.SearchLocation("New York")
if err != nil {
t.Fatal(err)
}
if len(results.Places) == 0 {
t.Fatal(errors.New("No search result found"))
}
location := results.Places[0].Location
results.RegisterLocationClick(location)
// Upload Photo
item, err := insta.Upload(
&goinsta.UploadOptions{
File: resp.Body,
Caption: "awesome! :) #41",
Location: location.NewPostTag(),
UserTags: &[]goinsta.UserTag{
{
// Single user tag
User: &goinsta.User{
ID: insta.Account.ID,
Position: [2]float64{0.5, 0.5},
},
},
},
},
)Video posts are exactly the same as photo posts, except that the io.Reader interface you pass in should contain an mp4 video. Video posts also respect the location and user tag attributes, as described above.
...
item, err := insta.Upload(
&goinsta.UploadOptions{
File: videoFile,
Caption: "awesome! :) #41",
},
)Carousel posts do not user the File property, but the Album property of the upload options, which instead of a single io reader, is a slice; []io.Reader. Carousel posts also respect the location and user tag attributes, as described above. If you provide one user tag, it will be used for all posts. If you want to set the tags per post, an equal amount of user tags need to be provided, they can be left empty to not use any tags in a specific post.
// Get random photos
album := []io.Reader{}
for i := 0; i < 5; i++ {
resp, err := http.Get("https://picsum.photos/1400/1400")
if err != nil {
log.Fatal(err)
}
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
t.Fatal(err)
}
if err := resp.Body.Close(); err != nil {
t.Fatal(err)
}
// The bytes.Reader type can be very useful to provide an io.Reader interface
buf := bytes.NewReader(bodyBytes)
album = append(album, buf)
}
// Upload Album
item, err := insta.Upload(
&goinsta.UploadOptions{
Album: album,
Caption: "The best photos I've seen all morning!",
},
)To upload a story to a photo, the only difference between a regular post upload and a story photo upload, is a single attribute IsStory. The caption field will have no effect if set. If the dimensions do not match the story aspect ratio, the center will be cropped out automatically by Instagram. A good guideline is a width of 1080px, and a height of 1920px.
// Get Random Photo
resp, err := http.Get("https://picsum.photos/1400/1400")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
// Upload Photo
item, err := insta.Upload(
&goinsta.UploadOptions{
File: resp.Body,
IsStory: true,
},
)Video story uploads are the same as photo story uploads, except from the data contained in the io.Reader. Instagram stories are hard cut at 15 seconds, but goinsta is able to upload a maximum of 20-second videos, of which the last 5 seconds would then be cut off. Therefore you won't have to worry if your video is slightly longer than 15 seconds, as the end will automatically be cut off.
...
// Upload Video
item, err := insta.Upload(
&goinsta.UploadOptions{
File: videoFile,
IsStory: true,
},
)If you want to post a single video longer than 15 seconds, the Instagram app would automatically cut it up in 15-second intervals. While goinsta is unable to split a video, it is able to upload already splitter videos as a single sequence. While the result is exactly the same as multiple singular story video uploads, the requests do look slightly different.
...
// Upload Video Sequence
item, err := insta.Upload(
&goinsta.UploadOptions{
Album: []io.Reader{vid1, vid2, vid3, vid4, vid5},
IsStory: true,
},
)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.