├── InstagramAPI.py
├── README.md
└── response_example.json
/InstagramAPI.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | import requests
4 | import random
5 | import json
6 | import hashlib
7 | import hmac
8 | import urllib
9 |
10 | class InstagramAPI:
11 | API_URL = 'https://i.instagram.com/api/v1/'
12 | USER_AGENT = 'Instagram 8.0.0 Android (18/4.3; 320dpi; 720x1280; Xiaomi; HM 1SW; armani; qcom; en_US)'
13 | IG_SIG_KEY = '9b3b9e55988c954e51477da115c58ae82dcae7ac01c735b4443a3c5923cb593a'
14 | EXPERIMENTS = 'ig_android_progressive_jpeg,ig_creation_growth_holdout,ig_android_report_and_hide,ig_android_new_browser,ig_android_enable_share_to_whatsapp,ig_android_direct_drawing_in_quick_cam_universe,ig_android_huawei_app_badging,ig_android_universe_video_production,ig_android_asus_app_badging,ig_android_direct_plus_button,ig_android_ads_heatmap_overlay_universe,ig_android_http_stack_experiment_2016,ig_android_infinite_scrolling,ig_fbns_blocked,ig_android_white_out_universe,ig_android_full_people_card_in_user_list,ig_android_post_auto_retry_v7_21,ig_fbns_push,ig_android_feed_pill,ig_android_profile_link_iab,ig_explore_v3_us_holdout,ig_android_histogram_reporter,ig_android_anrwatchdog,ig_android_search_client_matching,ig_android_high_res_upload_2,ig_android_new_browser_pre_kitkat,ig_android_2fac,ig_android_grid_video_icon,ig_android_white_camera_universe,ig_android_disable_chroma_subsampling,ig_android_share_spinner,ig_android_explore_people_feed_icon,ig_explore_v3_android_universe,ig_android_media_favorites,ig_android_nux_holdout,ig_android_search_null_state,ig_android_react_native_notification_setting,ig_android_ads_indicator_change_universe,ig_android_video_loading_behavior,ig_android_black_camera_tab,liger_instagram_android_univ,ig_explore_v3_internal,ig_android_direct_emoji_picker,ig_android_prefetch_explore_delay_time,ig_android_business_insights_qe,ig_android_direct_media_size,ig_android_enable_client_share,ig_android_promoted_posts,ig_android_app_badging_holdout,ig_android_ads_cta_universe,ig_android_mini_inbox_2,ig_android_feed_reshare_button_nux,ig_android_boomerang_feed_attribution,ig_android_fbinvite_qe,ig_fbns_shared,ig_android_direct_full_width_media,ig_android_hscroll_profile_chaining,ig_android_feed_unit_footer,ig_android_media_tighten_space,ig_android_private_follow_request,ig_android_inline_gallery_backoff_hours_universe,ig_android_direct_thread_ui_rewrite,ig_android_rendering_controls,ig_android_ads_full_width_cta_universe,ig_video_max_duration_qe_preuniverse,ig_android_prefetch_explore_expire_time,ig_timestamp_public_test,ig_android_profile,ig_android_dv2_consistent_http_realtime_response,ig_android_enable_share_to_messenger,ig_explore_v3,ig_ranking_following,ig_android_pending_request_search_bar,ig_android_feed_ufi_redesign,ig_android_video_pause_logging_fix,ig_android_default_folder_to_camera,ig_android_video_stitching_7_23,ig_android_profanity_filter,ig_android_business_profile_qe,ig_android_search,ig_android_boomerang_entry,ig_android_inline_gallery_universe,ig_android_ads_overlay_design_universe,ig_android_options_app_invite,ig_android_view_count_decouple_likes_universe,ig_android_periodic_analytics_upload_v2,ig_android_feed_unit_hscroll_auto_advance,ig_peek_profile_photo_universe,ig_android_ads_holdout_universe,ig_android_prefetch_explore,ig_android_direct_bubble_icon,ig_video_use_sve_universe,ig_android_inline_gallery_no_backoff_on_launch_universe,ig_android_image_cache_multi_queue,ig_android_camera_nux,ig_android_immersive_viewer,ig_android_dense_feed_unit_cards,ig_android_sqlite_dev,ig_android_exoplayer,ig_android_add_to_last_post,ig_android_direct_public_threads,ig_android_prefetch_venue_in_composer,ig_android_bigger_share_button,ig_android_dv2_realtime_private_share,ig_android_non_square_first,ig_android_video_interleaved_v2,ig_android_follow_search_bar,ig_android_last_edits,ig_android_video_download_logging,ig_android_ads_loop_count_universe,ig_android_swipeable_filters_blacklist,ig_android_boomerang_layout_white_out_universe,ig_android_ads_carousel_multi_row_universe,ig_android_mentions_invite_v2,ig_android_direct_mention_qe,ig_android_following_follower_social_context'
15 | SIG_KEY_VERSION = '4'
16 |
17 | #username # Instagram username
18 | #password # Instagram password
19 | #debug # Debug
20 | #uuid # UUID
21 | #device_id # Device ID
22 | #username_id # Username ID
23 | #token # _csrftoken
24 | #isLoggedIn # Session status
25 | #rank_token # Rank token
26 | #IGDataPath # Data storage path
27 |
28 | def __init__(self, username, password, debug = False, IGDataPath = None):
29 | m = hashlib.md5()
30 | m.update(username.encode('utf-8') + password.encode('utf-8'))
31 | self.device_id = self.generateDeviceId(m.hexdigest())
32 | self.setUser(username, password)
33 | self.isLoggedIn = False
34 | self.LastResponse = None
35 |
36 | def setUser(self, username, password):
37 | self.username = username
38 | self.password = password
39 |
40 | self.uuid = self.generateUUID(True)
41 |
42 | # TODO save data to file...
43 |
44 | def login(self, force = False):
45 | if (not self.isLoggedIn or force):
46 | self.s = requests.Session()
47 | # if you need proxy make something like this:
48 | # self.s.proxies = {"https" : "http://proxyip:proxyport"}
49 | if (self.SendRequest('si/fetch_headers/?challenge_type=signup&guid=' + self.generateUUID(False), None, True)):
50 |
51 | data = {'phone_id' : self.generateUUID(True),
52 | '_csrftoken' : self.LastResponse.cookies['csrftoken'],
53 | 'username' : self.username,
54 | 'guid' : self.uuid,
55 | 'device_id' : self.device_id,
56 | 'password' : self.password,
57 | 'login_attempt_count' : '0'}
58 |
59 | if (self.SendRequest('accounts/login/', self.generateSignature(json.dumps(data)), True)):
60 | self.isLoggedIn = True
61 | self.username_id = self.LastJson["logged_in_user"]["pk"]
62 | self.rank_token = "%s_%s" % (self.username_id, self.uuid)
63 | self.token = self.LastResponse.cookies["csrftoken"]
64 |
65 | self.syncFeatures()
66 | self.autoCompleteUserList()
67 | self.timelineFeed()
68 | self.getv2Inbox()
69 | self.getRecentActivity()
70 | print ("Login success!\n")
71 | return True;
72 |
73 | def syncFeatures(self):
74 | data = json.dumps({
75 | '_uuid' : self.uuid,
76 | '_uid' : self.username_id,
77 | 'id' : self.username_id,
78 | '_csrftoken' : self.token,
79 | 'experiments' : self.EXPERIMENTS
80 | })
81 | return self.SendRequest('qe/sync/', self.generateSignature(data))
82 |
83 | def autoCompleteUserList(self):
84 | return self.SendRequest('friendships/autocomplete_user_list/')
85 |
86 | def timelineFeed(self):
87 | return self.SendRequest('feed/timeline/')
88 |
89 | def megaphoneLog(self):
90 | return self.SendRequest('megaphone/log/')
91 |
92 | def expose(self):
93 | data = json.dumps({
94 | '_uuid' : self.uuid,
95 | '_uid' : self.username_id,
96 | 'id' : self.username_id,
97 | '_csrftoken' : self.token,
98 | 'experiment' : 'ig_android_profile_contextual_feed'
99 | })
100 | return self.SendRequest('qe/expose/', self.generateSignature(data))
101 |
102 | def logout(self):
103 | logout = self.SendRequest('accounts/logout/')
104 | # TODO Instagram.php 180-185
105 |
106 | def uploadPhoto(self, photo, caption = None, upload_id = None):
107 | # TODO Instagram.php 200-290
108 | return False
109 |
110 | def uploadVideo(self, video, caption = None):
111 | # TODO Instagram.php 290-415
112 | return False
113 |
114 | def direct_share(self, media_id, recipients, text = None):
115 | # TODO Instagram.php 420-490
116 | return False
117 |
118 | def configureVideo(upload_id, video, caption = ''):
119 | # TODO Instagram.php 490-530
120 | return False
121 |
122 | def configure(upload_id, photo, caption = ''):
123 | # TODO Instagram.php 530-570
124 | return False
125 |
126 | def editMedia(self, mediaId, captionText = ''):
127 | data = json.dumps({
128 | '_uuid' : self.uuid,
129 | '_uid' : self.username_id,
130 | '_csrftoken' : self.token,
131 | 'caption_text' : captionText
132 | })
133 | return self.SendRequest('media/'+ str(mediaId) +'/edit_media/', self.generateSignature(data))
134 |
135 | def removeSelftag(self, mediaId):
136 | data = json.dumps({
137 | '_uuid' : self.uuid,
138 | '_uid' : self.username_id,
139 | '_csrftoken' : self.token
140 | })
141 | return self.SendRequest('media/'+ str(mediaId) +'/remove/', self.generateSignature(data))
142 |
143 | def mediaInfo(self, mediaId):
144 | data = json.dumps({
145 | '_uuid' : self.uuid,
146 | '_uid' : self.username_id,
147 | '_csrftoken' : self.token,
148 | 'media_id' : mediaId
149 | })
150 | return self.SendRequest('media/'+ str(mediaId) +'/info/', self.generateSignature(data))
151 |
152 | def deleteMedia(self, mediaId):
153 | data = json.dumps({
154 | '_uuid' : self.uuid,
155 | '_uid' : self.username_id,
156 | '_csrftoken' : self.token,
157 | 'media_id' : mediaId
158 | })
159 | return self.SendRequest('media/'+ str(mediaId) +'/delete/', self.generateSignature(data))
160 |
161 | def comment(self, mediaId, commentText):
162 | data = json.dumps({
163 | '_uuid' : self.uuid,
164 | '_uid' : self.username_id,
165 | '_csrftoken' : self.token,
166 | 'comment_text' : commentText
167 | })
168 | return self.SendRequest('media/'+ str(mediaId) +'/comment/', self.generateSignature(data))
169 |
170 | def deleteComment(self, mediaId, captionText, commentId):
171 | data = json.dumps({
172 | '_uuid' : self.uuid,
173 | '_uid' : self.username_id,
174 | '_csrftoken' : self.token,
175 | 'caption_text' : captionText
176 | })
177 | return self.SendRequest('media/'+ str(mediaId) +'/comment/'+ str(commentId) +'/delete/', self.generateSignature(data))
178 |
179 | def changeProfilePicture(self, photo):
180 | # TODO Instagram.php 705-775
181 | return False
182 |
183 | def removeProfilePicture(self):
184 | data = json.dumps({
185 | '_uuid' : self.uuid,
186 | '_uid' : self.username_id,
187 | '_csrftoken' : self.token
188 | })
189 | return self.SendRequest('accounts/remove_profile_picture/', self.generateSignature(data))
190 |
191 | def setPrivateAccount(self):
192 | data = json.dumps({
193 | '_uuid' : self.uuid,
194 | '_uid' : self.username_id,
195 | '_csrftoken' : self.token
196 | })
197 | return self.SendRequest('accounts/set_private/', self.generateSignature(data))
198 |
199 | def setPublicAccount(self):
200 | data = json.dumps({
201 | '_uuid' : self.uuid,
202 | '_uid' : self.username_id,
203 | '_csrftoken' : self.token
204 | })
205 | return self.SendRequest('accounts/set_public/', self.generateSignature(data))
206 |
207 | def getProfileData(self):
208 | data = json.dumps({
209 | '_uuid' : self.uuid,
210 | '_uid' : self.username_id,
211 | '_csrftoken' : self.token
212 | })
213 | return self.SendRequest('accounts/current_user/?edit=true', self.generateSignature(data))
214 |
215 | def editProfile(self, url, phone, first_name, biography, email, gender):
216 | data = json.dumps({
217 | '_uuid' : self.uuid,
218 | '_uid' : self.username_id,
219 | '_csrftoken' : self.token,
220 | 'external_url' : url,
221 | 'phone_number' : phone,
222 | 'username' : self.username,
223 | 'full_name' : first_name,
224 | 'biography' : biography,
225 | 'email' : email,
226 | 'gender' : gender,
227 | })
228 | return self.SendRequest('accounts/edit_profile/', self.generateSignature(data))
229 |
230 | def getUsernameInfo(self, usernameId):
231 | return self.SendRequest('users/'+ str(usernameId) +'/info/')
232 |
233 | def getSelfUsernameInfo(self):
234 | return self.getUsernameInfo(self.username_id)
235 |
236 | def getRecentActivity(self):
237 | activity = self.SendRequest('news/inbox/?')
238 | # TODO Instagram.php 911-925
239 | return activity
240 |
241 | def getFollowingRecentActivity(self):
242 | activity = self.SendRequest('news/?')
243 | # TODO Instagram.php 935-945
244 | return activity
245 |
246 | def getv2Inbox(self):
247 | inbox = self.SendRequest('direct_v2/inbox/?')
248 | # TODO Instagram.php 950-960
249 | return inbox
250 |
251 | def getUserTags(self, usernameId):
252 | tags = self.SendRequest('usertags/'+ str(usernameId) +'/feed/?rank_token='+ str(self.rank_token) +'&ranked_content=true&')
253 | # TODO Instagram.php 975-985
254 | return tags
255 |
256 | def getSelfUserTags(self):
257 | return self.getUserTags(self.username_id)
258 |
259 | def tagFeed(self, tag):
260 | userFeed = self.SendRequest('feed/tag/'+ str(tag) +'/?rank_token=' + str(self.rank_token) + '&ranked_content=true&')
261 | # TODO Instagram.php 1000-1015
262 | return userFeed
263 |
264 | def getMediaLikers(self, mediaId):
265 | likers = self.SendRequest('media/'+ str(mediaId) +'/likers/?')
266 | # TODO Instagram.php 1025-1035
267 | return likers
268 |
269 | def getGeoMedia(self, usernameId):
270 | locations = self.SendRequest('maps/user/'+ str(usernameId) +'/')
271 | # TODO Instagram.php 1050-1060
272 | return locations
273 |
274 | def getSelfGeoMedia(self):
275 | return self.getGeoMedia(self.username_id)
276 |
277 | def fbUserSearch(self, query):
278 | query = self.SendRequest('fbsearch/topsearch/?context=blended&query='+ str(query) +'&rank_token='+ str(self.rank_token))
279 | # TODO Instagram.php 1080-1090
280 | return query
281 |
282 | def searchUsers(self, query):
283 | query = self.SendRequest('users/search/?ig_sig_key_version='+ str(self.SIG_KEY_VERSION)
284 | +'&is_typeahead=true&query='+ str(query) +'&rank_token='+ str(self.rank_token))
285 | # TODO Instagram.php 1100-1110
286 | return query
287 |
288 | def searchUsername(self, usernameName):
289 | query = self.SendRequest('users/'+ str(usernameName) +'/usernameinfo/')
290 | # TODO Instagram.php 1080-1090
291 | return query
292 |
293 | def syncFromAdressBook(self, contacts):
294 | return self.SendRequest('address_book/link/?include=extra_display_name,thumbnails', json.dumps(contacts))
295 |
296 | def searchTags(self, query):
297 | query = self.SendRequest('tags/search/?is_typeahead=true&q='+ str(query) +'&rank_token='+ str(self.rank_token))
298 | # TODO Instagram.php 1160-1170
299 | return query
300 |
301 | def getTimeline(self):
302 | query = self.SendRequest('feed/timeline/?rank_token='+ str(self.rank_token) +'&ranked_content=true&')
303 | # TODO Instagram.php 1180-1190
304 | return query
305 |
306 | def getUserFeed(self, usernameId, maxid = '', minTimestamp = None):
307 | # TODO Instagram.php 1200-1220
308 | return False
309 |
310 | def getSelfUserFeed(self):
311 | return self.getUserFeed(self.username_id)
312 |
313 | def getHashtagFeed(self, hashtagString, maxid = ''):
314 | # TODO Instagram.php 1230-1250
315 | return False
316 |
317 | def searchLocation(self, query):
318 | locationFeed = self.SendRequest('fbsearch/places/?rank_token='+ str(self.rank_token) +'&query=' + str(query))
319 | # TODO Instagram.php 1250-1270
320 | return locationFeed
321 |
322 | def getLocationFeed(self, locationId, maxid = ''):
323 | # TODO Instagram.php 1280-1300
324 | return False
325 |
326 | def getPopularFeed(self):
327 | popularFeed = self.SendRequest('feed/popular/?people_teaser_supported=1&rank_token='+ str(self.rank_token) +'&ranked_content=true&')
328 | # TODO Instagram.php 1315-1325
329 | return popularFeed
330 |
331 | def getUserFollowings(self, usernameId, maxid = ''):
332 | return self.SendRequest('friendships/'+ str(usernameId) +'/following/?max_id='+ str(maxid)
333 | +'&ig_sig_key_version='+ self.SIG_KEY_VERSION +'&rank_token='+ self.rank_token)
334 |
335 | def getSelfUsersFollowing(self):
336 | return self.getUserFollowings(self.username_id)
337 |
338 | def getUserFollowers(self, usernameId, maxid = ''):
339 | return self.SendRequest('friendships/'+ str(usernameId) +'/followers/?max_id='+ str(maxid)
340 | +'&ig_sig_key_version='+ self.SIG_KEY_VERSION +'&rank_token='+ self.rank_token)
341 |
342 | def getSelfUserFollowers(self):
343 | return self.getUserFollowers(self.username_id)
344 |
345 | def like(self, mediaId):
346 | data = json.dumps({
347 | '_uuid' : self.uuid,
348 | '_uid' : self.username_id,
349 | '_csrftoken' : self.token,
350 | 'media_id' : mediaId
351 | })
352 | return self.SendRequest('media/'+ str(mediaId) +'/like/', self.generateSignature(data))
353 |
354 | def unlike(self, mediaId):
355 | data = json.dumps({
356 | '_uuid' : self.uuid,
357 | '_uid' : self.username_id,
358 | '_csrftoken' : self.token,
359 | 'media_id' : mediaId
360 | })
361 | return self.SendRequest('media/'+ str(mediaId) +'/unlike/', self.generateSignature(data))
362 |
363 | def getMediaComments(self, mediaId):
364 | return self.SendRequest('media/'+ mediaId +'/comments/?')
365 |
366 | def setNameAndPhone(self, name = '', phone = ''):
367 | data = json.dumps({
368 | '_uuid' : self.uuid,
369 | '_uid' : self.username_id,
370 | 'first_name' : name,
371 | 'phone_number' : phone,
372 | '_csrftoken' : self.token
373 | })
374 | return self.SendRequest('accounts/set_phone_and_name/', self.generateSignature(data))
375 |
376 | def getDirectShare(self):
377 | return self.SendRequest('direct_share/inbox/?')
378 |
379 | def backup(self):
380 | # TODO Instagram.php 1470-1485
381 | return False
382 |
383 | def follow(self, userId):
384 | data = json.dumps({
385 | '_uuid' : self.uuid,
386 | '_uid' : self.username_id,
387 | 'user_id' : userId,
388 | '_csrftoken' : self.token
389 | })
390 | return self.SendRequest('friendships/create/'+ str(userId) +'/', self.generateSignature(data))
391 |
392 | def unfollow(self, userId):
393 | data = json.dumps({
394 | '_uuid' : self.uuid,
395 | '_uid' : self.username_id,
396 | 'user_id' : userId,
397 | '_csrftoken' : self.token
398 | })
399 | return self.SendRequest('friendships/destroy/'+ str(userId) +'/', self.generateSignature(data))
400 |
401 | def block(self, userId):
402 | data = json.dumps({
403 | '_uuid' : self.uuid,
404 | '_uid' : self.username_id,
405 | 'user_id' : userId,
406 | '_csrftoken' : self.token
407 | })
408 | return self.SendRequest('friendships/block/'+ str(userId) +'/', self.generateSignature(data))
409 |
410 | def unblock(self, userId):
411 | data = json.dumps({
412 | '_uuid' : self.uuid,
413 | '_uid' : self.username_id,
414 | 'user_id' : userId,
415 | '_csrftoken' : self.token
416 | })
417 | return self.SendRequest('friendships/unblock/'+ str(userId) +'/', self.generateSignature(data))
418 |
419 | def userFriendship(self, userId):
420 | data = json.dumps({
421 | '_uuid' : self.uuid,
422 | '_uid' : self.username_id,
423 | 'user_id' : userId,
424 | '_csrftoken' : self.token
425 | })
426 | return self.SendRequest('friendships/show/'+ str(userId) +'/', self.generateSignature(data))
427 |
428 | def getLikedMedia(self):
429 | return self.SendRequest('feed/liked/?')
430 |
431 | def generateSignature(self, data):
432 | return 'ig_sig_key_version=' + self.SIG_KEY_VERSION + '&signed_body=' + hmac.new(self.IG_SIG_KEY.encode('utf-8'), data.encode('utf-8'), hashlib.sha256).hexdigest() + '.' + urllib.parse.quote(data)
433 |
434 | def generateDeviceId(self, seed):
435 | volatile_seed = "12345"
436 | m = hashlib.md5()
437 | m.update(seed.encode('utf-8') + volatile_seed.encode('utf-8'))
438 | return 'android-' + m.hexdigest()[:16]
439 |
440 | def generateUUID(self, type):
441 | uuid = '%04x%04x-%04x-%04x-%04x-%04x%04x%04x' % (random.randint(0, 0xffff),
442 | random.randint(0, 0xffff), random.randint(0, 0xffff),
443 | random.randint(0, 0x0fff) | 0x4000,
444 | random.randint(0, 0x3fff) | 0x8000,
445 | random.randint(0, 0xffff), random.randint(0, 0xffff),
446 | random.randint(0, 0xffff))
447 | if (type):
448 | return uuid
449 | else:
450 | return uuid.replace('-', '')
451 |
452 | def buildBody(bodies, boundary):
453 | # TODO Instagram.php 1620-1645
454 | return False
455 |
456 | def SendRequest(self, endpoint, post = None, login = False):
457 | if (not self.isLoggedIn and not login):
458 | raise Exception("Not logged in!\n")
459 | return;
460 |
461 | self.s.headers.update ({'Connection' : 'close',
462 | 'Accept' : '*/*',
463 | 'Content-type' : 'application/x-www-form-urlencoded; charset=UTF-8',
464 | 'Cookie2' : '$Version=1',
465 | 'Accept-Language' : 'en-US',
466 | 'User-Agent' : self.USER_AGENT})
467 |
468 | if (post != None): # POST
469 | response = self.s.post(self.API_URL + endpoint, data=post) # , verify=False
470 | else: # GET
471 | response = self.s.get(self.API_URL + endpoint) # , verify=False
472 |
473 | if response.status_code == 200:
474 | self.LastResponse = response
475 | self.LastJson = json.loads(response.text)
476 | return True
477 | else:
478 | print ("Request return " + str(response.status_code) + " error!")
479 | return False
480 |
481 |
482 | InstagramAPI = InstagramAPI("login", "password")
483 | InstagramAPI.login() # login
484 | InstagramAPI.tagFeed("cat") # get media list by tag #cat
485 | media_id = InstagramAPI.LastJson # media id of first media
486 | InstagramAPI.like(media_id["ranked_items"][0]["pk"]) # like first media
487 | InstagramAPI.getUserFollowers(media_id["ranked_items"][0]["user"]["pk"]) # get first media owner followers
488 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Instagram-API-python
2 |
3 |
4 |
5 |
6 | Unofficial instagram API, give you access to ALL instagram features (like, follow, upload photo and video and etc)! Write on python.
7 |
8 | This is python port of https://github.com/mgp25/Instagram-API, written on PHP. Work in progress to copy all functional...
9 |
10 | ### Now InstagramAPI.py can:
11 |
12 | 1) login;
13 |
14 | 2) tagFeed (TODO);
15 |
16 | 3) like;
17 |
18 | 4) comment;
19 |
20 | 5) deleteComment;
21 |
22 | 6) expose;
23 |
24 | 7) logout;
25 |
26 | 8) editMedia;
27 |
28 | 9) removeSelftag;
29 |
30 | 10) mediaInfo;
31 |
32 | 11) deleteMedia;
33 |
34 | 12) getv2Inbox (TODO);
35 |
36 | 13) getRecentActivity (TODO);
37 |
38 | 14) megaphoneLog;
39 |
40 | 15) timelineFeed;
41 |
42 | 16) autoCompleteUserList;
43 |
44 | 17) syncFeatures;
45 |
46 | 18) removeProfilePicture;
47 |
48 | 19) setPrivateAccount;
49 |
50 | 20) setPublicAccount;
51 |
52 | 21) getProfileData;
53 |
54 | 22) editProfile;
55 |
56 | 23) getUsernameInfo;
57 |
58 | 24) getSelfUsernameInfo;
59 |
60 | 25) getFollowingRecentActivity (TODO);
61 |
62 | 26) getUserTags (TODO);
63 |
64 | 27) getSelfUserTags;
65 |
66 | 28) getMediaLikers (TODO);
67 |
68 | 29) getGeoMedia (TODO);
69 |
70 | 30) getSelfGeoMedia;
71 |
72 | 31) fbUserSearch (TODO);
73 |
74 | 32) searchUsers (TODO);
75 |
76 | 33) searchUsername (TODO);
77 |
78 | 34) syncFromAdressBook;
79 |
80 | 35) searchTags (TODO);
81 |
82 | 36) getTimeline (TODO);
83 |
84 | 37) searchLocation (TODO);
85 |
86 | 38) getSelfUserFeed;
87 |
88 | 39) getPopularFeed (TODO);
89 |
90 | 40) getUserFollowings;
91 |
92 | 41) getUserFollowers;
93 |
94 | 42) getSelfUserFollowers;
95 |
96 | 43) getSelfUsersFollowing;
97 |
98 | 44) unlike;
99 |
100 | 45) getMediaComments;
101 |
102 | 46) setNameAndPhone;
103 |
104 | 47) getDirectShare;
105 |
106 | 48) follow;
107 |
108 | 49) unfollow;
109 |
110 | 50) block;
111 |
112 | 51) unblock;
113 |
114 | 52) userFriendship;
115 |
116 | 53) getLikedMedia;
117 |
118 | ### TODO:
119 |
120 | 1) changeProfilePicture;
121 |
122 | 2) uploadPhoto;
123 |
124 | 3) uploadVideo;
125 |
126 | 4) direct_share;
127 |
128 | 5) configureVideo;
129 |
130 | 6) configure;
131 |
132 | 7) getUserFeed;
133 |
134 | 8) getHashtagFeed;
135 |
136 | 9) getLocationFeed;
137 |
138 | 10) backup;
139 |
140 | 11) buildBody;
141 |
142 | If you want to help - write what you want to do. In other cases, you can do the exact same work with another assistant or me.
143 |
--------------------------------------------------------------------------------
/response_example.json:
--------------------------------------------------------------------------------
1 | {
2 | "ranked_items":[
3 | {
4 | "taken_at":1465197632,
5 | "pk":1266491991547726373,
6 | "id":"1266491991547726373_1733371297",
7 | "device_timestamp":1465197488,
8 | "media_type":1,
9 | "code":"BGTe8GTFEol",
10 | "client_cache_key":"MTI2NjQ5MTk5MTU0NzcyNjM3Mw==.2",
11 | "filter_type":0,
12 | "image_versions2":{},
13 | "original_width":1080,
14 | "original_height":1080,
15 | "user":{
16 | "username":"hosico_cat",
17 | "has_anonymous_profile_picture":false,
18 | "is_unpublished":false,
19 | "friendship_status":{
20 | "following":false,
21 | "outgoing_request":false
22 | },
23 | "profile_pic_url":"http://scontent.cdninstagram.com/t51.2885-19/11008076_933721613312233_2134339792_a.jpg",
24 | "is_favorite":false,
25 | "full_name":"Hosico Cat \ud83d\udca0",
26 | "pk":1733371297,
27 | "is_private":false
28 | },
29 | "organic_tracking_token":"eyJ2ZXJzaW9uIjo1LCJwYXlsb2FkIjp7ImlzX2FuYWx5dGljc190cmFja2VkIjpmYWxzZSwidXVpZCI6IjNjMzkzMTQ1ODQ0OTQ0MDZiYWY4MTAwODczYTYyMmMzMTI2NjQ5MTk5MTU0NzcyNjM3MyIsInNlcnZlcl90b2tlbiI6IjE0NjUyMDcwNTU5MTN8MTI2NjQ5MTk5MTU0NzcyNjM3M3wyMzIxODQwODMzfDU3ZmE2ZWUxMTJjZDdiNWFlZGQ1NWQ3ZmNlYjgyZjgxMTE1NGZhYTIyMjlhM2QzZGNjMzk3ZWUyYWJiZTJjNzMifSwic2lnbmF0dXJlIjoiIn0=",
30 | "like_count":6618,
31 | "has_liked":false,
32 | "has_more_comments":true,
33 | "next_max_id":17848359943090570,
34 | "max_num_visible_preview_comments":2,
35 | "comments":[
36 | {
37 | "status":"Active",
38 | "user_id":1683404619,
39 | "created_at_utc":1465206156,
40 | "created_at":1465206156,
41 | "bit_flags":0,
42 | "user":{
43 | "username":"ttattiaanna",
44 | "profile_pic_url":"http://scontent.cdninstagram.com/t51.2885-19/11282290_828025840614091_1370030454_a.jpg",
45 | "full_name":"\u0442\u0430\u0442\u044c\u044f\u043d\u0430 \u043f\u0435\u0442\u0440\u043e\u0432\u0430",
46 | "pk":1683404619,
47 | "is_verified":false,
48 | "is_private":false
49 | },
50 | "content_type":"comment",
51 | "text":"\u041a\u0440\u0430\u0441\u0430\u0442\u0443\u043b\u0435\u043d\u044c\u043a\u0430!!!",
52 | "media_id":1266491991547726373,
53 | "pk":17848359793090570,
54 | "type":0
55 | },
56 | {
57 | "status":"Active",
58 | "user_id":200553009,
59 | "created_at_utc":1465206915,
60 | "created_at":1465206915,
61 | "bit_flags":0,
62 | "user":{
63 | "username":"tommy.117",
64 | "profile_pic_url":"http://scontent.cdninstagram.com/t51.2885-19/s150x150/13108538_515308845320021_1577254003_a.jpg",
65 | "full_name":"",
66 | "pk":200553009,
67 | "is_verified":false,
68 | "is_private":true
69 | },
70 | "content_type":"comment",
71 | "text":"@isabelmalfoy \ud83d\ude0a",
72 | "media_id":1266491991547726373,
73 | "pk":17848359943090570,
74 | "type":0
75 | }
76 | ],
77 | "comment_count":57,
78 | "caption":{
79 | "status":"Active",
80 | "user_id":1733371297,
81 | "created_at_utc":1465197632,
82 | "created_at":1465197632,
83 | "bit_flags":0,
84 | "user":{
85 | "username":"hosico_cat",
86 | "has_anonymous_profile_picture":false,
87 | "is_unpublished":false,
88 | "friendship_status":{
89 | "following":false,
90 | "outgoing_request":false
91 | },
92 | "profile_pic_url":"http://scontent.cdninstagram.com/t51.2885-19/11008076_933721613312233_2134339792_a.jpg",
93 | "is_favorite":false,
94 | "full_name":"Hosico Cat \ud83d\udca0",
95 | "pk":1733371297,
96 | "is_private":false
97 | },
98 | "content_type":"comment",
99 | "text":"Get up, get up, today is Monday! \ud83d\ude4c\ud83c\udffb\ud83d\udcbc\ud83d\udc54 #weeklyfluff #hosico #cute #beautiful #cat #pet #catsofinstagram #cats #kitty #kitten #animal #kawaii #meow #instacat #catstagram #\u732b #catlover #ilovemycat #catoftheday #neko #\u306d\u3053 #chat #gato #\u043a\u043e\u0442 #\uace0\uc591\uc774 #gatto #katze #kedi #\u0e41\u0e21\u0e27 #scottishstraight",
100 | "media_id":1266491991547726373,
101 | "pk":17848357837090570,
102 | "type":1
103 | },
104 | "caption_is_edited":false,
105 | "photo_of_you":false
106 | }
107 | ]
108 | }
109 |
--------------------------------------------------------------------------------