darkob 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- darkob-0.2.0/LICENSE +21 -0
- darkob-0.2.0/PKG-INFO +282 -0
- darkob-0.2.0/README.md +225 -0
- darkob-0.2.0/darkob/TheBot.py +114 -0
- darkob-0.2.0/darkob/TheClient.py +234 -0
- darkob-0.2.0/darkob/__init__.py +169 -0
- darkob-0.2.0/darkob/bot/__init__.py +86 -0
- darkob-0.2.0/darkob/bot/auto_delete_message.py +24 -0
- darkob-0.2.0/darkob/bot/ban_member.py +37 -0
- darkob-0.2.0/darkob/bot/bot_status.py +31 -0
- darkob-0.2.0/darkob/bot/bridge.py +97 -0
- darkob-0.2.0/darkob/bot/callback.py +24 -0
- darkob-0.2.0/darkob/bot/command.py +37 -0
- darkob-0.2.0/darkob/bot/delete_message.py +36 -0
- darkob-0.2.0/darkob/bot/download_file.py +186 -0
- darkob-0.2.0/darkob/bot/edit_chat_keypad.py +84 -0
- darkob-0.2.0/darkob/bot/edit_inline_keypad.py +87 -0
- darkob-0.2.0/darkob/bot/edit_message.py +67 -0
- darkob-0.2.0/darkob/bot/event_data.py +46 -0
- darkob-0.2.0/darkob/bot/exceptions.py +93 -0
- darkob-0.2.0/darkob/bot/file_extensions.py +205 -0
- darkob-0.2.0/darkob/bot/filters.py +523 -0
- darkob-0.2.0/darkob/bot/forward_message.py +60 -0
- darkob-0.2.0/darkob/bot/get_chat_info.py +22 -0
- darkob-0.2.0/darkob/bot/get_chat_member.py +37 -0
- darkob-0.2.0/darkob/bot/get_file.py +12 -0
- darkob-0.2.0/darkob/bot/get_me.py +11 -0
- darkob-0.2.0/darkob/bot/get_token_string.py +23 -0
- darkob-0.2.0/darkob/bot/get_updates.py +27 -0
- darkob-0.2.0/darkob/bot/keypad_mixin.py +131 -0
- darkob-0.2.0/darkob/bot/lifecycle.py +27 -0
- darkob-0.2.0/darkob/bot/member_is_admin.py +24 -0
- darkob-0.2.0/darkob/bot/member_is_joined.py +24 -0
- darkob-0.2.0/darkob/bot/member_is_owner.py +24 -0
- darkob-0.2.0/darkob/bot/message.py +77 -0
- darkob-0.2.0/darkob/bot/message_result.py +40 -0
- darkob-0.2.0/darkob/bot/metadata.py +175 -0
- darkob-0.2.0/darkob/bot/middleware.py +25 -0
- darkob-0.2.0/darkob/bot/plugin.py +541 -0
- darkob-0.2.0/darkob/bot/register_all_endpoints.py +45 -0
- darkob-0.2.0/darkob/bot/registry.py +143 -0
- darkob-0.2.0/darkob/bot/remove_chat_keypad.py +24 -0
- darkob-0.2.0/darkob/bot/remove_member.py +32 -0
- darkob-0.2.0/darkob/bot/request.py +113 -0
- darkob-0.2.0/darkob/bot/request_send_file.py +42 -0
- darkob-0.2.0/darkob/bot/run.py +45 -0
- darkob-0.2.0/darkob/bot/send_contact.py +83 -0
- darkob-0.2.0/darkob/bot/send_file.py +136 -0
- darkob-0.2.0/darkob/bot/send_gif.py +54 -0
- darkob-0.2.0/darkob/bot/send_image.py +54 -0
- darkob-0.2.0/darkob/bot/send_location.py +87 -0
- darkob-0.2.0/darkob/bot/send_message.py +88 -0
- darkob-0.2.0/darkob/bot/send_music.py +54 -0
- darkob-0.2.0/darkob/bot/send_poll.py +102 -0
- darkob-0.2.0/darkob/bot/send_quiz.py +134 -0
- darkob-0.2.0/darkob/bot/send_video.py +54 -0
- darkob-0.2.0/darkob/bot/send_voice.py +54 -0
- darkob-0.2.0/darkob/bot/session.py +97 -0
- darkob-0.2.0/darkob/bot/set_commands.py +55 -0
- darkob-0.2.0/darkob/bot/start.py +142 -0
- darkob-0.2.0/darkob/bot/token.py +79 -0
- darkob-0.2.0/darkob/bot/unban_member.py +37 -0
- darkob-0.2.0/darkob/bot/update_bot_endpoints.py +56 -0
- darkob-0.2.0/darkob/bot/updates.py +39 -0
- darkob-0.2.0/darkob/bot/upload_file.py +134 -0
- darkob-0.2.0/darkob/client/__init__.py +31 -0
- darkob-0.2.0/darkob/client/base/__init__.py +26 -0
- darkob-0.2.0/darkob/client/base/connect.py +28 -0
- darkob-0.2.0/darkob/client/base/disconnect.py +41 -0
- darkob-0.2.0/darkob/client/base/download_file.py +170 -0
- darkob-0.2.0/darkob/client/base/get_string_session.py +33 -0
- darkob-0.2.0/darkob/client/base/get_updates.py +101 -0
- darkob-0.2.0/darkob/client/base/request.py +108 -0
- darkob-0.2.0/darkob/client/base/run.py +19 -0
- darkob-0.2.0/darkob/client/base/send_code.py +30 -0
- darkob-0.2.0/darkob/client/base/sign_in.py +32 -0
- darkob-0.2.0/darkob/client/base/start.py +288 -0
- darkob-0.2.0/darkob/client/base/upload_file.py +173 -0
- darkob-0.2.0/darkob/client/bots/__init__.py +18 -0
- darkob-0.2.0/darkob/client/bots/delete_bot_chat.py +40 -0
- darkob-0.2.0/darkob/client/bots/delete_service_chat.py +38 -0
- darkob-0.2.0/darkob/client/bots/get_bot_info.py +21 -0
- darkob-0.2.0/darkob/client/bots/get_inline_bots.py +35 -0
- darkob-0.2.0/darkob/client/bots/get_service_info.py +18 -0
- darkob-0.2.0/darkob/client/bots/start_bot.py +19 -0
- darkob-0.2.0/darkob/client/bots/stop_bot.py +19 -0
- darkob-0.2.0/darkob/client/channels/__init__.py +44 -0
- darkob-0.2.0/darkob/client/channels/check_channel_username.py +17 -0
- darkob-0.2.0/darkob/client/channels/create_channel.py +100 -0
- darkob-0.2.0/darkob/client/channels/delete_channel.py +46 -0
- darkob-0.2.0/darkob/client/channels/edit_channel_info.py +101 -0
- darkob-0.2.0/darkob/client/channels/edit_channel_title.py +19 -0
- darkob-0.2.0/darkob/client/channels/get_channel_admin_access.py +35 -0
- darkob-0.2.0/darkob/client/channels/get_channel_admins.py +72 -0
- darkob-0.2.0/darkob/client/channels/get_channel_info.py +21 -0
- darkob-0.2.0/darkob/client/channels/get_channel_link.py +21 -0
- darkob-0.2.0/darkob/client/channels/get_channel_members.py +36 -0
- darkob-0.2.0/darkob/client/channels/get_channel_post_by_link.py +105 -0
- darkob-0.2.0/darkob/client/channels/get_channel_seen_count.py +36 -0
- darkob-0.2.0/darkob/client/channels/get_channel_statistics.py +27 -0
- darkob-0.2.0/darkob/client/channels/get_post_by_ask_link.py +90 -0
- darkob-0.2.0/darkob/client/channels/join_channel.py +33 -0
- darkob-0.2.0/darkob/client/channels/leave_channel.py +24 -0
- darkob-0.2.0/darkob/client/channels/seen_channel_messages.py +36 -0
- darkob-0.2.0/darkob/client/channels/set_channel_link.py +21 -0
- darkob-0.2.0/darkob/client/channels/set_channel_type.py +20 -0
- darkob-0.2.0/darkob/client/channels/update_channel_username.py +58 -0
- darkob-0.2.0/darkob/client/chats/__init__.py +162 -0
- darkob-0.2.0/darkob/client/chats/accept_all_join_requests.py +72 -0
- darkob-0.2.0/darkob/client/chats/accept_join_request.py +40 -0
- darkob-0.2.0/darkob/client/chats/accept_ownership_request.py +30 -0
- darkob-0.2.0/darkob/client/chats/add_members.py +59 -0
- darkob-0.2.0/darkob/client/chats/archive_chat.py +22 -0
- darkob-0.2.0/darkob/client/chats/ban_member.py +49 -0
- darkob-0.2.0/darkob/client/chats/ban_members.py +24 -0
- darkob-0.2.0/darkob/client/chats/cancel_change_owner.py +27 -0
- darkob-0.2.0/darkob/client/chats/change_owner.py +43 -0
- darkob-0.2.0/darkob/client/chats/check_join.py +108 -0
- darkob-0.2.0/darkob/client/chats/clear_all_drafts.py +11 -0
- darkob-0.2.0/darkob/client/chats/clear_black_list.py +68 -0
- darkob-0.2.0/darkob/client/chats/clear_chat_draft.py +25 -0
- darkob-0.2.0/darkob/client/chats/click_chat_ads.py +25 -0
- darkob-0.2.0/darkob/client/chats/click_keypad_button.py +70 -0
- darkob-0.2.0/darkob/client/chats/create_join_link.py +47 -0
- darkob-0.2.0/darkob/client/chats/delete_all_avatars.py +47 -0
- darkob-0.2.0/darkob/client/chats/delete_avatar.py +35 -0
- darkob-0.2.0/darkob/client/chats/delete_chat_history.py +36 -0
- darkob-0.2.0/darkob/client/chats/discard_voice_chat.py +40 -0
- darkob-0.2.0/darkob/client/chats/dont_show_chat_ads.py +25 -0
- darkob-0.2.0/darkob/client/chats/download_profile_picture.py +176 -0
- darkob-0.2.0/darkob/client/chats/edit_join_link.py +71 -0
- darkob-0.2.0/darkob/client/chats/get_all_drafts.py +11 -0
- darkob-0.2.0/darkob/client/chats/get_avatars.py +20 -0
- darkob-0.2.0/darkob/client/chats/get_banned_members.py +70 -0
- darkob-0.2.0/darkob/client/chats/get_chat_ads.py +19 -0
- darkob-0.2.0/darkob/client/chats/get_chat_info.py +66 -0
- darkob-0.2.0/darkob/client/chats/get_chat_voice_chat.py +40 -0
- darkob-0.2.0/darkob/client/chats/get_chats.py +65 -0
- darkob-0.2.0/darkob/client/chats/get_chats_info.py +30 -0
- darkob-0.2.0/darkob/client/chats/get_chats_updates.py +23 -0
- darkob-0.2.0/darkob/client/chats/get_guid.py +78 -0
- darkob-0.2.0/darkob/client/chats/get_info_by_link.py +47 -0
- darkob-0.2.0/darkob/client/chats/get_info_by_username.py +39 -0
- darkob-0.2.0/darkob/client/chats/get_join_links.py +32 -0
- darkob-0.2.0/darkob/client/chats/get_join_requests.py +77 -0
- darkob-0.2.0/darkob/client/chats/get_my_guid.py +11 -0
- darkob-0.2.0/darkob/client/chats/get_pending_owner.py +25 -0
- darkob-0.2.0/darkob/client/chats/get_profile_link_items.py +16 -0
- darkob-0.2.0/darkob/client/chats/get_related_chats.py +16 -0
- darkob-0.2.0/darkob/client/chats/get_voice_chat_participants.py +88 -0
- darkob-0.2.0/darkob/client/chats/get_voice_chat_updates.py +50 -0
- darkob-0.2.0/darkob/client/chats/join_chat.py +24 -0
- darkob-0.2.0/darkob/client/chats/join_voice_chat.py +63 -0
- darkob-0.2.0/darkob/client/chats/leave_chat.py +24 -0
- darkob-0.2.0/darkob/client/chats/leave_voice_chat.py +40 -0
- darkob-0.2.0/darkob/client/chats/member_is_admin.py +37 -0
- darkob-0.2.0/darkob/client/chats/mute_chat.py +41 -0
- darkob-0.2.0/darkob/client/chats/pin_chat.py +19 -0
- darkob-0.2.0/darkob/client/chats/pin_chat_in_folder.py +29 -0
- darkob-0.2.0/darkob/client/chats/play_voice_chat.py +172 -0
- darkob-0.2.0/darkob/client/chats/reject_join_request.py +40 -0
- darkob-0.2.0/darkob/client/chats/reject_ownership_request.py +27 -0
- darkob-0.2.0/darkob/client/chats/report_chat.py +70 -0
- darkob-0.2.0/darkob/client/chats/report_chat_ads.py +26 -0
- darkob-0.2.0/darkob/client/chats/revoke_join_link.py +35 -0
- darkob-0.2.0/darkob/client/chats/search_global_chats.py +46 -0
- darkob-0.2.0/darkob/client/chats/seen_chats.py +14 -0
- darkob-0.2.0/darkob/client/chats/send_chat_activity.py +36 -0
- darkob-0.2.0/darkob/client/chats/send_voice_chat_activity.py +51 -0
- darkob-0.2.0/darkob/client/chats/set_admin.py +89 -0
- darkob-0.2.0/darkob/client/chats/set_ask_spam.py +55 -0
- darkob-0.2.0/darkob/client/chats/set_chat_auto_delete.py +46 -0
- darkob-0.2.0/darkob/client/chats/set_chat_protected_content.py +30 -0
- darkob-0.2.0/darkob/client/chats/set_chat_use_time.py +30 -0
- darkob-0.2.0/darkob/client/chats/set_voice_chat_setting.py +58 -0
- darkob-0.2.0/darkob/client/chats/set_voice_chat_state.py +48 -0
- darkob-0.2.0/darkob/client/chats/start_voice_chat.py +24 -0
- darkob-0.2.0/darkob/client/chats/unarchive_chat.py +19 -0
- darkob-0.2.0/darkob/client/chats/unban_all_members.py +68 -0
- darkob-0.2.0/darkob/client/chats/unban_member.py +49 -0
- darkob-0.2.0/darkob/client/chats/unban_members.py +24 -0
- darkob-0.2.0/darkob/client/chats/unmute_chat.py +19 -0
- darkob-0.2.0/darkob/client/chats/unpin_chat.py +19 -0
- darkob-0.2.0/darkob/client/chats/unpin_chat_in_folder.py +29 -0
- darkob-0.2.0/darkob/client/chats/unset_admin.py +51 -0
- darkob-0.2.0/darkob/client/chats/upload_avatar.py +73 -0
- darkob-0.2.0/darkob/client/chats/view_chat_ads.py +25 -0
- darkob-0.2.0/darkob/client/core/__init__.py +8 -0
- darkob-0.2.0/darkob/client/core/api.py +376 -0
- darkob-0.2.0/darkob/client/core/cipher.py +128 -0
- darkob-0.2.0/darkob/client/core/configs.py +142 -0
- darkob-0.2.0/darkob/client/core/handler_manager.py +17 -0
- darkob-0.2.0/darkob/client/core/handlers.py +87 -0
- darkob-0.2.0/darkob/client/core/media.py +276 -0
- darkob-0.2.0/darkob/client/core/metadata.py +180 -0
- darkob-0.2.0/darkob/client/core/session.py +308 -0
- darkob-0.2.0/darkob/client/decorators/__init__.py +38 -0
- darkob-0.2.0/darkob/client/decorators/on_add_reaction.py +37 -0
- darkob-0.2.0/darkob/client/decorators/on_call_signal.py +23 -0
- darkob-0.2.0/darkob/client/decorators/on_call_update.py +23 -0
- darkob-0.2.0/darkob/client/decorators/on_chat_updates.py +23 -0
- darkob-0.2.0/darkob/client/decorators/on_delete_message.py +32 -0
- darkob-0.2.0/darkob/client/decorators/on_draft_message.py +23 -0
- darkob-0.2.0/darkob/client/decorators/on_edit_message.py +32 -0
- darkob-0.2.0/darkob/client/decorators/on_message.py +12 -0
- darkob-0.2.0/darkob/client/decorators/on_new_message.py +32 -0
- darkob-0.2.0/darkob/client/decorators/on_remove_notifications.py +21 -0
- darkob-0.2.0/darkob/client/decorators/on_remove_reaction.py +37 -0
- darkob-0.2.0/darkob/client/decorators/on_scheduled_message.py +23 -0
- darkob-0.2.0/darkob/client/decorators/on_show_activities.py +23 -0
- darkob-0.2.0/darkob/client/decorators/on_show_notifications.py +23 -0
- darkob-0.2.0/darkob/client/decorators/on_unconfirmed_session.py +23 -0
- darkob-0.2.0/darkob/client/decorators/on_voice_chat_participant.py +23 -0
- darkob-0.2.0/darkob/client/decorators/on_voice_chat_update.py +17 -0
- darkob-0.2.0/darkob/client/enums.py +94 -0
- darkob-0.2.0/darkob/client/exceptions.py +249 -0
- darkob-0.2.0/darkob/client/extras/__init__.py +64 -0
- darkob-0.2.0/darkob/client/extras/add_live_comment.py +28 -0
- darkob-0.2.0/darkob/client/extras/add_sticker_set.py +23 -0
- darkob-0.2.0/darkob/client/extras/add_to_my_gif_set.py +25 -0
- darkob-0.2.0/darkob/client/extras/archive_sticker_set.py +23 -0
- darkob-0.2.0/darkob/client/extras/delete_all_my_gif_set.py +35 -0
- darkob-0.2.0/darkob/client/extras/delete_my_gif_set.py +14 -0
- darkob-0.2.0/darkob/client/extras/delete_sticker_set.py +19 -0
- darkob-0.2.0/darkob/client/extras/feedback_voice_transcription.py +46 -0
- darkob-0.2.0/darkob/client/extras/get_available_reactions.py +11 -0
- darkob-0.2.0/darkob/client/extras/get_link_from_app_url.py +20 -0
- darkob-0.2.0/darkob/client/extras/get_live_comments.py +25 -0
- darkob-0.2.0/darkob/client/extras/get_live_play_url.py +25 -0
- darkob-0.2.0/darkob/client/extras/get_live_status.py +25 -0
- darkob-0.2.0/darkob/client/extras/get_location_view.py +40 -0
- darkob-0.2.0/darkob/client/extras/get_my_archived_sticker_sets.py +24 -0
- darkob-0.2.0/darkob/client/extras/get_my_gif_set.py +11 -0
- darkob-0.2.0/darkob/client/extras/get_my_sticker_sets.py +11 -0
- darkob-0.2.0/darkob/client/extras/get_sticker_set_by_id.py +17 -0
- darkob-0.2.0/darkob/client/extras/get_sticker_setting.py +11 -0
- darkob-0.2.0/darkob/client/extras/get_stickers_by_emoji.py +22 -0
- darkob-0.2.0/darkob/client/extras/get_stickers_by_set_ids.py +21 -0
- darkob-0.2.0/darkob/client/extras/get_time.py +11 -0
- darkob-0.2.0/darkob/client/extras/get_trend_sticker_sets.py +17 -0
- darkob-0.2.0/darkob/client/extras/get_wallet_transaction_message.py +25 -0
- darkob-0.2.0/darkob/client/extras/get_wallpapers.py +11 -0
- darkob-0.2.0/darkob/client/extras/reorder_sticker_sets.py +28 -0
- darkob-0.2.0/darkob/client/extras/report_live.py +68 -0
- darkob-0.2.0/darkob/client/extras/reset_wallpapers.py +11 -0
- darkob-0.2.0/darkob/client/extras/search_stickers.py +21 -0
- darkob-0.2.0/darkob/client/extras/set_current_live_location.py +42 -0
- darkob-0.2.0/darkob/client/filters.py +502 -0
- darkob-0.2.0/darkob/client/groups/__init__.py +48 -0
- darkob-0.2.0/darkob/client/groups/create_group.py +96 -0
- darkob-0.2.0/darkob/client/groups/delete_group.py +46 -0
- darkob-0.2.0/darkob/client/groups/edit_group_info.py +198 -0
- darkob-0.2.0/darkob/client/groups/edit_group_timer.py +18 -0
- darkob-0.2.0/darkob/client/groups/edit_group_title.py +19 -0
- darkob-0.2.0/darkob/client/groups/edit_slow_mode.py +18 -0
- darkob-0.2.0/darkob/client/groups/get_group_admin_access.py +35 -0
- darkob-0.2.0/darkob/client/groups/get_group_admins.py +72 -0
- darkob-0.2.0/darkob/client/groups/get_group_default_access.py +21 -0
- darkob-0.2.0/darkob/client/groups/get_group_info.py +21 -0
- darkob-0.2.0/darkob/client/groups/get_group_link.py +21 -0
- darkob-0.2.0/darkob/client/groups/get_group_members.py +36 -0
- darkob-0.2.0/darkob/client/groups/get_group_mention_list.py +29 -0
- darkob-0.2.0/darkob/client/groups/get_group_message_read_participants.py +33 -0
- darkob-0.2.0/darkob/client/groups/get_group_online_count.py +21 -0
- darkob-0.2.0/darkob/client/groups/get_unread_mentions.py +43 -0
- darkob-0.2.0/darkob/client/groups/join_group.py +25 -0
- darkob-0.2.0/darkob/client/groups/leave_group.py +21 -0
- darkob-0.2.0/darkob/client/groups/lock_group.py +32 -0
- darkob-0.2.0/darkob/client/groups/set_group_default_access.py +49 -0
- darkob-0.2.0/darkob/client/groups/set_group_link.py +21 -0
- darkob-0.2.0/darkob/client/groups/unlock_group.py +32 -0
- darkob-0.2.0/darkob/client/messages/__init__.py +124 -0
- darkob-0.2.0/darkob/client/messages/add_reaction.py +32 -0
- darkob-0.2.0/darkob/client/messages/auto_delete_message.py +27 -0
- darkob-0.2.0/darkob/client/messages/click_inline_button.py +43 -0
- darkob-0.2.0/darkob/client/messages/click_message_url.py +31 -0
- darkob-0.2.0/darkob/client/messages/delete_all_messages.py +79 -0
- darkob-0.2.0/darkob/client/messages/delete_messages.py +62 -0
- darkob-0.2.0/darkob/client/messages/delete_my_messages.py +58 -0
- darkob-0.2.0/darkob/client/messages/edit_message.py +47 -0
- darkob-0.2.0/darkob/client/messages/forward_messages.py +90 -0
- darkob-0.2.0/darkob/client/messages/get_all_messages.py +75 -0
- darkob-0.2.0/darkob/client/messages/get_chat_messages.py +124 -0
- darkob-0.2.0/darkob/client/messages/get_first_message.py +33 -0
- darkob-0.2.0/darkob/client/messages/get_first_messages.py +54 -0
- darkob-0.2.0/darkob/client/messages/get_last_message.py +32 -0
- darkob-0.2.0/darkob/client/messages/get_last_messages.py +64 -0
- darkob-0.2.0/darkob/client/messages/get_message_info.py +32 -0
- darkob-0.2.0/darkob/client/messages/get_message_url.py +28 -0
- darkob-0.2.0/darkob/client/messages/get_messages.py +223 -0
- darkob-0.2.0/darkob/client/messages/get_messages_by_id.py +64 -0
- darkob-0.2.0/darkob/client/messages/get_messages_interval.py +28 -0
- darkob-0.2.0/darkob/client/messages/get_messages_reactions.py +31 -0
- darkob-0.2.0/darkob/client/messages/get_messages_updates.py +28 -0
- darkob-0.2.0/darkob/client/messages/get_pinned_messages.py +37 -0
- darkob-0.2.0/darkob/client/messages/get_poll_option_voters.py +27 -0
- darkob-0.2.0/darkob/client/messages/get_poll_status.py +14 -0
- darkob-0.2.0/darkob/client/messages/get_scheduled_messages.py +29 -0
- darkob-0.2.0/darkob/client/messages/mark_as_read.py +24 -0
- darkob-0.2.0/darkob/client/messages/mark_as_seen.py +25 -0
- darkob-0.2.0/darkob/client/messages/message_result.py +30 -0
- darkob-0.2.0/darkob/client/messages/pin_message.py +29 -0
- darkob-0.2.0/darkob/client/messages/remove_reaction.py +32 -0
- darkob-0.2.0/darkob/client/messages/report_message.py +73 -0
- darkob-0.2.0/darkob/client/messages/request_send_file.py +27 -0
- darkob-0.2.0/darkob/client/messages/retract_poll.py +23 -0
- darkob-0.2.0/darkob/client/messages/search_chat_messages.py +38 -0
- darkob-0.2.0/darkob/client/messages/search_global_messages.py +33 -0
- darkob-0.2.0/darkob/client/messages/search_messages.py +42 -0
- darkob-0.2.0/darkob/client/messages/send_contact.py +62 -0
- darkob-0.2.0/darkob/client/messages/send_file.py +59 -0
- darkob-0.2.0/darkob/client/messages/send_gif.py +73 -0
- darkob-0.2.0/darkob/client/messages/send_image.py +72 -0
- darkob-0.2.0/darkob/client/messages/send_live.py +69 -0
- darkob-0.2.0/darkob/client/messages/send_location.py +50 -0
- darkob-0.2.0/darkob/client/messages/send_message.py +275 -0
- darkob-0.2.0/darkob/client/messages/send_message_api_call.py +50 -0
- darkob-0.2.0/darkob/client/messages/send_music.py +64 -0
- darkob-0.2.0/darkob/client/messages/send_now_scheduled_message.py +29 -0
- darkob-0.2.0/darkob/client/messages/send_poll.py +63 -0
- darkob-0.2.0/darkob/client/messages/send_quiz.py +94 -0
- darkob-0.2.0/darkob/client/messages/send_rubino_post.py +35 -0
- darkob-0.2.0/darkob/client/messages/send_rubino_product.py +38 -0
- darkob-0.2.0/darkob/client/messages/send_rubino_story.py +42 -0
- darkob-0.2.0/darkob/client/messages/send_sticker.py +57 -0
- darkob-0.2.0/darkob/client/messages/send_video.py +75 -0
- darkob-0.2.0/darkob/client/messages/send_video_message.py +75 -0
- darkob-0.2.0/darkob/client/messages/send_voice.py +61 -0
- darkob-0.2.0/darkob/client/messages/stop_poll.py +23 -0
- darkob-0.2.0/darkob/client/messages/transcribe_voice.py +45 -0
- darkob-0.2.0/darkob/client/messages/unpin_all_messages.py +23 -0
- darkob-0.2.0/darkob/client/messages/unpin_message.py +29 -0
- darkob-0.2.0/darkob/client/messages/vote_poll.py +22 -0
- darkob-0.2.0/darkob/client/settings/__init__.py +100 -0
- darkob-0.2.0/darkob/client/settings/abort_two_step_setup.py +11 -0
- darkob-0.2.0/darkob/client/settings/add_folder.py +159 -0
- darkob-0.2.0/darkob/client/settings/add_saved_music_playlist.py +81 -0
- darkob-0.2.0/darkob/client/settings/add_saved_music_track.py +78 -0
- darkob-0.2.0/darkob/client/settings/auto_delete_account.py +23 -0
- darkob-0.2.0/darkob/client/settings/change_password.py +28 -0
- darkob-0.2.0/darkob/client/settings/check_two_step_passcode.py +14 -0
- darkob-0.2.0/darkob/client/settings/confirm_unconfirmed_session.py +23 -0
- darkob-0.2.0/darkob/client/settings/delete_account.py +16 -0
- darkob-0.2.0/darkob/client/settings/delete_folder.py +17 -0
- darkob-0.2.0/darkob/client/settings/delete_saved_music_playlist.py +46 -0
- darkob-0.2.0/darkob/client/settings/deny_unconfirmed_session.py +23 -0
- darkob-0.2.0/darkob/client/settings/edit_can_called_by.py +27 -0
- darkob-0.2.0/darkob/client/settings/edit_can_join_chat_by.py +27 -0
- darkob-0.2.0/darkob/client/settings/edit_show_birthday.py +27 -0
- darkob-0.2.0/darkob/client/settings/edit_show_last_online.py +27 -0
- darkob-0.2.0/darkob/client/settings/edit_show_phone_number.py +27 -0
- darkob-0.2.0/darkob/client/settings/edit_show_profile_photo.py +27 -0
- darkob-0.2.0/darkob/client/settings/get_folders.py +19 -0
- darkob-0.2.0/darkob/client/settings/get_my_sessions.py +11 -0
- darkob-0.2.0/darkob/client/settings/get_notification_setting.py +11 -0
- darkob-0.2.0/darkob/client/settings/get_privacy_setting.py +11 -0
- darkob-0.2.0/darkob/client/settings/get_suggested_folders.py +11 -0
- darkob-0.2.0/darkob/client/settings/get_two_passcode_status.py +11 -0
- darkob-0.2.0/darkob/client/settings/get_unconfirmed_sessions.py +11 -0
- darkob-0.2.0/darkob/client/settings/login_disable_two_step.py +32 -0
- darkob-0.2.0/darkob/client/settings/login_two_step_forget_password.py +30 -0
- darkob-0.2.0/darkob/client/settings/logout.py +38 -0
- darkob-0.2.0/darkob/client/settings/register_device.py +135 -0
- darkob-0.2.0/darkob/client/settings/reorder_folder.py +24 -0
- darkob-0.2.0/darkob/client/settings/request_change_phone_number.py +30 -0
- darkob-0.2.0/darkob/client/settings/request_forget_password.py +11 -0
- darkob-0.2.0/darkob/client/settings/request_recovery_email.py +25 -0
- darkob-0.2.0/darkob/client/settings/set_notification.py +64 -0
- darkob-0.2.0/darkob/client/settings/set_saved_music_playlist.py +78 -0
- darkob-0.2.0/darkob/client/settings/set_setting.py +233 -0
- darkob-0.2.0/darkob/client/settings/set_two_step_verification.py +29 -0
- darkob-0.2.0/darkob/client/settings/terminate_other_sessions.py +11 -0
- darkob-0.2.0/darkob/client/settings/terminate_session.py +14 -0
- darkob-0.2.0/darkob/client/settings/turn_off_two_step.py +14 -0
- darkob-0.2.0/darkob/client/settings/update_my_bio.py +27 -0
- darkob-0.2.0/darkob/client/settings/update_my_birthday.py +38 -0
- darkob-0.2.0/darkob/client/settings/update_my_name.py +38 -0
- darkob-0.2.0/darkob/client/settings/update_my_profile.py +74 -0
- darkob-0.2.0/darkob/client/settings/update_my_username.py +41 -0
- darkob-0.2.0/darkob/client/settings/upgrade_to_api6.py +59 -0
- darkob-0.2.0/darkob/client/settings/verify_change_phone_number.py +32 -0
- darkob-0.2.0/darkob/client/settings/verify_recovery_email.py +27 -0
- darkob-0.2.0/darkob/client/users/__init__.py +51 -0
- darkob-0.2.0/darkob/client/users/add_contact.py +50 -0
- darkob-0.2.0/darkob/client/users/block_user.py +24 -0
- darkob-0.2.0/darkob/client/users/check_user_username.py +14 -0
- darkob-0.2.0/darkob/client/users/delete_contact.py +24 -0
- darkob-0.2.0/darkob/client/users/delete_user_chat.py +40 -0
- darkob-0.2.0/darkob/client/users/discard_call.py +30 -0
- darkob-0.2.0/darkob/client/users/get_blocked_users.py +62 -0
- darkob-0.2.0/darkob/client/users/get_common_groups.py +24 -0
- darkob-0.2.0/darkob/client/users/get_contacts.py +63 -0
- darkob-0.2.0/darkob/client/users/get_contacts_last_online.py +33 -0
- darkob-0.2.0/darkob/client/users/get_contacts_stories.py +11 -0
- darkob-0.2.0/darkob/client/users/get_contacts_updates.py +20 -0
- darkob-0.2.0/darkob/client/users/get_last_online.py +44 -0
- darkob-0.2.0/darkob/client/users/get_me.py +22 -0
- darkob-0.2.0/darkob/client/users/get_saved_music_playlist.py +27 -0
- darkob-0.2.0/darkob/client/users/get_top_users.py +14 -0
- darkob-0.2.0/darkob/client/users/get_user_info.py +28 -0
- darkob-0.2.0/darkob/client/users/remove_from_top_users.py +24 -0
- darkob-0.2.0/darkob/client/users/request_video_call.py +49 -0
- darkob-0.2.0/darkob/client/users/request_voice_call.py +49 -0
- darkob-0.2.0/darkob/client/users/reset_contacts.py +13 -0
- darkob-0.2.0/darkob/client/users/set_ask_spam.py +57 -0
- darkob-0.2.0/darkob/client/users/unblock_all_users.py +65 -0
- darkob-0.2.0/darkob/client/users/unblock_user.py +24 -0
- darkob-0.2.0/darkob/data.py +232 -0
- darkob-0.2.0/darkob/fsm.py +281 -0
- darkob-0.2.0/darkob/hybrid.py +216 -0
- darkob-0.2.0/darkob/router.py +160 -0
- darkob-0.2.0/darkob/shad.py +68 -0
- darkob-0.2.0/darkob/types/__init__.py +7 -0
- darkob-0.2.0/darkob/types/event.py +681 -0
- darkob-0.2.0/darkob/types/incoming.py +669 -0
- darkob-0.2.0/darkob.egg-info/PKG-INFO +282 -0
- darkob-0.2.0/darkob.egg-info/SOURCES.txt +432 -0
- darkob-0.2.0/darkob.egg-info/dependency_links.txt +1 -0
- darkob-0.2.0/darkob.egg-info/requires.txt +31 -0
- darkob-0.2.0/darkob.egg-info/top_level.txt +1 -0
- darkob-0.2.0/pyproject.toml +106 -0
- darkob-0.2.0/setup.cfg +4 -0
- darkob-0.2.0/setup.py +10 -0
- darkob-0.2.0/tests/test_bot_registry.py +171 -0
- darkob-0.2.0/tests/test_bot_request.py +102 -0
- darkob-0.2.0/tests/test_cipher.py +113 -0
- darkob-0.2.0/tests/test_client_api.py +362 -0
- darkob-0.2.0/tests/test_data.py +103 -0
- darkob-0.2.0/tests/test_filters.py +94 -0
- darkob-0.2.0/tests/test_fsm.py +194 -0
- darkob-0.2.0/tests/test_import_offline.py +62 -0
- darkob-0.2.0/tests/test_package.py +82 -0
- darkob-0.2.0/tests/test_router.py +136 -0
- darkob-0.2.0/tests/test_tls_defaults.py +36 -0
darkob-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MEHRAB Farahmand
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
darkob-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: darkob
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Fast, stable async Python library for the Rubika & Shad platforms - build bots and userbots.
|
|
5
|
+
Author-email: MEHRAB Farahmand <MEH2RABx@gmail.com>
|
|
6
|
+
Maintainer: Mani Keikhosravi
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/ManiTheFerfri/darkob
|
|
9
|
+
Project-URL: Documentation, https://ManiTheFerfri.github.io/darkob
|
|
10
|
+
Project-URL: Repository, https://github.com/ManiTheFerfri/darkob
|
|
11
|
+
Project-URL: Issues, https://github.com/ManiTheFerfri/darkob/issues
|
|
12
|
+
Project-URL: Upstream, https://github.com/MEH2RAB/maxrubika
|
|
13
|
+
Keywords: darkob,rubika,shad,bot,robot,asyncio,client,userbot,self-bot
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
22
|
+
Classifier: Operating System :: OS Independent
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
24
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
25
|
+
Classifier: Topic :: Communications :: Chat
|
|
26
|
+
Classifier: Framework :: AsyncIO
|
|
27
|
+
Classifier: Typing :: Typed
|
|
28
|
+
Requires-Python: >=3.9
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
License-File: LICENSE
|
|
31
|
+
Requires-Dist: aiohttp>=3.9
|
|
32
|
+
Requires-Dist: aiofiles
|
|
33
|
+
Requires-Dist: mutagen
|
|
34
|
+
Requires-Dist: pycryptodome
|
|
35
|
+
Requires-Dist: rich
|
|
36
|
+
Provides-Extra: opencv
|
|
37
|
+
Requires-Dist: opencv-python; extra == "opencv"
|
|
38
|
+
Provides-Extra: movie
|
|
39
|
+
Requires-Dist: numpy; extra == "movie"
|
|
40
|
+
Requires-Dist: moviepy; extra == "movie"
|
|
41
|
+
Provides-Extra: pillow
|
|
42
|
+
Requires-Dist: pillow; extra == "pillow"
|
|
43
|
+
Provides-Extra: aiortc
|
|
44
|
+
Requires-Dist: aiortc; extra == "aiortc"
|
|
45
|
+
Provides-Extra: pro
|
|
46
|
+
Requires-Dist: aiortc; extra == "pro"
|
|
47
|
+
Requires-Dist: pillow; extra == "pro"
|
|
48
|
+
Requires-Dist: opencv-python; extra == "pro"
|
|
49
|
+
Requires-Dist: numpy; extra == "pro"
|
|
50
|
+
Requires-Dist: moviepy; extra == "pro"
|
|
51
|
+
Provides-Extra: dev
|
|
52
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
53
|
+
Requires-Dist: pytest-asyncio>=0.24; extra == "dev"
|
|
54
|
+
Requires-Dist: pytest-cov>=5; extra == "dev"
|
|
55
|
+
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
56
|
+
Dynamic: license-file
|
|
57
|
+
|
|
58
|
+
<p align="center">
|
|
59
|
+
<img src="assets/darkob-logo.png" alt="darkob" width="180"/>
|
|
60
|
+
</p>
|
|
61
|
+
|
|
62
|
+
<h1 align="center">darkob</h1>
|
|
63
|
+
|
|
64
|
+
<p align="center">
|
|
65
|
+
<strong>Fast, stable async Python for the Rubika & Shad platforms.</strong><br/>
|
|
66
|
+
Build bots and userbots that stay up, without the boilerplate.
|
|
67
|
+
</p>
|
|
68
|
+
|
|
69
|
+
<p align="center">
|
|
70
|
+
<a href="https://github.com/ManiTheFerfri/darkob/actions/workflows/ci.yml"><img src="https://github.com/ManiTheFerfri/darkob/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
|
|
71
|
+
<a href="https://pypi.org/project/darkob/"><img src="https://img.shields.io/pypi/v/darkob?color=blue" alt="PyPI"></a>
|
|
72
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="MIT"></a>
|
|
73
|
+
<img src="https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue.svg" alt="Python 3.9-3.14">
|
|
74
|
+
<img src="https://img.shields.io/badge/tests-121%20passing-brightgreen.svg" alt="Tests">
|
|
75
|
+
</p>
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
**darkob** (دارکوب, *woodpecker*) is a fork of
|
|
80
|
+
[maxrubika](https://github.com/MEH2RAB/maxrubika) by
|
|
81
|
+
[MEHRAB Farahmand](https://github.com/MEH2RAB), rebuilt around
|
|
82
|
+
foundations you can trust. Same protocol, same power, far less
|
|
83
|
+
guesswork when something goes wrong.
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from darkob import Bot
|
|
87
|
+
|
|
88
|
+
bot = Bot(token="YOUR_BOT_TOKEN")
|
|
89
|
+
|
|
90
|
+
@bot.on_command("start")
|
|
91
|
+
async def start(bot, event):
|
|
92
|
+
await event.reply("Welcome 👋")
|
|
93
|
+
|
|
94
|
+
bot.run()
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## ✨ Why darkob
|
|
100
|
+
|
|
101
|
+
The upstream library is feature-complete, but its foundations were never
|
|
102
|
+
hardened. Speed and new features are only worth having on a base that
|
|
103
|
+
does not quietly fail, so darkob starts there.
|
|
104
|
+
|
|
105
|
+
| Inherited problem | What darkob does instead |
|
|
106
|
+
| --- | --- |
|
|
107
|
+
| Contacted PyPI at startup (`urlopen` inside the package init) | Importing darkob performs **no network I/O**. The update check is opt-in via `darkob.check_for_updates()`. |
|
|
108
|
+
| TLS verification disabled on every connector | Verification is **on by default**; opt out explicitly with `verify_ssl=False`. |
|
|
109
|
+
| Bare `except:` swallowed `KeyboardInterrupt` and `SystemExit` | Narrowed to `except Exception:`; session-loading failures are logged rather than silently returning `None`. |
|
|
110
|
+
| `Data` used without being imported in the request path | Fixed — that branch would have raised `NameError` at runtime. |
|
|
111
|
+
| Every update scanned **all** handlers, rebuilt the update name per handler, and spawned an OS thread per synchronous handler | **Indexed dispatch**: handlers grouped by update name once; blocking handlers run in the loop's bounded executor. |
|
|
112
|
+
| Retries were `endpoints × max_retries` — 3 endpoints meant 9 attempts with exponential backoff | **Bounded budget** per request, endpoint rotation, jitter, and explicit `429` / `TOO_REQUESTS` backoff. |
|
|
113
|
+
| A fresh `ClientSession` (and TLS handshake) per file download | **Pooled sessions** per file server, reused across downloads. |
|
|
114
|
+
| No tests, no CI, no `pyproject.toml` | 121 tests, GitHub Actions across 3.9–3.14 plus Windows, modern packaging. |
|
|
115
|
+
|
|
116
|
+
## 🚀 Install
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
pip install darkob
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
From source (until the first PyPI release lands):
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
pip install git+https://github.com/ManiTheFerfri/darkob.git
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## 📦 What's inside
|
|
129
|
+
|
|
130
|
+
- **Two surfaces, one library.** `Bot` talks to the official Bot API;
|
|
131
|
+
`Messenger` drives a real user account, including channels, groups,
|
|
132
|
+
voice chats and stickers. `Shad` is the same Messenger protocol against
|
|
133
|
+
the Shad platform.
|
|
134
|
+
- **Async first, sync friendly.** Every method works with `await` or
|
|
135
|
+
without it — darkob runs one background loop and hops onto it for you.
|
|
136
|
+
- **Decorator handlers.** `on_message`, `on_command`, `on_callback`,
|
|
137
|
+
`on_edit_message`, and friends, with a composable filter system
|
|
138
|
+
(`&`, `|`, `~`).
|
|
139
|
+
- **Routers.** Split a bot into feature modules and include them in one line.
|
|
140
|
+
- **Finite state machines.** Multi-step conversations with pluggable
|
|
141
|
+
storage that can survive a restart.
|
|
142
|
+
- **Polling or webhook.** `bot.run()` polls; `bot.run(webhook_url=...)`
|
|
143
|
+
serves a webhook instead.
|
|
144
|
+
|
|
145
|
+
## 🔀 Routers
|
|
146
|
+
|
|
147
|
+
Handlers can live in their own modules and be registered from one place:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
from darkob import Bot, Router
|
|
151
|
+
|
|
152
|
+
bot = Bot(token="YOUR_BOT_TOKEN")
|
|
153
|
+
admin = Router("admin")
|
|
154
|
+
|
|
155
|
+
@admin.command("ban")
|
|
156
|
+
async def ban(bot, event):
|
|
157
|
+
await bot.ban_member(event.chat_id, event.author_id)
|
|
158
|
+
await event.reply("Banned.")
|
|
159
|
+
|
|
160
|
+
bot.include_router(admin)
|
|
161
|
+
bot.run()
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Routers nest, so a larger bot can keep one root router per feature area.
|
|
165
|
+
|
|
166
|
+
## 🧠 Conversations (FSM)
|
|
167
|
+
|
|
168
|
+
Track which step a user is on and remember what they told you:
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
from darkob import Bot, FSMContext, JsonFileStorage, StateFilter
|
|
172
|
+
|
|
173
|
+
bot = Bot(token="YOUR_BOT_TOKEN")
|
|
174
|
+
storage = JsonFileStorage("fsm.json") # survives restarts
|
|
175
|
+
|
|
176
|
+
@bot.on_command("order")
|
|
177
|
+
async def order(bot, event):
|
|
178
|
+
ctx = FSMContext(storage, key=event.chat_id)
|
|
179
|
+
await ctx.set_state("address")
|
|
180
|
+
await event.reply("What is your delivery address?")
|
|
181
|
+
|
|
182
|
+
@bot.on_new_message(StateFilter(storage, "address"))
|
|
183
|
+
async def address(bot, event):
|
|
184
|
+
ctx = FSMContext(storage, key=event.chat_id)
|
|
185
|
+
await ctx.update_data(address=event.text)
|
|
186
|
+
await ctx.clear()
|
|
187
|
+
await event.reply("Order received ✅")
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Swap `JsonFileStorage` for `MemoryStorage` in tests, or implement the
|
|
191
|
+
`Storage` interface to back it with Redis or SQL.
|
|
192
|
+
|
|
193
|
+
## 👤 Userbots
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
from darkob import Messenger
|
|
197
|
+
|
|
198
|
+
app = Messenger(auth="...", private_key="...")
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Authentication, session strings, platforms (`web`, `pwa`, `android`,
|
|
202
|
+
`rubx`, `rubino`, …) and the full method surface are covered in the
|
|
203
|
+
documentation.
|
|
204
|
+
|
|
205
|
+
## 📚 Documentation
|
|
206
|
+
|
|
207
|
+
The exhaustive, method-by-method reference lives in [`docs/`](docs/):
|
|
208
|
+
|
|
209
|
+
| Area | Start here |
|
|
210
|
+
| --- | --- |
|
|
211
|
+
| Getting started with bots | [bot-guide](docs/bot-guide.md) |
|
|
212
|
+
| Bot methods | [bot-methods](docs/bot-methods.md) |
|
|
213
|
+
| Bot filters | [bot-filters](docs/bot-filters.md) |
|
|
214
|
+
| Userbot guide | [client-guide](docs/client-guide.md) |
|
|
215
|
+
| Userbot methods | [client-methods](docs/client-methods.md) |
|
|
216
|
+
| Shad platform | [shad-guide](docs/shad-guide.md) |
|
|
217
|
+
|
|
218
|
+
Every public method also ships a full docstring:
|
|
219
|
+
|
|
220
|
+
```python
|
|
221
|
+
from darkob import Bot
|
|
222
|
+
import inspect
|
|
223
|
+
|
|
224
|
+
for name in dir(Bot):
|
|
225
|
+
if not name.startswith("_"):
|
|
226
|
+
print(f"{name}: {inspect.getdoc(getattr(Bot, name))}\n")
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## 🗂 Project layout
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
darkob/
|
|
233
|
+
├── bot/ # Bot API surface: endpoint mixins, filters, registry, plugins
|
|
234
|
+
├── client/ # Messenger API: chats, groups, channels, messages, settings
|
|
235
|
+
├── types/ # Event and update models
|
|
236
|
+
├── router.py # Composable routers
|
|
237
|
+
├── fsm.py # Conversation state + pluggable storage
|
|
238
|
+
├── hybrid.py # Sync/async bridge
|
|
239
|
+
└── data.py # Attribute/item-accessible response wrapper
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## 🛠 Development
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
git clone https://github.com/ManiTheFerfri/darkob.git
|
|
246
|
+
cd darkob
|
|
247
|
+
pip install -e ".[dev]"
|
|
248
|
+
|
|
249
|
+
pytest # 121 tests, no network required
|
|
250
|
+
ruff check . # lint
|
|
251
|
+
pytest --cov=darkob # coverage
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
The suite never opens a socket: HTTP goes through fake transports, and a
|
|
255
|
+
subprocess test asserts that importing `darkob` cannot reach the network.
|
|
256
|
+
|
|
257
|
+
## 🗺 Roadmap
|
|
258
|
+
|
|
259
|
+
- [x] Foundation: packaging, TLS, logging, test suite, CI
|
|
260
|
+
- [x] Performance: indexed dispatch, bounded retries, pooled sessions
|
|
261
|
+
- [x] Routers and FSM
|
|
262
|
+
- [ ] Middleware chain on routers
|
|
263
|
+
- [ ] Pagination helpers (`async for` over messages and members)
|
|
264
|
+
- [ ] Redis storage backend
|
|
265
|
+
- [ ] CLI (`darkob new`, `darkob run`)
|
|
266
|
+
- [ ] Type-complete public API and `mypy` in CI
|
|
267
|
+
|
|
268
|
+
## 🤝 Contributing
|
|
269
|
+
|
|
270
|
+
Issues and pull requests are welcome. Please run `pytest` and
|
|
271
|
+
`ruff check .` before opening a PR; CI runs both on every push.
|
|
272
|
+
|
|
273
|
+
## 📄 License & credits
|
|
274
|
+
|
|
275
|
+
MIT. darkob is derived from
|
|
276
|
+
[maxrubika](https://github.com/MEH2RAB/maxrubika), copyright
|
|
277
|
+
MEHRAB Farahmand, and keeps the original MIT notice. See [LICENSE](LICENSE).
|
|
278
|
+
|
|
279
|
+
Maintained by [Mani Keikhosravi](https://github.com/ManiTheFerfri).
|
|
280
|
+
|
|
281
|
+
> Not affiliated with Rubika or Shad. Use responsibly and in line with
|
|
282
|
+
> the platforms' terms of service.
|
darkob-0.2.0/README.md
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/darkob-logo.png" alt="darkob" width="180"/>
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">darkob</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>Fast, stable async Python for the Rubika & Shad platforms.</strong><br/>
|
|
9
|
+
Build bots and userbots that stay up, without the boilerplate.
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="https://github.com/ManiTheFerfri/darkob/actions/workflows/ci.yml"><img src="https://github.com/ManiTheFerfri/darkob/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
|
|
14
|
+
<a href="https://pypi.org/project/darkob/"><img src="https://img.shields.io/pypi/v/darkob?color=blue" alt="PyPI"></a>
|
|
15
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="MIT"></a>
|
|
16
|
+
<img src="https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue.svg" alt="Python 3.9-3.14">
|
|
17
|
+
<img src="https://img.shields.io/badge/tests-121%20passing-brightgreen.svg" alt="Tests">
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
**darkob** (دارکوب, *woodpecker*) is a fork of
|
|
23
|
+
[maxrubika](https://github.com/MEH2RAB/maxrubika) by
|
|
24
|
+
[MEHRAB Farahmand](https://github.com/MEH2RAB), rebuilt around
|
|
25
|
+
foundations you can trust. Same protocol, same power, far less
|
|
26
|
+
guesswork when something goes wrong.
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
from darkob import Bot
|
|
30
|
+
|
|
31
|
+
bot = Bot(token="YOUR_BOT_TOKEN")
|
|
32
|
+
|
|
33
|
+
@bot.on_command("start")
|
|
34
|
+
async def start(bot, event):
|
|
35
|
+
await event.reply("Welcome 👋")
|
|
36
|
+
|
|
37
|
+
bot.run()
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## ✨ Why darkob
|
|
43
|
+
|
|
44
|
+
The upstream library is feature-complete, but its foundations were never
|
|
45
|
+
hardened. Speed and new features are only worth having on a base that
|
|
46
|
+
does not quietly fail, so darkob starts there.
|
|
47
|
+
|
|
48
|
+
| Inherited problem | What darkob does instead |
|
|
49
|
+
| --- | --- |
|
|
50
|
+
| Contacted PyPI at startup (`urlopen` inside the package init) | Importing darkob performs **no network I/O**. The update check is opt-in via `darkob.check_for_updates()`. |
|
|
51
|
+
| TLS verification disabled on every connector | Verification is **on by default**; opt out explicitly with `verify_ssl=False`. |
|
|
52
|
+
| Bare `except:` swallowed `KeyboardInterrupt` and `SystemExit` | Narrowed to `except Exception:`; session-loading failures are logged rather than silently returning `None`. |
|
|
53
|
+
| `Data` used without being imported in the request path | Fixed — that branch would have raised `NameError` at runtime. |
|
|
54
|
+
| Every update scanned **all** handlers, rebuilt the update name per handler, and spawned an OS thread per synchronous handler | **Indexed dispatch**: handlers grouped by update name once; blocking handlers run in the loop's bounded executor. |
|
|
55
|
+
| Retries were `endpoints × max_retries` — 3 endpoints meant 9 attempts with exponential backoff | **Bounded budget** per request, endpoint rotation, jitter, and explicit `429` / `TOO_REQUESTS` backoff. |
|
|
56
|
+
| A fresh `ClientSession` (and TLS handshake) per file download | **Pooled sessions** per file server, reused across downloads. |
|
|
57
|
+
| No tests, no CI, no `pyproject.toml` | 121 tests, GitHub Actions across 3.9–3.14 plus Windows, modern packaging. |
|
|
58
|
+
|
|
59
|
+
## 🚀 Install
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pip install darkob
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
From source (until the first PyPI release lands):
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pip install git+https://github.com/ManiTheFerfri/darkob.git
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## 📦 What's inside
|
|
72
|
+
|
|
73
|
+
- **Two surfaces, one library.** `Bot` talks to the official Bot API;
|
|
74
|
+
`Messenger` drives a real user account, including channels, groups,
|
|
75
|
+
voice chats and stickers. `Shad` is the same Messenger protocol against
|
|
76
|
+
the Shad platform.
|
|
77
|
+
- **Async first, sync friendly.** Every method works with `await` or
|
|
78
|
+
without it — darkob runs one background loop and hops onto it for you.
|
|
79
|
+
- **Decorator handlers.** `on_message`, `on_command`, `on_callback`,
|
|
80
|
+
`on_edit_message`, and friends, with a composable filter system
|
|
81
|
+
(`&`, `|`, `~`).
|
|
82
|
+
- **Routers.** Split a bot into feature modules and include them in one line.
|
|
83
|
+
- **Finite state machines.** Multi-step conversations with pluggable
|
|
84
|
+
storage that can survive a restart.
|
|
85
|
+
- **Polling or webhook.** `bot.run()` polls; `bot.run(webhook_url=...)`
|
|
86
|
+
serves a webhook instead.
|
|
87
|
+
|
|
88
|
+
## 🔀 Routers
|
|
89
|
+
|
|
90
|
+
Handlers can live in their own modules and be registered from one place:
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
from darkob import Bot, Router
|
|
94
|
+
|
|
95
|
+
bot = Bot(token="YOUR_BOT_TOKEN")
|
|
96
|
+
admin = Router("admin")
|
|
97
|
+
|
|
98
|
+
@admin.command("ban")
|
|
99
|
+
async def ban(bot, event):
|
|
100
|
+
await bot.ban_member(event.chat_id, event.author_id)
|
|
101
|
+
await event.reply("Banned.")
|
|
102
|
+
|
|
103
|
+
bot.include_router(admin)
|
|
104
|
+
bot.run()
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Routers nest, so a larger bot can keep one root router per feature area.
|
|
108
|
+
|
|
109
|
+
## 🧠 Conversations (FSM)
|
|
110
|
+
|
|
111
|
+
Track which step a user is on and remember what they told you:
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
from darkob import Bot, FSMContext, JsonFileStorage, StateFilter
|
|
115
|
+
|
|
116
|
+
bot = Bot(token="YOUR_BOT_TOKEN")
|
|
117
|
+
storage = JsonFileStorage("fsm.json") # survives restarts
|
|
118
|
+
|
|
119
|
+
@bot.on_command("order")
|
|
120
|
+
async def order(bot, event):
|
|
121
|
+
ctx = FSMContext(storage, key=event.chat_id)
|
|
122
|
+
await ctx.set_state("address")
|
|
123
|
+
await event.reply("What is your delivery address?")
|
|
124
|
+
|
|
125
|
+
@bot.on_new_message(StateFilter(storage, "address"))
|
|
126
|
+
async def address(bot, event):
|
|
127
|
+
ctx = FSMContext(storage, key=event.chat_id)
|
|
128
|
+
await ctx.update_data(address=event.text)
|
|
129
|
+
await ctx.clear()
|
|
130
|
+
await event.reply("Order received ✅")
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Swap `JsonFileStorage` for `MemoryStorage` in tests, or implement the
|
|
134
|
+
`Storage` interface to back it with Redis or SQL.
|
|
135
|
+
|
|
136
|
+
## 👤 Userbots
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
from darkob import Messenger
|
|
140
|
+
|
|
141
|
+
app = Messenger(auth="...", private_key="...")
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Authentication, session strings, platforms (`web`, `pwa`, `android`,
|
|
145
|
+
`rubx`, `rubino`, …) and the full method surface are covered in the
|
|
146
|
+
documentation.
|
|
147
|
+
|
|
148
|
+
## 📚 Documentation
|
|
149
|
+
|
|
150
|
+
The exhaustive, method-by-method reference lives in [`docs/`](docs/):
|
|
151
|
+
|
|
152
|
+
| Area | Start here |
|
|
153
|
+
| --- | --- |
|
|
154
|
+
| Getting started with bots | [bot-guide](docs/bot-guide.md) |
|
|
155
|
+
| Bot methods | [bot-methods](docs/bot-methods.md) |
|
|
156
|
+
| Bot filters | [bot-filters](docs/bot-filters.md) |
|
|
157
|
+
| Userbot guide | [client-guide](docs/client-guide.md) |
|
|
158
|
+
| Userbot methods | [client-methods](docs/client-methods.md) |
|
|
159
|
+
| Shad platform | [shad-guide](docs/shad-guide.md) |
|
|
160
|
+
|
|
161
|
+
Every public method also ships a full docstring:
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from darkob import Bot
|
|
165
|
+
import inspect
|
|
166
|
+
|
|
167
|
+
for name in dir(Bot):
|
|
168
|
+
if not name.startswith("_"):
|
|
169
|
+
print(f"{name}: {inspect.getdoc(getattr(Bot, name))}\n")
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## 🗂 Project layout
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
darkob/
|
|
176
|
+
├── bot/ # Bot API surface: endpoint mixins, filters, registry, plugins
|
|
177
|
+
├── client/ # Messenger API: chats, groups, channels, messages, settings
|
|
178
|
+
├── types/ # Event and update models
|
|
179
|
+
├── router.py # Composable routers
|
|
180
|
+
├── fsm.py # Conversation state + pluggable storage
|
|
181
|
+
├── hybrid.py # Sync/async bridge
|
|
182
|
+
└── data.py # Attribute/item-accessible response wrapper
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## 🛠 Development
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
git clone https://github.com/ManiTheFerfri/darkob.git
|
|
189
|
+
cd darkob
|
|
190
|
+
pip install -e ".[dev]"
|
|
191
|
+
|
|
192
|
+
pytest # 121 tests, no network required
|
|
193
|
+
ruff check . # lint
|
|
194
|
+
pytest --cov=darkob # coverage
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
The suite never opens a socket: HTTP goes through fake transports, and a
|
|
198
|
+
subprocess test asserts that importing `darkob` cannot reach the network.
|
|
199
|
+
|
|
200
|
+
## 🗺 Roadmap
|
|
201
|
+
|
|
202
|
+
- [x] Foundation: packaging, TLS, logging, test suite, CI
|
|
203
|
+
- [x] Performance: indexed dispatch, bounded retries, pooled sessions
|
|
204
|
+
- [x] Routers and FSM
|
|
205
|
+
- [ ] Middleware chain on routers
|
|
206
|
+
- [ ] Pagination helpers (`async for` over messages and members)
|
|
207
|
+
- [ ] Redis storage backend
|
|
208
|
+
- [ ] CLI (`darkob new`, `darkob run`)
|
|
209
|
+
- [ ] Type-complete public API and `mypy` in CI
|
|
210
|
+
|
|
211
|
+
## 🤝 Contributing
|
|
212
|
+
|
|
213
|
+
Issues and pull requests are welcome. Please run `pytest` and
|
|
214
|
+
`ruff check .` before opening a PR; CI runs both on every push.
|
|
215
|
+
|
|
216
|
+
## 📄 License & credits
|
|
217
|
+
|
|
218
|
+
MIT. darkob is derived from
|
|
219
|
+
[maxrubika](https://github.com/MEH2RAB/maxrubika), copyright
|
|
220
|
+
MEHRAB Farahmand, and keeps the original MIT notice. See [LICENSE](LICENSE).
|
|
221
|
+
|
|
222
|
+
Maintained by [Mani Keikhosravi](https://github.com/ManiTheFerfri).
|
|
223
|
+
|
|
224
|
+
> Not affiliated with Rubika or Shad. Use responsibly and in line with
|
|
225
|
+
> the platforms' terms of service.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import asyncio
|
|
3
|
+
from typing import Union, Optional
|
|
4
|
+
import aiohttp
|
|
5
|
+
from rich.console import Console
|
|
6
|
+
|
|
7
|
+
import darkob
|
|
8
|
+
from .bot import Methods
|
|
9
|
+
from .bot.session import Session
|
|
10
|
+
from .bot.updates import Updates
|
|
11
|
+
from .bot.token import TokenString
|
|
12
|
+
from .bot.exceptions import TokenError
|
|
13
|
+
from .bot.registry import HandlerRegistry
|
|
14
|
+
from .bot.bridge import DecoratorBridge
|
|
15
|
+
from .bot.plugin import PluginManager
|
|
16
|
+
|
|
17
|
+
console = Console(highlight=False)
|
|
18
|
+
|
|
19
|
+
class Bot(Session, Updates, Methods):
|
|
20
|
+
TOKEN_PATTERN = re.compile(r'^[A-Z]{5}[0-9A-Z]{59}$')
|
|
21
|
+
DEFAULT_BASE_URL = "https://botapi.rubika.ir/v3"
|
|
22
|
+
|
|
23
|
+
def __init__(
|
|
24
|
+
self,
|
|
25
|
+
token: Optional[str] = None,
|
|
26
|
+
token_string: Optional[str] = None,
|
|
27
|
+
password: Optional[str] = None,
|
|
28
|
+
base_url: str = DEFAULT_BASE_URL,
|
|
29
|
+
timeout: Union[int, float] = 30,
|
|
30
|
+
max_retries: Union[int, float] = 5,
|
|
31
|
+
verify_ssl: bool = True,
|
|
32
|
+
show_welcome: bool = True,
|
|
33
|
+
run_all_handlers: bool = True
|
|
34
|
+
):
|
|
35
|
+
"""
|
|
36
|
+
Initialize the Bot instance.
|
|
37
|
+
|
|
38
|
+
Parameters:
|
|
39
|
+
token (Optional[str]): Bot authentication token. If not provided
|
|
40
|
+
or invalid, the bot will prompt for it via console input.
|
|
41
|
+
token_string (Optional[str]): Encrypted TokenString. Takes priority over token.
|
|
42
|
+
password (Optional[str]): Password for encrypted TokenString.
|
|
43
|
+
base_url (str): Base API URL. Defaults to "https://botapi.rubika.ir/v3".
|
|
44
|
+
timeout (int): Request timeout in seconds. Defaults to 30.
|
|
45
|
+
max_retries (int): Maximum number of retry attempts on network
|
|
46
|
+
errors. Defaults to 5.
|
|
47
|
+
verify_ssl (bool): Verify TLS certificates. Defaults to True.
|
|
48
|
+
Only disable this if you understand the interception risk.
|
|
49
|
+
show_welcome (bool, optional): If True, show welcome message (default: True).
|
|
50
|
+
run_all_handlers (bool, optional): If True (default), every handler whose
|
|
51
|
+
constraints match an event is run, in registration order. If False,
|
|
52
|
+
only the first matching handler runs, so registration order decides
|
|
53
|
+
which handler wins.
|
|
54
|
+
"""
|
|
55
|
+
darkob.show_welcome_message(show_welcome)
|
|
56
|
+
|
|
57
|
+
self._session: Optional[aiohttp.ClientSession] = None
|
|
58
|
+
self._close_task: Optional["asyncio.Task"] = None
|
|
59
|
+
self._session_loop: Optional["asyncio.AbstractEventLoop"] = None
|
|
60
|
+
|
|
61
|
+
if token_string:
|
|
62
|
+
token = TokenString(token_string).to_token(password)
|
|
63
|
+
if not token:
|
|
64
|
+
raise TokenError(
|
|
65
|
+
"Invalid token_string or wrong password.")
|
|
66
|
+
else:
|
|
67
|
+
token = (token or "").strip()
|
|
68
|
+
if not self.TOKEN_PATTERN.match(token):
|
|
69
|
+
token = self._get_token()
|
|
70
|
+
|
|
71
|
+
self.token = token
|
|
72
|
+
self.timeout = float(timeout)
|
|
73
|
+
self.max_retries = int(max_retries)
|
|
74
|
+
self.verify_ssl = bool(verify_ssl)
|
|
75
|
+
self.base_url = f"{base_url.rstrip('/')}/{token}"
|
|
76
|
+
self.run_all_handlers = bool(run_all_handlers)
|
|
77
|
+
|
|
78
|
+
self._registry = HandlerRegistry(self)
|
|
79
|
+
self._bridge = DecoratorBridge(self._registry)
|
|
80
|
+
self.plugin_manager = PluginManager(self)
|
|
81
|
+
|
|
82
|
+
for name in dir(type(self._bridge)):
|
|
83
|
+
if name.startswith('_'):
|
|
84
|
+
continue
|
|
85
|
+
attr = getattr(type(self._bridge), name, None)
|
|
86
|
+
if isinstance(attr, property):
|
|
87
|
+
setattr(self, name, getattr(self._bridge, name))
|
|
88
|
+
|
|
89
|
+
def _get_token(self) -> str:
|
|
90
|
+
while True:
|
|
91
|
+
console.print("Enter your bot token: ", style="bold yellow", end="")
|
|
92
|
+
token = input().strip()
|
|
93
|
+
if self.TOKEN_PATTERN.match(token):
|
|
94
|
+
return token
|
|
95
|
+
console.print("\nInvalid token format. Try again.\n", style="bold red")
|
|
96
|
+
|
|
97
|
+
def include_router(self, router):
|
|
98
|
+
"""Register every handler declared on *router*, recursively.
|
|
99
|
+
|
|
100
|
+
Lets a bot be split into feature modules::
|
|
101
|
+
|
|
102
|
+
bot.include_router(admin_router)
|
|
103
|
+
|
|
104
|
+
Returns the router so calls can be chained.
|
|
105
|
+
"""
|
|
106
|
+
from .router import Router
|
|
107
|
+
|
|
108
|
+
if not isinstance(router, Router):
|
|
109
|
+
raise TypeError(
|
|
110
|
+
f"include_router expects a Router, got {type(router).__name__}"
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
router.apply(self)
|
|
114
|
+
return router
|