class ItsAGramLive: ig: InstagramAPI = None previewWidth: int = 1080 previewHeight: int = 1920 broadcastMessage: str = "" sendNotification: bool = True share_to_story: bool = False last_comment_ts: int = 1 def __init__(self): parser = argparse.ArgumentParser(add_help=True) parser.add_argument("-u", "--username", type=str, help="username", required=True) parser.add_argument("-p", "--password", type=str, help="password", required=True) parser.add_argument("-share", type=bool, help="Share to Story after ended", default=self.share_to_story) parser.add_argument("-proxy", type=str, help="Proxy format - user:password@ip:port", default=None) args = parser.parse_args() self.share_to_story = args.share self.ig = InstagramAPI(username=args.username, password=args.password) self.ig.setProxy(proxy=args.proxy) def create_broadcast(self): if self.ig.login(): data = json.dumps({'_uuid': self.ig.uuid, '_uid': self.ig.username_id, 'preview_height': self.previewHeight, 'preview_width': self.previewWidth, 'broadcast_message': self.broadcastMessage, 'broadcast_type': 'RTMP', 'internal_only': 0, '_csrftoken': self.ig.token}) if self.ig.SendRequest(endpoint='live/create/', post=self.ig.generateSignature(data)): last_json = self.ig.LastJson broadcast_id = last_json['broadcast_id'] upload_url = last_json['upload_url'] splited = upload_url.split(str(broadcast_id)) stream_key = "{}{}".format(str(broadcast_id), splited[1]) server = splited[0] print("Server: {}".format(server)) pyperclip.copy(stream_key) print("Stream Key (copied to clipboard): {}".format(stream_key)) else: return False else: return False return broadcast_id def start_broadcast(self, broadcast_id): data = json.dumps({'_uuid': self.ig.uuid, '_uid': self.ig.username_id, 'should_send_notifications': int(self.sendNotification), '_csrftoken': self.ig.token}) if self.ig.SendRequest(endpoint='live/' + str(broadcast_id) + '/start/', post=self.ig.generateSignature(data)): print('CTRL+C to quit.') spinner = Spinner(" - ") try: while True: spinner.next() except KeyboardInterrupt: spinner.finish() pass except Exception as error: print(error) self.end_broadcast(broadcast_id) def end_broadcast(self, broadcast_id): data = json.dumps({'_uuid': self.ig.uuid, '_uid': self.ig.username_id, '_csrftoken': self.ig.token}) if self.ig.SendRequest(endpoint='live/' + str(broadcast_id) + '/end_broadcast/', post=self.ig.generateSignature(data)): if self.share_to_story: self.ig.SendRequest(endpoint='live/' + str(broadcast_id) + '/add_to_post_live/', post=self.ig.generateSignature(data)) print('Ending Broadcasting')
class Osintgram: api = None geolocator = Nominatim() user_id = None target_id = None is_private = True target = "" writeFile = False def __init__(self, target): u = self.__getUsername__() p = self.__getPassword__() self.api = InstagramAPI(u, p) print("\nAttempt to login...") self.api.login() self.setTarget(target) def setTarget(self, target): self.target = target user = self.getUser(target) self.target_id = user['id'] self.is_private = user['is_private'] self.__printTargetBanner__() def __getUsername__(self): u = open("config/username.conf", "r").read() u = u.replace("\n", "") return u def __getPassword__(self): p = open("config/pw.conf", "r").read() p = p.replace("\n", "") return p def __getAdressesTimes__(self, id): only_id = {} photos = [] a = None while True: if (a == None): self.api.getUserFeed(id) a = self.api.LastJson['items'] only_id = self.api.LastJson else: self.api.getUserFeed(id, only_id['next_max_id']) only_id = self.api.LastJson a = self.api.LastJson['items'] photos.append(a) if not 'next_max_id' in only_id: break locations = {} for i in photos: for j in i: if 'lat' in j.keys(): lat = j.get('lat') lng = j.get('lng') locations[str(lat) + ', ' + str(lng)] = j.get('taken_at') address = {} for k, v in locations.items(): details = self.geolocator.reverse(k) unix_timestamp = datetime.datetime.fromtimestamp(v) address[details.address] = unix_timestamp.strftime( '%Y-%m-%d %H:%M:%S') sort_addresses = sorted(address.items(), key=lambda p: p[1], reverse=True) return sort_addresses def __printTargetBanner__(self): pc.printout("\nLogged as ", pc.GREEN) pc.printout(self.api.username, pc.CYAN) pc.printout(" (" + str(self.api.username_id) + ") ") pc.printout("target: ", pc.GREEN) pc.printout(str(self.target), pc.CYAN) pc.printout(" (private: " + str(self.is_private) + ")") print('\n') def setWriteFile(self, bool): if (bool): pc.printout("Write to file: ") pc.printout("enabled", pc.GREEN) pc.printout("\n") else: pc.printout("Write to file: ") pc.printout("disabled", pc.RED) pc.printout("\n") self.writeFile = bool def __getUserFollowigs__(self, id): following = [] next_max_id = True while next_max_id: # first iteration hack if next_max_id is True: next_max_id = '' _ = self.api.getUserFollowings(id, maxid=next_max_id) following.extend(self.api.LastJson.get('users', [])) next_max_id = self.api.LastJson.get('next_max_id', '') len(following) unique_following = {f['pk']: f for f in following} len(unique_following) return following def __getTotalFollowers__(self, user_id): followers = [] next_max_id = True while next_max_id: # first iteration hack if next_max_id is True: next_max_id = '' _ = self.api.getUserFollowers(user_id, maxid=next_max_id) followers.extend(self.api.LastJson.get('users', [])) next_max_id = self.api.LastJson.get('next_max_id', '') return followers def getHashtags(self): if (self.is_private): pc.printout( "Impossible to execute command: user has private profile\n", pc.RED) return pc.printout("Searching for target hashtags...\n") text = [] only_id = {} a = None hashtags = [] counter = 1 while True: if (a == None): self.api.getUserFeed(self.target_id) a = self.api.LastJson['items'] only_id = self.api.LastJson with open('data.json', 'w') as outfile: json.dump(only_id, outfile) else: self.api.getUserFeed(self.target_id, only_id['next_max_id']) only_id = self.api.LastJson a = self.api.LastJson['items'] try: for i in a: c = i.get('caption', {}).get('text') text.append(c) counter = counter + 1 except AttributeError: pass if not 'next_max_id' in only_id: break hashtag_counter = {} for i in text: for j in i.split(): if j.startswith('#'): hashtags.append(j.encode('UTF-8')) for i in hashtags: if i in hashtag_counter: hashtag_counter[i] += 1 else: hashtag_counter[i] = 1 sortE = sorted(hashtag_counter.items(), key=lambda value: value[1], reverse=True) if (self.writeFile): file_name = "output/" + self.target + "_hashtags.txt" file = open(file_name, "w") for k, v in sortE: file.write(str(v) + ". " + str(k.decode('utf-8')) + "\n") file.close() for k, v in sortE: print(str(v) + ". " + str(k.decode('utf-8'))) def getTotalLikes(self): if (self.is_private): pc.printout( "Impossible to execute command: user has private profile\n", pc.RED) return pc.printout("Searching for target total likes...\n") like_counter = 0 only_id = {} a = None counter = 0 while True: if (a == None): self.api.getUserFeed(self.target_id) a = self.api.LastJson['items'] only_id = self.api.LastJson else: self.api.getUserFeed(self.target_id, only_id['next_max_id']) only_id = self.api.LastJson a = self.api.LastJson['items'] try: for i in a: c = int(i.get('like_count')) like_counter += c counter = counter + 1 except AttributeError: pass if not 'next_max_id' in only_id: break if (self.writeFile): file_name = "output/" + self.target + "_likes.txt" file = open(file_name, "w") file.write( str(like_counter) + " likes in " + str(counter) + " posts\n") file.close() pc.printout(str(like_counter), pc.MAGENTA) pc.printout(" likes in " + str(counter) + " posts\n") def getTotalComments(self): if (self.is_private): pc.printout( "Impossible to execute command: user has private profile\n", pc.RED) return pc.printout("Searching for target total comments...\n") comment_counter = 0 only_id = {} a = None counter = 0 while True: if (a == None): self.api.getUserFeed(self.target_id) a = self.api.LastJson['items'] only_id = self.api.LastJson else: self.api.getUserFeed(self.target_id, only_id['next_max_id']) only_id = self.api.LastJson a = self.api.LastJson['items'] try: for i in a: c = int(i.get('comment_count')) comment_counter += c counter = counter + 1 except AttributeError: pass if not 'next_max_id' in only_id: break if (self.writeFile): file_name = "output/" + self.target + "_comments.txt" file = open(file_name, "w") file.write( str(comment_counter) + " comments in " + str(counter) + " posts\n") file.close() pc.printout(str(comment_counter), pc.MAGENTA) pc.printout(" comments in " + str(counter) + " posts\n") def getPeopleTaggedByUser(self): pc.printout("Searching for users tagged by target...\n") ids = [] username = [] full_name = [] post = [] only_id = {} a = None counter = 1 while True: if (a == None): self.api.getUserFeed(self.target_id) a = self.api.LastJson['items'] only_id = self.api.LastJson else: self.api.getUserFeed(self.target_id, only_id['next_max_id']) only_id = self.api.LastJson a = self.api.LastJson['items'] try: for i in a: if "usertags" in i: c = i.get('usertags').get('in') for cc in c: if cc.get('user').get('pk') not in ids: ids.append(cc.get('user').get('pk')) username.append(cc.get('user').get('username')) full_name.append( cc.get('user').get('full_name')) post.append(1) else: index = ids.index(cc.get('user').get('pk')) post[index] += 1 counter = counter + 1 except AttributeError as ae: pc.printout("\nERROR: an error occurred: ", pc.RED) print(ae) print("") pass if not 'next_max_id' in only_id: break if len(ids) > 0: t = PrettyTable() t.field_names = ['Posts', 'Full Name', 'Username', 'ID'] t.align["Posts"] = "l" t.align["Full Name"] = "l" t.align["Username"] = "******" t.align["ID"] = "l" pc.printout( "\nWoohoo! We found " + str(len(ids)) + " (" + str(counter) + ") users\n", pc.GREEN) for i in range(len(ids)): t.add_row([post[i], full_name[i], username[i], str(ids[i])]) if (self.writeFile): file_name = "output/" + self.target + "_tagged.txt" file = open(file_name, "w") file.write(str(t)) file.close() print(t) else: pc.printout("Sorry! No results found :-(\n", pc.RED) def getAddrs(self): if (self.is_private): pc.printout( "Impossible to execute command: user has private profile\n", pc.RED) return pc.printout( "Searching for target address... this may take a few minutes...\n") addrs = self.__getAdressesTimes__(self.target_id) t = PrettyTable() t.field_names = ['Post', 'Address', 'time'] t.align["Post"] = "l" t.align["Address"] = "l" t.align["Time"] = "l" pc.printout("\nWoohoo! We found " + str(len(addrs)) + " addresses\n", pc.GREEN) i = 1 for address, time in addrs: t.add_row([str(i), address, time]) i = i + 1 if (self.writeFile): file_name = "output/" + self.target + "_addrs.txt" file = open(file_name, "w") file.write(str(t)) file.close() print(t) def getFollowers(self): if (self.is_private): pc.printout( "Impossible to execute command: user has private profile\n", pc.RED) return pc.printout("Searching for target followers...\n") followers = self.__getTotalFollowers__(self.target_id) t = PrettyTable(['ID', 'Username', 'Full Name']) t.align["ID"] = "l" t.align["Username"] = "******" t.align["Full Name"] = "l" for i in followers: t.add_row([str(i['pk']), i['username'], i['full_name']]) if (self.writeFile): file_name = "output/" + self.target + "_followers.txt" file = open(file_name, "w") file.write(str(t)) file.close() print(t) def getFollowings(self): if (self.is_private): pc.printout( "Impossible to execute command: user has private profile\n", pc.RED) return pc.printout("Searching for target followings...\n") followings = self.__getUserFollowigs__(self.target_id) t = PrettyTable(['ID', 'Username', 'Full Name']) t.align["ID"] = "l" t.align["Username"] = "******" t.align["Full Name"] = "l" for i in followings: t.add_row([str(i['pk']), i['username'], i['full_name']]) if (self.writeFile): file_name = "output/" + self.target + "_followings.txt" file = open(file_name, "w") file.write(str(t)) file.close() print(t) def getUser(self, username): try: content = urllib.request.urlopen("https://www.instagram.com/" + username + "/?__a=1") except urllib.error.HTTPError as err: if (err.code == 404): print("Oops... " + username + " non exist, please enter a valid username.") sys.exit(2) data = json.load(content) if (self.writeFile): file_name = "output/" + self.target + "_user_id.txt" file = open(file_name, "w") file.write(str(data['graphql']['user']['id'])) file.close() user = dict() user['id'] = data['graphql']['user']['id'] user['is_private'] = data['graphql']['user']['is_private'] return user def getUserInfo(self): try: content = urllib.request.urlopen("https://www.instagram.com/" + str(self.target) + "/?__a=1") except urllib.error.HTTPError as err: if (err.code == 404): print("Oops... " + str(self.target) + " non exist, please enter a valid username.") sys.exit(2) data = json.load(content) data = data['graphql']['user'] pc.printout("[ID] ", pc.GREEN) pc.printout(str(data['id']) + '\n') pc.printout("[FULL NAME] ", pc.RED) pc.printout(str(data['full_name']) + '\n') pc.printout("[BIOGRAPHY] ", pc.CYAN) pc.printout(str(data['biography']) + '\n') pc.printout("[FOLLOWED] ", pc.GREEN) pc.printout(str(data['edge_followed_by']['count']) + '\n') pc.printout("[FOLLOW] ", pc.BLUE) pc.printout(str(data['edge_follow']['count']) + '\n') pc.printout("[BUSINESS ACCOUNT] ", pc.RED) pc.printout(str(data['is_business_account']) + '\n') if data['is_business_account'] == True: pc.printout("[BUSINESS CATEGORY] ") pc.printout(str(data['business_category_name']) + '\n') pc.printout("[VERIFIED ACCOUNT] ", pc.CYAN) pc.printout(str(data['is_verified']) + '\n') def getPhotoDescription(self): if (self.is_private): pc.printout( "Impossible to execute command: user has private profile\n", pc.RED) return content = self.api.SendRequest2(self.target + '/?__a=1') data = self.api.LastJson dd = data['graphql']['user']['edge_owner_to_timeline_media']['edges'] if len(dd) > 0: pc.printout( "\nWoohoo! We found " + str(len(dd)) + " descriptions\n", pc.GREEN) count = 1 t = PrettyTable(['Photo', 'Description']) t.align["Photo"] = "l" t.align["Description"] = "l" for i in dd: node = i.get('node') t.add_row([str(count), node.get('accessibility_caption')]) count += 1 if (self.writeFile): file_name = "output/" + self.target + "_photodes.txt" file = open(file_name, "w") file.write(str(t)) file.close() print(t) else: pc.printout("Sorry! No results found :-(\n", pc.RED) def getUserPhoto(self): if (self.is_private): pc.printout( "Impossible to execute command: user has private profile\n", pc.RED) return limit = -1 pc.printout("How many photos you want to download (default all): ", pc.YELLOW) l = input() try: if l == "": pc.printout("Downloading all photos avaible...\n") else: limit = int(l) pc.printout("Downloading " + l + " photos...\n") except ValueError: pc.printout("Wrong value entered\n", pc.RED) return a = None counter = 0 while True: if (a == None): self.api.getUserFeed(self.target_id) a = self.api.LastJson['items'] only_id = self.api.LastJson else: self.api.getUserFeed(self.target_id, only_id['next_max_id']) only_id = self.api.LastJson a = self.api.LastJson['items'] try: for item in a: if counter == limit: break if "image_versions2" in item: counter = counter + 1 url = item["image_versions2"]["candidates"][0]["url"] photo_id = item["id"] end = "output/" + self.target + "_" + photo_id + ".jpg" urllib.request.urlretrieve(url, end) sys.stdout.write("\rDownloaded %i" % counter) sys.stdout.flush() else: carousel = item["carousel_media"] for i in carousel: if counter == limit: break counter = counter + 1 url = i["image_versions2"]["candidates"][0]["url"] photo_id = i["id"] end = "output/" + self.target + "_" + photo_id + ".jpg" urllib.request.urlretrieve(url, end) sys.stdout.write("\rDownloaded %i" % counter) sys.stdout.flush() except AttributeError: pass except KeyError: pass if not 'next_max_id' in only_id: break sys.stdout.write(" photos") sys.stdout.flush() pc.printout( "\nWoohoo! We downloaded " + str(counter) + " photos (saved in output/ folder) \n", pc.GREEN) def getCaptions(self): if (self.is_private): pc.printout( "Impossible to execute command: user has private profile\n", pc.RED) return pc.printout("Searching for target captions...\n") a = None counter = 0 captions = [] while True: if (a == None): self.api.getUserFeed(self.target_id) a = self.api.LastJson['items'] only_id = self.api.LastJson else: self.api.getUserFeed(self.target_id, only_id['next_max_id']) only_id = self.api.LastJson a = self.api.LastJson['items'] try: for item in a: if "caption" in item: if item["caption"] != None: text = item["caption"]["text"] captions.append(text) counter = counter + 1 sys.stdout.write("\rFound %i" % counter) sys.stdout.flush() except AttributeError: pass except KeyError: pass if not 'next_max_id' in only_id: break sys.stdout.write(" captions") sys.stdout.flush() if counter > 0: pc.printout("\nWoohoo! We found " + str(counter) + " captions\n", pc.GREEN) if (self.writeFile): file_name = "output/" + self.target + "_captions.txt" file = open(file_name, "w") for s in captions: file.write(s + "\n") file.close() for s in captions: print(s + "\n") else: pc.printout("Sorry! No results found :-(\n", pc.RED) return def getMediaType(self): if (self.is_private): pc.printout( "Impossible to execute command: user has private profile\n", pc.RED) return pc.printout("Searching for target captions...\n") a = None counter = 0 photo_counter = 0 video_counter = 0 while True: if (a == None): self.api.getUserFeed(self.target_id) a = self.api.LastJson['items'] only_id = self.api.LastJson else: self.api.getUserFeed(self.target_id, only_id['next_max_id']) only_id = self.api.LastJson a = self.api.LastJson['items'] try: for item in a: if "media_type" in item: if item["media_type"] == 1: photo_counter = photo_counter + 1 elif item["media_type"] == 2: video_counter = video_counter + 1 counter = counter + 1 sys.stdout.write("\rChecked %i" % counter) sys.stdout.flush() except AttributeError: pass except KeyError: pass if not 'next_max_id' in only_id: break sys.stdout.write(" posts") sys.stdout.flush() if counter > 0: if (self.writeFile): file_name = "output/" + self.target + "_mediatype.txt" file = open(file_name, "w") file.write(str(photo_counter) + " photos and " + str(video_counter) \ + " video posted by target\n") file.close() pc.printout("\nWoohoo! We found " + str(photo_counter) + " photos and " + str(video_counter) \ + " video posted by target\n", pc.GREEN) else: pc.printout("Sorry! No results found :-(\n", pc.RED) return def getUserPropic(self): try: content = urllib.request.urlopen("https://www.instagram.com/" + str(self.target) + "/?__a=1") except urllib.error.HTTPError as err: if (err.code == 404): print("Oops... " + str(self.target) + " non exist, please enter a valid username.") sys.exit(2) data = json.load(content) URL = "" uurl = data["graphql"]["user"] if "profile_pic_url_hd" in uurl: URL = data["graphql"]["user"]["profile_pic_url_hd"] else: URL = data["graphql"]["user"]["profile_pic_url"] if URL != "": end = "output/" + self.target + "_propic.jpg" urllib.request.urlretrieve(URL, end) pc.printout("Target propic saved in output folder\n", pc.GREEN) else: pc.printout("Sorry! No results found :-(\n", pc.RED) def getUserStories(self): if (self.is_private): pc.printout( "Impossible to execute command: user has private profile\n", pc.RED) return pc.printout("Searching for target stories...\n") endpoint = 'feed/user/{id!s}/story/'.format(**{'id': self.target_id}) content = self.api.SendRequest(endpoint) data = self.api.LastJson counter = 0 if data['reel'] != None: # no stories avaibile for i in data['reel']['items']: story_id = i["id"] if i["media_type"] == 1: # it's a photo url = i['image_versions2']['candidates'][0]['url'] end = "output/" + self.target + "_" + story_id + ".jpg" urllib.request.urlretrieve(url, end) counter += 1 elif i["media_type"] == 2: # it's a gif or video url = i['video_versions'][0]['url'] end = "output/" + self.target + "_" + story_id + ".mp4" urllib.request.urlretrieve(url, end) counter += 1 if counter > 0: pc.printout( str(counter) + " target stories saved in output folder\n", pc.GREEN) else: pc.printout("Sorry! No results found :-(\n", pc.RED) def changeTarget(self): pc.printout("Insert new target username: ", pc.YELLOW) l = input() self.setTarget(l) return
class User: #Setup custom user class def __init__(self, usr_name, password): self.name = usr_name self.api = InstagramAPI(usr_name, password) InstagramAPI.USER_AGENT = "Instagram 99.0.0.19.93 Android (5000/5000.0; 1dpi; 1x1; noname; noname; noname; noname)" #Setup custom UA to ensure reading dms allowed def sendMessage(self, target, msgText): targets = [] if type(target) != type([]): target = [target] for user in target: try: int(user) targets.append(str(user)) except ValueError: target = self.api.searchUsername(user) try: targets.append(str(self.api.LastJson["user"]["pk"])) except: return ValueError("Invalid User") url = "direct_v2/threads/broadcast/text/" target = "[[{}]]".format(",".join([str(user) for user in targets])) data = { "text": msgText, "_uuid": self.api.uuid, "_csrftoken": self.api.token, "recipient_users": target, "_uid": self.api.username_id, "action": "send_item", "client_context": self.api.generateUUID(True)} return self.api.SendRequest(url, data) def getChats(self): #TODO: Find some way of checking if thread is unread self.api.getv2Inbox() content = json.loads(self.api.LastResponse.content)["inbox"]["threads"] chats = [] for chat in content: users = [] if len(chat["users"]) == 0: self.api.searchUsername(self.name) response = json.loads(json.dumps(self.api.LastJson)) chats.append({ "thread_name": self.name, "thread_id" : chat["thread_id"], "users" : [self.name], "thread_icon": response["user"]["profile_pic_url"] }) continue for user in chat["users"]: users.append(user["username"]) chats.append({ "thread_name": chat["thread_title"], "thread_id" : chat["thread_id"], "users" : [user["username"] for user in chat["users"]], "thread_icon": chat["users"][0]["profile_pic_url"] }) return chats def getMessages(self, chat_id): self.api.getv2Threads(str(chat_id)) thread = json.loads(json.dumps(self.api.LastJson))["thread"] users = {} #Get list of people for user in thread["users"]: users[user["pk"]] = user["username"] items = [] #List of dict(UID: Item data) for item in thread["items"]: type = item["item_type"] # TODO: Add new messages in this order: image, link, profile if type == "text": items.append({"user" : item["user_id"], "text" : " " * 4 + item["text"], "time" : item["timestamp"], "item_id" : item["item_id"], "show_pfp": True}) elif type == "video_call_event": items.append({"user" : item["user_id"], "text" : " " * 4 + item["video_call_event"]["description"], "time" : item["timestamp"], "item_id" : item["item_id"], "show_pfp": False}) elif type == "like": items.append({"user" : item["user_id"], "text" : u" \u2764\uFE0F", "time" : item["timestamp"], "item_id" : item["item_id"], "show_pfp": True}) else: items.append({"user" : item["user_id"], "text" : " Unsupported message type: " + item["item_type"], "time" : item["timestamp"], "item_id" : item["item_id"], "show_pfp": True}) return items def unsend(self, thread_id, item_id): thread_id = str(thread_id) item_id = str(item_id) endpoint = "direct_v2/threads/"+thread_id+"/items/"+item_id+"/delete/" data = { "_uuid": self.api.uuid, "_csrftoken": self.api.token} response = self.api.s.post(self.api.API_URL + endpoint, data=data) if response.status_code == 200: self.api.LastResponse = response self.api.LastJson = json.loads(response.text) return True else: try: self.api.LastResponse = response self.api.LastJson = json.loads(response.text) except: pass return False
class Main: def __init__(self): IG_NAME = input('Username: '******'Password: '******'10.26.0', '10.34.0') self.broadcast_id = 0 self.chat_thread = threading.Thread(target=self.chat_job, daemon=True) self.isRunning = True def chat_job(self): server = HTTPServer(('', 4132), chat_server.ChatServer) while self.isRunning: server.handle_request() time.sleep(1) a = self.SendRequest(f'live/{self.broadcast_id}/get_comment/', last=False) try: if a['comments']: for comment in a['comments']: try: if comment['user']['username'] == self.api.username: chatter = 'Me' else: chatter = comment['user']['username'] comment_user = {'username': chatter, 'user_id': comment['user_id']} timestamp = time.gmtime(comment['created_at_utc']) comment_time = time.strftime('%H:%M:%S', timestamp) comment_text = comment['text'] comment_id = comment['pk'] chat = { 'id': comment_id, 'user': comment_user, 'text': comment_text, 'time': comment_time } except Exception as e: print(e) if chat in chat_server.GARBAGE: pass else: chat_server.GARBAGE.append(chat) except Exception as e: pass print('Comment Thread Stopped') def create_live(self, msg=''): data = json.dumps({ '_uuid': self.api.uuid, '_csrftoken': self.api.token, 'preview_height': 1280, 'preview_width': 720, 'broadcast_message': msg }) self.api.SendRequest('live/create/', self.api.generateSignature(data)) broadcast_id, live_url, stream_key = (self.api.LastJson['broadcast_id'], self.api.LastJson['upload_url'][:43], self.api.LastJson['upload_url'][43:]) print(f'[*]Broadcast ID: {broadcast_id}\n') print(f'[*]Live Upload URL: {live_url}\n') print(f'[*]Stream Key:\n{stream_key}\n\n') self.broadcast_id = broadcast_id return True def start_live(self): notify = True data = json.dumps({ '_uuid': self.api.uuid, '_csrftoken': self.api.token, 'should_send_notifications': notify }) self.api.SendRequest(f'live/{self.broadcast_id}/start/', self.api.generateSignature(data)) return True def end_live(self): data = json.dumps({ '_uid': self.api.username_id, '_uuid': self.api.uuid, '_csrftoken': self.api.token, 'end_after_copyright_warning': False }) return self.api.SendRequest(f'live/{self.broadcast_id}/end_broadcast/', self.api.generateSignature(data)) def save_post_live(self): trial = 3 posted = bool while trial: trial -= 1 data = json.dumps({ '_uid': self.api.username_id, '_uuid': self.api.uuid, '_csrftoken': self.api.token }) self.api.SendRequest(f'live/{self.broadcast_id}/add_to_post_live', self.api.generateSignature(data)) if self.api.LastResponse.status_code == 200: print('Live Posted to Story!') posted = True break if not posted: print('Vailed to post live to story!') def delete_post_live(self): data = json.dumps({ '_uid': self.api.username_id, '_uuid': self.api.uuid, '_csrftoken': self.api.token }) return self.api.SendRequest(f'live/{self.broadcast_id}/delete_post_live', self.api.generateSignature(data)) def pin_comment(self, comment_id): data = json.dumps({ 'offset_to_video_start': 0, 'comment_id': comment_id, '_uid': self.api.username_id, '_uuid': self.api.uuid, '_csrftoken': self.api.token }) return self.api.SendRequest(f'live/{self.broadcast_id}/pin_comment', self.api.generateSignature(data)) def unpin_comment(self, comment_id): data = json.dumps({ 'offset_to_video_start': 0, 'comment_id': comment_id, '_uid': self.api.username_id, '_uuid': self.api.uuid, '_csrftoken': self.api.token }) return self.api.SendRequest(f'live/{self.broadcast_id}/unpin_comment', self.api.generateSignature(data)) def SendRequest(self, endpoint, post=None, login=False, last=True): verify = False # don't show request warning if not last: if (not self.api.isLoggedIn and not login): raise Exception("Not logged in!\n") self.api.s.headers.update({'Connection': 'close', 'Accept': '*/*', 'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8', 'Cookie2': '$Version=1', 'Accept-Language': 'en-US', 'User-Agent': self.api.USER_AGENT}) while True: try: if (post is not None): response = self.api.s.post(self.api.API_URL + endpoint, data=post, verify=verify) else: response = self.api.s.get(self.api.API_URL + endpoint, verify=verify) break except Exception as e: print('Except on SendRequest (wait 60 sec and resend): ' + str(e)) time.sleep(60) if response.status_code == 200: self.api.LastResponse = response self.api.LastJson = json.loads(response.text) else: print("Request return " + str(response.status_code) + " error!") # for debugging try: self.api.LastResponse = response self.api.LastJson = json.loads(response.text) print(self.api.LastJson) if 'error_type' in self.api.LastJson and self.api.LastJson['error_type'] == 'sentry_block': raise SentryBlockException(self.api.LastJson['message']) except SentryBlockException: raise except: pass return self.api.LastJson else: return self.api.SendRequest(endpoint, post=None, login=False) def live_info(self): _json = self.SendRequest(f'live/{self.broadcast_id}/info/', last=False) dash_url = _json['dash_playback_url'] viewer_count = _json['viewer_count'] _id = _json['id'] owner = _json['broadcast_owner']['username'] status = _json['broadcast_status'] print(f'[*]ID: {_id}') print(f'[*]Broadcast Owner: {owner}') print(f'[*]Dash URL: {dash_url}') print(f'[*]Viewer Count: {viewer_count}') print(f'[*]Status: {status}') def send_comment(self, msg): data = json.dumps({ 'idempotence_token': self.api.generateUUID(True), 'comment_text': msg, 'live_or_vod': 1, 'offset_to_video_start': 0 }) _json = self.SendRequest(f'live/{self.broadcast_id}/comment/', self.api.generateSignature(data), last=False) if _json['status'] == 'ok': return True def exit(self): self.end_live() print('Save Live replay to story ? <y/n>') save = input('command> ') if save == 'y': self.save_post_live() else: self.delete_post_live() print('Exiting...') self.isRunning = False self.chat_thread.join() print('All process Stopped') time.sleep(1) print('Cleaning cache...') def wave(self, userid): data = json.dumps({ '_uid': self.api.username_id, '_uuid': self.api.uuid, '_csrftoken': self.api.token, 'viewer_id': userid }) _json = self.SendRequest(f'live/{self.broadcast_id}/wave/', self.api.generateSignature(data), last=False) if _json: return True def get_viewer_list(self): _json = self.SendRequest(f'live/{self.broadcast_id}/get_viewer_list/', last=False) users = [] ids = [] for user in _json['users']: users.append(f"{user['username']}") ids.append(f"{user['pk']}") return users, ids def run(self): print('[!]logging in...') if self.api.login(): print('[*]logged in!!') print('[!]Generating stream upload_url and keys...\n') self.create_live() print('Now Open Broadcast Software and start streaming on given url and key') input('Press Enter after your Broadcast Software started streaming\n') self.start_live() self.chat_thread.start() print("Chat Server Started") while self.isRunning: cmd = input('command> ') if cmd == 'stop': self.exit() elif cmd == 'wave': users, ids = self.get_viewer_list() for i in range(len(users)): print(f'{i+1}. {users[i]}') print('Type number according to user e.g 1.') while True: cmd = input('number> ') if cmd == 'back': break try: userid = int(cmd) - 1 self.wave(ids[userid]) break except: print('Please type number e.g 1') elif cmd == 'info': self.live_info() elif cmd == 'viewers': users, ids = self.get_viewer_list() print(users) elif cmd[:4] == 'chat': to_send = cmd[5:] if to_send: self.send_comment(to_send) else: print('usage: chat <text to chat>') else: print('Available commands:\n\t"stop"\n\t"info"\n\t"viewers"\n\t"chat"\n\t"wave"')
from InstagramAPI import InstagramAPI api = InstagramAPI("aringhosh", "Asansol@123") if (api.login()): result = api.SendRequest('users/madhubanimotifs/media/recent/') # api.getSelfUserFeed() # get self user feed # print(api.LastJson) # print last response JSON print(result) else: print("Can't login!")