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 }