-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathwebstory.go
150 lines (131 loc) · 4.07 KB
/
webstory.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package instago
import (
"encoding/json"
"errors"
"strings"
)
type WebStoryInfo struct {
User struct {
Id string `json:"id"`
ProfilePicUrl string `json:"profile_pic_url"`
Username string `json:"username"`
} `json:"user"`
Highlight struct {
Id int64 `json:"id"`
Title string `json:"title"`
} `json:"highlight"`
}
type WebStoryQueryResponse struct {
Data struct {
ReelsMedia []IGReelMedia `json:"reels_media"`
} `json:"data"`
Status string `json:"status"`
}
type WebFeedReelsTrayResponse struct {
Data struct {
User struct {
FeedReelsTray struct {
EdgeReelsTrayToReel struct {
Edges []struct {
Node IGReelMedia `json:"node"`
} `json:"edges"`
} `json:"edge_reels_tray_to_reel"`
} `json:"feed_reels_tray"`
} `json:"user"`
} `json:"data"`
Status string `json:"status"`
}
type IGReelMediaUser struct {
Typename string `json:"__typename"`
Id string `json:"id"`
ProfilePicUrl string `json:"profile_pic_url"`
Username string `json:"username"`
FollowedByViewer bool `json:"followed_by_viewer"`
RequestedByViewer bool `json:"requested_by_viewer"`
}
// IGReelMedia represent story info of a user. web version of type IGReelTray
// This struct is returned from web GraphQL query.
type IGReelMedia struct {
Typename string `json:"__typename"`
Id string `json:"id"`
LatestReelMedia int64 `json:"latest_reel_media"`
CanReply bool `json:"can_reply"`
Owner IGReelMediaUser `json:"owner"`
CanReshare bool `json:"can_reshare"`
ExpiringAt int64 `json:"expiring_at"`
HasBestiesMedia bool `json:"has_besties_media"`
HasPrideMedia bool `json:"has_pride_media"`
Seen int64 `json:"seen"`
User IGReelMediaUser `json:"user"`
Items []IGReelMediaItem `json:"items"`
}
func (m *IGApiManager) GetInfoFromWebStoryUrl(url string) (user WebStoryInfo, err error) {
if !IsWebStoryUrl(url) {
err = errors.New(url + " is not a valid web story url")
return
}
jsonurl := url + "?__a=1"
b, err := m.getHTTPResponse(jsonurl, "GET")
if err != nil {
return
}
err = json.Unmarshal(b, &user)
return
}
func (m *IGApiManager) GetIdFromWebStoryUrl(url string) (id string, err error) {
user, err := m.GetInfoFromWebStoryUrl(url)
id = user.User.Id
return
}
func (m *IGApiManager) GetWebGraphqlStoriesJson(reelIds []string, storyQueryHash string) (b []byte, err error) {
if len(reelIds) == 0 {
err = errors.New("no reel_ids is given")
return
}
url := `https://www.instagram.com/graphql/query/?query_hash={{QueryHash}}&variables={"reel_ids":[{{ReelIds}}],"tag_names":[],"location_ids":[],"highlight_reel_ids":[],"precomposed_overlay":false,"show_story_viewer_list":true,"story_viewer_fetch_count":50,"story_viewer_cursor":"","stories_video_dash_manifest":false}`
url = strings.Replace(url, "{{QueryHash}}", storyQueryHash, 1)
rids := ""
for _, reelId := range reelIds {
rids += `"` + reelId + `",`
}
rids = strings.TrimSuffix(rids, ",")
url = strings.Replace(url, "{{ReelIds}}", rids, 1)
b, err = m.getHTTPResponse(url, "GET")
return
}
func (m *IGApiManager) GetUserStoryByWebGraphql(id, storyQueryHash string) (rm IGReelMedia, err error) {
b, err := m.GetWebGraphqlStoriesJson([]string{id}, storyQueryHash)
if err != nil {
return
}
rsp := WebStoryQueryResponse{}
err = json.Unmarshal(b, &rsp)
if err != nil {
return
}
if rsp.Status != "ok" {
err = errors.New("response status is not ok")
return
}
if len(rsp.Data.ReelsMedia) != 1 {
err = errors.New("response reels_media length is not 1")
return
}
rm = rsp.Data.ReelsMedia[0]
return
}
func (m *IGApiManager) GetWebFeedReelsTray(url string) (rms []IGReelMedia, err error) {
b, err := m.getHTTPResponse(url, "GET")
if err != nil {
return
}
rsp := WebFeedReelsTrayResponse{}
err = json.Unmarshal(b, &rsp)
if err != nil {
return
}
for _, edge := range rsp.Data.User.FeedReelsTray.EdgeReelsTrayToReel.Edges {
rms = append(rms, edge.Node)
}
return
}