async def open_stories_inline(client, callback): username = callback.data.split(' ')[1] language = get_language(callback.from_user.id, callback.from_user.language_code) key = callback.inline_message_id iterator: InlineStoriesIterator = inline_cached_stories.get(key) profile_userid: List[Profile, int] = inline_cached_profiles.get(key) if profile_userid is None: await callback.answer(get_message(language, "errors/not_cached_post"), show_alert=True) await client.edit_inline_text(key, "@instaStalkieBot", reply_markup="") return right_user_id = profile_userid[1] if callback.from_user.id != right_user_id: await callback.answer(get_message(language, "errors/wrong_id"), show_alert=True) return if iterator is None: user = get_user_id(username) if "username" not in user: await callback.answer(get_message(language, "errors/fail"), show_alert=True) return stories = _request_story(user["user_id"]) if stories == "fail": await callback.answer(get_message(language, "errors/fail"), show_alert=True) return if stories == "no_stories": await callback.answer(get_message(language, "errors/no_stories"), show_alert=True) return iterator = InlineStoriesIterator(stories, username) await callback.answer() story = iterator.next() if iterator.index == -1 else iterator.collection[ iterator.index] date = f"<a href='{story.url}'>{format_date(story.taken_at)}</a>" keyboard = create_keyboard_stories_from_inline(len(iterator.collection), language) await client.edit_inline_text(key, date, reply_markup=keyboard) inline_cached_stories[key] = iterator
async def back_to_profile(_, callback): language = get_language(callback.from_user.id, callback.from_user.language_code) key = f"{callback.message.chat.id}_{callback.message.message_id}" profile: Profile = cached_profiles.get(key) right_user_id = cached_ids.get(key) if profile is None or right_user_id is None: await callback.answer(get_message(language, "errors/not_cached_post"), show_alert=True) await callback.edit_message_text("", reply_markup="") return if callback.from_user.id != right_user_id: await callback.answer(get_message(language, 'errors/wrong_id'), show_alert=True) return await callback.answer() caption = create_caption_profile(profile, language) keyboard = create_keyboard_profile(profile.username, language, profile.is_private) await callback.edit_message_media(InputMediaPhoto(profile.profile_pic, caption=caption), reply_markup=keyboard)
async def open_posts(_, callback): username = callback.data.split(' ')[1] language = get_language(callback.from_user.id, callback.from_user.language_code) key = f"{callback.message.chat.id}_{callback.message.message_id}" profile: Profile = cached_profiles.get(key) right_user_id = cached_ids.get(key) if profile is None or right_user_id is None: await callback.answer(get_message(language, "errors/not_cached_post"), show_alert=True) await callback.edit_message_text("", reply_markup="") return if callback.from_user.id != right_user_id: await callback.answer(get_message(language, "errors/wrong_id"), show_alert=True) return iterator: PostsIterator = cached_posts.get(key) if iterator is None: posts = get_user_posts(username) if posts == "Fail": await callback.answer(get_message(language, "errors/fail"), show_alert=True) return next_max_id = posts.get("next_max_id") iterator = PostsIterator(posts["post_list"], username, next_max_id) cached_posts[key] = iterator await callback.answer() post: Post = iterator.next( ) if iterator.index != -1 else iterator.collection[iterator.index] caption = create_caption_posts(post.caption, post.taken_at, post.views, post.is_video) keyboard = create_keyboard_posts(post.likes, post.comment_number, iterator.username, len(iterator.collection), language, callback.from_user.id, from_profile=True) media = InputMediaVideo(post.source) if post.is_video else InputMediaPhoto( post.source) media.caption = caption await callback.edit_message_media(media) await callback.edit_message_reply_markup(keyboard)
async def back_to_profile_inline(client, callback): key = callback.inline_message_id profile_userid: List[Profile, int] = inline_cached_profiles.get(key) language = get_language(callback.from_user.id, callback.from_user.language_code) if profile_userid is None: await callback.answer(get_message(language, "errors/not_cached_post"), show_alert=True) await client.edit_inline_text(key, "@instaStalkieBot", reply_markup="") return profile = profile_userid[0] right_user_id = profile_userid[1] if callback.from_user.id != right_user_id: await callback.answer(get_message(language, "errors/wrong_id"), show_alert=True) return await callback.answer() caption = create_caption_profile(profile, language, use_link=True) keyboard = create_keyboard_profile_from_inline(profile.username, language, profile.is_private) await client.edit_inline_text(key, caption, reply_markup=keyboard)
async def open_posts_inline(client, callback): username = callback.data.split(' ')[1] language = get_language(callback.from_user.id, callback.from_user.language_code) key = callback.inline_message_id iterator: InlinePostsIterator = inline_cached_posts.get(key) profile_userid: List[Profile, int] = inline_cached_profiles.get(key) if profile_userid is None: await callback.answer(get_message(language, "errors/not_cached_post"), show_alert=True) await client.edit_inline_text(key, "@instaStalkieBot", reply_markup="") return right_user_id = profile_userid[1] if callback.from_user.id != right_user_id: await callback.answer(get_message(language, "errors/wrong_id"), show_alert=True) return if iterator is None: posts = get_user_posts(username) if posts == "Fail": await callback.answer(get_message(language, "errors/fail"), show_alert=True) return next_max_id = posts.get("next_max_id") iterator = InlinePostsIterator(posts["post_list"], username, next_max_id) await callback.answer() post = iterator.next() if iterator.index == -1 else iterator.collection[ iterator.index] caption = create_caption_posts(post.caption, post.taken_at, post.views, post.is_video, link=post.source) keyboard = create_keyboard_posts_from_inline(post.likes, post.comment_number, len(iterator.collection), language) await client.edit_inline_text(key, caption, disable_web_page_preview=False, reply_markup=keyboard) inline_cached_posts[key] = iterator
async def on_stories(_, message): username = '******'.join(message.command[1:]) language = get_language(message.from_user.id, message.from_user.language_code) if username == "": await message.reply_text( get_message(language, "errors/username_not_specified")) return user = get_user_id(username) if "username" not in user: await message.reply_text(get_message(language, "errors/fail")) return wait_message = await message.reply_text(get_message(language, "loading")) stories = _request_story(user["user_id"]) if stories == "private_account": await message.reply_text( get_message(language, "errors/private_account")) return if stories == "no_stories": await message.reply_text(get_message(language, "errors/no_stories")) return iterator = StoriesIterator(stories, username, message.from_user.id) story = iterator.next() date = format_date(story.taken_at) keyboard = create_keyboard_stories(username, len(iterator.collection), language, from_profile=False) try: await wait_message.delete() except: pass if story.type_story == "mp4/video/boomerang": message = await message.reply_video(story.url, caption=date, reply_markup=keyboard) else: message = await message.reply_photo(story.url, caption=date, reply_markup=keyboard) key = f"{message.chat.id}_{message.message_id}" cached_stories[key] = iterator
async def next_post(_, callback): message_id = callback.message.message_id chat_id = callback.message.chat.id key = f"{chat_id}_{message_id}" iterator: PostsIterator = cached_posts.get(key) language = get_language(callback.from_user.id, callback.from_user.language_code) if iterator is None: await callback.answer(get_message(language, "errors/not_cached_post"), show_alert=True) await callback.edit_message_text("", reply_markup="") return if iterator.right_user_id is None: iterator.right_user_id = cached_ids.get(key) if iterator.right_user_id is None: await callback.answer(get_message(language, "errors/not_cached_stories"), show_alert=True) await callback.edit_message_text("", reply_markup="") return if callback.from_user.id != iterator.right_user_id: await callback.answer(get_message(language, "errors/wrong_id"), show_alert=True) return post = iterator.next() if post == "Fail": await callback.answer(get_message(language, "errors/fail"), show_alert=True) return await callback.answer() caption = create_caption_posts(post.caption, post.taken_at, post.views, post.is_video) from_profile = len(callback.data.split(' ')) > 1 keyboard = create_keyboard_posts(post.likes, post.comment_number, iterator.username, len(iterator.collection), callback.from_user.language_code, callback.from_user.id, from_profile=from_profile) media = InputMediaVideo(post.source) if post.is_video else InputMediaPhoto( post.source) media.caption = caption await callback.edit_message_media(media, reply_markup=keyboard)
async def get_comments(_, callback): language = get_language(callback.from_user.id, callback.from_user.language_code) message_id = callback.message.message_id chat_id = callback.message.chat.id key = f"{chat_id}_{message_id}" iterator: PostsIterator = cached_posts.get(key) if iterator is None: await callback.answer(get_message(language, "errors/not_cached_post"), show_alert=True) await callback.edit_message_text("", reply_markup="") return if iterator.right_user_id is None: iterator.right_user_id = cached_ids.get(key) if iterator.right_user_id is None: await callback.answer(get_message(language, "errors/not_cached_stories"), show_alert=True) await callback.edit_message_text("", reply_markup="") return if callback.from_user.id != iterator.right_user_id: await callback.answer(get_message(language, "errors/wrong_id"), show_alert=True) return post = iterator.collection[iterator.index] response = get_post_details(post.shortcode) if response["status"] != "Success": await callback.answer(get_message(language, "errors/fail"), show_alert=True) return await callback.answer() comments_json = response["body"]["edge_media_to_parent_comment"]["edges"] comments = create_caption_comments(comments_json, language) from_profile = len(callback.data.split(' ')) > 1 keyboard = InlineKeyboardMarkup([[ InlineKeyboardButton( f"{emoji.BACK_ARROW} {get_message(language, 'keyboards/back')}", callback_data="back" if not from_profile else "back profile") ]]) await callback.edit_message_caption(comments) await callback.edit_message_reply_markup(keyboard)
async def select_language(_, callback): await callback.answer() language = get_language(callback.from_user.id, callback.from_user.language_code) keyboard = create_languages_keyboard(language) await callback.edit_message_text(get_message(language, "languages/choose_language"), reply_markup=keyboard)
async def on_posts(_, message): username = '******'.join(message.command[1:]) language = get_language(message.from_user.id, message.from_user.language_code) if username == "": await message.reply_text( get_message(language, "errors/username_not_specified")) return wait_message = await message.reply_text(get_message(language, "loading")) posts = get_user_posts(username) if posts == "Fail": await message.reply_text(get_message(language, "errors/fail")) return next_max_id = posts.get("next_max_id") iterator = PostsIterator(posts["post_list"], username, next_max_id, message.from_user.id) post = iterator.next() caption = create_caption_posts(post.caption, post.taken_at, post.views, post.is_video) keyboard = create_keyboard_posts(post.likes, post.comment_number, iterator.username, len(iterator.collection), message.from_user.language_code, message.from_user.id) try: await wait_message.delete() except: pass if post.is_video: message = await message.reply_video(post.source, caption=caption, reply_markup=keyboard) else: message = await message.reply_photo(post.source, caption=caption, reply_markup=keyboard) key = f"{message.chat.id}_{message.message_id}" cached_posts[key] = iterator
async def comments_inline(client, callback): language = get_language(callback.from_user.id, callback.from_user.language_code) key = callback.inline_message_id iterator: InlinePostsIterator = inline_cached_posts.get(key) profile_userid: List[Profile, int] = inline_cached_profiles.get(key) if profile_userid is None: await callback.answer(get_message(language, "errors/not_cached_post"), show_alert=True) await client.edit_inline_text(key, "@instaStalkieBot", reply_markup="") return right_user_id = profile_userid[1] if callback.from_user.id != right_user_id: await callback.answer(get_message(language, "errors/wrong_id"), show_alert=True) return if iterator is None: await callback.answer(get_message(language, "errors/not_cached_post"), show_alert=True) await client.edit_inline_text(key, "@instaStalkieBot", reply_markup="") return await callback.answer() post = iterator.collection[iterator.index] response = get_post_details(post.shortcode) if response["status"] != "Success": await callback.answer(get_message(language, "errors/fail"), show_alert=True) return comments_json = response["body"]["edge_media_to_parent_comment"]["edges"] comments = create_caption_comments(comments_json, language) keyboard = InlineKeyboardMarkup([[ InlineKeyboardButton( f"{emoji.BACK_ARROW} {get_message(language, 'keyboards/back')}", callback_data="inline_back") ]]) await client.edit_inline_text(key, comments, reply_markup=keyboard)
async def next_post_inline(client, callback): key = callback.inline_message_id iterator: InlinePostsIterator = inline_cached_posts.get(key) language = get_language(callback.from_user.id, callback.from_user.language_code) profile_userid: List[Profile, int] = inline_cached_profiles.get(key) if profile_userid is None: await callback.answer(get_message(language, "errors/not_cached_post"), show_alert=True) await client.edit_inline_text(key, "@instaStalkieBot", reply_markup="") return right_user_id = profile_userid[1] if callback.from_user.id != right_user_id: await callback.answer(get_message(language, "errors/wrong_id"), show_alert=True) return if iterator is None: await callback.answer(get_message(language, "errors/not_cached_post"), show_alert=True) await client.edit_inline_text(key, "@instaStalkieBot", reply_markup="") return post = iterator.next() if post == "Fail": await callback.answer(get_message(language, "errors/fail"), show_alert=True) return await callback.answer() caption = create_caption_posts(post.caption, post.taken_at, post.views, post.is_video, link=post.source) keyboard = create_keyboard_posts_from_inline(post.likes, post.comment_number, len(iterator.collection), language) await client.edit_inline_text(key, caption, reply_markup=keyboard)
async def languages_back(_, callback): await callback.answer() language = get_language(callback.from_user.id, callback.from_user.language_code) keyboard = InlineKeyboardMarkup([[ InlineKeyboardButton( f"{get_flag(language)} {get_message(language, 'languages/language')}", callback_data="open_languages_menu") ]]) await callback.edit_message_text(get_message(language, 'languages/click_to_choose'), reply_markup=keyboard)
async def on_profile(_, message, username: str = None): if username is None: username = '******'.join(message.command[1:]) language = get_language(message.from_user.id, message.from_user.language_code) user = get_user_id(username) wait_message = await message.reply_text(get_message(language, "loading")) if "user_id" not in user: await message.reply_text( get_message(language, "errors/non_existent_profile")) return profile = get_email_and_details(user["user_id"]) if profile == "error": await message.reply_text( get_message(language, "errors/non_existent_profile")) return right_user_id = message.from_user.id caption = create_caption_profile(profile, language) keyboard = create_keyboard_profile(profile.username, language, profile.is_private) try: await wait_message.delete() except: pass message = await message.reply_photo(profile.profile_pic, caption=caption, reply_markup=keyboard) key = f"{message.chat.id}_{message.message_id}" cached_profiles[key] = profile cached_ids[key] = right_user_id
async def on_start(_, message): argument = " ".join( message.command[1:]) if len(message.command) > 1 else "" if "profile" in argument: username = argument[len("profile"):] await on_profile(_, message, username) return if argument == "languages": await on_languages(_, message) elif message.chat.type == "private": language = get_language(message.from_user.id, message.from_user.language_code) text = get_message(language, "menu") await message.reply_text('\n'.join(text))
async def on_inline_query(_, query: InlineQuery): to_search = query.query profile_list = search(to_search) inline_query_results = [] language = get_language(query.from_user.id) if profile_list != "nothing_found": if len(profile_list) > 30: profile_list = profile_list[:30] for profile in profile_list: id = str(uuid4()) title = profile.username if profile.is_verified: title += f" {emoji.CHECK_MARK_BUTTON}" new_result = InlineQueryResultArticle( title=title, id=id, thumb_url=profile.profile_pic, description=profile.full_name or None, input_message_content=InputTextMessageContent( message_text=get_message(language, "loading")), reply_markup=InlineKeyboardMarkup([[ InlineKeyboardButton( get_message(language, "loading"), url=f"https://www.instagram.com/{profile.username}") ]])) CACHE[id] = [profile.username, language] inline_query_results.append(new_result) else: inline_query_results.append(profiles_not_found(language)) await query.answer(inline_query_results, cache_time=0)
async def random_story_inline(client, callback): key = callback.inline_message_id iterator: InlineStoriesIterator = inline_cached_stories.get(key) language = get_language(callback.from_user.id, callback.from_user.language_code) profile_userid: List[Profile, int] = inline_cached_profiles.get(key) if profile_userid is None: await callback.answer(get_message(language, "errors/not_cached_post"), show_alert=True) await client.edit_inline_text(key, "@instaStalkieBot", reply_markup="") return right_user_id = profile_userid[1] if callback.from_user.id != right_user_id: await callback.answer(get_message(language, "errors/wrong_id"), show_alert=True) return if iterator is None: await callback.answer(get_message(language, "errors/not_cached_post"), show_alert=True) await client.edit_inline_text(key, "@instaStalkieBot", reply_markup="") return await callback.answer() story = iterator.random() caption = f"<a href='{story.url}'>{format_date(story.taken_at)}</a>" keyboard = create_keyboard_stories_from_inline(len(iterator.collection), language) await client.edit_inline_text(key, caption, reply_markup=keyboard)
async def on_languages(_, message): language = get_language(message.from_user.id, message.from_user.language_code) if message.chat.type == "private": text = get_message(language, 'languages/click_to_choose') keyboard = InlineKeyboardMarkup([[ InlineKeyboardButton( f"{get_flag(language)} {get_message(language, 'languages/language')}", callback_data="open_languages_menu") ]]) else: text = get_message(language, 'languages/redirect_text') keyboard = InlineKeyboardMarkup([[ InlineKeyboardButton( emoji.LOCKED, url="https://t.me/instaStalkieBot?start=languages") ]]) await message.reply_text(text, reply_markup=keyboard)
def create_keyboard_posts(post_likes: int, post_comments: int, username: str, num_posts: int, language_code: str, user_id: int, from_profile: bool = False) -> InlineKeyboardMarkup: language = get_language(user_id, language_code) keyboard = [ [ InlineKeyboardButton(f"{emoji.RED_HEART} {human_format(post_likes)}", callback_data="likes" if not from_profile else "likes profile"), InlineKeyboardButton(f"{emoji.BOOKMARK_TABS} {human_format(post_comments)}", callback_data="comments" if not from_profile else "comments profile") ] ] if num_posts != 1: keyboard.append([ InlineKeyboardButton(f"{emoji.LEFT_ARROW} {get_message(language, 'posts/previous')}", callback_data="previous_post" if not from_profile else "previous_post profile"), InlineKeyboardButton(f"{emoji.GAME_DIE} {get_message(language, 'posts/random')}", callback_data="random_post" if not from_profile else "previous_post profile"), InlineKeyboardButton(f"{emoji.RIGHT_ARROW} {get_message(language, 'posts/next')}", callback_data="next_post" if not from_profile else "next_post profile") ]) if from_profile: end_button = InlineKeyboardButton( f"{emoji.BACK_ARROW} {get_message(language, 'keyboards/back')}", callback_data=f"to-profile-back {username}" ) else: end_button = InlineKeyboardButton( f"{emoji.BOY_LIGHT_SKIN_TONE} {get_message(language, 'keyboards/view_online')}", url=f"https://www.instagram.com/{username}" ) keyboard.append([end_button]) return InlineKeyboardMarkup(keyboard)
async def open_stories(_, callback): username = callback.data.split(' ')[1] language = get_language(callback.from_user.id, callback.from_user.language_code) key = f"{callback.message.chat.id}_{callback.message.message_id}" profile: Profile = cached_profiles.get(key) right_user_id = cached_ids.get(key) if profile is None or right_user_id is None: await callback.answer(get_message(language, "errors/no_cached_post"), show_alert=True) await callback.edit_message_text("", reply_markup="") return if callback.from_user.id != right_user_id: await callback.answer(get_message(language, 'errors/wrong_id'), show_alert=True) return iterator: StoriesIterator = cached_stories.get(key) if iterator is None: user = get_user_id(username) if "username" not in user: await callback.answer(get_message(language, "errors/fail")) return stories = _request_story(user["user_id"]) if stories == "private_account": await callback.answer( get_message(language, "errors/private_account")) return if stories == "no_stories": await callback.answer(get_message(language, "errors/no_stories")) return iterator = StoriesIterator(stories, username) cached_stories[key] = iterator await callback.answer() story: Story = iterator.next( ) if iterator.index != -1 else iterator.collection[iterator.index] caption = format_date(story.taken_at) keyboard = create_keyboard_stories(iterator.username, len(iterator.collection), language, from_profile=True) media = InputMediaVideo( story.url ) if story.type_story == "mp4/video/boomerang" else InputMediaPhoto( story.url) media.caption = caption await callback.edit_message_media(media, reply_markup=keyboard)