Files
datahop/runner/instagram.go
2021-11-29 21:25:59 -06:00

160 lines
4.1 KiB
Go

package runner
import (
_ "embed"
"encoding/json"
"fmt"
"time"
"github.com/go-rod/rod"
)
type InstaRes struct {
Followers int `json:"followers"`
Urls []string `json:"urls"`
Engagement int `json:"engagement"`
Posts []InstaPost `json:"posts"`
}
type InstaPost struct {
Engagement int `json:"engagement"`
Body string `json:"body"`
Timestamp time.Time `json:"timestamp"`
Comments int `json:"comments"`
Likes int `json:"likes"`
Views int `json:"views"`
URL string `json:"url"`
Type string `json:"type"`
}
//go:embed js/instagram_followers_urls.js
var instagram_followers_urls string
//go:embed js/instagram_post_data.js
var instagram_post_data string
//go:embed js/instagram_liked_by_url.js
var instagram_liked_by_url string
//go:embed js/instagram_liked_by.js
var instagram_liked_by string
const insta_login_url = "https://www.instagram.com/accounts/login/"
func (r *Runner) CheckInstaGram() {
r.page.MustNavigate(insta_login_url)
r.page.WaitLoad()
location := r.page.MustEval("window.location.href").Str()
if location == insta_login_url {
r.page.MustElement(`input[name="username"]`).Input(r.InstaUser)
time.Sleep(time.Millisecond * 113)
r.page.MustElement(`input[name="password"]`).Input(r.InstaPass)
time.Sleep(time.Millisecond * 72)
r.page.MustElementsByJS(`document.querySelectorAll("button")`).Last().MustClick()
time.Sleep(time.Millisecond * 5000)
}
}
func (r *Runner) InstaPageNavigate(index int) {
r.page.MustNavigate(r.Targets[index].Instagram)
r.page.MustWaitLoad()
r.Scroll(3, 250)
}
func (r *Runner) InstaGetRes() InstaRes {
r.page.MustEval(instagram_followers_urls)
data := r.page.MustEval("data").JSON("", "")
var res InstaRes
err := json.Unmarshal([]byte(data), &res)
checkErr(err)
return res
}
func (r *Runner) calcInstaPostData(posts []InstaPost) (int, int) {
total_engagement := 0
total_posts := 0
for _, elm := range posts {
if elm.Timestamp.After(r.weekago) {
total_engagement += elm.Engagement
total_posts += 1
}
}
return total_engagement, total_posts
}
func (r *Runner) GetInstaDataByIndex(index int) Result {
r.InstaPageNavigate(index)
res := r.InstaGetRes()
posts := r.GetIntsaEgagement(res.Urls)
total_engagement, total_posts := r.calcInstaPostData(posts)
r.logger.LogInstaRes(posts, r.Targets[index].Name)
result := Result{r.Targets[index].Name, "Instagram", res.Followers, total_engagement, total_posts}
r.logger.LogResult(result, "Insta")
return result
}
func (r *Runner) GetInstaData() []Result {
var results []Result
for i := range r.Targets {
fmt.Println("Processing " + r.Targets[i].Name + "'s Instagram")
results = append(results, r.GetInstaDataByIndex(i))
}
return results
}
func (r *Runner) GetIntsaEgagement(urls []string) []InstaPost {
var posts []InstaPost
for _, url := range urls {
fmt.Print("https://www.instagram.com" + url + " ---> ")
r.page.MustNavigate("https://www.instagram.com" + url)
r.page.MustWaitLoad()
r.Scroll(10, 250)
data := r.page.MustEval(instagram_post_data).JSON("", "")
var res InstaPost
err := json.Unmarshal([]byte(data), &res)
checkErr(err)
if res.Timestamp.Before(r.weekago) {
fmt.Println("Reached post outside range ", res.Timestamp)
return posts
}
res.URL = "https://www.instagram.com" + url
if res.Timestamp.Before(r.currentTime) {
//Hard get the likes
if res.Likes == 0 && res.Views == 0 {
element, err := r.page.ElementByJS(&rod.EvalOptions{JS: instagram_liked_by_url})
if err != nil {
fmt.Println("Edge Case Where Likes and Comments are Zero")
} else {
element.MustClick()
r.page.MustWaitLoad()
r.Scroll(99999, longTimeOut)
likes := r.page.MustEval(instagram_liked_by).Int()
res.Likes = likes
}
}
if res.Views != 0 {
res.Type = "Video"
//res.Engagement = res.Views + res.Comments
res.Engagement = 0
} else {
res.Type = "Image"
res.Engagement = res.Likes + res.Comments
}
fmt.Println("Likes :", res.Likes, ", Comments: ", res.Comments)
posts = append(posts, res)
} else {
fmt.Println("Posted Today ", res.Timestamp)
}
}
return posts
}