├── 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 | --------------------------------------------------------------------------------