├── .devcontainer ├── devcontainer.json └── docker-compose.yml ├── .dockerignore ├── .github ├── ISSUE_TEMPLATE │ └── bug_report.md └── workflows │ ├── codeql.yml │ ├── deploy-docusaurus.yml │ └── pypi_push.yml ├── .gitignore ├── Dockerfile ├── LICENSE.md ├── README.md ├── docs ├── .gitignore ├── README.md ├── babel.config.js ├── docs │ ├── api_reference │ │ ├── _category_.json │ │ ├── client.md │ │ ├── functions.md │ │ ├── methods │ │ │ ├── _category_.json │ │ │ ├── add_handler.md │ │ │ ├── answer_inline_query.md │ │ │ ├── ban_user.md │ │ │ ├── clear_conversation.md │ │ │ ├── create_sticker.md │ │ │ ├── create_sticker_pack.md │ │ │ ├── deduct_xp.md │ │ │ ├── delete_media.md │ │ │ ├── delete_message.md │ │ │ ├── delete_sticker.md │ │ │ ├── delete_sticker_pack.md │ │ │ ├── download_media.md │ │ │ ├── edit_media.md │ │ │ ├── edit_message.md │ │ │ ├── forward_message.md │ │ │ ├── get_active_commands.md │ │ │ ├── get_all_channels.md │ │ │ ├── get_all_groups.md │ │ │ ├── get_all_sticker_packs.md │ │ │ ├── get_bot_info.md │ │ │ ├── get_channel.md │ │ │ ├── get_channel_chat_history.md │ │ │ ├── get_community.md │ │ │ ├── get_community_media_files.md │ │ │ ├── get_community_media_files_by_status.md │ │ │ ├── get_community_member.md │ │ │ ├── get_group.md │ │ │ ├── get_group_chat_history.md │ │ │ ├── get_last_seen.md │ │ │ ├── get_media.md │ │ │ ├── get_message.md │ │ │ ├── get_messages.md │ │ │ ├── get_organization_apps.md │ │ │ ├── get_organization_by_id.md │ │ │ ├── get_organization_followers.md │ │ │ ├── get_organizations.md │ │ │ ├── get_stickers.md │ │ │ ├── get_unread_messages_count.md │ │ │ ├── get_user.md │ │ │ ├── list_restricted_users.md │ │ │ ├── remove_handler.md │ │ │ ├── run.md │ │ │ ├── search_sticker_packs.md │ │ │ ├── send_media.md │ │ │ ├── send_message.md │ │ │ ├── send_sticker.md │ │ │ ├── sort_stickers.md │ │ │ ├── start.md │ │ │ ├── stop.md │ │ │ └── update_media_info.md │ │ └── types │ │ │ ├── _category_.json │ │ │ ├── botinfo.md │ │ │ ├── channel.md │ │ │ ├── community.md │ │ │ ├── communitymember.md │ │ │ ├── embed_inline_field.md │ │ │ ├── embedded_media.md │ │ │ ├── gameinfo.md │ │ │ ├── group.md │ │ │ ├── inline │ │ │ ├── _category_.json │ │ │ ├── inline_query.md │ │ │ ├── inline_query_answer.md │ │ │ ├── inline_query_result.md │ │ │ └── input_message_content.md │ │ │ ├── inline_keyboard_button.md │ │ │ ├── inline_markup.md │ │ │ ├── media.md │ │ │ ├── message.md │ │ │ ├── organization.md │ │ │ ├── orgapp.md │ │ │ ├── restricteduser.md │ │ │ ├── tournament.md │ │ │ └── user.md │ ├── basic-concepts │ │ ├── _category_.json │ │ ├── calling-api.md │ │ ├── events.md │ │ ├── logging.md │ │ └── project-setup.md │ ├── deploy │ │ ├── _category_.json │ │ └── ubuntu.md │ ├── examples │ │ ├── _category_.json │ │ ├── calculator-bot.md │ │ ├── echo-bot.md │ │ ├── mini-app-bot.md │ │ ├── poll-bot.md │ │ ├── restaurant-menu-bot.md │ │ ├── task-management-bot.md │ │ ├── travel-planner-bot.md │ │ └── weather-bot.md │ ├── fundamentals │ │ ├── _category_.json │ │ ├── bots.md │ │ ├── context.md │ │ ├── decorators.md │ │ ├── events.md │ │ ├── filters.md │ │ ├── handlers.md │ │ └── upload_speed.md │ ├── interactions │ │ ├── _category_.json │ │ ├── advertising.md │ │ ├── callback_queries.md │ │ ├── commands.md │ │ ├── games.md │ │ ├── inline_queries.md │ │ ├── keyboards.md │ │ └── stickers.md │ ├── intro.md │ └── mini-apps │ │ ├── AppBar.md │ │ ├── AppPage.md │ │ ├── BottomBar.md │ │ ├── _category_.json │ │ ├── callback_methods.md │ │ ├── components │ │ ├── AudioPlayer.md │ │ ├── Badge.md │ │ ├── Button.md │ │ ├── ButtonGroup.md │ │ ├── Carousel.md │ │ ├── Dropdown.md │ │ ├── Embed.md │ │ ├── FilePicker.md │ │ ├── Grid.md │ │ ├── GridItem.md │ │ ├── Icon.md │ │ ├── Image.md │ │ ├── ListItem.md │ │ ├── ListTile.md │ │ ├── ListView.md │ │ ├── SearchBar.md │ │ ├── SearchHolder.md │ │ ├── StickyHeader.md │ │ ├── Tab.md │ │ ├── Text.md │ │ ├── TextInput.md │ │ ├── VideoPlayer.md │ │ └── _category_.json │ │ └── intro.mdx ├── docusaurus.config.js ├── package.json ├── sidebars.js ├── src │ ├── components │ │ └── HomepageFeatures │ │ │ ├── index.js │ │ │ └── styles.module.css │ ├── css │ │ └── custom.css │ └── pages │ │ ├── custom.css │ │ ├── index.js │ │ └── index.module.css ├── static │ ├── .nojekyll │ └── img │ │ ├── docusaurus.png │ │ ├── favicon.ico │ │ ├── imdb.jpg │ │ ├── imdb2.jpg │ │ ├── logo.png │ │ ├── switch-logo-white.png │ │ └── switch-logo.png └── yarn.lock ├── publish.sh ├── requirements-dev.txt ├── requirements.txt ├── samples ├── ads.py ├── ads_session.py ├── app.py ├── channel_example.py ├── decoratorbot.py ├── echobot.py ├── example_01.py ├── example_02.py ├── example_download.py ├── inline_keyboard.py ├── inline_query_example.py └── mini_app_example.py ├── setup.py └── swibots ├── __init__.py ├── api ├── __init__.py ├── airdrop │ ├── __init__.py │ ├── client.py │ ├── controllers │ │ ├── __init__.py │ │ └── tournament_controller.py │ ├── methods │ │ ├── __init__.py │ │ ├── get_referral.py │ │ └── get_tournaments.py │ └── models │ │ ├── __init__.py │ │ ├── referral.py │ │ └── tournament.py ├── api_client.py ├── auth │ ├── __init__.py │ ├── auth_client.py │ ├── methods │ │ ├── __init__.py │ │ └── get_me.py │ └── models │ │ ├── __init__.py │ │ ├── auth_result.py │ │ └── auth_user.py ├── bot │ ├── __init__.py │ ├── bot_client.py │ ├── controllers │ │ ├── __init__.py │ │ ├── bot_controller.py │ │ └── game_controller.py │ ├── methods │ │ ├── __init__.py │ │ ├── answer_callback_query.py │ │ ├── delete_bot_info.py │ │ ├── game_methods.py │ │ ├── get_bot_info.py │ │ └── update_bot_info.py │ └── models │ │ ├── __init__.py │ │ ├── bot_command.py │ │ ├── bot_info.py │ │ └── game_info.py ├── callback │ ├── Accordian.py │ ├── AppPage.py │ ├── BottomBar.py │ ├── Button.py │ ├── Card.py │ ├── Carousel.py │ ├── Dropdown.py │ ├── FAB.py │ ├── Feed.py │ ├── Grid.py │ ├── Inputs.py │ ├── ListItem.py │ ├── ListView.py │ ├── Players.py │ ├── Progress.py │ ├── Search.py │ ├── Tab.py │ ├── Table.py │ ├── __init__.py │ ├── callbackResponse.py │ └── types.py ├── chat │ ├── __init__.py │ ├── chat_client.py │ ├── controllers │ │ ├── __init__.py │ │ ├── ads_controller.py │ │ ├── chat_controller.py │ │ ├── heading_controller.py │ │ ├── media_controller.py │ │ ├── message_controller.py │ │ ├── organization_controller.py │ │ └── sticker_controller.py │ ├── events │ │ ├── __init__.py │ │ ├── callback_query_event.py │ │ ├── chat_event.py │ │ ├── command_event.py │ │ ├── inline_query_event.py │ │ └── message_event.py │ ├── methods │ │ ├── __init__.py │ │ ├── ad_methods.py │ │ ├── answer_inline_query.py │ │ ├── clear_conversation.py │ │ ├── delete_message.py │ │ ├── delete_messages_from_user.py │ │ ├── download_media.py │ │ ├── edit_message.py │ │ ├── flag_message.py │ │ ├── forward_message.py │ │ ├── get_channel_chat_history.py │ │ ├── get_community_media_files.py │ │ ├── get_community_media_files_by_status.py │ │ ├── get_flag_messages.py │ │ ├── get_group_chat_history.py │ │ ├── get_message.py │ │ ├── get_messages.py │ │ ├── get_messages_between_users.py │ │ ├── get_unread_messages_count.py │ │ ├── get_user.py │ │ ├── get_user_media_files.py │ │ ├── heading_methods.py │ │ ├── listen_messages.py │ │ ├── organization_methods.py │ │ ├── pin_message.py │ │ ├── send_message.py │ │ ├── sticker_methods.py │ │ └── upload_media.py │ └── models │ │ ├── __init__.py │ │ ├── ads.py │ │ ├── group_chat_history.py │ │ ├── inline │ │ ├── __init__.py │ │ ├── base_typed_inline_query_result.py │ │ ├── inline_query.py │ │ ├── inline_query_answer.py │ │ ├── inline_query_result.py │ │ ├── inline_query_result_article.py │ │ ├── inline_query_result_document.py │ │ ├── inline_query_result_photo.py │ │ ├── inline_query_result_video.py │ │ ├── input_message_content.py │ │ └── types.py │ │ ├── inline_keyboard_button.py │ │ ├── inline_markup.py │ │ ├── message.py │ │ ├── organization.py │ │ ├── session.py │ │ └── sticker.py ├── common │ ├── __init__.py │ ├── events │ │ ├── __init__.py │ │ └── event.py │ └── models │ │ ├── __init__.py │ │ ├── embed_inline_field.py │ │ ├── embedded_media.py │ │ ├── media.py │ │ ├── user.py │ │ └── usertournament.py └── community │ ├── __init__.py │ ├── community_client.py │ ├── controllers │ ├── __init__.py │ ├── ban_controller.py │ ├── channel_controller.py │ ├── community_controller.py │ ├── group_controller.py │ ├── messaging_controller.py │ ├── permissions_controller.py │ ├── quest_controller.py │ ├── restrict_controller.py │ ├── rolemember_controller.py │ └── roles_controller.py │ ├── events │ ├── __init__.py │ ├── channel_created_event.py │ ├── channel_deleted_event.py │ ├── channel_updated_event.py │ ├── community_event.py │ ├── community_updated_event.py │ ├── group_created_event.py │ ├── group_deleted_event.py │ ├── group_updated_event.py │ ├── member_joined_event.py │ ├── member_left_event.py │ └── user_banned_event.py │ ├── methods │ ├── __init__.py │ ├── ban_user.py │ ├── channel_methods.py │ ├── community_methods.py │ ├── deduct_xp.py │ ├── group_methods.py │ ├── instant_messaging.py │ ├── permission.py │ ├── quest_methods.py │ ├── restrict_user.py │ ├── rolemember.py │ ├── roles.py │ └── unban_user.py │ └── models │ ├── __init__.py │ ├── baninfo.py │ ├── channel.py │ ├── community.py │ ├── community_member.py │ ├── group.py │ ├── instantmessaging.py │ ├── private_join_response.py │ ├── quest.py │ ├── restricteduser.py │ ├── role.py │ ├── rolemember.py │ └── rolepermission.py ├── base ├── __init__.py ├── rest_controller.py ├── rest_request.py ├── rest_response.py ├── switch_client.py ├── switch_object.py └── switch_ws_async_client.py ├── bot_app.py ├── bots ├── __init__.py ├── bot.py ├── bot_context.py ├── decorators │ ├── __init__.py │ ├── on_callback_query.py │ ├── on_channel_created.py │ ├── on_channel_deleted.py │ ├── on_channel_updated.py │ ├── on_command.py │ ├── on_community_updated.py │ ├── on_group_created.py │ ├── on_group_deleted.py │ ├── on_group_updated.py │ ├── on_inline_query.py │ ├── on_member_joined.py │ ├── on_member_left.py │ ├── on_message.py │ ├── on_unknown_command.py │ └── on_user_banned.py ├── filters │ ├── __init__.py │ └── filter.py └── handlers │ ├── __init__.py │ ├── base_handler.py │ ├── callback_query_handler.py │ ├── channel_created_handler.py │ ├── channel_deleted_handler.py │ ├── channel_updated_handler.py │ ├── command_handler.py │ ├── community_updated_handler.py │ ├── event_handler.py │ ├── group_created_handler.py │ ├── group_deleted_handler.py │ ├── group_updated_handler.py │ ├── inline_query_handler.py │ ├── member_joined_handler.py │ ├── member_left_handler.py │ ├── message_handler.py │ ├── unknown_command_handler.py │ └── user_banned_handler.py ├── config.py ├── errors.py ├── rate_limiter.py ├── responses.py ├── types.py └── utils ├── __init__.py ├── rest_client.py ├── types.py └── ws ├── __init__.py ├── asyncstomp ├── __init__.py ├── async_ws_client.py └── async_ws_subscription.py └── common ├── __init__.py ├── ws_frame.py └── ws_message.py /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the 2 | // README at: https://github.com/devcontainers/templates/tree/main/src/docker-existing-dockerfile 3 | { 4 | "name": "Python wrapper", 5 | // The order of the files is important since later files override previous ones 6 | "dockerComposeFile": [ 7 | "./docker-compose.yml" 8 | ], 9 | "service": "switch_python_lib", 10 | "workspaceFolder": "/workspace", 11 | "shutdownAction": "stopCompose", 12 | "customizations": { 13 | "vscode": { 14 | "extensions": [ 15 | "GitHub.copilot", 16 | "ms-azuretools.vscode-docker", 17 | "rangav.vscode-thunder-client", 18 | "ms-python.python", 19 | "ms-python.vscode-pylance", 20 | "ms-python.isort", 21 | "donjayamanne.python-environment-manager" 22 | ] 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /.devcontainer/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | switch_python_lib: 4 | build: 5 | context: .. 6 | dockerfile: Dockerfile 7 | volumes: 8 | - ..:/workspace 9 | - /workspace/src/venv 10 | - /workspace/docs/node_modules 11 | networks: 12 | - switch-network 13 | networks: 14 | switch-network: 15 | external: 16 | name: 17 | dev-network 18 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | venv -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG]" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **System info** 14 | - Device: [e.g. Windows] 15 | - Library Version [e.g. 1.4.0] 16 | 17 | **Additional context** 18 | Add any other context about the problem here. 19 | -------------------------------------------------------------------------------- /.github/workflows/pypi_push.yml: -------------------------------------------------------------------------------- 1 | name: Upload Package 2 | 3 | on: 4 | workflow_dispatch: 5 | # push: 6 | # paths: 7 | # - "setup.py" 8 | 9 | jobs: 10 | deploy: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Set up Python 17 | uses: actions/setup-python@v2 18 | with: 19 | python-version: '3.10' 20 | - name: Install dependencies 21 | run: | 22 | python -m pip install --upgrade pip 23 | pip install build 24 | - name: Build package 25 | run: | 26 | python -m build 27 | - name: Publish package 28 | uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 29 | with: 30 | user: __token__ 31 | password: ${{ secrets.PYPI_API_TOKEN }} 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | __pycache__ 3 | .env 4 | .env* 5 | .private 6 | dist 7 | .idea 8 | src/venv 9 | *.egg-info 10 | build 11 | .DS_Store 12 | # **/bots_impl 13 | **.log 14 | test* 15 | *png 16 | *.sqlite 17 | downloads/ 18 | *sh -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:alpine 2 | ARG WORKDIR=/workspace 3 | 4 | WORKDIR $WORKDIR 5 | 6 | 7 | COPY . $WORKDIR 8 | 9 | 10 | RUN apk add --no-cache --virtual .build-deps \ 11 | gcc \ 12 | musl-dev \ 13 | libffi-dev \ 14 | openssl-dev \ 15 | && apk add --no-cache \ 16 | bash \ 17 | git \ 18 | openssh \ 19 | && apk del .build-deps 20 | 21 | RUN pip install wheel && \ 22 | pip install setuptools && \ 23 | pip install twine 24 | 25 | ENV VIRTUAL_ENV=$WORKDIR/src/venv 26 | RUN python -m venv $VIRTUAL_ENV 27 | ENV PATH="$VIRTUAL_ENV/bin:$PATH" 28 | 29 | RUN pip install -r $WORKDIR/requirements-dev.txt 30 | 31 | 32 | CMD [ "/bin/sh", "-c", "while sleep 1000; do :; done"] -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | /.yarn 11 | 12 | # Misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | 23 | package-lock.json -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Website 2 | 3 | This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. 4 | 5 | ### Installation 6 | 7 | ``` 8 | $ yarn 9 | ``` 10 | 11 | ### Local Development 12 | 13 | ``` 14 | $ yarn start 15 | ``` 16 | 17 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. 18 | 19 | ### Build 20 | 21 | ``` 22 | $ yarn build 23 | ``` 24 | 25 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 26 | 27 | ### Deployment 28 | 29 | Using SSH: 30 | 31 | ``` 32 | $ USE_SSH=true yarn deploy 33 | ``` 34 | 35 | Not using SSH: 36 | 37 | ``` 38 | $ GIT_USER= yarn deploy 39 | ``` 40 | 41 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. 42 | -------------------------------------------------------------------------------- /docs/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /docs/docs/api_reference/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "API Reference", 3 | "position": 5, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Api reference." 7 | }, 8 | "collapsed": true 9 | } -------------------------------------------------------------------------------- /docs/docs/api_reference/client.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Client 6 | 7 | `Class swibots.Client` 8 | 9 | This is the main class of the library. It is used to create a bot app and to call the API methods. 10 | 11 | 12 | ## Properties 13 | - `token` (`str`, Optional): Bot token (This is the token you must use to authenticate the bot) 14 | - `email` (`str`, Optional): Email (only required for user login) 15 | - `password` (`str`, Optional): Password (only required for user login) 16 | - `bot_description` (`str`, Optional): Bot description (This is the description of the bot) 17 | - `auto_update_bot` (`bool`, Optional): Auto update bot (This is the flag to enable/disable the auto update of the bot into the database) 18 | - `receive_updates` (`bool`, Optional): Whether to receive event updates, defaults to `True`. 19 | - `loop` (`asyncio.AbstractEventLoop`, Optional): AsyncIO Event loop (This is used in case you want to use a custom event loop) 20 | - `is_app` (`bool`, Optional): Whether to mark the bot as a APP! 21 | - `home_callback` (`str`, Optional): The default callback data to send, if opened through 'open app' button! 22 | 23 | 24 | ## Example 25 | 26 | ```python 27 | from swibots import Client 28 | 29 | # login as a bot 30 | app = Client("token", bot_description="This is a bot") 31 | # login as a user 32 | app = Client( 33 | email="user@mail.com", 34 | password="password" 35 | ) 36 | 37 | async def main(): 38 | await app.send_message(123, "Hello world") 39 | 40 | app.run(main()) 41 | ``` 42 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Methods", 3 | "position": 2, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Available methods to interact with the Switch Api." 7 | } 8 | } -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/add_handler.md: -------------------------------------------------------------------------------- 1 | # add_handler 2 | 3 | Add a handler to the bot. 4 | 5 | ## Signature 6 | 7 | `def add_handler(self, handler: BaseHandler | List[BaseHandler]) -> Client` 8 | 9 | ## Parameters 10 | 11 | - `handler` (`BaseHandler | List[BaseHandler]`): The handler to add to the bot, or a list of handlers to add to the bot (see [Hanlders](../../fundamentals/handlers) for more information on handlers) 12 | 13 | 14 | ## Example 15 | 16 | ```python 17 | 18 | 19 | from swibots import Client, BotContext, CommandEvent, MessageEvent, CallbackQueryEvent, filters, InlineKeyboardButton, InlineMarkup, BotCommandInfo 20 | 21 | from swibots.bots.handlers import ( 22 | MessageHandler, 23 | UnknownCommandHandler, 24 | CallbackQueryHandler, 25 | CommandHandler, 26 | ) 27 | 28 | 29 | async def echo(ctx: BotContext[CommandEvent]): 30 | m = await ctx.bot.prepare_response_message(ctx.event.message) 31 | text = ctx.event.params or "No args" 32 | m.message = f"Your message: {text}" 33 | await ctx.bot.send_message(m) 34 | 35 | app = Client() 36 | 37 | # register your handlers here 38 | 39 | echo_handler = CommandHandler( 40 | command="echo", 41 | callback=echo, 42 | ) 43 | 44 | app.add_handler( 45 | echo_handler 46 | ) 47 | 48 | app.run() 49 | 50 | ``` -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/answer_inline_query.md: -------------------------------------------------------------------------------- 1 | # answer_inline_query 2 | 3 | This method sends an answer to an inline query. On success, True is returned. 4 | 5 | ## Signature 6 | 7 | `async def answer_inline_query(query: InlineQuery, answer: InlineQueryAnswer) -> bool` 8 | 9 | ## Parameters 10 | 11 | - `query` ([InlineQuery](../types/inline/inline_query)): The inline query to answer 12 | - `answer` ([InlineQueryAnswer](../types/inline/inline_query_answer)): The answer to the inline query -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/ban_user.md: -------------------------------------------------------------------------------- 1 | # ban an user 2 | 3 | ban an user from the community 4 | 5 | ## Signature 6 | 7 | `async def ban_user(community_id: str, user_id: str) -> BanInfo` 8 | 9 | ## Parameters 10 | 11 | - `community_id` (`str`): The community id 12 | - `user_id` `str`: The user id to ban -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/clear_conversation.md: -------------------------------------------------------------------------------- 1 | # clear_conversation 2 | 3 | Clears the conversation history of the current user. 4 | 5 | ## Signature 6 | 7 | `async def clear_conversation(receiver_id: int) -> bool` 8 | 9 | ## Parameters 10 | 11 | - `receiver_id` (int): The ID of the user to clear the conversation history of -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/create_sticker.md: -------------------------------------------------------------------------------- 1 | ## `create_sticker` 2 | Creates a new sticker and adds it to a sticker pack. 3 | 4 | ### Signature 5 | 6 | ```python 7 | async def create_sticker( 8 | self: "swibots.ApiClient", 9 | sticker: str | BytesIO, 10 | name: str, 11 | description: str, 12 | emoji: str, 13 | pack_id: str, 14 | ) -> Sticker: 15 | ``` 16 | 17 | ### Parameters 18 | 19 | - `sticker` (str | BytesIO): Path to the sticker file or BytesIO object with a `.name` attribute. 20 | - `name` (str): Name of the sticker. 21 | - `description` (str): Description of the sticker. 22 | - `emoji` (str): Emoji linked with the sticker. 23 | - `pack_id` (str): Pack ID to which the sticker belongs. 24 | 25 | ### Returns 26 | 27 | - `Sticker`: The created sticker object. -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/create_sticker_pack.md: -------------------------------------------------------------------------------- 1 | # `create_sticker_pack` Method 2 | 3 | Creates a new sticker pack. 4 | 5 | ### Signature 6 | 7 | ```python 8 | async def create_sticker_pack( 9 | name: str, 10 | pack_type: str, 11 | access: str = "GLOBAL", 12 | thumb: Optional[str | BytesIO] = None, 13 | ) -> StickerPack: 14 | ``` 15 | 16 | ### Parameters 17 | 18 | - `name` (str): Name of the sticker pack. 19 | - `pack_type` (str): Pack type for the sticker pack (STATIC, ANIMATED, VIDEO). 20 | - `access` (str, optional): Access mode for the pack. Defaults to "GLOBAL". 21 | - `thumb` (Optional[str | BytesIO], optional): Path to the sticker pack thumbnail. Defaults to None. 22 | 23 | ### Returns 24 | 25 | - `StickerPack`: The resultant StickerPack object. 26 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/deduct_xp.md: -------------------------------------------------------------------------------- 1 | # deduct_xp 2 | 3 | Deduct the XP of user. 4 | 5 | ## Signature 6 | 7 | `async def deduct_xp(community_id: str, user_id: int, xp: int, description: str = None) -> Channel` 8 | 9 | ## Parameters 10 | - `community_id` (`str`): The ID of the community. 11 | - `user_id` (`int`): The ID of the user. 12 | - `xp` (`int`): The amount of XP to deduct. 13 | - `description` (`str`): An optional description of the reason for the deduction. -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/delete_media.md: -------------------------------------------------------------------------------- 1 | # delete_media 2 | 3 | Delete a [Media](../types/media.md) by its ID. 4 | 5 | ## Signature 6 | 7 | `async def delete_media(media_id: str)` 8 | 9 | ## Parameters 10 | 11 | - `media_id` (`str`): The ID of the media. 12 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/delete_message.md: -------------------------------------------------------------------------------- 1 | # delete_messages 2 | 3 | Delete messages. 4 | 5 | Usually you will call this method using the `delete` method of the message object itself. 6 | 7 | ## Signature 8 | 9 | `async def delete_messages(message_ids: List[int | Message]) -> bool` 10 | 11 | ## Parameters 12 | 13 | - `message` (int | [Message](../types/message)): The message to delete (either the message ID or the message object itself) -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/delete_sticker.md: -------------------------------------------------------------------------------- 1 | # `delete_sticker` 2 | Deletes a sticker by its ID. 3 | 4 | ### Signature 5 | 6 | ```python 7 | async def delete_sticker(sticker_id: str) -> bool: 8 | ``` 9 | 10 | ### Parameters 11 | 12 | - `sticker_id` (str): Sticker ID to delete. 13 | 14 | ### Returns 15 | 16 | - `bool`: Whether the sticker was successfully deleted. -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/delete_sticker_pack.md: -------------------------------------------------------------------------------- 1 | # `delete_sticker_pack` 2 | Deletes a sticker pack by its ID. 3 | 4 | ### Signature 5 | 6 | ```python 7 | async def delete_sticker_pack(pack_id: str) -> bool: 8 | ``` 9 | 10 | ### Parameters 11 | 12 | - `pack_id` (str): Pack ID to delete. 13 | 14 | ### Returns 15 | 16 | - `bool`: Whether the sticker pack was successfully deleted. -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/edit_message.md: -------------------------------------------------------------------------------- 1 | # edit_message 2 | 3 | Edits a message 4 | 5 | # Signature 6 | 7 | ```python 8 | async def edit_message( 9 | self, 10 | message_id: int, 11 | text: str, 12 | embed_message: EmbeddedMedia = None, 13 | inline_markup: InlineMarkup = None, 14 | **kwargs)-> Message: 15 | ``` 16 | 17 | # Parameters 18 | 19 | - `message` ([Message](../types/message)): The message to edit (if the message has not ID, it will be sent as a new message) 20 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/forward_message.md: -------------------------------------------------------------------------------- 1 | # forward_message 2 | 3 | Forwards a message to a user, channel or group. 4 | 5 | # Signature 6 | 7 | `async def forward_message(message: Message | int,group_channel: Group | Channel | str = None,receiver_id: int = None) -> Message` 8 | 9 | # Parameters 10 | 11 | - `message` (`Message` | `int`): The message to forward or its ID 12 | - `group_channel` Optional (`Group` | `Channel`| `str`, Optional): The group or channel to forward the message to (or its ID) 13 | - `receiver_id` Optional (`int`): The ID of the user to forward the message to 14 | 15 | 16 | - > Specify group_channel to forward message to the group or channel 17 | - > and receiver_id to forward to the user. -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_active_commands.md: -------------------------------------------------------------------------------- 1 | # get_active_commands 2 | 3 | Get active commands in the community. 4 | 5 | ## Signature 6 | 7 | `async def get_active_commands(community_id: str, channel_id: str = None, group_id: str = None) -> List[BotInfo]` 8 | 9 | ## Parameters 10 | 11 | - `community_id` (`str`): The ID of the community 12 | - `channel_id` (`str`): Channel ID. 13 | - `group_id` (`str`): Group ID 14 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_all_channels.md: -------------------------------------------------------------------------------- 1 | # get_all_channels 2 | 3 | Gets a list of [Channel](../types/channel.md) present in the community. 4 | 5 | ## Signature 6 | 7 | `async def get_all_channels(community_id: str) -> List[Channel]` 8 | 9 | ## Parameters 10 | 11 | - `community_id` (`str`): The ID of the community 12 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_all_groups.md: -------------------------------------------------------------------------------- 1 | # get_all_groups 2 | 3 | Gets a list of [Group](../types/group) present in the community. 4 | 5 | ## Signature 6 | 7 | `async def get_all_groups(community_id: str) -> List[Group]` 8 | 9 | ## Parameters 10 | 11 | - `community_id` (`str`): The ID of the community 12 | 13 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_all_sticker_packs.md: -------------------------------------------------------------------------------- 1 | ## `get_all_sticker_packs` 2 | Retrieves all sticker packs. 3 | 4 | ### Signature 5 | 6 | ```python 7 | async def get_all_sticker_packs( 8 | limit: Optional[int] = 20, 9 | offset: Optional[int] = 0, 10 | ) -> List[StickerPack]: 11 | ``` 12 | 13 | ### Parameters 14 | 15 | - `limit` (Optional[int]): The maximum number of sticker packs to retrieve. Defaults to 20. 16 | - `offset` (Optional[int]): The offset for fetching sticker packs. Defaults to 0. 17 | 18 | ### Returns 19 | 20 | - `List[StickerPack]`: List of all available sticker packs. -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_bot_info.md: -------------------------------------------------------------------------------- 1 | # get_bot_info 2 | 3 | Gets a bot info by its ID. 4 | 5 | ## Parameters 6 | - `bot_id` (int): The ID of the bot. 7 | 8 | ## Returns 9 | - [BotInfo](../types/botinfo.md): The Bot info.. -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_channel.md: -------------------------------------------------------------------------------- 1 | # get_channel 2 | 3 | Gets a [Channel](../types/channel) by its ID. 4 | 5 | ## Signature 6 | 7 | `async def get_channel(channel_id: str) -> Channel` 8 | 9 | ## Parameters 10 | 11 | - `channel_id` (`str`): The ID of the channel 12 | 13 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_channel_chat_history.md: -------------------------------------------------------------------------------- 1 | # get_channel_chat_history 2 | 3 | Get the chat history of a channel or group. 4 | 5 | ## Signature 6 | 7 | `async def get_channel_chat_history(channel_id:str, community_id: str, user_id:int =None, page_limit:int=100, page_offset:int=0) -> List[Message]:` 8 | 9 | 10 | ## Parameters 11 | 12 | - `channel_id` (str): The ID of the channel 13 | - `community_id` (str): The ID of the community 14 | - `user_id` (int): The ID of the user 15 | - `page_limit` (int): The maximum number of messages to return 16 | - `page_offset` (int): The offset of the first message to return 17 | 18 | 19 | :::tip 20 | There is an analogous method for getting the chat history of a group: [get_group_chat_history](../methods/get_group_chat_history). 21 | ::: 22 | 23 | 24 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_community.md: -------------------------------------------------------------------------------- 1 | # get_community 2 | 3 | Gets a [Community](../types/community) by its ID. 4 | 5 | ## Signature 6 | 7 | `async def get_community(community_id: str) -> Community` 8 | 9 | ## Parameters 10 | 11 | - `community_id` (`str`): The ID of the community 12 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_community_media_files.md: -------------------------------------------------------------------------------- 1 | # get_community_media_files: 2 | Get community media files. 3 | 4 | ### Parameters: 5 | 6 | - `community_id` (str): The ID of the community. 7 | 8 | ### Returns: 9 | 10 | - List[[Message](../types/message.md)]: A list of Message objects representing media files. 11 | 12 | ### Raises: 13 | - `switch.error.SwitchError`: If the messages could not be retrieved. 14 | 15 | ### Example: 16 | 17 | ```python 18 | media_files = await client.get_community_media_files("communityID") 19 | print(media_files) 20 | ``` 21 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_community_media_files_by_status.md: -------------------------------------------------------------------------------- 1 | # get_community_media_files by status: 2 | Get community media files by status. 3 | 4 | ### Parameters: 5 | - `community_id` (`str`): The ID of the community. 6 | - `status` (`int` | `List[int]`): status to look for. 7 | - `channel_id` (`str`, optional): Channel id 8 | - `group_id` (`str`, optional): group id 9 | - `user_id` (`str`, optional): user id 10 | 11 | ### Returns: 12 | 13 | - List[[Message](../types/message.md)]: A list of Message objects representing media files. 14 | 15 | ### Raises: 16 | - `switch.error.SwitchError`: If the messages could not be retrieved. 17 | 18 | ### Example: 19 | ```python 20 | # look for images 21 | 22 | media_files = await client.get_community_media_files_by_status(community_id="communityID", status=1) 23 | print(media_files) 24 | 25 | # or to get the status, use enum 26 | from swibots.types import MediaType 27 | # status=MediaType.DOCUMENT.value 28 | ``` 29 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_community_member.md: -------------------------------------------------------------------------------- 1 | # get_community_member 2 | 3 | Gets a community member by their ID. 4 | 5 | ## Parameters 6 | - `community_id` (str): The ID of the community. 7 | - `user_id` (int): The ID of the user. 8 | 9 | ## Returns 10 | - [CommunityMember](../types/communitymember.md): The community member. -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_group.md: -------------------------------------------------------------------------------- 1 | # get_group 2 | 3 | Gets a [Group](../types/group) by its ID. 4 | 5 | ## Signature 6 | 7 | `async def get_group(group_id: str) -> Group` 8 | 9 | ## Parameters 10 | 11 | - `group_id` (`str`): The ID of the group 12 | 13 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_group_chat_history.md: -------------------------------------------------------------------------------- 1 | # get_group_chat_history 2 | 3 | Get the chat history of a channel or group. 4 | 5 | ## Signature 6 | 7 | `async def get_group_chat_history(group_id:str, community_id: str, user_id:int =None, page_limit:int=100, page_offset:int=0) -> List[Message]:` 8 | 9 | 10 | ## Parameters 11 | 12 | - `group_id` (str): The ID of the group 13 | - `community_id` (str): The ID of the community 14 | - `user_id` (int): The ID of the user 15 | - `page_limit` (int): The maximum number of messages to return 16 | - `page_offset` (int): The offset of the first message to return 17 | 18 | 19 | :::tip 20 | There is an analogous method for getting the chat history of a channel: [get_channel_chat_history](../methods/get_channel_chat_history). 21 | ::: 22 | 23 | 24 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_last_seen.md: -------------------------------------------------------------------------------- 1 | # get_last_seen 2 | 3 | Get last seen of the user. 4 | 5 | ## Signature 6 | 7 | `async def get_last_seen(user_id: str) -> int` 8 | 9 | ## Parameters 10 | 11 | - `user_id` (`int`): User ID 12 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_media.md: -------------------------------------------------------------------------------- 1 | ## `get_media` Method 2 | 3 | Retrieves media content by its media ID. 4 | 5 | ### Signature 6 | 7 | ```python 8 | async def get_media( 9 | media_id: int 10 | ) -> Media: 11 | ``` 12 | 13 | ### Parameters 14 | - `media_id` (int): The unique identifier of the media content. 15 | 16 | ### Returns 17 | - [Media](../types/media.md): The retrieved media content. 18 | 19 | ### Description 20 | 21 | The `get_media` method allows you to fetch media content, such as images, videos, or other multimedia assets, by providing its unique media ID. This method is useful for accessing and displaying media content within your application. 22 | 23 | ## Example 24 | 25 | ```python 26 | # Usage example: 27 | media_id = 12345 # Replace with the actual media ID 28 | media = await app.get_media(media_id) 29 | # Now you can use the 'media' object for further processing or display. 30 | ``` 31 | 32 | Use this method to retrieve media content based on its ID, enabling you to integrate and showcase media elements within your application easily. -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_message.md: -------------------------------------------------------------------------------- 1 | # get_message 2 | 3 | Gets a [Message](../types/message) by its ID. 4 | 5 | ## Signature 6 | 7 | `async def get_message(message_id: int) -> Message` 8 | 9 | ## Parameters 10 | 11 | - `message_id` (int): The ID of the message 12 | 13 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_messages.md: -------------------------------------------------------------------------------- 1 | # get_messages 2 | 3 | Get a list of [messages](../types/message) by user ID. 4 | 5 | ## Signature 6 | 7 | `async def get_message(user_id: int) -> List[Message]` 8 | 9 | ## Parameters 10 | 11 | - `user_id` (int): The ID of the user 12 | 13 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_organization_apps.md: -------------------------------------------------------------------------------- 1 | # `get_organization_apps` 2 | 3 | Retrieve the apps associated with a specific organization. 4 | 5 | #### Signature: 6 | ```python 7 | async def get_organization_apps(self: "swibots.ApiClient", id: str) -> List[OrgApp]: 8 | ``` 9 | 10 | #### Arguments: 11 | - `id` (str): The ID of the organization. 12 | 13 | #### Return Value: 14 | - List[OrgApp]: The OrgApp object. 15 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_organization_by_id.md: -------------------------------------------------------------------------------- 1 | # `get_organization_by_id` 2 | Get Organization by ID 3 | 4 | #### Description: 5 | Retrieve details of an organization by its ID. 6 | 7 | #### Signature: 8 | ```python 9 | async def get_organization_by_id(self: "swibots.ApiClient", id: str) -> Organization: 10 | ``` 11 | 12 | #### Arguments: 13 | - `id` (str): The ID of the organization. 14 | 15 | #### Return Value: 16 | - Organization: The Organization object. 17 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_organization_followers.md: -------------------------------------------------------------------------------- 1 | # `get_organization_followers` 2 | Retrieve the followers of a specific organization. 3 | 4 | #### Signature: 5 | ```python 6 | async def get_organization_followers(self: "swibots.ApiClient", id: str) -> List[User]: 7 | ``` 8 | 9 | #### Arguments: 10 | - `id` (str): The ID of the organization. 11 | 12 | #### Return Value: 13 | - List[User]: A list of User objects representing followers. 14 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_organizations.md: -------------------------------------------------------------------------------- 1 | # `get_organizations` 2 | Retrieve a list of organizations based on specified parameters. 3 | 4 | #### Signature: 5 | ```python 6 | async def get_organizations( 7 | self, 8 | bot_id: int = None, 9 | community_id: str = None, 10 | user_id: str = None, 11 | ) -> List[Organization]: 12 | ``` 13 | 14 | #### Arguments: 15 | - `bot_id` (int, optional): The ID of the bot associated with the organizations. 16 | - `community_id` (str, optional): The ID of the community associated with the organizations. 17 | - `user_id` (str, optional): The ID of the user associated with the organizations. 18 | 19 | #### Return Value: 20 | - List[Organization]: A list of Organization objects. 21 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_stickers.md: -------------------------------------------------------------------------------- 1 | ## `get_stickers` Method 2 | 3 | Retrieves a list of stickers from a sticker pack. 4 | 5 | ### Signature 6 | 7 | ```python 8 | async def get_stickers( 9 | pack_id: str, 10 | limit: Optional[int] = 30, 11 | offset: Optional[int] = 0, 12 | ) -> List[Sticker]: 13 | ``` 14 | 15 | ### Parameters 16 | 17 | - `pack_id` (str): Pack ID of the sticker pack. 18 | - `limit` (Optional[int]): The maximum number of stickers to retrieve. Defaults to 30. 19 | - `offset` (Optional[int]): The offset to fetch stickers. Defaults to 0. 20 | 21 | ### Returns 22 | 23 | - `List[Sticker]`: List of stickers from the specified pack. 24 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_unread_messages_count.md: -------------------------------------------------------------------------------- 1 | # get_unread_messages_count 2 | 3 | Get the amount of unread messages 4 | 5 | ## Signature 6 | `async def get_unread_messages_count() -> int` 7 | 8 | ## Returns: 9 | - ``int``: The amount of unread messages -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/get_user.md: -------------------------------------------------------------------------------- 1 | # get_user 2 | 3 | get the [User](../types/user.md) info from user id. 4 | 5 | ## Signature 6 | 7 | `async def get_user(user_id: int=None, username: str = None) -> User` 8 | 9 | ## Parameters 10 | 11 | - `user_id` (int): The ID of the user to get info. 12 | - `username` (str): username 13 | 14 | ## Raises 15 | - ValueError: if both user_id and username are used. -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/list_restricted_users.md: -------------------------------------------------------------------------------- 1 | # list_restricted_users 2 | 3 | get the list of [RestrictedUser](../types/user.md) in the community! 4 | 5 | ## Signature 6 | 7 | `async def list_restricted_users(community_id: str) -> List[RestrictedUser]` 8 | 9 | ## Parameters 10 | - `community_id` (str): The ID of the community. -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/remove_handler.md: -------------------------------------------------------------------------------- 1 | # remove_handler 2 | 3 | Remove a handler from the bot. 4 | 5 | ## Signature 6 | 7 | `def remove_handler(self, handler: BaseHandler | List[BaseHandler]) -> Client` 8 | 9 | ## Parameters 10 | 11 | - `handler` (`BaseHandler | List[BaseHandler]`): The handler to remove from the bot, or a list of handlers to add to the bot (see [Hanlders](../../fundamentals/handlers) for more information on handlers) 12 | 13 | 14 | ## Example 15 | 16 | ```python 17 | 18 | 19 | from swibots import Client, BotContext, CommandEvent, MessageEvent, CallbackQueryEvent, filters, InlineKeyboardButton, InlineMarkup, BotCommandInfo 20 | 21 | from swibots.bots.handlers import ( 22 | MessageHandler, 23 | UnknownCommandHandler, 24 | CallbackQueryHandler, 25 | CommandHandler, 26 | ) 27 | 28 | 29 | async def echo(ctx: BotContext[CommandEvent]): 30 | m = await ctx.bot.prepare_response_message(ctx.event.message) 31 | text = ctx.event.params or "No args" 32 | m.message = f"Your message: {text}" 33 | await ctx.bot.send_message(m) 34 | 35 | app = Client() 36 | 37 | # register your handlers here 38 | 39 | echo_handler = CommandHandler( 40 | command="echo", 41 | callback=echo, 42 | ) 43 | app.add_handler( 44 | echo_handler 45 | ) 46 | 47 | # remove the handler 48 | app.remove_handler( 49 | echo_handler 50 | ) 51 | 52 | # now the handler won't be called when the user sends the /echo command 53 | 54 | app.run() 55 | 56 | ``` -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/run.md: -------------------------------------------------------------------------------- 1 | # run 2 | 3 | Starts the app and handles the start/stop of the bot. 4 | 5 | You are most likely to use this method in your main function. 6 | 7 | ## Example 8 | 9 | ```python 10 | 11 | from swibots import Client 12 | 13 | app = Client() 14 | 15 | # register your handlers here 16 | 17 | app.run() 18 | 19 | ``` -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/search_sticker_packs.md: -------------------------------------------------------------------------------- 1 | ## `search_sticker_packs``` 2 | Searches for sticker packs using a query. 3 | 4 | ### Signature 5 | 6 | ```python 7 | async def search_sticker_packs( 8 | query: str, 9 | limit: Optional[int] = 20, 10 | offset: Optional[int] = 0, 11 | ) -> List[StickerPack]: 12 | ``` 13 | 14 | ### Parameters 15 | 16 | - `query` (str): Query to search for sticker packs. 17 | - `limit` (Optional[int]): The maximum number of sticker packs to retrieve. Defaults to 20. 18 | - `offset` (Optional[int]): The offset for fetching sticker packs. Defaults to 0. 19 | 20 | ### Returns 21 | 22 | - `List[StickerPack]`: List of matching sticker packs. -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/send_media.md: -------------------------------------------------------------------------------- 1 | # send_media 2 | 3 | Send a message with media to a user, channel or group. 4 | 5 | ## Signature 6 | 7 | ```python 8 | async def send_media( 9 | message: str, 10 | document: str, 11 | community_id: Optional[str] = None, 12 | channel_id: Optional[str] = None, 13 | group_id: Optional[str] = None, 14 | user_id: Optional[int] = None, 15 | user_session_id: Optional[str] = None, 16 | embed_message: Optional[EmbeddedMedia] = None, 17 | inline_markup: InlineMarkup = None, 18 | scheduled_at: Optional[int] = None 19 | **kwargs 20 | ) -> Message: 21 | ``` 22 | 23 | ## Parameters 24 | 25 | - `message` (`str`): The message to send 26 | - `document` (`str`): Path to file 27 | - `community_id` (`str`): The community id to send message. 28 | - `group_id` (`str`): The Group ID. 29 | - `channel_id` (`str`): Channel ID. 30 | - `user_id` (`int`): User ID to send message. 31 | - `user_session_id` (`str`): Session ID, present if bot is added as channel in the community. 32 | - `embed_message` ([EmbeddedMedia](../types/embedded_media.md)). 33 | - `inline_markup` ([InlineMarkup](../types/inline_markup.md)): Inline Markup linked with message. 34 | - `scheduled_at` (`int`): timestamp to schedule message. -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/send_message.md: -------------------------------------------------------------------------------- 1 | # send_message 2 | 3 | Send a text message to a user, channel or group. 4 | 5 | ## Signature 6 | 7 | ```python 8 | async def send_message( 9 | message: str, 10 | community_id: Optional[str] = None, 11 | channel_id: Optional[str] = None, 12 | group_id: Optional[str] = None, 13 | user_id: Optional[int] = None, 14 | user_session_id: Optional[str] = None, 15 | embed_message: Optional[EmbeddedMedia] = None, 16 | inline_markup: InlineMarkup = None, 17 | ) -> Message: 18 | ``` 19 | 20 | ## Parameters 21 | 22 | - `message` (`str`): The message to send 23 | - `community_id` (`str`): The community id to send message. 24 | - `group_id` (`str`): The Group ID. 25 | - `channel_id` (`str`): Channel ID. 26 | - `user_id` (`int`): User ID to send message. 27 | - `user_session_id` (`str`): Session ID, present if bot is added as channel in the community. 28 | - `embed_message` ([EmbeddedMedia](../types/embedded_media.md)). 29 | - `inline_markup` ([InlineMarkup](../types/inline_markup.md)): Inline Markup linked with message. 30 | - `document` (`str`): Path to the local file to send as document. -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/send_sticker.md: -------------------------------------------------------------------------------- 1 | # Send sticker 2 | 3 | ### Parameters: 4 | - `sticker`: [Sticker] 5 | - `community_id`: Community ID 6 | - `group_id`: Group id 7 | - `channel_id`: Channel ID 8 | - `user_id`: User id to send message 9 | - `user_session_id`: Session ID, present if bot is added as channel in the community. 10 | 11 | # Returns 12 | - [Message](../types/message.md) -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/sort_stickers.md: -------------------------------------------------------------------------------- 1 | ## `sort_stickers` Method 2 | 3 | Sorts stickers within a sticker pack. 4 | 5 | ### Signature 6 | 7 | ```python 8 | async def sort_stickers( 9 | pack: StickerPack, sorted_stickers: List[str] 10 | ) -> StickerPack: 11 | ``` 12 | 13 | ### Parameters 14 | 15 | - `pack` (StickerPack): Sticker pack to sort stickers within. 16 | - `sorted_stickers` (List[str]): List of sticker IDs representing the desired sorting order. 17 | 18 | ### Returns 19 | 20 | - `StickerPack`: Sticker pack with stickers sorted as specified. 21 | ``` -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/start.md: -------------------------------------------------------------------------------- 1 | # start 2 | 3 | Starts the app and starts listening for updates. 4 | 5 | ## Example 6 | 7 | ```python 8 | from swibots import Client 9 | 10 | app = Client("TOKEN") 11 | 12 | async def main(): 13 | await app.start() 14 | ... # Invoke API methods 15 | await app.stop() 16 | 17 | 18 | app.run(main()) 19 | ``` 20 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/stop.md: -------------------------------------------------------------------------------- 1 | # stop 2 | 3 | Stops the app and stops listening for updates. 4 | 5 | ## Example 6 | 7 | ```python 8 | from swibots import Client 9 | 10 | app = Client("TOKEN") 11 | 12 | async def main(): 13 | await app.start() 14 | ... # Invoke API methods 15 | await app.stop() 16 | 17 | 18 | app.run(main()) 19 | ``` 20 | -------------------------------------------------------------------------------- /docs/docs/api_reference/methods/update_media_info.md: -------------------------------------------------------------------------------- 1 | # update_media_info 2 | 3 | Update a [Media](../types/media.md) info by its ID. 4 | 5 | ## Signature 6 | 7 | `async def update_media_info(media_id: int, caption: str, description: str) -> Media` 8 | 9 | ## Parameters 10 | - `media_id` (`int`): Media ID to update. 11 | - `caption` (`str`): caption of media. 12 | - `description` (`str`): Description of media. -------------------------------------------------------------------------------- /docs/docs/api_reference/types/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Types", 3 | "position": 3, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Available Types." 7 | } 8 | } -------------------------------------------------------------------------------- /docs/docs/api_reference/types/botinfo.md: -------------------------------------------------------------------------------- 1 | # BotInfo 2 | 3 | `Class swibots.api.bot.models.BotInfo` 4 | 5 | The `BotInfo` class contain information of bot profile. 6 | 7 | 8 | # Parameters 9 | - `id` (`str`): the bot id 10 | - `name` (`str`): the name of bot. 11 | - `description` (`str`): the description of profile. 12 | - `username` (`str`): the username. 13 | - `image_url` (`str`): the url to the bot profile photo. 14 | - `active` (`bool`): whether bot is active. 15 | - `deleted` (`bool`): if profile is deleted. 16 | - `is_bot` (`bool`): if profile belongs to bot. 17 | - `commands` (`List[BotCommandInfo]`): the list of bot commands. 18 | - `role_info` (`str`): the role info. 19 | -------------------------------------------------------------------------------- /docs/docs/api_reference/types/channel.md: -------------------------------------------------------------------------------- 1 | # Channel 2 | 3 | `Class swibots.api.community.models.Channel` 4 | 5 | The `Channel` class represents a channel. 6 | 7 | ## Properties 8 | 9 | - `id` (`str`): The channel's id. 10 | - `name` (`str`): The channel's name. 11 | - `community_id` (`str`): The channel's community id. 12 | - `enabled_free` (`bool`): Whether the channel is enabled for free users. 13 | - `enabled_public` (`bool`): Whether the channel is enabled for public users. 14 | - `default_channel` (`bool`): Whether the channel is the default channel. 15 | - `is_public` (`bool`): Whether the channel is public. 16 | - `created_by` (`str`): The channel's creator's id. 17 | - `icon` (`str`): The channel's icon. 18 | - `channel_logo_url` (`str`): The channel's logo url. 19 | - `allowed_content` (`str`): The channel's allowed content. 20 | - `created_at` (`str`): The channel's creation date. 21 | - `updated_at` (`str`): The channel's last update date. 22 | -------------------------------------------------------------------------------- /docs/docs/api_reference/types/community.md: -------------------------------------------------------------------------------- 1 | # Community 2 | 3 | `Class swibots.api.community.models.Community` 4 | 5 | The `Community` class represents a community. 6 | 7 | ## Properties 8 | 9 | - `id` (`str`): The community's id. 10 | - `name` (`str`): The community's name. 11 | - `username` (`str`): The community's username. 12 | - `profile_url` (`str`): The community's profile image url. 13 | - `cover_url` (`str`): The community's cover image url. 14 | - `is_public` (`bool`): Whether the community is public. 15 | - `is_free` (`bool`): Whether the community is free. 16 | - `created_by` (`str`): The community's creator's id. 17 | - `guidelines` (`str`): The community's guidelines. 18 | - `description` (`str`): The community's description. 19 | - `verified` (`bool`): Whether the community is verified. 20 | - `category` (`str`): The community's category. 21 | - `type` (`str`): The community's type. 22 | - `link` (`str`): The community's link. 23 | - `icon` (`str`): The community's icon. 24 | -------------------------------------------------------------------------------- /docs/docs/api_reference/types/communitymember.md: -------------------------------------------------------------------------------- 1 | # CommunityMember 2 | 3 | `Class swibots.api.community.models.CommunityMember` 4 | 5 | The `CommunityMember` class contains the info of the user linked with the community. 6 | 7 | ## Properties 8 | - `id` (`int`): ID 9 | - `admin` (`bool`): Is user admin. 10 | - `username` (`str`): username of user. 11 | - `user_id` (int): User Id of user. 12 | - `community_id` (str): The community id. 13 | - `user` ([User](./user.md)): The User Info. 14 | - `xp` (int): The xp of the user. 15 | - `xp_spend` (int): The xp spend by the user. 16 | - `enable_notification` (`bool`): is User's notification are enabled. 17 | - `role_info` (`dict`): the role info of user. 18 | - `mute_period` (`str`): the mute period. 19 | - `mute_notification` (`bool`): 20 | - `mute_groups`: (`List[str]`): the muted groups. 21 | - `mute_channels` (`List[str]`): the muted channels. -------------------------------------------------------------------------------- /docs/docs/api_reference/types/embed_inline_field.md: -------------------------------------------------------------------------------- 1 | # EmbedInlineField 2 | 3 | `Class swibots.api.chat.models.EmbedInlineField` 4 | 5 | The `EmbedInlineField` class represents a field that can be added to an [embedded message.](./embedded_media.md). 6 | 7 | ## Properties 8 | 9 | - `title` (`str`): The field's text. 10 | - `key` (`str`): The field's value. 11 | - `icon` (`str`): the field's icon (`URL`). -------------------------------------------------------------------------------- /docs/docs/api_reference/types/embedded_media.md: -------------------------------------------------------------------------------- 1 | # EmbeddedMedia 2 | 3 | The `EmbeddedMedia` class is used to send embedded media in messages. 4 | 5 | ## Parameters 6 | 7 | - `thumbnail` (str): The path to file or cover Url in updates. 8 | - `title` `(str)`: title of message. 9 | - `description` (`str`): description of message. 10 | - `header_name` (`str`): header name. 11 | - `header_icon` (`str`): header icon (URL) 12 | - `footer_title` (`str`): footer title. 13 | - `footer_icon` (`str`): footer icon (URL). 14 | - `inline_fields` (List[List[EmbedInlineField]](./embed_inline_field.md)): The inline fields. 15 | 16 | 17 | ## Usage 18 | 19 | ```python 20 | from swibots import EmbeddedMedia, EmbedInlineField, MediaUploadRequest 21 | 22 | embedded = EmbeddedMedia( 23 | thumbnail="image.png", 24 | title="Embedded Message", 25 | description="This is description", 26 | header_name="header", 27 | header_icon="https://icons8.com/icon/6nsw3h9gk8M8/bot", 28 | footer_title="footer", 29 | footer_icon="https://icons8.com/icon/6nsw3h9gk8M8/bot", 30 | inline_fields=[[ 31 | EmbedInlineField("", "Value", "Title") 32 | ]] 33 | ) 34 | await message.respond("Embedded Message", media=embedded) 35 | ``` -------------------------------------------------------------------------------- /docs/docs/api_reference/types/gameinfo.md: -------------------------------------------------------------------------------- 1 | # GameInfo 2 | - `GameInfo` object contains the info of the user's game score, level and the chat it is linked with. 3 | 4 | ### Properties 5 | - `score` (int): the score of the game. 6 | - `user_id` (int): the user id of user. 7 | - `level` (Optional | `int`): the level 8 | - `community_id` (Optional | `str`): community ID, present only if the user played in the community. -------------------------------------------------------------------------------- /docs/docs/api_reference/types/group.md: -------------------------------------------------------------------------------- 1 | # Group 2 | 3 | `Class swibots.api.community.models.Group` 4 | 5 | The `Group` class represents a group. 6 | 7 | ## Properties 8 | 9 | - `id` (`str`): The group's id. 10 | - `name` (`str`): The group's name. 11 | - `community_id` (`str`): The group's community id. 12 | - `enabled_free` (`bool`): Whether the group is enabled for free users. 13 | - `enabled_public` (`bool`): Whether the group is enabled for public users. 14 | - `default_group` (`bool`): Whether the group is the default group. 15 | - `is_public` (`bool`): Whether the group is public. 16 | - `created_by` (`str`): The group's creator's id. 17 | - `icon` (`str`): The group's icon. 18 | - `group_logo_url` (`str`): The group's logo url. 19 | - `allowed_content` (`str`): The group's allowed content. 20 | - `created_at` (`str`): The group's creation date. 21 | - `updated_at` (`str`): The group's last update date. 22 | -------------------------------------------------------------------------------- /docs/docs/api_reference/types/inline/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Inline Types", 3 | "position": 2, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Inline query types. These are used as a result of an inline query." 7 | } 8 | } -------------------------------------------------------------------------------- /docs/docs/api_reference/types/inline/inline_query_answer.md: -------------------------------------------------------------------------------- 1 | # InlineQueryAnswer 2 | 3 | `Class swibots.api.chat.models.inline.InlineQueryAnswer` 4 | 5 | Represents a result of an inline query that was chosen by the user and sent to their chat partner. 6 | 7 | ## Properties 8 | - `query_id` (`str`): Unique identifier for the answered query 9 | - `user_id` (`int`): The ID of the user who sent the query 10 | - `title` (`str`): Title of the result 11 | - `results` (List[[InlineQueryResult](./inline_query_result)]): A list of results for the inline query 12 | - `next_offset` (`str`): Pass the offset that a client should send in the next query with the same text to receive more results. Pass an empty string if there are no more results or if you don‘t support pagination. Offset length can’t exceed 64 bytes. 13 | 14 | -------------------------------------------------------------------------------- /docs/docs/api_reference/types/inline/input_message_content.md: -------------------------------------------------------------------------------- 1 | # InputMessageContent 2 | 3 | `Class swibots.api.chat.models.inline.InputMessageContent` 4 | 5 | Represents the content of a message to be sent as a result of an inline query. 6 | 7 | 8 | ## Properties 9 | 10 | - `message_text` (`str`): Text of the message to be sent, 1-4096 characters -------------------------------------------------------------------------------- /docs/docs/api_reference/types/inline_keyboard_button.md: -------------------------------------------------------------------------------- 1 | # InlineKeyboardButton 2 | 3 | `Class swibots.api.chat.models.InlineKeyboardButton` 4 | 5 | The `InlineKeyboardButton` class represents a button that can be added to an [inline keyboard](./inline_markup). 6 | 7 | ## Properties 8 | 9 | - `text` (`str`): The button's text. 10 | - `url` (`str`): The button's url. 11 | - `callback_data` (`str`): The button's callback data. 12 | 13 | ## Usage 14 | 15 | ```python 16 | from swibots import InlineKeyboardButton, InlineMarkup 17 | 18 | button1 = InlineKeyboardButton( 19 | text="Button Text", 20 | url="https://example.com", 21 | callback_data="callback_data" 22 | ) 23 | 24 | button2 = InlineKeyboardButton( 25 | text="Button Text", 26 | url="https://example.com", 27 | callback_data="callback_data" 28 | ) 29 | 30 | button3 = InlineKeyboardButton( 31 | text="Button Text", 32 | url="https://example.com", 33 | callback_data="callback_data" 34 | ) 35 | 36 | ## create a row of buttons 37 | row1 = [button1, button2, button3] 38 | 39 | # add the row to the keyboard 40 | 41 | keyboard = InlineMarkup(inline_keyboard=[row1]) 42 | 43 | 44 | 45 | ``` -------------------------------------------------------------------------------- /docs/docs/api_reference/types/inline_markup.md: -------------------------------------------------------------------------------- 1 | # InlineMarkup 2 | 3 | `Class swibots.api.chat.models.InlineMarkup` 4 | 5 | The `InlineMarkup` class represents a markup that can be added to a message (Only bots can add markup to the messages). 6 | 7 | ## Properties 8 | 9 | - `inline_keyboard` (List[List[[InlineKeyboardButton](./inline_keyboard_button)]]): The markup's buttons. 10 | 11 | 12 | ## Usage 13 | 14 | ```python 15 | from swibots import InlineKeyboardButton, InlineMarkup 16 | 17 | button1 = InlineKeyboardButton( 18 | text="Button Text", 19 | url="https://example.com", 20 | callback_data="callback_data" 21 | ) 22 | 23 | button2 = InlineKeyboardButton( 24 | text="Button Text", 25 | url="https://example.com", 26 | callback_data="callback_data" 27 | ) 28 | 29 | button3 = InlineKeyboardButton( 30 | text="Button Text", 31 | url="https://example.com", 32 | callback_data="callback_data" 33 | ) 34 | 35 | ## create a row of buttons 36 | row1 = [button1, button2, button3] 37 | 38 | # add the row to the keyboard 39 | 40 | keyboard = InlineMarkup(inline_keyboard=[row1]) 41 | 42 | # add the keyboard to the message 43 | 44 | message = Message(text="Hello World", inline_markup=keyboard) 45 | 46 | ``` -------------------------------------------------------------------------------- /docs/docs/api_reference/types/media.md: -------------------------------------------------------------------------------- 1 | # Media 2 | 3 | `Class swibots.api.common.models.Media` 4 | 5 | The `Media` class represents a media (file, audio, video, etc) that has been uploaded to the server. 6 | 7 | ## Properties 8 | 9 | - `id` (`int`): The media's id. 10 | - `caption` (`str`): The media's caption. 11 | - `description` (`str`): The media's description. 12 | - `thumbnail_url` (`str`): The media's thumbnail url. 13 | - `source_id` (`int`): The media's source id. 14 | - `media_type` (`int`): The media's type (1 = Photo, 2 = Video, 3= Audio, 7 = Document). 15 | - `mime_type` (`str`): The media's mime type. 16 | - `file_name` (`str`): The media's file name. 17 | - `file_size` (`int`): The media's file size. 18 | - `url` (`str`): The media's url. 19 | 20 | ## Methods 21 | 22 | > **async def edit(self, caption: str, description: str):** 23 | - `caption` (`str`): caption of media. 24 | - `description` (`str`): description of media. -------------------------------------------------------------------------------- /docs/docs/api_reference/types/orgapp.md: -------------------------------------------------------------------------------- 1 | # OrgApp 2 | App/Bot linked with organization. 3 | 4 | #### Parameters: 5 | 6 | - `app` (`swibots.App`, optional): The chat application instance. 7 | - `commands` (`List[BotCommand]`, optional): List of bot commands associated with the organization app. 8 | - `created_at` (`str`, optional): The timestamp when the organization app was created. 9 | - `org_id` (`str`, optional): The ID of the organization to which the app belongs. 10 | - `name` (`str`, optional): The name of the organization app. 11 | - `role` (`str`, optional): The role associated with the organization app. 12 | - `id` (`str`, optional): The ID of the organization app. 13 | - `status` (`str`, optional): The status of the organization app. 14 | -------------------------------------------------------------------------------- /docs/docs/api_reference/types/restricteduser.md: -------------------------------------------------------------------------------- 1 | # RestrictedUser 2 | 3 | `Class swibots.api.community.models.RestrictedUser` 4 | 5 | The `RestrictedUser` class contains the info of the restricted user in the community. 6 | 7 | ## Properties 8 | - `restricted` (`bool`): Is User restricted 9 | - `user_id` (int): User Id of user. 10 | - `community_id` (str): The community id. 11 | - `restricted_till` (int | dict): the date info. 12 | - `user` ([User](../types/user.md)): The User Info. 13 | -------------------------------------------------------------------------------- /docs/docs/api_reference/types/tournament.md: -------------------------------------------------------------------------------- 1 | # Tournament 2 | 3 | `Class swibots.api.airdrop.models.Tournament` 4 | 5 | The `Group` class represents a group. 6 | 7 | ## Properties 8 | 9 | - `id` (`str`): The tournament's id. 10 | - `community_id` (`str`): The community id. 11 | - `creator` (`str`): the creator name. 12 | - `name` (`str`): the Tournament name. 13 | - `description` (`str`): description of tournament. 14 | - `cover_img` (`str`): the cover image url. 15 | - `status` (`str`): the status 16 | - `start_time` (`str`): start time of tournament. 17 | - `end_time` (`str`): the end time 18 | - `prizes` (`str`): the prize 19 | - `link` (`str`): the link to the tournament 20 | - `xp`: (`int`): the xp linked with it. 21 | - `state` (`str`): the state. -------------------------------------------------------------------------------- /docs/docs/api_reference/types/user.md: -------------------------------------------------------------------------------- 1 | # User 2 | 3 | `Class swibots.api.common.models.User` 4 | 5 | The `User` class represents a user. 6 | 7 | ## Properties 8 | 9 | - `id` (`int`): The user's id. 10 | - `name` (`str`): The user's full name. 11 | - `username` (`str`): The user's username. 12 | - `image_url` (`str`): The user's profile image url. 13 | - `active` (`bool`): Whether the user is active. 14 | - `deleted` (`bool`): Whether the user is deleted. 15 | - `role_info` (`str`): The user's role info. 16 | - `admin` (`bool`): Whether the user is an admin. 17 | - `is_bot` (`bool`): Whether the user is a bot. 18 | -------------------------------------------------------------------------------- /docs/docs/basic-concepts/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Basic Concepts", 3 | "position": 2, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "5 minutes to learn the most important SwiBots concepts." 7 | }, 8 | "collapsed": true 9 | 10 | } -------------------------------------------------------------------------------- /docs/docs/basic-concepts/logging.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Logging 6 | 7 | It is crucial you turn on the logging for swibots for better productivity! 8 | 9 | ```python {3,4} title="main.py" 10 | from switbots import Client 11 | 12 | import logging 13 | logging.basicConfig(level=logging.INFO) 14 | 15 | TOKEN = "" # Always import from [.env] file or system env 16 | 17 | bot = Client(TOKEN, "My bot description") 18 | 19 | bot.run() 20 | ``` 21 | 22 | :::info 23 | The output these 2 specific lines produce is very informative! 24 | ::: 25 | 26 | ```bash title="Output" 27 | INFO:swibots.bot_app:🚀 Starting app... 28 | INFO:swibots.bot_app:Logged in as ['Bot Name'][bot_username_bot][bot_id] 29 | INFO:swibots.bot_app:🚀 App started! 30 | ``` -------------------------------------------------------------------------------- /docs/docs/basic-concepts/project-setup.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Project setup 6 | 7 | You have learned how to create a very [basic bot](../intro) in the Quick start guide. In this page we will discuss 8 | how to configure the project to properly create your bots 9 | 10 | # Auth Key 11 | 12 | You will need an AuthKey to use SwiBots, you can obtain your key on the Switch app 13 | 14 | :::danger 15 | Never share your AuthKey or commit it to any source code versioning system! 16 | ::: 17 | 18 | # Configuration 19 | 20 | Having the API key from the previous step, we can now begin to configure a SwiBots project: pass your API key to SwiBots by using the token parameter of the Client class: 21 | 22 | ```python 23 | from swibots import Client 24 | 25 | TOKEN = "MY SUPER SECRET TOKEN" 26 | 27 | # initialize the app 28 | app = Client( 29 | TOKEN 30 | ) 31 | ``` -------------------------------------------------------------------------------- /docs/docs/deploy/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Deploy", 3 | "position": 6, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Deploy your bots" 7 | }, "collapsed": true 8 | 9 | } -------------------------------------------------------------------------------- /docs/docs/examples/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Example", 3 | "position": 5, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "5 minutes to learn the most important SwiBots concepts." 7 | }, 8 | "collapsed": true 9 | } -------------------------------------------------------------------------------- /docs/docs/examples/echo-bot.md: -------------------------------------------------------------------------------- 1 | # Creating Your First Bot: Echo Bot 2 | 3 | In this example, we'll create a simple echo bot using SwiBots. This bot will respond to any message it receives by sending the same message back to the user. 4 | 5 | ## Prerequisites 6 | 7 | Before you begin, make sure you have: 8 | 9 | 1. Installed SwiBots (`pip install swibots`) 10 | 2. Obtained a bot token from the Switch platform 11 | 12 | ## The Code 13 | 14 | Here's the complete code for our echo bot: 15 | 16 | ```python 17 | from swibots import Client, BotContext, MessageEvent 18 | 19 | app = Client("YOUR_BOT_TOKEN") 20 | 21 | @app.on_message() 22 | async def message_handler(ctx: BotContext[MessageEvent]): 23 | message = ctx.event.message 24 | await message.respond(f"Received: {message.message}") 25 | 26 | 27 | app.run() 28 | ``` 29 | 30 | ## Running the Bot 31 | 32 | To run the bot, simply execute the script: 33 | 34 | ```bash 35 | python echo_bot.py 36 | ``` 37 | 38 | ## Testing the Bot 39 | -------------------------------------------------------------------------------- /docs/docs/fundamentals/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Fundamentals", 3 | "position": 3, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "5 minutes to learn the most important SwiBots concepts." 7 | }, 8 | "collapsed": true 9 | 10 | } -------------------------------------------------------------------------------- /docs/docs/fundamentals/context.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | 5 | # Bot Context 6 | 7 | The `BotContext` is the object that is passed to the handler functions. It contains the information of the bot and the event that triggered the handler. 8 | You can use the `BotContext` to send messages, get information about the user, etc (All of the methods available in the API are callable via the context). 9 | 10 | ## BotContext properties 11 | 12 | - `bot:Bot` - The bot that owns the current context. 13 | - `event:Event` - The event that triggered the handler. -------------------------------------------------------------------------------- /docs/docs/fundamentals/upload_speed.md: -------------------------------------------------------------------------------- 1 | # Getting higher upload speed 2 | 3 | ### Default Parameters 4 | - By default, library doesn't use of concurrent upload or threading. 5 | - For the fan of speed and large files, one can make use of the below guide to get higher speed. 6 | 7 | :::info 8 | Upload speed can be increased by using `part_size` and `task_count` parameter in any of the upload methods (`reply_media`, `send_media`). 9 | ::: 10 | 11 | ### Example 12 | - The below example use `100MB as part_size` and `30 as task_count`. 13 | - It will create 30 threads and each will upload 100MB, until the complete file gets uploaded! 14 | ```python 15 | await client.send_media( 16 | user_id=76, 17 | document="path/to/file.ext", 18 | part_size=100*1024*1024, 19 | task_count=30 20 | ) 21 | ``` 22 | 23 | :::warning 24 | This parameters should be used depending on the machine, where the task is being executed! 25 | ::: 26 | -------------------------------------------------------------------------------- /docs/docs/interactions/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Interactions", 3 | "position": 3, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Interactions api" 7 | }, 8 | "collapsed": true 9 | } -------------------------------------------------------------------------------- /docs/docs/interactions/callback_queries.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Callback queries 6 | with the callback queries, you can respond the user with Alert, 7 | callback queries are called after the user click the `InlineKeyboardButton` 8 | 9 | ## `answer()` 10 | #### Arguments 11 | - `text` (`str`) the text to show. 12 | - `show_alert` (`bool`): whether to show large/splash alert. 13 | - `url` (`str`): the url as callback. 14 | - `cache_time` (`int`): 15 | 16 | ### Example 17 | ```python 18 | from swibots import Client, CallbackQueryEvent, BotContext 19 | 20 | app = Client('TOKEN') 21 | 22 | @Client.on_callback_query() 23 | async def onCallback(ctx: BotContext[CallbackQueryEvent]): 24 | await ctx.event.answer( 25 | text="Hello this is a alert!", 26 | show_alert=True, 27 | ) 28 | 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/docs/interactions/games.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | 5 | # Games 6 | Games on the are the termed referred to the web game (HTML5, any). 7 | 8 | ```python 9 | from swibots import Client, InlineKeyboardButton, InlineMarkup 10 | 11 | app = Client('TOKEN') 12 | 13 | await app.send_message( 14 | message="Hi", 15 | user_id=100, 16 | inline_markup=InlineMarkup([ 17 | [InlineKeyboardButton(text="Play Game", game=True)] 18 | ]) 19 | ) 20 | ``` 21 | 22 | ## Leaderboards 23 | - User is allowed to have 2 classification, (one for the private chats, and other per each community.) 24 | 25 | ### Creating leaderboard 26 | ```python 27 | await app.create_leaderboard( 28 | user_id=user_id, 29 | community_id=community_id, 30 | score=score 31 | ) 32 | ``` 33 | 34 | ### Getting Global leaderboard 35 | ```python 36 | await app.get_global_leaderboard() 37 | ``` 38 | 39 | ### Getting Community leaderboard 40 | ```python 41 | await app.get_community_leaderboard( 42 | community_id=communityId 43 | ) 44 | ``` 45 | 46 | ### Getting User's score 47 | ```python 48 | await app.get_game_score( 49 | user_id=user_id, 50 | community_id=communityId 51 | # ignore community id to get score in user's private 52 | ) 53 | ``` 54 | -------------------------------------------------------------------------------- /docs/docs/interactions/stickers.md: -------------------------------------------------------------------------------- 1 | # Stickers 2 | 3 | #### Management 4 | - [Create Sticker Pack](../api_reference/methods/create_sticker_pack.md) 5 | - [Create Sticker](../api_reference/methods/create_sticker.md) 6 | - [Get Stickers](../api_reference/methods/get_stickers.md) 7 | - [Sort Stickers](../api_reference/methods/sort_stickers.md) 8 | - [Delete Sticker](../api_reference/methods/delete_sticker.md) 9 | - [Delete Sticker Pack](../api_reference/methods/delete_sticker_pack.md) 10 | 11 | #### Search 12 | - [Get All sticker packs](../api_reference/methods/get_all_sticker_packs.md) 13 | - [Search Sticker packs](../api_reference/methods/search_sticker_packs.md) -------------------------------------------------------------------------------- /docs/docs/mini-apps/AppBar.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # AppBar 6 | 7 | The `AppBar` class represents an app bar in a user interface. 8 | 9 | #### Properties 10 | 11 | - `title` (Optional): The title of the app bar, default is "App". 12 | - `subtitle` (Optional): The subtitle or additional information about the app bar. 13 | - `left_icon` (Optional): The icon on the left side of the app bar. It can be either a string (URL) or an `Icon` component. 14 | - `secondary_icon` (Optional): The secondary icon on the app bar. It can be either a string (URL) or an `Icon` component. 15 | - `tertiary_icon` (Optional): The tertiary icon on the app bar. It can be either a string (URL) or an `Icon` component. 16 | 17 | #### Methods 18 | 19 | - **Constructor** 20 | 21 | ```python 22 | def __init__( 23 | self, 24 | title: str = "App", 25 | subtitle: str = "", 26 | left_icon: Union[Icon, str] = Icon(...), 27 | secondary_icon: Union[Icon, str] = None, 28 | tertiary_icon: Union[Icon, str] = "" 29 | ) 30 | ``` 31 | 32 | #### Usage Example 33 | 34 | ```python 35 | # Create an AppBar instance: 36 | app_bar = AppBar( 37 | title="My App", 38 | subtitle="Subtitle Text", 39 | left_icon="https://raw.githubusercontent.com/switchcollab/Switch-Bots-Python-Library/main/docs/static/img/logo.png", 40 | secondary_icon="https://example.com/secondary-icon.png", 41 | tertiary_icon="https://example.com/tertiary-icon.png" 42 | ) 43 | ``` -------------------------------------------------------------------------------- /docs/docs/mini-apps/AppPage.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | ### AppPage 6 | 7 | The `AppPage` class represents a page within a Switch application. 8 | 9 | #### Properties 10 | 11 | - `screen` (Optional): The type of screen for the page, default is `ScreenType.SCREEN`. 12 | - `components` (Optional): A list of standalone components to be included in the page. 13 | - `app_bar` (Optional): The app bar component for the page. 14 | - `disable_appbar` (Optional, bool): Whether to disable the appbar for current page. 15 | - `bottom_bar` (Optional): The bottom bar component for the page. 16 | 17 | #### Methods 18 | 19 | - **Constructor** 20 | 21 | ```python 22 | def __init__( 23 | self, 24 | app: "swibots.App" = None, 25 | screen: ScreenType = ScreenType.SCREEN, 26 | components: List[Component] = None, 27 | app_bar: AppBar = None, 28 | disable_appbar: bool = None, 29 | bottom_bar: BottomBar = None, 30 | ) 31 | ``` 32 | 33 | #### Usage Example 34 | 35 | ```python 36 | # Create an AppPage instance: 37 | app_page = AppPage( 38 | screen=ScreenType.FULLSCREEN, 39 | components=[ 40 | Carousel(images=[Image(url="https://example.com/image1.jpg")]), 41 | Button(text="Click Me")], 42 | app_bar=AppBar(title="My Page") 43 | ) 44 | ``` 45 | 46 | ### ScreenType (Enum): 47 | - `BOTTOM`: to display bottom sheet. 48 | - `SCREEN`: to display as page. -------------------------------------------------------------------------------- /docs/docs/mini-apps/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "MiniApps", 3 | "position": 4, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Building feature rich mini-apps on Switch." 7 | }, 8 | "collapsed": true 9 | } -------------------------------------------------------------------------------- /docs/docs/mini-apps/callback_methods.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | title: "Callback Methods" 4 | --- 5 | This page contain certain tasks which are made available to the mini-apps to interact with user. 6 | 7 | ## copy 8 | #### Arguments: 9 | - `text`: (str): text to copy on user's device. 10 | 11 | #### Example 12 | ```python 13 | @app.on_callback_query() 14 | async def onQuery(ctx: BotContext[CallbackQueryEvent]): 15 | await ctx.event.copy( 16 | "Here is the secret copied message, https://switch.pe/" 17 | ) 18 | ``` 19 | 20 | ## redirect 21 | #### Arguments: 22 | - `url`: (str): redirect user to the given url! 23 | 24 | #### Example 25 | ```python 26 | @app.on_callback_query() 27 | async def onQuery(ctx: BotContext[CallbackQueryEvent]): 28 | await ctx.event.redirect( 29 | url="https://switch.pe/" 30 | ) 31 | ``` 32 | 33 | ## share 34 | #### Arguments: 35 | - `text` (str): text to prompt share on user device. 36 | #### Example 37 | ```python 38 | @app.on_callback_query() 39 | async def onQuery(ctx: BotContext[CallbackQueryEvent]): 40 | await ctx.event.share( 41 | text="Share this cool app with yours friends! https://switch.pe/" 42 | 43 | ) 44 | ``` -------------------------------------------------------------------------------- /docs/docs/mini-apps/components/AudioPlayer.md: -------------------------------------------------------------------------------- 1 | ### AudioPlayer 2 | 3 | The `AudioPlayer` class represents a component for playing audio in a user interface. 4 | 5 | #### Properties 6 | 7 | - `id` (Optional): Any random id 8 | - `title` (Required): The title of the audio track. 9 | - `url` (Required): The URL of the audio file to be played. 10 | - `subtitle` (Optional): The subtitle or additional information about the audio track. 11 | - `thumb` (Optional): The thumbnail image associated with the audio track. It can be an `Image` class or URL string. 12 | - `callback_data` (Optional, str): Detail about video player changes. 13 | - `next_callback` (Optional): Callback for the next page. 14 | - `previous_callback` (Optional): Callback for the previous page 15 | 16 | #### Usage Example 17 | 18 | ```python 19 | # Create an AudioPlayer instance: 20 | audio_player = AudioPlayer( 21 | title="Example Audio Track", 22 | url="https://example.com/audio.mp3", 23 | subtitle="Artist: John Doe", 24 | thumb="https://example.com/thumbnail.jpg" 25 | ) 26 | ``` -------------------------------------------------------------------------------- /docs/docs/mini-apps/components/Badge.md: -------------------------------------------------------------------------------- 1 | # Badge 2 | 3 | The `Badge` class represents a badge component in a user interface. 4 | 5 | ### Properties 6 | 7 | - `text` (Required): The text content of the badge. 8 | - `background` (Optional): The background color of the badge. 9 | - `text_color` (Optional): The text color of the badge. 10 | 11 | ### Methods 12 | 13 | ```python 14 | def __init__( 15 | self, 16 | text: str, 17 | background: str = None, 18 | text_color: str = None 19 | ) 20 | ``` 21 | 22 | ### Usage Example: 23 | ```python 24 | # Create a Badge instance: 25 | 26 | badge = Badge( 27 | text="New", 28 | background="blue", 29 | text_color="white" 30 | ) 31 | ``` -------------------------------------------------------------------------------- /docs/docs/mini-apps/components/ButtonGroup.md: -------------------------------------------------------------------------------- 1 | # ButtonGroup 2 | 3 | The `ButtonGroup` class represents a group of action buttons in a user interface. 4 | 5 | #### Properties 6 | 7 | - `buttons` (Required, List[[Button](./Button.md)]): A list of `Button` components representing the buttons in the group. 8 | 9 | #### Usage Example 10 | 11 | ```python 12 | # Create a list of Button components for the ButtonGroup: 13 | button_group_buttons = [ 14 | Button(text="Button 1", callback_data="Callback Data 1"), 15 | Button(text="Button 2", callback_data="Callback Data 2"), 16 | Button(text="Button 3", callback_data="Callback Data 3"), 17 | ] 18 | 19 | # Create a ButtonGroup instance: 20 | button_group = ButtonGroup(buttons=button_group_buttons) 21 | ``` -------------------------------------------------------------------------------- /docs/docs/mini-apps/components/Carousel.md: -------------------------------------------------------------------------------- 1 | ### Carousel 2 | 3 | The `Carousel` class represents a carousel layout in a user interface. 4 | 5 | #### Properties 6 | 7 | - `images` (Required): A list of `Image` components representing the carousel images. 8 | - `title` (Optional): The title of the carousel. 9 | - `subtitle` (Optional): The subtitle or additional information about the carousel. 10 | 11 | #### Usage Example 12 | 13 | ```python 14 | # Create a list of Image components for the Carousel: 15 | carousel_images = [ 16 | Image(url="https://example.com/image1.jpg", callback_data="Callback Data 1"), 17 | Image(url="https://example.com/image2.jpg", callback_data="Callback Data 2"), 18 | Image(url="https://example.com/image3.jpg", callback_data="Callback Data 3"), 19 | ] 20 | 21 | # Create a Carousel instance: 22 | carousel = Carousel( 23 | images=carousel_images, 24 | title="Carousel Title", 25 | subtitle="Carousel Subtitle" 26 | ) 27 | ``` -------------------------------------------------------------------------------- /docs/docs/mini-apps/components/Dropdown.md: -------------------------------------------------------------------------------- 1 | # Dropdown 2 | 3 | The `Dropdown` class represents a dropdown in a user interface. 4 | 5 | ## Properties 6 | 7 | - `placeholder` (Optional, `str`): The placeholder text for the dropdown. 8 | - `selected` (Optional, `int`): The index of the selected item in the dropdown. 9 | - `options` (List[ListTile]): A list of items representing the dropdown options. 10 | - `disabled` (Optional, `bool`): A flag indicating whether the dropdown is disabled. 11 | 12 | 13 | ## Example 14 | ```python 15 | from swibots import CallbackQueryEvent, BotContext 16 | from swibots import AppPage, AppBar, Dropdown, ListItem 17 | 18 | # handle callback query 19 | @app.on_callback_query() 20 | async def onCallback(ctx: BotContext[CallbackQueryEvent]): 21 | # create a callback component 22 | await ctx.event.answer( 23 | callback=AppPage( 24 | app_bar=AppBar(title="Hello from Swibots"), 25 | components=[ 26 | Dropdown( 27 | placeholder="Choose Option", 28 | options=[ 29 | ListItem("1. Orange", callback_data="option1"), 30 | ListItem("2. Yellow", callback_data="option2"), 31 | ListItem("3. Green", callback_data="option3"), 32 | ListItem("4. Green", callback_data="option4"), 33 | ], 34 | ) 35 | ], 36 | ) 37 | ) 38 | ``` 39 | -------------------------------------------------------------------------------- /docs/docs/mini-apps/components/FilePicker.md: -------------------------------------------------------------------------------- 1 | ### FilePicker 2 | 3 | The `FilePicker` class represents a component for selecting files in a user interface. 4 | 5 | #### Properties 6 | 7 | - `callback_data` (Required): Data associated with a callback. 8 | - `files_count` (Optional): The maximum number of files that can be selected (default is 1). 9 | - `mime_type` (Optional): A list of allowed file types based on MIME types. By default, it allows "png", "jpg", "jpeg", and "webp" files. 10 | 11 | #### Usage Example 12 | 13 | ```python 14 | # Create a FilePicker instance: 15 | file_picker = FilePicker( 16 | callback_data="FilePickerCallback", 17 | files_count=1, 18 | mime_type=["png", "jpg", "jpeg", "webp"] 19 | ) 20 | ``` 21 | 22 | :::note 23 | The response can be obtained as shown below: 24 | 25 | ```python 26 | @app.on_callback_query(regexp(...)) 27 | async def onCallback(ctx: BotContext[CallbackQueryEvent]): 28 | details = ctx.event.details 29 | print("User Upload", details.file_name, details.file_url) 30 | ``` 31 | ::: -------------------------------------------------------------------------------- /docs/docs/mini-apps/components/Grid.md: -------------------------------------------------------------------------------- 1 | # Grid 2 | 3 | The `Grid` class represents a grid layout. 4 | 5 | #### Properties 6 | 7 | - `title` (Optional | `str`): The title of the grid. 8 | - `horizontal` (Optional | `bool` = `False`): A flag indicating whether the grid layout is a scrollable horizontal layout. 9 | - `options` (Optional | `List[GridItem]`): A list of `GridItem` objects representing the grid items. 10 | - `size` (Optional | int = `3`): The size of the grid. If `horizontal` is false, this many numbers of `GridItem`s will be shown per line. 11 | - `expansion` (Optional | `Expansion` = `Expansion.DEFAULT`): The expansion type of the grid. 12 | - `right_image` (Optional | `str`): A link to image to show at end of the Grid title towards right. 13 | - `image_callback` (Optional | `str`): The callback data to the `right_image` 14 | 15 | #### Usage Example 16 | 17 | ```python 18 | # Create a Grid instance: 19 | grid_layout = Grid( 20 | title="Grid Title", 21 | horizontal=False, 22 | options=[GridItem(...), GridItem(...), GridItem(...)], 23 | size=3, 24 | expansion=Expansion.HORIZONTAL, 25 | right_image='https://i.imgur.com/rfukFDY.png', 26 | image_callback='some_callback_data', 27 | ) 28 | ``` -------------------------------------------------------------------------------- /docs/docs/mini-apps/components/GridItem.md: -------------------------------------------------------------------------------- 1 | ### GridItem 2 | 3 | The `GridItem` class represents a tile within a grid. 4 | 5 | #### Properties 6 | 7 | - `title` (Required | `str`): The title of the grid tile. 8 | - `media` (Required | `str`): Link to an image to be shown as media. 9 | - `dark_media` (Optional | `str`): Link to an image to be shown in dark mode. 10 | - `subtitle` (Optional | `str`): The subtitle of the grid tile. 11 | - `callback_data` (Optional | `str`): Data associated with a callback. 12 | - `selective` (Optional | `bool` = `False`): A flag indicating whether the grid tile is selective. 13 | 14 | #### Usage Example 15 | 16 | ```python 17 | # Create a GridTile instance: 18 | grid_item = GridItem( 19 | title="Tile Title", 20 | media="https://i.imgur.com/0Gzqukk.jpeg", 21 | subtitle="Tile Subtitle", 22 | callback_data="Callback Data", 23 | selective=False, 24 | ) 25 | ``` -------------------------------------------------------------------------------- /docs/docs/mini-apps/components/Icon.md: -------------------------------------------------------------------------------- 1 | # Icon 2 | 3 | The `Icon` class represents an icon component in a user interface. 4 | 5 | ### Properties 6 | 7 | - `url` (Required): The URL of the icon. 8 | - `dark_url` (Optional): The URL of the icon to be used in dark mode. If not provided, the default icon URL will be used. 9 | 10 | ### Methods 11 | 12 | ```python 13 | def __init__(self, url: str, dark_url: str = None) 14 | ``` 15 | 16 | #### Usage Example 17 | ```python 18 | 19 | # Create an Icon instance: 20 | icon = Icon(url="https://example.com/icon.png", dark_url="https://example.com/dark-icon.png") 21 | ``` -------------------------------------------------------------------------------- /docs/docs/mini-apps/components/Image.md: -------------------------------------------------------------------------------- 1 | # Image 2 | The `Image` class represents an image in a user interface. 3 | 4 | #### Properties 5 | - `url` (Required, `str`): The URL of the image. 6 | - `dark_url` (Optional, `str`): The URL of the image for dark mode. 7 | - `callback_data` (Optional, `str`): Data associated with a callback. 8 | 9 | #### Usage Example 10 | 11 | ```python 12 | # Create an Image instance: 13 | image = Image(url="https://example.com/image.jpg", callback_data="Callback Data") 14 | ``` 15 | -------------------------------------------------------------------------------- /docs/docs/mini-apps/components/ListItem.md: -------------------------------------------------------------------------------- 1 | # ListItem 2 | 3 | The `ListItem` class represents a list tile in a user interface. 4 | 5 | ## Properties 6 | 7 | - `title` (Optional): The main title of the list tile. 8 | - `subtitle` (Optional): The subtitle of the list tile. 9 | - `subtitle2` (Optional): An additional subtitle for the list tile. 10 | - `subtitle_action` (Optional): Action associated with the subtitle. 11 | - `callback_data` (Optional): Data associated with a callback. 12 | - `right` (Optional): A list of components to be displayed on the right side of the list tile. 13 | - `left` (Optional): A list of components to be displayed on the left side of the list tile. 14 | 15 | ## Usage Example 16 | 17 | ```python 18 | # Create a ListItem instance: 19 | list_item = ListItem( 20 | title="Item Title", 21 | subtitle="Item Subtitle", 22 | subtitle2="Additional Subtitle", 23 | subtitle_action="Subtitle Action", 24 | callback_data="Callback Data", 25 | # right=[Components...], 26 | # left=[Components...] 27 | ) 28 | ``` 29 | 30 | :::info 31 | Unlike `GridItem` which is used in `Grid`, `ListItem` is used in `Dropdown` and not `List`. 32 | ::: 33 | -------------------------------------------------------------------------------- /docs/docs/mini-apps/components/ListView.md: -------------------------------------------------------------------------------- 1 | # ListView 2 | 3 | Represents a list view containing multiple list tiles. 4 | 5 | ### Constructor: 6 | 7 | - `options`: A list of `ListTile` or `SmallListTile` instances. 8 | - `view_type` (Optional): The type of the list view, default is `ListViewType.DEFAULT`. 9 | 10 | ## ListViewType 11 | 12 | Enumerates the types of list views available. 13 | 14 | #### Enum Values: 15 | 16 | - `DEFAULT`: Represents the default list view type. 17 | - `SMALL`: Represents a small-sized list view. 18 | - `LARGE`: Represents a large-sized list view. 19 | - `COMPACT`: Represents a different view with large thumbnail with badges. 20 | 21 | 22 | 23 | ### Usage Example: 24 | 25 | ```python 26 | list_view = ListView( 27 | options=[list_tile, small_list_tile], 28 | view_type=ListViewType.SMALL 29 | ) 30 | ``` 31 | 32 | -------------------------------------------------------------------------------- /docs/docs/mini-apps/components/SearchBar.md: -------------------------------------------------------------------------------- 1 | # SearchBar 2 | 3 | The `SearchBar` class represents a search bar in a user interface. 4 | 5 | #### Properties 6 | 7 | - `placeholder` (Optional): The placeholder text for the search bar. 8 | - `label` (Optional): The label for the search bar. 9 | - `value` (Optional): The current value of the search bar. 10 | - `right_icon` (Optional): The icon on the right side of the search bar. 11 | - `left_icon` (Optional): The icon on the left side of the search bar. 12 | - `callback_data` (Optional): Data associated with a callback. 13 | 14 | #### Usage Example 15 | 16 | ```python 17 | # Create a SearchBar instance: 18 | search_bar = SearchBar( 19 | placeholder="Search", 20 | label="Search Label", 21 | value="Initial Value", 22 | right_icon="https://img.icons8.com/?size=50&id=12773&format=png", 23 | left_icon="https://img.icons8.com/?size=50&id=47516&format=png", 24 | callback_data="Callback Data" 25 | ) 26 | ``` 27 | 28 | :::note 29 | The search query can be obtained as shown below: 30 | 31 | ```python 32 | @app.on_callback_query(regexp(...)) 33 | async def onCallback(ctx: BotContext[CallbackQueryEvent]): 34 | input_ = ctx.event.details.search_query 35 | print("User searched for", input_) 36 | ``` 37 | ::: -------------------------------------------------------------------------------- /docs/docs/mini-apps/components/SearchHolder.md: -------------------------------------------------------------------------------- 1 | ### SearchHolder 2 | 3 | The `SearchHolder` class represents a search holder in a user interface. 4 | 5 | #### Properties 6 | 7 | - `placeholder` (Optional): The placeholder text for the search holder. 8 | - `callback_data` (Optional): Data associated with a callback. 9 | 10 | #### Usage Example 11 | 12 | ```python 13 | # Create a SearchHolder instance: 14 | search_holder = SearchHolder( 15 | placeholder="Search..", 16 | callback_data="Callback Data" 17 | ) 18 | ``` -------------------------------------------------------------------------------- /docs/docs/mini-apps/components/StickyHeader.md: -------------------------------------------------------------------------------- 1 | ### StickyHeader 2 | 3 | The `StickyHeader` class represents a sticky header component in a user interface. 4 | 5 | #### Properties 6 | 7 | - `text` (Required): The text content of the sticky header. 8 | - `color` (Optional): The color of the sticky header. If not provided, the default color is used. 9 | - `callback_data` (Optional): Data associated with a callback. 10 | - `icon` (Optional): An icon associated with the sticky header, represented by an instance of the `Icon` class. 11 | 12 | #### Usage Example 13 | 14 | ```python 15 | # Create a StickyHeader instance: 16 | sticky_header = StickyHeader( 17 | text="Example Sticky Header", 18 | color="#3498db", 19 | callback_data="StickyHeaderCallback", 20 | icon=Icon("https://example.com/icon.png") 21 | ) 22 | ``` -------------------------------------------------------------------------------- /docs/docs/mini-apps/components/Tab.md: -------------------------------------------------------------------------------- 1 | # TabBar 2 | 3 | Represents a component containing a tab bar. 4 | 5 | ### Properties: 6 | - `tabs`: A list of `TabBarTile` instances representing individual tabs. 7 | - `bar_type`: The type of the tab bar, default is `TabBarType.SWIPE`. 8 | 9 | 10 | # TabBarType 11 | 12 | Enumerates the types of tab bars available. 13 | 14 | ### Enum Values: 15 | 16 | - `SWIPE`: Represents a swipeable tab bar. 17 | - `SEGMENTED`: Represents a segmented tab bar. 18 | - `BUTTON`: Represents a button-based tab bar. 19 | 20 | # TabBarTile 21 | Represents a tile in a tab bar. 22 | 23 | ### Properties: 24 | 25 | - `title`: The title or icon of the tab. 26 | - `callback_data` (Optional): Callback data associated with the tab. 27 | - `selected`: Indicates whether the tab is selected (`True`) or not (`False`). 28 | 29 | ### Usage Example: 30 | 31 | ```python 32 | tab_tile = TabBarTile( 33 | title="Tab Title", 34 | callback_data="tab_callback_data", 35 | selected=True 36 | ) 37 | ``` 38 | 39 | ### Usage Example: 40 | 41 | ```python 42 | tab_bar = TabBar( 43 | tabs=[tab_tile1, tab_tile2, tab_tile3], 44 | bar_type=TabBarType.SWIPE 45 | ) 46 | ``` -------------------------------------------------------------------------------- /docs/docs/mini-apps/components/Text.md: -------------------------------------------------------------------------------- 1 | # Text 2 | 3 | The `Text` class represents text in a user interface. 4 | 5 | #### Properties 6 | 7 | - `text` (Required, `str`): The text content. 8 | - `size` (Optional, `TextSize`): The size of the text, default is `TextSize.BODY`. 9 | - `opacity` (Optional): The opacity of the text, default is `1`. 10 | 11 | #### Usage Example 12 | 13 | ```python 14 | # Create a Text instance: 15 | text_component = Text(text="Hello, World!", size=TextSize.HEADER, opacity=0.8) 16 | ``` 17 | 18 | ## TextSize 19 | 20 | The `TextSize` enumeration defines different sizes for text in a user interface. 21 | 22 | #### Values 23 | 24 | - `SMALL`: Represents small text size. 25 | - `MEDIUM`: Represents medium text size. 26 | - `LARGE`: Represents large text size. 27 | - `BODY`: Represents the default body text size. 28 | - `BOLD`: Represents bold body text size. 29 | - `MARKDOWN`: Represents text size for Markdown content. 30 | -------------------------------------------------------------------------------- /docs/docs/mini-apps/components/VideoPlayer.md: -------------------------------------------------------------------------------- 1 | # VideoPlayer 2 | 3 | The `VideoPlayer` class represents a video player in a user interface. 4 | 5 | #### Properties 6 | 7 | - `id` (Optional): Any random id 8 | - `url` (Required): The URL of the video. 9 | - `title` (Optional): The title of the video. 10 | - `subtitle` (Optional): The subtitle or additional information about the video. 11 | - `full_screen` (Optional, bool): Whether to open in full page 12 | - `callback_data` (Optional, str): Detail about video player changes. 13 | - `badges` (Optional, List[[Badge](../components/Badge.md)]): List of badges to display in full screen mode. 14 | 15 | #### Usage Example 16 | 17 | ```python 18 | # Create a VideoPlayer instance: 19 | video_player = VideoPlayer( 20 | url="https://example.com/video.mp4", 21 | title="Video Title", 22 | subtitle="Video Subtitle" 23 | ) 24 | ``` -------------------------------------------------------------------------------- /docs/docs/mini-apps/components/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Components", 3 | "link": { 4 | "type": "generated-index", 5 | "description": "Building feature rich mini-apps on Switch." 6 | } 7 | } -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "documentation", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "docusaurus": "docusaurus", 7 | "start": "docusaurus start", 8 | "build": "docusaurus build", 9 | "swizzle": "docusaurus swizzle", 10 | "deploy": "docusaurus deploy", 11 | "clear": "docusaurus clear", 12 | "serve": "docusaurus serve", 13 | "write-translations": "docusaurus write-translations", 14 | "write-heading-ids": "docusaurus write-heading-ids" 15 | }, 16 | "dependencies": { 17 | "@docusaurus/core": "^3.1.0", 18 | "@docusaurus/preset-classic": "^3.1.0", 19 | "@docusaurus/plugin-sitemap": "^3.1.0", 20 | "@mdx-js/react": "^3.0.0", 21 | "clsx": "^1.2.1", 22 | "prism-react-renderer": "^1.3.5", 23 | "react": "^18.2.0", 24 | "react-dom": "^18.2.0" 25 | }, 26 | "devDependencies": { 27 | "@docusaurus/module-type-aliases": "2.4.3" 28 | }, 29 | "browserslist": { 30 | "production": [ 31 | ">0.5%", 32 | "not dead", 33 | "not op_mini all" 34 | ], 35 | "development": [ 36 | "last 1 chrome version", 37 | "last 1 firefox version", 38 | "last 1 safari version" 39 | ] 40 | }, 41 | "engines": { 42 | "node": ">=16.14" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /docs/sidebars.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Creating a sidebar enables you to: 3 | - create an ordered group of docs 4 | - render a sidebar for each doc of that group 5 | - provide next/previous navigation 6 | 7 | The sidebars can be generated from the filesystem, or explicitly defined here. 8 | 9 | Create as many sidebars as you want. 10 | */ 11 | 12 | // @ts-check 13 | 14 | /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ 15 | const sidebars = { 16 | // By default, Docusaurus generates a sidebar from the docs folder structure 17 | tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], 18 | 19 | // But you can create a sidebar manually 20 | /* 21 | tutorialSidebar: [ 22 | 'intro', 23 | 'hello', 24 | { 25 | type: 'category', 26 | label: 'Tutorial', 27 | items: ['tutorial-basics/create-a-document'], 28 | }, 29 | ], 30 | */ 31 | }; 32 | 33 | module.exports = sidebars; 34 | -------------------------------------------------------------------------------- /docs/src/components/HomepageFeatures/styles.module.css: -------------------------------------------------------------------------------- 1 | .features { 2 | display: flex; 3 | align-items: center; 4 | padding: 2rem 0; 5 | width: 100%; 6 | } 7 | 8 | .featureSvg { 9 | height: 200px; 10 | width: 200px; 11 | } 12 | -------------------------------------------------------------------------------- /docs/src/pages/index.module.css: -------------------------------------------------------------------------------- 1 | /** 2 | * CSS files with the .module.css suffix will be treated as CSS modules 3 | * and scoped locally. 4 | */ 5 | 6 | .heroBanner { 7 | padding: 4rem 0; 8 | text-align: center; 9 | position: relative; 10 | overflow: hidden; 11 | } 12 | 13 | @media screen and (max-width: 996px) { 14 | .heroBanner { 15 | padding: 2rem; 16 | } 17 | } 18 | 19 | .buttons { 20 | display: flex; 21 | align-items: center; 22 | justify-content: center; 23 | } 24 | -------------------------------------------------------------------------------- /docs/static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/switchcollab/Switch-Bots-Python-Library/28addb2c51c57ba278a4795565cf77023b9f4553/docs/static/.nojekyll -------------------------------------------------------------------------------- /docs/static/img/docusaurus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/switchcollab/Switch-Bots-Python-Library/28addb2c51c57ba278a4795565cf77023b9f4553/docs/static/img/docusaurus.png -------------------------------------------------------------------------------- /docs/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/switchcollab/Switch-Bots-Python-Library/28addb2c51c57ba278a4795565cf77023b9f4553/docs/static/img/favicon.ico -------------------------------------------------------------------------------- /docs/static/img/imdb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/switchcollab/Switch-Bots-Python-Library/28addb2c51c57ba278a4795565cf77023b9f4553/docs/static/img/imdb.jpg -------------------------------------------------------------------------------- /docs/static/img/imdb2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/switchcollab/Switch-Bots-Python-Library/28addb2c51c57ba278a4795565cf77023b9f4553/docs/static/img/imdb2.jpg -------------------------------------------------------------------------------- /docs/static/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/switchcollab/Switch-Bots-Python-Library/28addb2c51c57ba278a4795565cf77023b9f4553/docs/static/img/logo.png -------------------------------------------------------------------------------- /docs/static/img/switch-logo-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/switchcollab/Switch-Bots-Python-Library/28addb2c51c57ba278a4795565cf77023b9f4553/docs/static/img/switch-logo-white.png -------------------------------------------------------------------------------- /docs/static/img/switch-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/switchcollab/Switch-Bots-Python-Library/28addb2c51c57ba278a4795565cf77023b9f4553/docs/static/img/switch-logo.png -------------------------------------------------------------------------------- /publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This script is used to publish the swibots package to the pip repository. 4 | 5 | # This script is part of the swibots package. 6 | rm -rf dist 7 | rm -rf build 8 | mkdir dist 9 | mkdir build 10 | python setup.py sdist bdist_wheel 11 | twine upload dist/* -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | -r requirements.txt 2 | python-dotenv<=0.21.0 -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | httpx 2 | websockets 3 | aiofiles -------------------------------------------------------------------------------- /samples/channel_example.py: -------------------------------------------------------------------------------- 1 | import os # noqa 2 | import sys # noqa 3 | import inspect # noqa 4 | 5 | currentdir = os.path.dirname( 6 | os.path.abspath(inspect.getfile(inspect.currentframe())) 7 | ) # noqa 8 | parentdir = os.path.dirname(currentdir) # noqa 9 | sys.path.insert(0, parentdir) # noqa 10 | from dotenv import load_dotenv 11 | 12 | env_file = os.path.join(os.path.dirname(__file__), "..", "..", ".env") # noqa 13 | load_dotenv(env_file) # noqa 14 | 15 | from swibots import BotApp, BotContext, ChannelCreatedEvent, Message 16 | from swibots.bots.filters import channel 17 | import logging 18 | 19 | logging.basicConfig(level=logging.DEBUG) 20 | 21 | logger = logging.getLogger(__name__) 22 | 23 | 24 | env_file = os.path.join(os.path.dirname(__file__), "..", "..", ".env") 25 | load_dotenv(env_file) 26 | 27 | 28 | TOKEN = os.getenv("TOKEN") 29 | 30 | 31 | app = BotApp(TOKEN, "your bot description") 32 | 33 | 34 | @app.on_channel_created(channel("d71e33f9-8e12-491f-b041-d02ea6ec6520")) 35 | async def channel_created_handler(ctx: BotContext[ChannelCreatedEvent]): 36 | new_channel_name = ctx.event.channel.name 37 | new_channel_id = ctx.event.channel.id 38 | m = Message() 39 | m.message = f"Channel {new_channel_name} created with id {new_channel_id}" 40 | m.community_id = ctx.event.community.id 41 | m.channel_id = "d71e33f9-8e12-491f-b041-d02ea6ec6520" 42 | await ctx.send_message(message=m) 43 | 44 | 45 | app.run() 46 | -------------------------------------------------------------------------------- /samples/decoratorbot.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from dotenv import load_dotenv 4 | 5 | from swibots import ( 6 | BotApp, 7 | RegisterCommand, 8 | BotContext, 9 | MessageEvent, 10 | CallbackQueryEvent, 11 | ) 12 | 13 | 14 | env_file = os.path.join(os.path.dirname(__file__), "..", "..", ".env") 15 | load_dotenv(env_file) 16 | 17 | 18 | TOKEN = os.getenv("TOKEN") 19 | 20 | logging.basicConfig(level=logging.INFO) 21 | 22 | logger = logging.getLogger(__name__) 23 | 24 | 25 | # initialize the app and register commands 26 | app = BotApp( 27 | TOKEN, "A cool bot with annotations and everything you could possibly want :)" 28 | ).register_command( 29 | [ 30 | RegisterCommand("test", "Test command", True), 31 | RegisterCommand("echo", "Echoes the message", True), 32 | RegisterCommand("buttons", "Shows buttons", True), 33 | ] 34 | ) 35 | 36 | 37 | @app.on_message() 38 | async def message_handler(ctx: BotContext[MessageEvent]): 39 | m = await ctx.prepare_response_message(ctx.event.message) 40 | m.message = f"Thank you! I received your message: {ctx.event.message.message}" 41 | await ctx.send_message(m) 42 | 43 | 44 | @app.on_callback_query() 45 | async def query_callback_handler(ctx: BotContext[CallbackQueryEvent]): 46 | m = await ctx.prepare_response_message(ctx.event.message) 47 | m.message = f"Thank you! I received your callback: {ctx.event.callback_data}" 48 | m.inline_markup = None 49 | await ctx.edit_message(m) 50 | 51 | 52 | app.run() 53 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | try: 4 | with open("requirements.txt", encoding="utf-8") as r: 5 | requires = [i.strip() for i in r] 6 | except FileNotFoundError: 7 | requires = ["httpx>=0.25.0", "websockets>=11.0.3", "aiofiles"] 8 | 9 | try: 10 | import pypandoc 11 | 12 | long_description = pypandoc.convert_file("README.md", "rst") 13 | except (IOError, ImportError): 14 | long_description = open("README.md", encoding="utf8").read() 15 | 16 | 17 | setup( 18 | name="swibots", 19 | version="1.4.62", 20 | packages=find_packages(include=['swibots*']), 21 | long_description=long_description, 22 | long_description_content_type="text/markdown", 23 | url="https://github.com/switchcollab/Switch-Bots-Python-Library", 24 | description="Bots Library for Switch", 25 | author="switchadmin", 26 | author_email="support@switch.pe", 27 | license="LGPLv3", 28 | python_requires=">=3.10", 29 | install_requires=requires, 30 | ) 31 | -------------------------------------------------------------------------------- /swibots/__init__.py: -------------------------------------------------------------------------------- 1 | from .utils import * 2 | from .api import * 3 | from .base import * 4 | from .errors import * 5 | from .config import * 6 | from .types import * 7 | 8 | # from .bot_client import SwitchBotClient 9 | from .bot_app import BotApp, Client 10 | from .bots import * 11 | 12 | App = BotApp 13 | -------------------------------------------------------------------------------- /swibots/api/__init__.py: -------------------------------------------------------------------------------- 1 | from .api_client import ApiClient 2 | from .chat import * 3 | from .auth import * 4 | from .community import * 5 | from .common import * 6 | from .bot import * 7 | from .airdrop import * 8 | from .callback import * 9 | -------------------------------------------------------------------------------- /swibots/api/airdrop/__init__.py: -------------------------------------------------------------------------------- 1 | from .client import AirdropClient 2 | from .models import * 3 | from .controllers import * 4 | from .methods import * 5 | -------------------------------------------------------------------------------- /swibots/api/airdrop/client.py: -------------------------------------------------------------------------------- 1 | import swibots 2 | from swibots.base import SwitchRestClient 3 | from swibots.config import get_config 4 | from .controllers import TournamentController 5 | 6 | 7 | class AirdropClient(SwitchRestClient): 8 | def __init__( 9 | self, 10 | app: "swibots.App" = None, 11 | base_url: str = None, 12 | ): 13 | base_url = base_url or get_config()["AIRDROP_SERVICE"]["BASE_URL"] 14 | super().__init__(app, base_url) 15 | 16 | self._tournament: TournamentController = None 17 | 18 | @property 19 | def tournament(self) -> TournamentController: 20 | """Get the controller""" 21 | if self._tournament is None: 22 | self._tournament = TournamentController(self) 23 | return self._tournament 24 | 25 | def prepare_request_headers(self, headers: dict) -> dict: 26 | headers = super().prepare_request_headers(headers) 27 | if self.token is not None: 28 | headers["authtoken"] = f"{self.token}" 29 | return headers 30 | -------------------------------------------------------------------------------- /swibots/api/airdrop/controllers/__init__.py: -------------------------------------------------------------------------------- 1 | from .tournament_controller import TournamentController 2 | -------------------------------------------------------------------------------- /swibots/api/airdrop/controllers/tournament_controller.py: -------------------------------------------------------------------------------- 1 | import json 2 | import logging 3 | from typing import TYPE_CHECKING, List 4 | from swibots.api.airdrop.models import Referral, Tournament 5 | from swibots.errors import SwitchError 6 | from swibots.utils.types import JSONDict 7 | 8 | if TYPE_CHECKING: 9 | from swibots.api.airdrop import AirdropClient 10 | 11 | log = logging.getLogger(__name__) 12 | 13 | BASE_PATH = "/v1/tournament" 14 | 15 | 16 | class TournamentController: 17 | """Airdrop controller 18 | 19 | This controller is used to communicate with the airdrop endpoints. 20 | """ 21 | 22 | def __init__(self, client: "AirdropClient"): 23 | self.client = client 24 | 25 | async def get_referrals(self, id: str | int, user_id: str | int) -> List[Referral]: 26 | """Get referrals""" 27 | response = await self.client.get( 28 | f"{BASE_PATH}/getUserReferrals/{id}?user_id={user_id}" 29 | ) 30 | return self.client.build_list(Referral, response.data) 31 | 32 | async def get_tournaments(self, community_id: str) -> List[Tournament]: 33 | """Get tournaments by community_id""" 34 | response = await self.client.get( 35 | f"{BASE_PATH}/getTournamentsByCommunityId/{community_id}" 36 | ) 37 | return self.client.build_list(Tournament, response.data) 38 | -------------------------------------------------------------------------------- /swibots/api/airdrop/methods/__init__.py: -------------------------------------------------------------------------------- 1 | from .get_referral import GetReferrals 2 | from .get_tournaments import GetTournaments 3 | 4 | 5 | class AirdropMethods(GetReferrals, GetTournaments): ... 6 | -------------------------------------------------------------------------------- /swibots/api/airdrop/methods/get_referral.py: -------------------------------------------------------------------------------- 1 | from typing import List, Optional 2 | import swibots 3 | from swibots.api.airdrop.models import Referral 4 | 5 | 6 | class GetReferrals: 7 | async def get_referral( 8 | self: "swibots.ApiClient", tournament_id: str | int, user_id: str | int 9 | ) -> List[Referral]: 10 | """Get referrals from tournament_id 11 | 12 | Args: 13 | tournament_id: The Tournament ID to get referrals for. 14 | user_id: The User ID 15 | 16 | Returns: 17 | A list of referrals. 18 | """ 19 | return await self.airdrop_service.tournament.get_referrals( 20 | tournament_id, user_id 21 | ) 22 | -------------------------------------------------------------------------------- /swibots/api/airdrop/methods/get_tournaments.py: -------------------------------------------------------------------------------- 1 | from typing import List, Optional 2 | import swibots 3 | from swibots.api.airdrop.models import Tournament 4 | 5 | 6 | class GetTournaments: 7 | async def get_tournaments( 8 | self: "swibots.ApiClient", community_id: str 9 | ) -> List[Tournament]: 10 | """Get tournaments from community_id 11 | 12 | Args: 13 | community_id: community id to get tournaments from. 14 | 15 | Returns: 16 | A list of tournaments 17 | """ 18 | return await self.airdrop_service.tournament.get_tournaments(community_id) 19 | -------------------------------------------------------------------------------- /swibots/api/airdrop/models/__init__.py: -------------------------------------------------------------------------------- 1 | from .referral import Referral 2 | from .tournament import Tournament 3 | 4 | __all__ = ["Referral", "Tournament"] 5 | -------------------------------------------------------------------------------- /swibots/api/auth/__init__.py: -------------------------------------------------------------------------------- 1 | from .models import * 2 | from .auth_client import AuthClient 3 | from .methods import AuthMethods 4 | -------------------------------------------------------------------------------- /swibots/api/auth/methods/__init__.py: -------------------------------------------------------------------------------- 1 | from .get_me import GetMe 2 | 3 | 4 | class AuthMethods(GetMe): ... 5 | -------------------------------------------------------------------------------- /swibots/api/auth/methods/get_me.py: -------------------------------------------------------------------------------- 1 | from typing import Type, TypeVar 2 | import swibots 3 | from swibots.api.common.models import User 4 | from swibots.api.auth.models import AuthUser 5 | 6 | T = TypeVar("T", bound="swibots.AuthUser") 7 | 8 | 9 | class GetMe: 10 | async def get_me(self: "swibots.ApiClient", user_type: Type[T] = AuthUser) -> T: 11 | """Get the current user 12 | 13 | Parameters: 14 | user_type (``Type[T]``, *optional*): The user type to return. Defaults to :obj:`~switch.api.auth.models.AuthUser`. 15 | 16 | Returns: 17 | ``T``: The current user 18 | 19 | This functions does the same as :meth:`~switch.api.auth.controllers.UserController.me`. 20 | 21 | """ 22 | return await self.auth_service.get_me(user_type=user_type) 23 | 24 | async def update_user_info(self: "swibots.ApiClient", user_info: User) -> bool: 25 | """update_user_info 26 | 27 | Args: 28 | user_info (User): User info 29 | 30 | Returns: 31 | bool: Whether request was successful 32 | """ 33 | data = {x: y for x, y in user_info.to_json_request().items() if y is not None} 34 | response = await self.auth_service.post("/api/update/bot", data=data) 35 | return response.data 36 | -------------------------------------------------------------------------------- /swibots/api/auth/models/__init__.py: -------------------------------------------------------------------------------- 1 | from .auth_user import AuthUser 2 | from .auth_result import AuthResult 3 | 4 | __all__ = ["AuthUser", "AuthResult"] 5 | -------------------------------------------------------------------------------- /swibots/api/auth/models/auth_result.py: -------------------------------------------------------------------------------- 1 | from typing import Optional, List 2 | from swibots.base.switch_object import SwitchObject 3 | from swibots.utils.types import JSONDict 4 | 5 | 6 | class AuthResult(SwitchObject): 7 | def __init__( 8 | self, 9 | access_token: Optional[str] = None, 10 | refresh_token: Optional[str] = None, 11 | user_id: Optional[int] = None, 12 | is_bot: Optional[bool] = False, 13 | roles: Optional[List[str]] = None, 14 | active: Optional[bool] = False, 15 | ): 16 | self.access_token = access_token 17 | self.refresh_token = refresh_token 18 | self.user_id = user_id 19 | self.is_bot = is_bot 20 | self.roles = roles 21 | self.active = active 22 | 23 | def from_json(self, data: Optional[JSONDict]) -> "AuthResult": 24 | super().from_json(data) 25 | if data is not None: 26 | self.access_token = data.get("access_token") 27 | self.refresh_token = data.get("refresh_token") 28 | self.user_id = data.get("user_id") 29 | self.is_bot = data.get("is_bot") 30 | self.roles = data.get("roles") 31 | self.active = data.get("active") 32 | return self 33 | -------------------------------------------------------------------------------- /swibots/api/bot/__init__.py: -------------------------------------------------------------------------------- 1 | from .bot_client import BotClient 2 | from .models import * 3 | from .controllers import * 4 | -------------------------------------------------------------------------------- /swibots/api/bot/bot_client.py: -------------------------------------------------------------------------------- 1 | from swibots.api.auth.models.auth_user import AuthUser 2 | from swibots.api.bot.controllers import BotController, GameController 3 | from swibots.base import SwitchRestClient 4 | from swibots.config import get_config 5 | import swibots 6 | 7 | 8 | class BotClient(SwitchRestClient): 9 | """Bot client 10 | 11 | This client is used to communicate with the bot service. 12 | 13 | Controllers: 14 | - :attr:`bots`: :obj:`~switch.api.bot.controllers.BotController` : The bot controller 15 | 16 | Properties: 17 | - :attr:`user`: :obj:`~switch.api.auth.models.auth_user.AuthUser` : The current user 18 | 19 | """ 20 | 21 | def __init__(self, app: "swibots.App" = None, base_url: str = None): 22 | """Initialize the bot client 23 | 24 | Parameters: 25 | base_url (``str``): The base url of the bot service. Defaults to the value in the config. 26 | """ 27 | base_url = base_url or get_config()["BOT_SERVICE"]["BASE_URL"] 28 | super().__init__(app, base_url) 29 | self._bots: BotController = None 30 | self._games: GameController = None 31 | 32 | @property 33 | def bots(self) -> BotController: 34 | """Get the bot controller""" 35 | if self._bots is None: 36 | self._bots = BotController(self) 37 | return self._bots 38 | 39 | @property 40 | def games(self) -> GameController: 41 | if self._games is None: 42 | self._games = GameController(self) 43 | return self._games 44 | -------------------------------------------------------------------------------- /swibots/api/bot/controllers/__init__.py: -------------------------------------------------------------------------------- 1 | from .bot_controller import BotController 2 | from .game_controller import GameController 3 | 4 | __all__ = ["BotController", "GameController"] 5 | -------------------------------------------------------------------------------- /swibots/api/bot/methods/__init__.py: -------------------------------------------------------------------------------- 1 | from .delete_bot_info import DeleteBotInfo 2 | from .get_bot_info import GetBotInfo 3 | from .update_bot_info import UpdateBotInfo 4 | from .game_methods import GameMethods 5 | from .answer_callback_query import AnswerCallback 6 | 7 | 8 | class BotMethods(DeleteBotInfo, GetBotInfo, UpdateBotInfo, GameMethods, AnswerCallback): 9 | pass 10 | -------------------------------------------------------------------------------- /swibots/api/bot/methods/delete_bot_info.py: -------------------------------------------------------------------------------- 1 | from typing import Type, TypeVar 2 | import swibots 3 | 4 | 5 | class DeleteBotInfo: 6 | async def delete_bot_info(self: "swibots.ApiClient", bot_id: str) -> bool: 7 | """Delete bot info 8 | 9 | Parameters: 10 | bot_id (``str``): The bot id. Defaults to the current bot id. 11 | 12 | Returns: 13 | ``bool``: True if the bot info was deleted 14 | 15 | This functions does the same as :meth:`~switch.api.bot.controllers.BotController.delete_bot_info`. 16 | """ 17 | return await self.bots_service.bots.delete_bot_info(bot_id=bot_id) 18 | -------------------------------------------------------------------------------- /swibots/api/bot/methods/get_bot_info.py: -------------------------------------------------------------------------------- 1 | from typing import Type, TypeVar 2 | import swibots 3 | from swibots.api.bot.models import BotInfo 4 | 5 | 6 | class GetBotInfo: 7 | async def get_bot_info(self: "swibots.ApiClient", bot_id: str) -> BotInfo: 8 | """Get bot info 9 | 10 | Parameters: 11 | bot_id (``str``): The bot id. Defaults to the current bot id. 12 | 13 | Returns: 14 | :obj:``~switch.api.bot.models.BotInfo``: The bot info 15 | 16 | This functions does the same as :meth:`~switch.api.bot.controllers.BotController.get_bot_info`. 17 | """ 18 | return await self.bots_service.bots.get_bot_info(bot_id=bot_id) 19 | -------------------------------------------------------------------------------- /swibots/api/bot/methods/update_bot_info.py: -------------------------------------------------------------------------------- 1 | from typing import Type, TypeVar 2 | import swibots 3 | from swibots.api.bot.models import BotInfo 4 | 5 | 6 | class UpdateBotInfo: 7 | async def update_bot_info(self: "swibots.ApiClient", bot_info: BotInfo) -> BotInfo: 8 | """Update bot info 9 | 10 | Parameters: 11 | bot_info (``~switch.api.bot.models.BotInfo``): The bot info to update 12 | 13 | Returns: 14 | :obj:``~switch.api.bot.models.BotInfo``: The bot info 15 | 16 | This functions does the same as :meth:`~switch.api.bot.controllers.BotController.update_bot_info`. 17 | """ 18 | return await self.bots_service.bots.update_bot_info(bot_info=bot_info) 19 | 20 | async def set_welcome( 21 | self: "swibots.ApiClient", 22 | text: str = None, 23 | thumb: str = None, 24 | button: str = None, 25 | command: str = None, 26 | ): 27 | """Set bot welcome message 28 | 29 | Args: 30 | text (str, optional): welcome text 31 | thumb (str, optional): welcome image 32 | button (str, optional): button title 33 | command (str, optional): button command 34 | 35 | Returns: 36 | `BotInfo`: updated bot info 37 | """ 38 | return await self.bots_service.bots.set_welcome( 39 | text=text, thumb=thumb, button=button, command=command 40 | ) 41 | -------------------------------------------------------------------------------- /swibots/api/bot/models/__init__.py: -------------------------------------------------------------------------------- 1 | from .bot_command import BotCommand, BotSubCommand 2 | from .bot_info import BotInfo, BotWelcome 3 | from .game_info import GameInfo 4 | 5 | __all__ = ["BotCommand", "BotInfo", "GameInfo", "BotSubCommand", "BotWelcome"] 6 | -------------------------------------------------------------------------------- /swibots/api/callback/Accordian.py: -------------------------------------------------------------------------------- 1 | from typing import Union, List 2 | 3 | from swibots.utils.types import JSONDict 4 | from .types import Component, Icon 5 | 6 | 7 | class Accordian(Component): 8 | def __init__( 9 | self, 10 | title: str, 11 | icon: Union[Icon, str] = "", 12 | components: List[Component] = None, 13 | ): 14 | self.title = title 15 | if isinstance(icon, str): 16 | icon = Icon(icon) 17 | self.icon = icon 18 | self.components = components 19 | 20 | def to_json(self): 21 | data = { 22 | "title": self.title, 23 | "icon": self.icon.to_json() if self.icon else None, 24 | } 25 | if self.components: 26 | data["components"] = ( 27 | [component.to_json() for component in self.components], 28 | ) 29 | return data 30 | -------------------------------------------------------------------------------- /swibots/api/callback/Carousel.py: -------------------------------------------------------------------------------- 1 | from swibots.utils.types import JSONDict 2 | from .types import Image, Component 3 | from typing import List, Any 4 | 5 | 6 | class Carousel(Component): 7 | type = "carousel" 8 | 9 | def __init__( 10 | self, 11 | images: List[Image], 12 | title: str = "", 13 | subtitle: str = "", 14 | max_size: bool = None, 15 | ): 16 | self.title = title 17 | self.subtitle = subtitle 18 | self.images = images 19 | self.max_size = max_size 20 | 21 | def to_json(self): 22 | data = { 23 | "type": self.type, 24 | "components": [image.to_json() for image in self.images], 25 | "title": self.title, 26 | "subTitle": self.subtitle, 27 | "mainAxisSize": "max" if self.max_size else "min", 28 | } 29 | return data 30 | -------------------------------------------------------------------------------- /swibots/api/callback/Dropdown.py: -------------------------------------------------------------------------------- 1 | from swibots.utils.types import JSONDict 2 | from .types import Component 3 | from typing import List, Optional, Any, Dict 4 | from .ListItem import ListItem 5 | 6 | 7 | class Dropdown(Component): 8 | type = "dropdown" 9 | 10 | def __init__( 11 | self, 12 | placeholder: str = None, 13 | selected: int = None, 14 | options: List[ListItem] = None, 15 | disabled: bool = None, 16 | max_size: bool = None, 17 | ): 18 | self.disabled = disabled 19 | self.options = options 20 | self.selected = selected 21 | self.placeholder = placeholder 22 | self.max_size = max_size 23 | 24 | def to_json(self) -> JSONDict: 25 | data = { 26 | "type": self.type, 27 | "placeHolder": self.placeholder, 28 | "options": [listitem.to_json() for listitem in self.options], 29 | "disabled": self.disabled, 30 | } 31 | if self.selected: 32 | data["selectedIndex"] = self.selected 33 | data["mainAxisSize"] = "max" if self.max_size else "min" 34 | return data 35 | -------------------------------------------------------------------------------- /swibots/api/callback/FAB.py: -------------------------------------------------------------------------------- 1 | from swibots.utils.types import JSONDict 2 | from .types import Component, Icon, Text 3 | from typing import Union 4 | 5 | 6 | class FAB(Component): 7 | type = "fab" 8 | 9 | def __init__( 10 | self, 11 | icon: Union[Icon, str], 12 | name: Union[Text, str] = None, 13 | color: str = None, 14 | callback_data: str = None, 15 | ): 16 | if isinstance(name, str): 17 | name = Text(name) 18 | self.name = name 19 | if isinstance(icon, str): 20 | self.icon = Icon(icon) 21 | self.color = color 22 | self.callback_data = callback_data 23 | 24 | def to_json(self): 25 | data = { 26 | "type": self.type, 27 | "icon": self.icon.to_json(), 28 | "text": self.name.to_json(), 29 | } 30 | if self.color: 31 | data["colour"] = self.color 32 | if self.callback_data: 33 | data["callbackData"] = self.callback_data 34 | return data 35 | -------------------------------------------------------------------------------- /swibots/api/callback/Feed.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from .types import Component, Icon, Any, Dict 3 | 4 | 5 | class ShortVideo(Component): 6 | type = "short_video" 7 | 8 | def __init__( 9 | self, 10 | url: str = None, 11 | icons: List[Icon] = None, 12 | user_image: str = None, 13 | user_name: str = None, 14 | title: str = None, 15 | description: str = None, 16 | ): 17 | self.url = url 18 | self.icons = icons 19 | self.user_image = user_image 20 | self.user_name = user_name 21 | self.title = title 22 | self.description = description 23 | 24 | def to_json(self): 25 | data = { 26 | "type": "short_video", 27 | "videoUrl": self.url, 28 | "bottom": [icon.to_json() for icon in self.icons], 29 | "extraOptions": { 30 | "userAvatar": self.user_image, 31 | "userName": self.user_name, 32 | "description": self.description, 33 | "title": self.title, 34 | }, 35 | } 36 | return data 37 | 38 | 39 | class FeedPanel(Component): 40 | def __init__(self, feeds, next_callback: str): 41 | self.feeds = feeds 42 | self.next_callback = next_callback 43 | 44 | def to_json(self) -> Dict[str, Any]: 45 | data = { 46 | "type": "feed_panel", 47 | "feeds": [feed.to_json() for feed in self.feeds], 48 | "offsetCallbackData": self.next_callback, 49 | } 50 | return data 51 | -------------------------------------------------------------------------------- /swibots/api/callback/ListItem.py: -------------------------------------------------------------------------------- 1 | from swibots.utils.types import JSONDict 2 | from .types import SwitchObject, Component 3 | from typing import List, Optional 4 | 5 | 6 | class ListItem(Component): 7 | type = "list_tile" 8 | 9 | def __init__( 10 | self, 11 | title: str = None, 12 | subtitle: str = None, 13 | callback_data: str = None, 14 | ): 15 | self.title = title 16 | self.subtitle = subtitle 17 | self.callback_data = callback_data 18 | 19 | def to_json(self) -> JSONDict: 20 | data = {"type": self.type} 21 | if self.title: 22 | data["title"] = self.title 23 | if self.subtitle: 24 | data["subTitle"] = self.subtitle 25 | if self.callback_data: 26 | data["callbackData"] = self.callback_data 27 | return data 28 | -------------------------------------------------------------------------------- /swibots/api/callback/Progress.py: -------------------------------------------------------------------------------- 1 | from swibots.utils.types import JSONDict 2 | from .types import Component 3 | from enum import Enum 4 | 5 | 6 | class Size(Enum): 7 | LARGE = "large" 8 | MEDIUM = "medium" 9 | SMALL = "small" 10 | 11 | 12 | class ProgressStyle(Enum): 13 | LINEAR = "linear" 14 | CIRCULAR = "circular" 15 | 16 | 17 | class Progress(Component): 18 | type = "progress_bar" 19 | 20 | def __init__( 21 | self, 22 | color: str = None, 23 | size: Size = Size.MEDIUM, 24 | radius: int = 2, 25 | progress: int = False, 26 | animation: bool = False, 27 | progress_style: ProgressStyle = ProgressStyle.LINEAR, 28 | ): 29 | self.color = color 30 | self.size = size 31 | self.radius = radius 32 | self.progress = progress 33 | self.animation = animation 34 | self.progress_style = progress_style 35 | 36 | def to_json(self): 37 | return { 38 | "type": self.type, 39 | "color": self.color, 40 | "radius": self.radius, 41 | "interdeterminate": self.animation, 42 | "progress": self.progress, 43 | "barSize": self.size.value, 44 | "progressBarType": self.progress_style.value, 45 | } 46 | 47 | 48 | class ListTileProgress(Progress): 49 | def __init__( 50 | self, color: str = None, progress: str = None, animation: bool = False 51 | ): 52 | super().__init__(color, progress=progress, animation=animation) 53 | -------------------------------------------------------------------------------- /swibots/api/callback/callbackResponse.py: -------------------------------------------------------------------------------- 1 | from typing import Dict, Any 2 | from swibots.base import SwitchObject 3 | 4 | 5 | class CallbackResponse(SwitchObject): 6 | 7 | def __init__(self): 8 | self.search_query = None 9 | self.file_url = None 10 | self.file_name = None 11 | self.input_value = None 12 | self.parent_id = None 13 | self.new_url = None 14 | self.__data = None 15 | 16 | def get(self, key: str): 17 | if self.__data and (val := self.__data.get(key)): 18 | return val 19 | return self.to_json().get(key) 20 | 21 | def from_json(self, data: Dict[str, Any] | None) -> Any: 22 | if data is not None: 23 | self.search_query = data.get("searchQuery") 24 | self.file_url = data.get("fileResponse") 25 | self.file_name = data.get("fileName") 26 | self.parent_id = data.get("callbackQueryId") 27 | self.input_value = data.get("inputValue") 28 | self.new_url = data.get("url") 29 | self.__data = data 30 | return self 31 | 32 | def to_json(self) -> Dict[str, Any]: 33 | return { 34 | "searchQuery": self.search_query, 35 | "fileResponse": self.file_url, 36 | "fileName": self.file_name, 37 | "callbackQueryId": self.parent_id, 38 | "inputValue": self.input_value, 39 | "url": self.new_url, 40 | } 41 | -------------------------------------------------------------------------------- /swibots/api/chat/__init__.py: -------------------------------------------------------------------------------- 1 | from .chat_client import ChatClient 2 | from .models import * 3 | from .events import * 4 | from .controllers import * 5 | -------------------------------------------------------------------------------- /swibots/api/chat/controllers/__init__.py: -------------------------------------------------------------------------------- 1 | from .message_controller import MessageController 2 | from .chat_controller import ChatController 3 | from .media_controller import MediaController 4 | from .sticker_controller import StickerController 5 | from .organization_controller import OrganizationController 6 | from .ads_controller import AdvertisingController 7 | from .heading_controller import HeadingsController 8 | 9 | __all__ = [ 10 | "AdvertisingController", 11 | "MessageController", 12 | "ChatController", 13 | "MediaController", 14 | "StickerController", 15 | "OrganizationController", 16 | "HeadingsController", 17 | ] 18 | -------------------------------------------------------------------------------- /swibots/api/chat/controllers/ads_controller.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from typing import TYPE_CHECKING 3 | 4 | if TYPE_CHECKING: 5 | from swibots.api.chat import ChatClient 6 | 7 | from swibots.api.chat.models import ADInfo 8 | from swibots.api.common import User 9 | from urllib.parse import urlencode 10 | 11 | log = logging.getLogger(__name__) 12 | 13 | BASE_PATH = "/add" 14 | 15 | 16 | class AdvertisingController: 17 | """Ads controller""" 18 | 19 | def __init__(self, client: "ChatClient") -> None: 20 | self.client = client 21 | 22 | async def get_all_ads( 23 | self, 24 | limit: int = 100, 25 | page: int = 0, 26 | ): 27 | param = urlencode({"page": page, "limit": limit, "appId": self.client.user.id}) 28 | response = await self.client.get(f"{BASE_PATH}/byAppId?{param}") 29 | return self.client.build_list(ADInfo, response.data) 30 | 31 | async def get_organization_followers(self, id: str): 32 | response = await self.client.get(f"{BASE_PATH}/followers?orgId={id}") 33 | return self.client.build_list(User, response.data) 34 | -------------------------------------------------------------------------------- /swibots/api/chat/events/__init__.py: -------------------------------------------------------------------------------- 1 | from .chat_event import ChatEvent 2 | from .message_event import MessageEvent 3 | from .command_event import CommandEvent 4 | from .callback_query_event import CallbackQueryEvent 5 | from .inline_query_event import InlineQueryEvent 6 | 7 | __all__ = [ 8 | "ChatEvent", 9 | "MessageEvent", 10 | "CommandEvent", 11 | "CallbackQueryEvent", 12 | "InlineQueryEvent", 13 | ] 14 | -------------------------------------------------------------------------------- /swibots/api/chat/methods/ad_methods.py: -------------------------------------------------------------------------------- 1 | from typing import Type, TypeVar, List 2 | import swibots 3 | from swibots.api.chat.models import ADInfo 4 | 5 | 6 | class AdMethods: 7 | async def get_all_ads( 8 | self: "swibots.ApiClient", limit: int = 100, page: int = 0 9 | ) -> List[ADInfo]: 10 | """Get all ads created by the user 11 | 12 | Parameters: 13 | page (``int``): The page number to offset. 14 | limit (``int``): The number of result to include. 15 | 16 | Returns: 17 | List[ADInfo] 18 | """ 19 | return await self.chat_service.ads.get_all_ads(page=page, limit=limit) 20 | -------------------------------------------------------------------------------- /swibots/api/chat/methods/answer_inline_query.py: -------------------------------------------------------------------------------- 1 | from typing import Type, TypeVar 2 | import swibots 3 | from swibots.api.chat.models import InlineQueryAnswer, InlineQuery 4 | 5 | 6 | class AnswerInlineQuery: 7 | async def answer_inline_query( 8 | self: "swibots.ApiClient", query: InlineQuery, answer: InlineQueryAnswer 9 | ) -> bool: 10 | """Answer inline query 11 | 12 | Args: 13 | query (:obj:`InlineQuery`): Inline query to answer to 14 | answer (str | InlineQueryAnswer): Answer to inline query, it can be either a string or an InlineQueryAnswer object, if it's a string, it will be used as the text of the answer 15 | """ 16 | return await self.chat_service.messages.answer_inline_query(query, answer) 17 | -------------------------------------------------------------------------------- /swibots/api/chat/methods/clear_conversation.py: -------------------------------------------------------------------------------- 1 | from typing import Type, TypeVar 2 | import swibots 3 | from swibots.api.chat.models import Message 4 | 5 | 6 | class ClearConversation: 7 | async def clear_conversation(self: "swibots.ApiClient", receiver_id: int) -> bool: 8 | """Clear a conversation 9 | 10 | Parameters: 11 | receiver_id (``int``): The receiver id 12 | 13 | Returns: 14 | ``bool``: True if the conversation was cleared 15 | 16 | Raises: 17 | ``~switch.error.SwitchError``: If the conversation could not be cleared 18 | 19 | This method does the same as :meth:`~switch.api.chat.controllers.MessageController.clear_conversation`. 20 | """ 21 | return await self.chat_service.messages.clear_conversation(receiver_id) 22 | -------------------------------------------------------------------------------- /swibots/api/chat/methods/delete_messages_from_user.py: -------------------------------------------------------------------------------- 1 | from typing import Type, TypeVar 2 | import swibots 3 | from swibots.api.chat.models import Message 4 | 5 | 6 | class DeleteMessagesFromUser: 7 | async def delete_messages_from_user( 8 | self: "swibots.ApiClient", user_id: int 9 | ) -> bool: 10 | """Delete all messages from a user 11 | 12 | Parameters: 13 | user_id (``int``): The user id 14 | 15 | Returns: 16 | ``bool``: Whether the messages were deleted 17 | 18 | Raises: 19 | ``~switch.error.SwitchError``: If the messages could not be deleted 20 | 21 | This method does the same as :meth:`~switch.api.chat.controllers.MessageController.delete_messages_from_user`. 22 | """ 23 | return await self.chat_service.messages.delete_messages_from_user(user_id) 24 | -------------------------------------------------------------------------------- /swibots/api/chat/methods/flag_message.py: -------------------------------------------------------------------------------- 1 | from typing import Type, TypeVar 2 | import swibots 3 | from swibots.api.chat.models import Message 4 | 5 | 6 | class FlagMessage: 7 | async def flag_message(self: "swibots.ApiClient", message: Message | int) -> bool: 8 | """Flag a message 9 | 10 | Parameters: 11 | message (``~switch.api.chat.models.Message`` | ``int``): The message to flag 12 | 13 | Returns: 14 | ``bool``: True if the message was flagged 15 | 16 | Raises: 17 | ``~switch.error.SwitchError``: If the message could not be flagged 18 | 19 | This method does the same as :meth:`~switch.api.chat.controllers.MessageController.flag_message`. 20 | """ 21 | return await self.chat_service.messages.flag_message(message) 22 | -------------------------------------------------------------------------------- /swibots/api/chat/methods/forward_message.py: -------------------------------------------------------------------------------- 1 | from typing import Type, TypeVar, Optional, List 2 | import swibots 3 | from swibots.api.chat.models import Message 4 | from swibots.api.community.models import Group, Channel 5 | 6 | 7 | class ForwardMessage: 8 | async def forward_message( 9 | self: "swibots.ApiClient", 10 | message_id: int | List[int], 11 | group_channel: Optional[Group | Channel | str] = None, 12 | user_id: Optional[int] = None, 13 | ) -> Message | List[Message]: 14 | """Forward a message 15 | 16 | Parameters: 17 | message (``~switch.api.chat.models.Message`` | ``int``): The message to forward 18 | group_channel (``~switch.api.community.models.Group`` | ``~switch.api.community.models.Channel`` | ``str``): The group/channel to forward the message to 19 | receiver_id (``str``): The receiver id to forward the message to 20 | 21 | Returns: 22 | ``~switch.api.chat.models.Message``: The forwarded message 23 | 24 | Raises: 25 | ``~switch.error.SwitchError``: If the message could not be forwarded 26 | 27 | This functions does the same as :meth:`~switch.api.chat.controllers.MessageController.forward_message`. 28 | """ 29 | return await self.chat_service.messages.forward_message( 30 | message_id, group_channel, user_id 31 | ) 32 | -------------------------------------------------------------------------------- /swibots/api/chat/methods/get_channel_chat_history.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | import swibots 3 | from swibots.api.chat.models import GroupChatHistory 4 | 5 | 6 | class GetChannelChatHistory: 7 | async def get_channel_chat_history( 8 | self: "swibots.ApiClient", 9 | channel_id: str, 10 | community_id: str, 11 | user_id: int = None, 12 | page_limit: int = 100, 13 | page_offset=0, 14 | ) -> GroupChatHistory: 15 | """Get channel chat history 16 | 17 | 18 | Parameters: 19 | channel_id (``str``): The channel id 20 | limit (``int``, *optional*): The maximum number of messages to return. Defaults to 100. 21 | offset (``int``, *optional*): The offset. Defaults to 0. 22 | community_id (``str``): The community id 23 | user_id (``int``, *optional*): The user id. Defaults to the current user id. 24 | 25 | Returns: 26 | ``List[~switch.api.chat.models.GroupChatHistory]``: The messages 27 | 28 | Raises: 29 | ``~switch.error.SwitchError``: If the messages could not be retrieved 30 | """ 31 | return await self.chat_service.messages.get_channel_chat_history( 32 | channel_id, community_id, user_id, page_limit, page_offset 33 | ) 34 | -------------------------------------------------------------------------------- /swibots/api/chat/methods/get_community_media_files_by_status.py: -------------------------------------------------------------------------------- 1 | from typing import List, Union 2 | import swibots 3 | from swibots.api.chat.models import Message 4 | 5 | 6 | class GetCommunityMediaFilesByStatus: 7 | async def get_community_media_files_by_status( 8 | self: "swibots.ApiClient", 9 | status: Union[str, List[str]], 10 | community_id: str = None, 11 | group_id: str = None, 12 | channel_id: str = None, 13 | user_id: int = None, 14 | ) -> List[Message]: 15 | """Get community media files by status 16 | 17 | Parameters: 18 | community_id (``int``): The community id 19 | status (``str`` | `List[str]`): The status 20 | 21 | Returns: 22 | ``List[~switch.api.chat.models.Message]``: The messages 23 | 24 | Raises: 25 | ``~switch.error.SwitchError``: If the messages could not be retrieved 26 | 27 | This function does the same as :meth:`~switch.api.chat.controllers.MessageController.get_community_media_files_by_status`. 28 | """ 29 | return await self.chat_service.messages.get_community_media_files_by_status( 30 | community_id=community_id, 31 | user_id=user_id, 32 | channel_id=channel_id, 33 | group_id=group_id, 34 | status=status, 35 | ) 36 | -------------------------------------------------------------------------------- /swibots/api/chat/methods/get_flag_messages.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | import swibots 3 | from swibots.api.chat.models import Message 4 | 5 | 6 | class GetFlagMessages: 7 | async def get_flag_messages( 8 | self: "swibots.ApiClient", user_id: int = None 9 | ) -> List[Message]: 10 | """Get flagged messages 11 | 12 | Parameters: 13 | user_id (``int``, *optional*): The user id. Defaults to the current user id. 14 | 15 | Returns: 16 | ``List[~switch.api.chat.models.Message]``: The flagged messages 17 | 18 | Raises: 19 | ``~switch.error.SwitchError``: If the flagged messages could not be retrieved 20 | """ 21 | return await self.chat_service.messages.get_flag_messages(user_id) 22 | -------------------------------------------------------------------------------- /swibots/api/chat/methods/get_group_chat_history.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | import swibots 3 | from swibots.api.chat.models import GroupChatHistory 4 | 5 | 6 | class GetGroupChatHistory: 7 | async def get_group_chat_history( 8 | self: "swibots.ApiClient", 9 | group_id: str, 10 | community_id: str, 11 | user_id: int = None, 12 | page_limit: int = 100, 13 | page_offset=0, 14 | ) -> GroupChatHistory: 15 | """Get group chat history 16 | 17 | Parameters: 18 | group_id (``int``): The group id 19 | limit (``int``, *optional*): The maximum number of messages to return. Defaults to 100. 20 | offset (``int``, *optional*): The offset. Defaults to 0. 21 | 22 | Returns: 23 | ``List[~switch.api.chat.models.Message]``: The messages 24 | 25 | Raises: 26 | ``~switch.error.SwitchError``: If the messages could not be retrieved 27 | 28 | This function does the same as :meth:`~switch.api.chat.controllers.MessageController.get_group_chat_history`. 29 | """ 30 | return await self.chat_service.messages.get_group_chat_history( 31 | group_id, community_id, user_id, page_limit, page_offset 32 | ) 33 | -------------------------------------------------------------------------------- /swibots/api/chat/methods/get_message.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | import swibots 3 | from swibots.api.chat.models import Message 4 | 5 | 6 | class GetMessage: 7 | async def get_message(self: "swibots.ApiClient", message_id: int) -> Message: 8 | """Get a message 9 | 10 | Parameters: 11 | message_id (``int``): The message id 12 | 13 | Returns: 14 | ``~switch.api.chat.models.Message``: The message 15 | 16 | Raises: 17 | ``~switch.error.SwitchError``: If the message could not be retrieved 18 | 19 | This function does the same as :meth:`~switch.api.chat.controllers.MessageController.get_message`. 20 | """ 21 | return await self.chat_service.messages.get_message(message_id) 22 | 23 | async def get_messages( 24 | self: "swibots.ApiClient", message_ids: List[int] | int 25 | ) -> Message | List[Message]: 26 | """Get messages by ids""" 27 | if isinstance(message_ids, list): 28 | return [await self.get_message(id) for id in message_ids] 29 | return await self.get_message(message_ids) 30 | -------------------------------------------------------------------------------- /swibots/api/chat/methods/get_messages.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | import swibots 3 | from swibots.api.chat.models import Message 4 | 5 | 6 | class GetMessages: 7 | async def get_messages( 8 | self: "swibots.ApiClient", user_id: int, limit: int = 100, offset: int = 0 9 | ) -> List[Message]: 10 | """Get messages 11 | 12 | Parameters: 13 | user_id (``int``, *optional*): The user id. 14 | limit (``int``, *optional*): The limit of messages to retrieve. Defaults to 100. 15 | offset (``int``, *optional*): The offset of messages to retrieve. Defaults to 0 16 | 17 | Returns: 18 | ``List[~switch.api.chat.models.Message]``: The messages 19 | 20 | Raises: 21 | ``~switch.error.SwitchError``: If the messages could not be retrieved 22 | 23 | This function does the same as :meth:`~switch.api.chat.controllers.MessageController.get_messages`. 24 | """ 25 | return await self.chat_service.messages.get_messages( 26 | user_id, limit=limit, offset=offset 27 | ) 28 | -------------------------------------------------------------------------------- /swibots/api/chat/methods/get_messages_between_users.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | import swibots 3 | from swibots.api.chat.models import Message 4 | 5 | 6 | class GetMessagesBetweenUsers: 7 | async def get_messages_between_users( 8 | self: "swibots.ApiClient", 9 | other_user_id: int, 10 | user_id: int = None, 11 | limit: int = 100, 12 | offset: int = 0, 13 | ) -> List[Message]: 14 | """Get messages between users 15 | 16 | Parameters: 17 | other_user_id (``int``): The other user id. 18 | user_id (``int``, *optional*): The user id. Defaults to the current user id. 19 | limit (``int``, *optional*): The maximum number of messages to retrieve. Defaults to 100. 20 | offset (``int``, *optional*): The offset. Defaults to 0. 21 | 22 | Returns: 23 | ``List[~switch.api.chat.models.Message]``: The messages 24 | 25 | Raises: 26 | ``~switch.error.SwitchError``: If the messages could not be retrieved 27 | 28 | This function does the same as :meth:`~switch.api.chat.controllers.MessageController.get_messages_between_users`. 29 | """ 30 | return await self.chat_service.messages.get_messages_between_users( 31 | other_user_id, user_id, limit, offset 32 | ) 33 | -------------------------------------------------------------------------------- /swibots/api/chat/methods/get_unread_messages_count.py: -------------------------------------------------------------------------------- 1 | import swibots 2 | 3 | 4 | class GetUnreadMessagesCount: 5 | async def get_unread_messages_count(self: "swibots.ApiClient") -> int: 6 | """Get the amount of unread messages 7 | 8 | Returns: 9 | ``int``: The amount of unread messages 10 | 11 | Raises: 12 | ``~switch.error.SwitchError``: If the amount of unread messages could not be retrieved 13 | 14 | This method does the same as :meth:`~switch.api.chat.controllers.MessageController.get_unread_messages_count`. 15 | """ 16 | return await self.chat_service.messages.get_unread_messages_count() 17 | -------------------------------------------------------------------------------- /swibots/api/chat/methods/get_user.py: -------------------------------------------------------------------------------- 1 | from typing import Type, TypeVar 2 | import swibots 3 | from swibots.api.common.models import User 4 | from swibots.api.chat.models import SessionInfo 5 | 6 | 7 | class GetUser: 8 | async def get_user( 9 | self: "swibots.ApiClient", user_id: int = None, username: str = None 10 | ) -> User: 11 | """Get User Info from user_id or username 12 | 13 | Args: 14 | user_id Optional(`int`): The user id to fetch info. 15 | username [Optional(`str`)]: The username. 16 | 17 | Raises: 18 | ValueError: if both user_id and username are provided or both are missing! 19 | 20 | """ 21 | return await self.chat_service.messages.get_user(user_id, username=username) 22 | 23 | async def get_session_info( 24 | self: "swibots.ApiClient", session_id: str 25 | ) -> SessionInfo: 26 | """Get session info from session id 27 | 28 | Args: 29 | session_id (str): session id to get info. 30 | 31 | Returns: 32 | SessionInfo: 33 | """ 34 | return await self.chat_service.posts.get_session_info(session_id=session_id) 35 | 36 | async def get_last_seen(self: "swibots.ApiClient", user_id: int) -> int: 37 | """Get last seen of user 38 | 39 | Args: 40 | user_id (int): User ID 41 | 42 | Returns: 43 | int: timestamp when user was last active. 44 | """ 45 | return await self.chat_service.posts.get_last_seen(user_id) 46 | -------------------------------------------------------------------------------- /swibots/api/chat/methods/get_user_media_files.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | import swibots 3 | from swibots.api.chat.models import Message 4 | 5 | 6 | class GetUserMediaFiles: 7 | async def get_user_media_files( 8 | self: "swibots.ApiClient", 9 | user_id: int = None, 10 | ) -> List[Message]: 11 | """Get user media files 12 | 13 | 14 | Parameters: 15 | user_id (``int``, *optional*): The user id. Defaults to the current user id. 16 | 17 | Returns: 18 | ``List[~switch.api.chat.models.Message]``: The user media files 19 | 20 | Raises: 21 | ``~switch.error.SwitchError``: If the user media files could not be retrieved 22 | 23 | This function does the same as :meth:`~switch.api.chat.controllers.MessageController.get_user_media_files`. 24 | """ 25 | return await self.chat_service.messages.get_user_media_files(user_id) 26 | -------------------------------------------------------------------------------- /swibots/api/chat/methods/listen_messages.py: -------------------------------------------------------------------------------- 1 | from typing import Type, TypeVar, Union 2 | import swibots, asyncio 3 | from swibots.api.community import Channel, Group 4 | from swibots.api.chat import Message 5 | from swibots.api.common.models import User 6 | from swibots.api.chat.events import MessageEvent 7 | 8 | 9 | class ListenMessages: 10 | async def listen_messages( 11 | self: "swibots.ApiClient", chat_id: str, count: int = 1, timeout: int = 60 12 | ): 13 | messageBox = [] 14 | 15 | async def _on_message(ctx: swibots.BotContext[MessageEvent]): 16 | msg = ctx.event.message 17 | if msg.chat_id == chat_id: 18 | messageBox.append(msg) 19 | 20 | async def getMessages(): 21 | while not len(messageBox) == count: 22 | await asyncio.sleep(0) 23 | 24 | app = self.bots_service.app 25 | 26 | from swibots.bots.handlers.message_handler import MessageHandler 27 | 28 | handler = MessageHandler(_on_message) 29 | try: 30 | app.add_handler(handler) 31 | await asyncio.wait_for(getMessages(), timeout=timeout) 32 | except TimeoutError as er: 33 | raise er 34 | finally: 35 | app.remove_handler(handler) 36 | 37 | if count == 1: 38 | return messageBox[0] 39 | return messageBox 40 | -------------------------------------------------------------------------------- /swibots/api/chat/methods/pin_message.py: -------------------------------------------------------------------------------- 1 | from typing import TYPE_CHECKING, Type, TypeVar, Optional 2 | import swibots 3 | from swibots.api.chat.models import Message 4 | 5 | if TYPE_CHECKING: 6 | from swibots.api import ApiClient 7 | 8 | 9 | class PinMessage: 10 | async def pin_message( 11 | self: "ApiClient", 12 | message: Message | int, 13 | detail: Optional[str] = None, 14 | message_type: Optional[str] = None, 15 | ) -> bool: 16 | """pin a message 17 | 18 | Parameters: 19 | message (``~switch.api.chat.models.Message``): The message to edit 20 | 21 | Raises: 22 | ``~switch.error.SwitchError``: If the message could not be pinned 23 | 24 | This method does the same as :meth:`~switch.api.chat.controllers.PostController.pin_message`. 25 | """ 26 | return await self.chat_service.posts.pin_message( 27 | message, detail=detail, message_type=message_type 28 | ) 29 | -------------------------------------------------------------------------------- /swibots/api/chat/models/__init__.py: -------------------------------------------------------------------------------- 1 | from .message import Message 2 | from .inline_markup import InlineMarkup 3 | from .inline_keyboard_button import InlineKeyboardButton 4 | from .group_chat_history import GroupChatHistory 5 | from .inline import * 6 | from .sticker import Sticker, StickerPack 7 | from .organization import Organization, OrgApp 8 | from .session import SessionInfo, SessionUser 9 | from .ads import ADInfo 10 | -------------------------------------------------------------------------------- /swibots/api/chat/models/ads.py: -------------------------------------------------------------------------------- 1 | import swibots 2 | from enum import Enum 3 | from swibots.base import SwitchObject 4 | from typing import Literal 5 | 6 | ADS_OPTIONS = ["VIDEO_1", "VIDEO_2"] 7 | 8 | 9 | class ADInfo(SwitchObject): 10 | def __init__( 11 | self, 12 | app: "swibots.Client" = None, 13 | access_id: str = None, 14 | admin_id: str = None, 15 | app_id: str = None, 16 | id: str = None, 17 | type: Literal["VIDEO_1", "VIDEO_2", "IMAGE"] = None, 18 | **kwargs 19 | ): 20 | super().__init__(app, **kwargs) 21 | self.type = type 22 | self.app_id = app_id 23 | self.id = id 24 | self.admin_id = admin_id 25 | self.access_id = access_id 26 | 27 | def to_json(self): 28 | return { 29 | "id": self.id, 30 | "appId": self.app_id, 31 | "adminId": self.admin_id, 32 | "addAccessId": self.access_id, 33 | "type": self.type, 34 | } 35 | -------------------------------------------------------------------------------- /swibots/api/chat/models/group_chat_history.py: -------------------------------------------------------------------------------- 1 | from swibots.base import SwitchObject 2 | from typing import List 3 | 4 | from .message import Message 5 | from swibots.api.common.models.user import User 6 | import swibots 7 | 8 | 9 | class GroupChatHistory(SwitchObject): 10 | def __init__( 11 | self, 12 | app: "swibots.App" = None, 13 | messages: List[Message] = None, 14 | ): 15 | super().__init__(app) 16 | self.messages = messages or [] 17 | 18 | def from_json(self, data: dict) -> "GroupChatHistory": 19 | self.messages = Message.build_from_json_list(data, self.app) 20 | return self 21 | 22 | def to_json(self) -> dict: 23 | return { 24 | "message": [message.to_json() for message in self.messages], 25 | } 26 | -------------------------------------------------------------------------------- /swibots/api/chat/models/inline/__init__.py: -------------------------------------------------------------------------------- 1 | from .inline_query import InlineQuery 2 | from .inline_query_answer import InlineQueryAnswer 3 | from .inline_query_result import InlineQueryResult 4 | from .types import InlineQueryResultType 5 | from .base_typed_inline_query_result import BaseTypedInlineQueryResult 6 | from .inline_query_result_article import InlineQueryResultArticle 7 | from .inline_query_result_photo import InlineQueryResultPhoto 8 | from .inline_query_result_document import InlineQueryResultDocument 9 | from .inline_query_result_video import InlineQueryResultVideo 10 | from .input_message_content import InputMessageContent 11 | -------------------------------------------------------------------------------- /swibots/api/chat/models/inline/base_typed_inline_query_result.py: -------------------------------------------------------------------------------- 1 | from .types import InlineQueryResultType 2 | import swibots 3 | from swibots.utils.types import JSONDict 4 | from swibots.base import SwitchObject 5 | from .input_message_content import InputMessageContent 6 | from ..inline_markup import InlineMarkup 7 | from .inline_query_result import InlineQueryResult 8 | 9 | 10 | class BaseTypedInlineQueryResult(InlineQueryResult): 11 | def __init__( 12 | self, 13 | id: str, 14 | type: InlineQueryResultType, 15 | title: str = None, 16 | description: str = None, 17 | thumb_url: str = None, 18 | thumb_width: int = None, 19 | thumb_height: int = None, 20 | input_message: "InputMessageContent" = None, 21 | reply_markup: "InlineMarkup" = None, 22 | ): 23 | super().__init__(id, type, input_message, reply_markup) 24 | self.type = type 25 | self.title = title 26 | self.description = description 27 | self.thumb_url = thumb_url 28 | self.thumb_width = thumb_width 29 | self.thumb_height = thumb_height 30 | 31 | def to_json(self) -> JSONDict: 32 | data = super().to_json() 33 | data.update( 34 | { 35 | "title": self.title, 36 | "description": self.description, 37 | "thumbUrl": self.thumb_url, 38 | "thumbWidth": self.thumb_width, 39 | "thumbHeight": self.thumb_height, 40 | } 41 | ) 42 | return data 43 | -------------------------------------------------------------------------------- /swibots/api/chat/models/inline/inline_query_result.py: -------------------------------------------------------------------------------- 1 | from .types import InlineQueryResultType 2 | import swibots 3 | from swibots.base import SwitchObject 4 | from swibots.utils.types import JSONDict 5 | from .input_message_content import InputMessageContent 6 | from ..inline_markup import InlineMarkup 7 | 8 | 9 | class InlineQueryResult(SwitchObject): 10 | def __init__( 11 | self, 12 | id: str, 13 | type: InlineQueryResultType, 14 | input_message: "InputMessageContent" = None, 15 | reply_markup: "InlineMarkup" = None, 16 | ): 17 | self.id = id 18 | self.type = type 19 | self.input_message = input_message 20 | self.reply_markup = reply_markup 21 | 22 | def to_json(self) -> JSONDict: 23 | data = { 24 | "id": self.id, 25 | "type": self.type.value, 26 | } 27 | if self.input_message is not None: 28 | data["inputMessage"] = self.input_message.to_json() 29 | if self.reply_markup is not None: 30 | data["replyMarkup"] = self.reply_markup.to_json() 31 | return data 32 | -------------------------------------------------------------------------------- /swibots/api/chat/models/inline/inline_query_result_article.py: -------------------------------------------------------------------------------- 1 | import swibots 2 | from swibots.utils.types import JSONDict 3 | from swibots.base import SwitchObject 4 | 5 | from .base_typed_inline_query_result import BaseTypedInlineQueryResult 6 | from .input_message_content import InputMessageContent 7 | from ..inline_markup import InlineMarkup 8 | from .types import InlineQueryResultType 9 | 10 | 11 | class InlineQueryResultArticle(BaseTypedInlineQueryResult): 12 | def __init__( 13 | self, 14 | id: str, 15 | title: str, 16 | article_url: str, 17 | input_message: "InputMessageContent" = None, 18 | description: str = None, 19 | thumb_url: str = None, 20 | thumb_width: int = None, 21 | thumb_height: int = None, 22 | reply_markup: "InlineMarkup" = None, 23 | ): 24 | super().__init__( 25 | id, 26 | InlineQueryResultType.ARTICLE, 27 | title, 28 | description, 29 | thumb_url, 30 | thumb_width, 31 | thumb_height, 32 | input_message, 33 | reply_markup, 34 | ) 35 | self.article_url = article_url 36 | 37 | def to_json(self) -> JSONDict: 38 | data = super().to_json() 39 | data.update( 40 | { 41 | "articleUrl": self.article_url, 42 | } 43 | ) 44 | return data 45 | -------------------------------------------------------------------------------- /swibots/api/chat/models/inline/inline_query_result_document.py: -------------------------------------------------------------------------------- 1 | import swibots 2 | from swibots.utils.types import JSONDict 3 | from swibots.base import SwitchObject 4 | 5 | from .base_typed_inline_query_result import BaseTypedInlineQueryResult 6 | from .input_message_content import InputMessageContent 7 | from ..inline_markup import InlineMarkup 8 | from .types import InlineQueryResultType 9 | 10 | 11 | class InlineQueryResultDocument(BaseTypedInlineQueryResult): 12 | def __init__( 13 | self, 14 | id: str, 15 | title: str, 16 | document_url: str, 17 | mime_type: str, 18 | input_message: "InputMessageContent" = None, 19 | description: str = None, 20 | thumb_url: str = None, 21 | thumb_width: int = None, 22 | thumb_height: int = None, 23 | reply_markup: "InlineMarkup" = None, 24 | ): 25 | super().__init__( 26 | id, 27 | InlineQueryResultType.DOCUMENT, 28 | title, 29 | description, 30 | thumb_url, 31 | thumb_width, 32 | thumb_height, 33 | input_message, 34 | reply_markup, 35 | ) 36 | self.document_url = document_url 37 | self.mime_type = mime_type 38 | 39 | def to_json(self) -> JSONDict: 40 | data = super().to_json() 41 | data.update( 42 | { 43 | "documentUrl": self.document_url, 44 | "mimeType": self.mime_type, 45 | } 46 | ) 47 | return data 48 | -------------------------------------------------------------------------------- /swibots/api/chat/models/inline/input_message_content.py: -------------------------------------------------------------------------------- 1 | from .types import InlineQueryResultType 2 | import swibots 3 | from swibots.utils.types import JSONDict 4 | from swibots.base import SwitchObject 5 | 6 | 7 | class InputMessageContent(SwitchObject): 8 | def __init__( 9 | self, 10 | message_text: str = None, 11 | ): 12 | self.message_text = message_text 13 | 14 | def to_json(self) -> JSONDict: 15 | return { 16 | "messageText": self.message_text, 17 | } 18 | 19 | def from_json(self, data: JSONDict) -> "InputMessageContent": 20 | if data is not None: 21 | self.message_text = data.get("messageText") 22 | return self 23 | -------------------------------------------------------------------------------- /swibots/api/chat/models/inline/types.py: -------------------------------------------------------------------------------- 1 | import enum 2 | 3 | 4 | class InlineQueryResultType(enum.Enum): 5 | """Represents the type of a inline query result.""" 6 | 7 | ARTICLE = "ARTICLE" 8 | PHOTO = "PHOTO" 9 | DOCUMENT = "DOCUMENT" 10 | VIDEO = "VIDEO" 11 | -------------------------------------------------------------------------------- /swibots/api/chat/models/inline_keyboard_button.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | from swibots.base import SwitchObject 4 | from swibots.utils.types import JSONDict 5 | 6 | 7 | class InlineKeyboardButton(SwitchObject): 8 | def __init__( 9 | self, 10 | text: Optional[str] = None, 11 | url: Optional[str] = None, 12 | callback_data: Optional[str] = None, 13 | game: Optional[bool] = False, 14 | app: Optional[bool] = False, 15 | ): 16 | super().__init__(None) 17 | self.text = text 18 | self.url = url 19 | self.callback_data = callback_data 20 | self.game = game 21 | self.is_app = app 22 | 23 | def to_json(self) -> JSONDict: 24 | return { 25 | "text": self.text, 26 | "url": self.url, 27 | "callbackData": self.callback_data, 28 | "game": self.game, 29 | "app": self.is_app, 30 | } 31 | 32 | def from_json(self, data: JSONDict) -> "InlineKeyboardButton": 33 | if data is not None: 34 | self.text = data.get("text") 35 | self.url = data.get("url") 36 | self.callback_data = data.get("callbackData") 37 | self.game = data.get("game") 38 | self.is_app = data.get("app") 39 | return self 40 | -------------------------------------------------------------------------------- /swibots/api/common/__init__.py: -------------------------------------------------------------------------------- 1 | from .models import * 2 | from .events import * 3 | -------------------------------------------------------------------------------- /swibots/api/common/events/__init__.py: -------------------------------------------------------------------------------- 1 | from .event import Event 2 | 3 | __all__ = ["Event"] 4 | -------------------------------------------------------------------------------- /swibots/api/common/models/__init__.py: -------------------------------------------------------------------------------- 1 | from .user import User 2 | from .media import Media 3 | from .embedded_media import EmbeddedMedia 4 | from .embed_inline_field import EmbedInlineField 5 | from .usertournament import UserTournament 6 | -------------------------------------------------------------------------------- /swibots/api/common/models/embed_inline_field.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | from swibots.utils.types import JSONDict 3 | from swibots.base.switch_object import SwitchObject 4 | 5 | 6 | class EmbedInlineField(SwitchObject): 7 | def __init__( 8 | self, 9 | icon: Optional[str] = None, 10 | key: Optional[str] = None, 11 | title: Optional[str] = None, 12 | ): 13 | super().__init__() 14 | self.icon = icon 15 | self.key = key 16 | self.title = title 17 | 18 | def to_json(self) -> JSONDict: 19 | return {"icon": self.icon, "key": self.key, "title": self.title} 20 | -------------------------------------------------------------------------------- /swibots/api/common/models/usertournament.py: -------------------------------------------------------------------------------- 1 | import swibots 2 | from typing import Optional 3 | from swibots.base import SwitchObject 4 | from swibots.utils.types import JSONDict 5 | 6 | 7 | class UserTournament(SwitchObject): 8 | def __init__( 9 | self, 10 | app: Optional["swibots.App"] = None, 11 | id: Optional[str] = None, 12 | type: Optional[type] = None, 13 | name: Optional[str] = None, 14 | user_id: Optional[str] = None, 15 | xp_earned: Optional[int] = None, 16 | ): 17 | super().__init__(app) 18 | self.id = id 19 | self.type = type 20 | self.name = name 21 | self.user_id = user_id 22 | self.xp_earned = xp_earned 23 | 24 | def to_json(self) -> JSONDict: 25 | return { 26 | "id": self.id, 27 | "type": self.type, 28 | "name": self.name, 29 | "userId": self.user_id, 30 | "xpEarned": self.xp_earned, 31 | } 32 | 33 | @classmethod 34 | def from_json(self, data: JSONDict = None) -> "UserTournament": 35 | if data: 36 | self.id = data.get("id") 37 | self.type = data.get("type") 38 | self.name = data.get("name") 39 | self.user_id = data.get("userId") 40 | self.xp_earned = data.get("xpEarned") 41 | return self 42 | -------------------------------------------------------------------------------- /swibots/api/community/__init__.py: -------------------------------------------------------------------------------- 1 | from .community_client import CommunityClient 2 | from .models import * 3 | from .events import * 4 | -------------------------------------------------------------------------------- /swibots/api/community/controllers/__init__.py: -------------------------------------------------------------------------------- 1 | from .community_controller import * 2 | from .channel_controller import * 3 | from .group_controller import * 4 | from .roles_controller import * 5 | from .permissions_controller import * 6 | from .rolemember_controller import * 7 | from .restrict_controller import * 8 | from .ban_controller import * 9 | from .quest_controller import * 10 | from .messaging_controller import InstantMessagingController 11 | -------------------------------------------------------------------------------- /swibots/api/community/controllers/ban_controller.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from typing import TYPE_CHECKING 3 | from swibots.api.community.models import BanInfo 4 | 5 | if TYPE_CHECKING: 6 | from swibots.api.community import CommunityClient 7 | 8 | log = logging.getLogger(__name__) 9 | 10 | BASE_PATH = "/v1/community/ban" 11 | 12 | 13 | class BanController: 14 | def __init__(self, client: "CommunityClient"): 15 | self.client = client 16 | 17 | async def ban_user(self, community_id: str, user_id: str): 18 | """ban a user from community""" 19 | response = await self.client.post( 20 | f"{BASE_PATH}", data={"communityId": community_id, "userId": user_id} 21 | ) 22 | return self.client.build_object(BanInfo, response.data.get("result")) 23 | 24 | async def unban_user(self, community_id: str, user_id: str): 25 | response = await self.client.post( 26 | f"{BASE_PATH}/unban", 27 | data={ 28 | "communityId": community_id, 29 | "userId": user_id, 30 | }, 31 | ) 32 | return response.data.get("result") 33 | -------------------------------------------------------------------------------- /swibots/api/community/events/__init__.py: -------------------------------------------------------------------------------- 1 | from .community_event import CommunityEvent 2 | from .channel_updated_event import ChannelUpdatedEvent 3 | from .channel_created_event import ChannelCreatedEvent 4 | from .channel_deleted_event import ChannelDeletedEvent 5 | from .community_updated_event import CommunityUpdatedEvent 6 | from .group_created_event import GroupCreatedEvent 7 | from .group_updated_event import GroupUpdatedEvent 8 | from .group_deleted_event import GroupDeletedEvent 9 | from .member_joined_event import MemberJoinedEvent 10 | from .member_left_event import MemberLeftEvent 11 | from .user_banned_event import UserBannedEvent 12 | -------------------------------------------------------------------------------- /swibots/api/community/events/group_created_event.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | import swibots 3 | from .community_event import CommunityEvent 4 | from swibots.api.community.models.channel import Channel 5 | from swibots.api.community.models.community import Community 6 | from swibots.api.community.models.group import Group 7 | from swibots.api.common.models.user import User 8 | from swibots.types import EventType 9 | 10 | 11 | class GroupCreatedEvent(CommunityEvent["GroupCreatedEvent"]): 12 | def __init__( 13 | self, 14 | app: "swibots.App" = None, 15 | community_id: Optional[str] = None, 16 | community: Optional[Community] = None, 17 | group_id: Optional[str] = None, 18 | group: Optional[Group] = None, 19 | channel_id: Optional[str] = None, 20 | channel: Optional[Channel] = None, 21 | action_by_id: Optional[str] = None, 22 | action_by: Optional[User] = None, 23 | data: Optional[dict] = None, 24 | user_id: Optional[str] = None, 25 | user: Optional[User] = None, 26 | ): 27 | super().__init__( 28 | app=app, 29 | type=EventType.COMMUNITY_GROUP_CREATE, 30 | data=data, 31 | action_by=action_by, 32 | action_by_id=action_by_id, 33 | community=community, 34 | community_id=community_id, 35 | group=group, 36 | group_id=group_id, 37 | channel=channel, 38 | channel_id=channel_id, 39 | user=user, 40 | user_id=user_id, 41 | ) 42 | -------------------------------------------------------------------------------- /swibots/api/community/events/group_deleted_event.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | import swibots 3 | from .community_event import CommunityEvent 4 | from swibots.api.community.models.channel import Channel 5 | from swibots.api.community.models.community import Community 6 | from swibots.api.community.models.group import Group 7 | from swibots.api.common.models.user import User 8 | from swibots.types import EventType 9 | 10 | 11 | class GroupDeletedEvent(CommunityEvent["GroupDeletedEvent"]): 12 | def __init__( 13 | self, 14 | app: "swibots.App" = None, 15 | community_id: Optional[str] = None, 16 | community: Optional[Community] = None, 17 | group_id: Optional[str] = None, 18 | group: Optional[Group] = None, 19 | channel_id: Optional[str] = None, 20 | channel: Optional[Channel] = None, 21 | action_by_id: Optional[str] = None, 22 | action_by: Optional[User] = None, 23 | data: Optional[dict] = None, 24 | user_id: Optional[str] = None, 25 | user: Optional[User] = None, 26 | ): 27 | super().__init__( 28 | app=app, 29 | type=EventType.COMMUNITY_GROUP_DELETE, 30 | data=data, 31 | action_by=action_by, 32 | action_by_id=action_by_id, 33 | community=community, 34 | community_id=community_id, 35 | group=group, 36 | group_id=group_id, 37 | channel=channel, 38 | channel_id=channel_id, 39 | user=user, 40 | user_id=user_id, 41 | ) 42 | -------------------------------------------------------------------------------- /swibots/api/community/events/member_left_event.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | import swibots 3 | from .community_event import CommunityEvent 4 | from swibots.api.community.models.channel import Channel 5 | from swibots.api.community.models.community import Community 6 | from swibots.api.community.models.group import Group 7 | from swibots.api.common.models.user import User 8 | from swibots.types import EventType 9 | 10 | 11 | class MemberLeftEvent(CommunityEvent["MemberLeftEvent"]): 12 | def __init__( 13 | self, 14 | app: "swibots.App" = None, 15 | community_id: Optional[str] = None, 16 | community: Optional[Community] = None, 17 | group_id: Optional[str] = None, 18 | group: Optional[Group] = None, 19 | channel_id: Optional[str] = None, 20 | channel: Optional[Channel] = None, 21 | action_by_id: Optional[str] = None, 22 | action_by: Optional[User] = None, 23 | data: Optional[dict] = None, 24 | user_id: Optional[str] = None, 25 | user: Optional[User] = None, 26 | ): 27 | super().__init__( 28 | app=app, 29 | type=EventType.COMMUNITY_MEMBER_LEAVE, 30 | data=data, 31 | action_by=action_by, 32 | action_by_id=action_by_id, 33 | community=community, 34 | community_id=community_id, 35 | group=group, 36 | group_id=group_id, 37 | channel=channel, 38 | channel_id=channel_id, 39 | user=user, 40 | user_id=user_id, 41 | ) 42 | -------------------------------------------------------------------------------- /swibots/api/community/events/user_banned_event.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | import swibots 3 | from .community_event import CommunityEvent 4 | from swibots.api.community.models.channel import Channel 5 | from swibots.api.community.models.community import Community 6 | from swibots.api.community.models.group import Group 7 | from swibots.api.common.models.user import User 8 | from swibots.types import EventType 9 | 10 | 11 | class UserBannedEvent(CommunityEvent["UserBannedEvent"]): 12 | def __init__( 13 | self, 14 | app: "swibots.App" = None, 15 | community_id: Optional[str] = None, 16 | community: Optional[Community] = None, 17 | group_id: Optional[str] = None, 18 | group: Optional[Group] = None, 19 | channel_id: Optional[str] = None, 20 | channel: Optional[Channel] = None, 21 | action_by_id: Optional[str] = None, 22 | action_by: Optional[User] = None, 23 | data: Optional[dict] = None, 24 | user_id: Optional[str] = None, 25 | user: Optional[User] = None, 26 | ): 27 | super().__init__( 28 | app=app, 29 | type=EventType.COMMUNITY_USER_BAN, 30 | data=data, 31 | action_by=action_by, 32 | action_by_id=action_by_id, 33 | community=community, 34 | community_id=community_id, 35 | group=group, 36 | group_id=group_id, 37 | channel=channel, 38 | channel_id=channel_id, 39 | user=user, 40 | user_id=user_id, 41 | ) 42 | -------------------------------------------------------------------------------- /swibots/api/community/methods/__init__.py: -------------------------------------------------------------------------------- 1 | from .group_methods import GroupMethods 2 | from .permission import PermissionMethods 3 | from .roles import RoleMethods 4 | from .rolemember import RoleMemberMethods 5 | from .ban_user import BanUser 6 | from .unban_user import UnbanUser 7 | from .channel_methods import ChannelMethods 8 | from .community_methods import CommunityMethods 9 | from .restrict_user import RestrictUser 10 | from .deduct_xp import DeductXP 11 | from .instant_messaging import InstantMessagingMethods 12 | from .quest_methods import QuestsMethods 13 | 14 | 15 | class CommunityMethods( 16 | CommunityMethods, 17 | GroupMethods, 18 | RoleMethods, 19 | PermissionMethods, 20 | RoleMemberMethods, 21 | BanUser, 22 | UnbanUser, 23 | ChannelMethods, 24 | RestrictUser, 25 | DeductXP, 26 | QuestsMethods, 27 | InstantMessagingMethods, 28 | ): 29 | pass 30 | -------------------------------------------------------------------------------- /swibots/api/community/methods/ban_user.py: -------------------------------------------------------------------------------- 1 | import swibots 2 | from swibots.api.community.models import BanInfo 3 | 4 | 5 | class BanUser: 6 | async def ban_user( 7 | self: "swibots.ApiClient", community_id: str, user_id: str 8 | ) -> BanInfo: 9 | """ 10 | Bans a user in a community. 11 | 12 | Args: 13 | community_id (str): The ID of the community. 14 | user_id (str): The ID of the user to ban. 15 | """ 16 | return await self.community_service.ban.ban_user(community_id, user_id) 17 | -------------------------------------------------------------------------------- /swibots/api/community/methods/deduct_xp.py: -------------------------------------------------------------------------------- 1 | import swibots 2 | from typing import Optional 3 | from swibots.api.community.models import Channel 4 | 5 | 6 | class DeductXP: 7 | async def deduct_xp( 8 | self: "swibots.ApiClient", 9 | community_id: str, 10 | user_id: str, 11 | xp: int = 0, 12 | description: Optional[str] = None, 13 | ) -> bool: 14 | """ 15 | Deducts XP from a user in a community. 16 | 17 | Args: 18 | community_id: The ID of the community. 19 | user_id: The ID of the user. 20 | xp: The amount of XP to deduct. 21 | description: An optional description of the reason for the deduction. 22 | 23 | Returns: 24 | True if the deduction was successful, False otherwise. 25 | """ 26 | return await self.community_service.communities.deduct_xp( 27 | community_id, user_id, xp, description 28 | ) 29 | -------------------------------------------------------------------------------- /swibots/api/community/methods/instant_messaging.py: -------------------------------------------------------------------------------- 1 | import swibots 2 | from typing import Optional 3 | 4 | from swibots.api.community.models import InstantMessaging 5 | 6 | 7 | class InstantMessagingMethods: 8 | async def enable_messages( 9 | self: "swibots.ApiClient", 10 | community_id: str, 11 | group_id: str, 12 | bot_id: Optional[str] = None, 13 | ) -> InstantMessaging: 14 | """Enable messaging in group""" 15 | return await self.community_service.instant_messaging.enable_messages( 16 | community_id, group_id, bot_id 17 | ) 18 | 19 | async def disable_messages( 20 | self: "swibots.ApiClient", 21 | community_id: str, 22 | group_id: str, 23 | bot_id: Optional[str] = None, 24 | ) -> InstantMessaging: 25 | """Disable messaging in group""" 26 | return await self.community_service.instant_messaging.disable_messages( 27 | community_id, group_id, bot_id 28 | ) 29 | 30 | async def get_messaging_enabled( 31 | self: "swibots.ApiClient", community_id: str, group_id: str 32 | ) -> InstantMessaging: 33 | """Get bot with messaging enable in the community""" 34 | return await self.community_service.instant_messaging.get_messaging_enabled( 35 | community_id, group_id 36 | ) 37 | -------------------------------------------------------------------------------- /swibots/api/community/methods/unban_user.py: -------------------------------------------------------------------------------- 1 | import swibots 2 | 3 | from swibots.api.community.models import Channel 4 | 5 | 6 | class UnbanUser: 7 | async def unban_user( 8 | self: "swibots.ApiClient", community_id: str, user_id: str 9 | ): 10 | """Unbans a user in a community. 11 | 12 | Args: 13 | community_id (str): The ID of the community. 14 | user_id (str): The ID of the user to unban. 15 | 16 | Returns: 17 | bool: Whether the unban was successful. 18 | """ 19 | return await self.community_service.ban.unban_user(community_id, user_id) 20 | -------------------------------------------------------------------------------- /swibots/api/community/models/__init__.py: -------------------------------------------------------------------------------- 1 | from .channel import Channel 2 | from .community import Community, CommunityHeading 3 | from .group import Group 4 | from .role import Role 5 | from .rolepermission import RolePermission 6 | from .rolemember import RoleMember 7 | from .baninfo import BanInfo 8 | from .community_member import CommunityMember, SearchResultUser 9 | from .restricteduser import RestrictedUser 10 | from .quest import Quest, QuestCategory 11 | from .instantmessaging import InstantMessaging 12 | 13 | __all__ = [ 14 | "Channel", 15 | "Community", 16 | "Group", 17 | "Role", 18 | "RolePermission", 19 | "RoleMember", 20 | "BanInfo", 21 | "CommunityHeading", 22 | "CommunityMember", 23 | "RestrictedUser", 24 | "Quest", 25 | "QuestCategory", 26 | "InstantMessaging", 27 | "SearchResultUser", 28 | ] 29 | -------------------------------------------------------------------------------- /swibots/api/community/models/baninfo.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | from swibots.utils.types import JSONDict 3 | from swibots.base.switch_object import SwitchObject 4 | import swibots 5 | 6 | 7 | class BanInfo(SwitchObject): 8 | def __init__( 9 | self, 10 | app: "swibots.App" = None, 11 | banned: Optional[bool] = None, 12 | message: Optional[str] = None, 13 | ): 14 | super().__init__(app) 15 | self.banned = banned 16 | self.message = message 17 | 18 | def to_json(self) -> JSONDict: 19 | return {"isBanned": self.banned, "message": self.message} 20 | 21 | @classmethod 22 | def from_json(self, data: JSONDict = None) -> "BanInfo": 23 | if data is not None: 24 | self.banned = data.get("isBanned") 25 | self.message = data.get("message") 26 | return self 27 | -------------------------------------------------------------------------------- /swibots/api/community/models/instantmessaging.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | from swibots.utils.types import JSONDict 3 | from swibots.base.switch_object import SwitchObject 4 | 5 | 6 | class InstantMessaging(SwitchObject): 7 | def __init__( 8 | self, 9 | id: Optional[str] = None, 10 | community_id: Optional[str] = None, 11 | group_id: Optional[str] = None, 12 | channel_id: Optional[str] = None, 13 | bot_id: Optional[int] = None, 14 | enabled: Optional[bool] = False, 15 | ): 16 | self.id = id 17 | self.community_id = community_id 18 | self.group_id = group_id 19 | self.channel_id = channel_id 20 | self.bot_id = bot_id 21 | self.enabled = enabled 22 | 23 | def from_json(self, data: JSONDict = None) -> "InstantMessaging": 24 | if data is not None: 25 | self.id = data.get("id") 26 | self.community_id = data.get("communityId") 27 | self.group_id = data.get("groupId") 28 | self.channel_id = data.get("channelId") 29 | self.bot_id = data.get("botId") 30 | self.enabled = data.get("enabled") 31 | return self 32 | -------------------------------------------------------------------------------- /swibots/api/community/models/private_join_response.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | from swibots.api.common.models import User 3 | from swibots.utils.types import JSONDict 4 | from swibots.base.switch_object import SwitchObject 5 | import swibots 6 | 7 | 8 | class PrivateJoinResponse(SwitchObject): 9 | def __init__( 10 | self, 11 | app: "swibots.App" = None, 12 | ): 13 | super().__init__(app) 14 | self.channel_id = None 15 | self.community_id = None 16 | self.group_id = None 17 | self.members = [] 18 | 19 | def from_json(self, data: JSONDict = None) -> "PrivateJoinResponse": 20 | if data: 21 | self.channel_id = data.get("channelId") 22 | self.community_id = data.get("communityId") 23 | self.group_id = data.get("groupId") 24 | self.members = [ 25 | User.build_from_json(member, self.app) for member in data.get("members") 26 | ] 27 | return self 28 | -------------------------------------------------------------------------------- /swibots/api/community/models/role.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | from swibots.utils.types import JSONDict 3 | from swibots.base.switch_object import SwitchObject 4 | import swibots 5 | 6 | 7 | class Role(SwitchObject): 8 | def __init__( 9 | self, 10 | app: "swibots.App" = None, 11 | id: Optional[int] = 0, 12 | community_id: Optional[str] = "", 13 | colour: Optional[str] = "", 14 | name: Optional[str] = "", 15 | members_count: Optional[int] = 0, 16 | ): 17 | super().__init__(app) 18 | 19 | self.id = id 20 | self.name = name 21 | self.community_id = community_id 22 | self.colour = colour 23 | self.members_count = members_count 24 | 25 | def to_json(self) -> JSONDict: 26 | return { 27 | "roleId": self.id, 28 | "roleColour": self.colour, 29 | "roleName": self.name, 30 | "noOfMembers": self.members_count, 31 | "communityId": self.community_id, 32 | } 33 | 34 | def from_json(self, data: JSONDict) -> "Role": 35 | if data is not None: 36 | self.id = data.get("id") 37 | self.name = data.get("roleName") 38 | self.colour = data.get("roleColour") 39 | self.community_id = data.get("communityId") 40 | self.members_count = data.get("noOfMembers") 41 | return self 42 | -------------------------------------------------------------------------------- /swibots/base/__init__.py: -------------------------------------------------------------------------------- 1 | from .rest_controller import RestController 2 | from .rest_request import RestRequest 3 | from .rest_response import RestResponse 4 | from .switch_object import SwitchObject 5 | from .switch_client import SwitchRestClient 6 | from .switch_ws_async_client import SwitchWSAsyncClient 7 | -------------------------------------------------------------------------------- /swibots/base/rest_controller.py: -------------------------------------------------------------------------------- 1 | class RestController: 2 | """Base class for REST controllers.""" 3 | -------------------------------------------------------------------------------- /swibots/base/rest_request.py: -------------------------------------------------------------------------------- 1 | from typing import Generic, TypeVar 2 | 3 | from swibots.utils.types import RequestMethod 4 | 5 | 6 | T = TypeVar("T") 7 | 8 | 9 | class RestRequest(Generic[T]): 10 | def __init__( 11 | self, 12 | path: str, 13 | method: RequestMethod = RequestMethod.GET, 14 | data=None, 15 | headers: dict = None, 16 | ): 17 | self.method = method 18 | self.path = path 19 | self.data = data 20 | self.headers = headers 21 | -------------------------------------------------------------------------------- /swibots/base/rest_response.py: -------------------------------------------------------------------------------- 1 | from typing import Generic, TypeVar 2 | from http.client import responses 3 | 4 | from swibots.utils.types import RequestMethod 5 | 6 | 7 | T = TypeVar("T") 8 | 9 | 10 | class RestResponse(Generic[T]): 11 | def __init__(self, data: T, status_code: int, headers: dict): 12 | self.data = data 13 | self.status_code = status_code 14 | self.headers = headers 15 | 16 | @property 17 | def is_error(self) -> bool: 18 | return self.status_code >= 400 19 | 20 | @property 21 | def error_message(self) -> str: 22 | err = ( 23 | self.data 24 | if self.data is not None and self.data != "" 25 | else responses[self.status_code] 26 | ) 27 | return f"Error {self.status_code}: {err}" 28 | -------------------------------------------------------------------------------- /swibots/base/switch_ws_async_client.py: -------------------------------------------------------------------------------- 1 | from swibots.utils.ws.asyncstomp import AsyncWsClient 2 | 3 | 4 | class SwitchWSAsyncClient(AsyncWsClient): 5 | def __init__(self, url: str, token: str = None): 6 | super().__init__(url) 7 | self._token = token 8 | 9 | @property 10 | def token(self) -> str: 11 | return self._token 12 | 13 | @token.setter 14 | def token(self, value: str): 15 | self._token = value 16 | 17 | def _set_default_headers(self, headers): 18 | headers = super()._set_default_headers(headers) 19 | headers["Authorization"] = f"Bearer {self._token}" 20 | return headers 21 | -------------------------------------------------------------------------------- /swibots/bots/__init__.py: -------------------------------------------------------------------------------- 1 | from .bot_context import BotContext 2 | from .handlers import * 3 | from .bot import Bot 4 | from .filters import * 5 | from .decorators import * 6 | -------------------------------------------------------------------------------- /swibots/bots/bot_context.py: -------------------------------------------------------------------------------- 1 | import swibots 2 | from typing import TYPE_CHECKING, Generic, TypeVar 3 | from swibots.api.api_client import ApiClient 4 | from swibots.api.chat.models import Message 5 | from .bot import Bot 6 | from swibots.api.common.events import Event 7 | 8 | EventType = TypeVar("EventType", bound="Event") 9 | 10 | 11 | class BotContext(Generic[EventType], ApiClient): 12 | def __init__(self, app: "swibots.App", event: EventType): 13 | self.event = event 14 | self.app = app 15 | self._user = app._user 16 | 17 | # copy the api client 18 | 19 | self._chat_client = app.chat_service 20 | self._auth_client = app.auth_service 21 | self._community_client = app.community_service 22 | self._bot_client = app.bots_service 23 | 24 | self.add_handler = self.app.add_handler 25 | self.remove_handler = self.app.remove_handler 26 | self.handlers = self.app.handlers 27 | self.update_bot_commands = self.app.update_bot_commands 28 | self.set_bot_commands = self.app.set_bot_commands 29 | self.delete_bot_commands = self.app.delete_bot_commands 30 | -------------------------------------------------------------------------------- /swibots/bots/decorators/__init__.py: -------------------------------------------------------------------------------- 1 | from .on_message import OnMessage 2 | from .on_callback_query import OnCallbackQuery 3 | from .on_channel_created import OnChannelCreated 4 | from .on_channel_deleted import OnChannelDeleted 5 | from .on_channel_updated import OnChannelUpdated 6 | from .on_command import OnCommand 7 | from .on_community_updated import OnCommunityUpdated 8 | from .on_group_created import OnGroupCreated 9 | from .on_group_deleted import OnGroupDeleted 10 | from .on_group_updated import OnGroupUpdated 11 | from .on_member_joined import OnMemberJoined 12 | from .on_member_left import OnMemberLeft 13 | from .on_user_banned import OnUserBanned 14 | from .on_unknown_command import OnUnknownCommand 15 | from .on_inline_query import OnInlineQuery 16 | 17 | 18 | class Decorators( 19 | OnMessage, 20 | OnCallbackQuery, 21 | OnChannelCreated, 22 | OnChannelDeleted, 23 | OnChannelUpdated, 24 | OnCommand, 25 | OnCommunityUpdated, 26 | OnGroupCreated, 27 | OnGroupDeleted, 28 | OnGroupUpdated, 29 | OnMemberJoined, 30 | OnMemberLeft, 31 | OnUserBanned, 32 | OnUnknownCommand, 33 | OnInlineQuery, 34 | ): 35 | pass 36 | -------------------------------------------------------------------------------- /swibots/bots/decorators/on_callback_query.py: -------------------------------------------------------------------------------- 1 | from typing import Callable, Optional 2 | import swibots 3 | from swibots.bots.filters.filter import Filter 4 | 5 | 6 | class OnCallbackQuery: 7 | def on_callback_query( 8 | self: "swibots.Client" = None, filter: Optional[Filter] = None 9 | ) -> Callable: 10 | """Decorator for handling callback queries.""" 11 | 12 | def decorator(func: Callable) -> Callable: 13 | if isinstance(self, swibots.Client): 14 | self.add_handler( 15 | swibots.bots.handlers.CallbackQueryHandler(func, filter) 16 | ) 17 | 18 | return func 19 | 20 | return decorator 21 | -------------------------------------------------------------------------------- /swibots/bots/decorators/on_channel_created.py: -------------------------------------------------------------------------------- 1 | from typing import Callable 2 | import swibots 3 | from swibots.bots.filters.filter import Filter 4 | 5 | 6 | class OnChannelCreated: 7 | def on_channel_created( 8 | self: "swibots.Client" = None, filter: Filter = None 9 | ) -> Callable: 10 | """Decorator for handling channel creations.""" 11 | 12 | def decorator(func: Callable) -> Callable: 13 | if isinstance(self, swibots.Client): 14 | self.add_handler( 15 | swibots.bots.handlers.ChannelCreatedHandler(func, filter) 16 | ) 17 | 18 | return func 19 | 20 | return decorator 21 | -------------------------------------------------------------------------------- /swibots/bots/decorators/on_channel_deleted.py: -------------------------------------------------------------------------------- 1 | from typing import Callable, Optional 2 | import swibots 3 | from swibots.bots.filters.filter import Filter 4 | 5 | 6 | class OnChannelDeleted: 7 | def on_channel_created( 8 | self: "swibots.Client" = None, filter: Optional[Filter] = None 9 | ) -> Callable: 10 | """Decorator for handling channel creations.""" 11 | 12 | def decorator(func: Callable) -> Callable: 13 | if isinstance(self, swibots.Client): 14 | self.add_handler( 15 | swibots.bots.handlers.ChannelDeletedHandler(func, filter) 16 | ) 17 | 18 | return func 19 | 20 | return decorator 21 | -------------------------------------------------------------------------------- /swibots/bots/decorators/on_channel_updated.py: -------------------------------------------------------------------------------- 1 | from typing import Callable, Optional 2 | import swibots 3 | from swibots.bots.filters.filter import Filter 4 | 5 | 6 | class OnChannelUpdated: 7 | def on_channel_updated( 8 | self: "swibots.Client" = None, filter: Optional[Filter] = None 9 | ) -> Callable: 10 | """Decorator for handling channel update.""" 11 | 12 | def decorator(func: Callable) -> Callable: 13 | if isinstance(self, swibots.Client): 14 | self.add_handler( 15 | swibots.bots.handlers.ChannelUpdatedHandler(func, filter) 16 | ) 17 | 18 | return func 19 | 20 | return decorator 21 | -------------------------------------------------------------------------------- /swibots/bots/decorators/on_command.py: -------------------------------------------------------------------------------- 1 | from typing import Callable, Optional 2 | import swibots 3 | from swibots.bots.filters.filter import Filter 4 | from swibots.utils.types import SCT 5 | 6 | 7 | class OnCommand: 8 | def on_command( 9 | self: "swibots.Client", command: SCT[str], filter: Optional[Filter] = None 10 | ) -> Callable: 11 | """Decorator for handling new commands.""" 12 | 13 | def decorator(func: Callable) -> Callable: 14 | if isinstance(self, swibots.Client): 15 | self.add_handler( 16 | swibots.bots.handlers.CommandHandler(command, func, filter) 17 | ) 18 | 19 | return func 20 | 21 | return decorator 22 | -------------------------------------------------------------------------------- /swibots/bots/decorators/on_community_updated.py: -------------------------------------------------------------------------------- 1 | from typing import Callable, Optional 2 | import swibots 3 | from swibots.bots.filters.filter import Filter 4 | 5 | 6 | class OnCommunityUpdated: 7 | def on_community_update( 8 | self: "swibots.Client" = None, filter: Optional[Filter] = None 9 | ) -> Callable: 10 | """Decorator for handling new commands.""" 11 | 12 | def decorator(func: Callable) -> Callable: 13 | if isinstance(self, swibots.Client): 14 | self.add_handler( 15 | swibots.bots.handlers.CommunityUpdatedHandler(func, filter) 16 | ) 17 | 18 | return func 19 | 20 | return decorator 21 | -------------------------------------------------------------------------------- /swibots/bots/decorators/on_group_created.py: -------------------------------------------------------------------------------- 1 | from typing import Callable, Optional 2 | import swibots 3 | from swibots.bots.filters.filter import Filter 4 | 5 | 6 | class OnGroupCreated: 7 | def on_group_created( 8 | self: "swibots.Client" = None, filter: Optional[Filter] = None 9 | ) -> Callable: 10 | """Decorator for handling group creations.""" 11 | 12 | def decorator(func: Callable) -> Callable: 13 | if isinstance(self, swibots.Client): 14 | self.add_handler( 15 | swibots.bots.handlers.GroupCreatedHandler(func, filter) 16 | ) 17 | 18 | return func 19 | 20 | return decorator 21 | -------------------------------------------------------------------------------- /swibots/bots/decorators/on_group_deleted.py: -------------------------------------------------------------------------------- 1 | from typing import Callable, Optional 2 | import swibots 3 | from swibots.bots.filters.filter import Filter 4 | 5 | 6 | class OnGroupDeleted: 7 | def on_group_deleted( 8 | self: "swibots.Client" = None, filter: Optional[Filter] = None 9 | ) -> Callable: 10 | """Decorator for handling group deletions.""" 11 | 12 | def decorator(func: Callable) -> Callable: 13 | if isinstance(self, swibots.Client): 14 | self.add_handler( 15 | swibots.bots.handlers.GroupDeletedHandler(func, filter) 16 | ) 17 | 18 | return func 19 | 20 | return decorator 21 | -------------------------------------------------------------------------------- /swibots/bots/decorators/on_group_updated.py: -------------------------------------------------------------------------------- 1 | from typing import Callable, Optional 2 | import swibots 3 | from swibots.bots.filters.filter import Filter 4 | 5 | 6 | class OnGroupUpdated: 7 | def on_group_updated( 8 | self: "swibots.Client" = None, filter: Optional[Filter] = None 9 | ) -> Callable: 10 | """Decorator for handling group updates.""" 11 | 12 | def decorator(func: Callable) -> Callable: 13 | if isinstance(self, swibots.Client): 14 | self.add_handler( 15 | swibots.bots.handlers.GroupUpdatedHandler(func, filter) 16 | ) 17 | 18 | return func 19 | 20 | return decorator 21 | -------------------------------------------------------------------------------- /swibots/bots/decorators/on_inline_query.py: -------------------------------------------------------------------------------- 1 | from typing import Callable, Optional 2 | import swibots 3 | from swibots.bots.filters.filter import Filter 4 | 5 | 6 | class OnInlineQuery: 7 | def on_inline_query( 8 | self: "swibots.Client" = None, filter: Optional[Filter] = None 9 | ) -> Callable: 10 | """Decorator for handling new messages.""" 11 | 12 | def decorator(func: Callable) -> Callable: 13 | if isinstance(self, swibots.Client): 14 | self.add_handler(swibots.bots.handlers.InlineQueryHandler(func, filter)) 15 | 16 | return func 17 | 18 | return decorator 19 | -------------------------------------------------------------------------------- /swibots/bots/decorators/on_member_joined.py: -------------------------------------------------------------------------------- 1 | from typing import Callable, Optional 2 | import swibots 3 | from swibots.bots.filters.filter import Filter 4 | 5 | 6 | class OnMemberJoined: 7 | def on_member_joined( 8 | self: "swibots.Client" = None, filter: Optional[Filter] = None 9 | ) -> Callable: 10 | """Decorator for handling members joins.""" 11 | 12 | def decorator(func: Callable) -> Callable: 13 | if isinstance(self, swibots.Client): 14 | self.add_handler( 15 | swibots.bots.handlers.MemberJoinedHandler(func, filter) 16 | ) 17 | 18 | return func 19 | 20 | return decorator 21 | -------------------------------------------------------------------------------- /swibots/bots/decorators/on_member_left.py: -------------------------------------------------------------------------------- 1 | from typing import Callable, Optional 2 | import swibots 3 | from swibots.bots.filters.filter import Filter 4 | 5 | 6 | class OnMemberLeft: 7 | def on_member_left( 8 | self: "swibots.Client" = None, filter: Optional[Filter] = None 9 | ) -> Callable: 10 | """Decorator for handling members joins.""" 11 | 12 | def decorator(func: Callable) -> Callable: 13 | if isinstance(self, swibots.Client): 14 | self.add_handler(swibots.bots.handlers.MemberLeftHandler(func, filter)) 15 | 16 | return func 17 | 18 | return decorator 19 | -------------------------------------------------------------------------------- /swibots/bots/decorators/on_message.py: -------------------------------------------------------------------------------- 1 | from typing import Callable, Optional 2 | import swibots 3 | from swibots.bots.filters.filter import Filter 4 | 5 | 6 | class OnMessage: 7 | def on_message( 8 | self: "swibots.Client" = None, filter: Optional[Filter] = None 9 | ) -> Callable: 10 | """Decorator for handling new messages.""" 11 | 12 | def decorator(func: Callable) -> Callable: 13 | if isinstance(self, swibots.Client): 14 | self.add_handler(swibots.bots.handlers.MessageHandler(func, filter)) 15 | 16 | return func 17 | 18 | return decorator 19 | -------------------------------------------------------------------------------- /swibots/bots/decorators/on_unknown_command.py: -------------------------------------------------------------------------------- 1 | from typing import Callable, Optional 2 | import swibots 3 | from swibots.bots.filters.filter import Filter 4 | 5 | 6 | class OnUnknownCommand: 7 | def on_unknown_command( 8 | self: "swibots.Client" = None, filter: Optional[Filter] = None 9 | ) -> Callable: 10 | """Decorator for handling unknown commands.""" 11 | 12 | def decorator(func: Callable) -> Callable: 13 | if isinstance(self, swibots.Client): 14 | self.add_handler( 15 | swibots.bots.handlers.UnknownCommandHandler(func, filter) 16 | ) 17 | 18 | return func 19 | 20 | return decorator 21 | -------------------------------------------------------------------------------- /swibots/bots/decorators/on_user_banned.py: -------------------------------------------------------------------------------- 1 | from typing import Callable, Optional 2 | import swibots 3 | from swibots.bots.filters.filter import Filter 4 | 5 | 6 | class OnUserBanned: 7 | def on_user_banned( 8 | self: "swibots.Client" = None, filter: Optional[Filter] = None 9 | ) -> Callable: 10 | """Decorator for handling user ban.""" 11 | 12 | def decorator(func: Callable) -> Callable: 13 | if isinstance(self, swibots.Client): 14 | self.add_handler(swibots.bots.handlers.UserBannedHandler(func, filter)) 15 | 16 | return func 17 | 18 | return decorator 19 | -------------------------------------------------------------------------------- /swibots/bots/filters/__init__.py: -------------------------------------------------------------------------------- 1 | from .filter import * 2 | -------------------------------------------------------------------------------- /swibots/bots/handlers/__init__.py: -------------------------------------------------------------------------------- 1 | from .base_handler import BaseHandler 2 | from .event_handler import EventHandler 3 | from .command_handler import CommandHandler 4 | from .message_handler import MessageHandler 5 | from .callback_query_handler import CallbackQueryHandler 6 | from .channel_created_handler import ChannelCreatedHandler 7 | from .channel_deleted_handler import ChannelDeletedHandler 8 | from .channel_updated_handler import ChannelUpdatedHandler 9 | from .group_created_handler import GroupCreatedHandler 10 | from .group_deleted_handler import GroupDeletedHandler 11 | from .group_updated_handler import GroupUpdatedHandler 12 | from .member_joined_handler import MemberJoinedHandler 13 | from .member_left_handler import MemberLeftHandler 14 | from .user_banned_handler import UserBannedHandler 15 | from .community_updated_handler import CommunityUpdatedHandler 16 | from .unknown_command_handler import UnknownCommandHandler 17 | from .inline_query_handler import InlineQueryHandler 18 | 19 | 20 | class Handlers( 21 | CommandHandler, 22 | MessageHandler, 23 | CallbackQueryHandler, 24 | UnknownCommandHandler, 25 | ChannelCreatedHandler, 26 | ChannelDeletedHandler, 27 | ChannelUpdatedHandler, 28 | GroupCreatedHandler, 29 | GroupDeletedHandler, 30 | GroupUpdatedHandler, 31 | MemberJoinedHandler, 32 | MemberLeftHandler, 33 | UserBannedHandler, 34 | CommunityUpdatedHandler, 35 | InlineQueryHandler, 36 | ): 37 | pass 38 | -------------------------------------------------------------------------------- /swibots/bots/handlers/base_handler.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | from typing import TYPE_CHECKING, Generic, Optional, TypeVar 3 | from swibots.bots.filters.filter import Filter 4 | from swibots.utils.types import HandlerCallback 5 | 6 | if TYPE_CHECKING: 7 | from swibots.bots.bot import Bot 8 | from switch.switch_client import SwitchApp 9 | 10 | 11 | CtxType = TypeVar("CtxType") 12 | ResType = TypeVar("ResType") 13 | 14 | 15 | class BaseHandler(Generic[CtxType, ResType], ABC): 16 | def __init__( 17 | self, 18 | callback: HandlerCallback[CtxType, ResType], 19 | filter: Optional[Filter] = None, 20 | **kwargs, 21 | ): 22 | self.callback = callback 23 | self.filter = filter 24 | 25 | async def on_app_start(self, app: "SwitchApp"): 26 | pass 27 | 28 | async def on_app_stop(self, app: "SwitchApp"): 29 | pass 30 | 31 | async def should_handle(self, context: CtxType) -> bool: 32 | return False 33 | 34 | async def handle( 35 | self, 36 | context: CtxType, 37 | ) -> ResType: 38 | if await self.should_handle(context=context) and self.callback is not None: 39 | return await self.callback(context) 40 | -------------------------------------------------------------------------------- /swibots/bots/handlers/callback_query_handler.py: -------------------------------------------------------------------------------- 1 | import re 2 | from typing import TYPE_CHECKING, Optional, TypeVar 3 | from swibots.api.chat.events import CallbackQueryEvent 4 | from swibots.bots.filters.filter import Filter 5 | from swibots.types import EventType 6 | 7 | from swibots.utils.types import SCT, HandlerCallback 8 | from swibots.bots.handlers.event_handler import EventHandler 9 | from swibots.bots.bot_context import BotContext 10 | 11 | if TYPE_CHECKING: 12 | pass 13 | 14 | ResType = TypeVar("ResType") 15 | 16 | 17 | class CallbackQueryHandler(EventHandler): 18 | def __init__( 19 | self, 20 | callback: HandlerCallback[BotContext[CallbackQueryEvent], ResType], 21 | filter: Optional[Filter] = None, 22 | **kwargs, 23 | ): 24 | super().__init__(EventType.CALLBACK_QUERY, callback, filter, **kwargs) 25 | 26 | async def should_handle(self, context: BotContext[CallbackQueryEvent]) -> bool: 27 | return ( 28 | await super().should_handle(context) 29 | and context.event.callback_data is not None 30 | and context.event.message is not None 31 | ) 32 | -------------------------------------------------------------------------------- /swibots/bots/handlers/channel_created_handler.py: -------------------------------------------------------------------------------- 1 | from typing import TYPE_CHECKING, Optional, TypeVar 2 | from swibots.api.community.events import ChannelCreatedEvent 3 | from swibots.bots.filters import Filter 4 | 5 | from swibots.bots import BotContext 6 | from .event_handler import EventHandler 7 | from swibots.types import EventType 8 | from swibots.utils.types import HandlerCallback 9 | 10 | 11 | ResType = TypeVar("ResType") 12 | 13 | 14 | class ChannelCreatedHandler(EventHandler): 15 | def __init__( 16 | self, 17 | callback: HandlerCallback[BotContext[ChannelCreatedEvent], ResType], 18 | filter: Optional[Filter] = None, 19 | **kwargs, 20 | ): 21 | super().__init__(EventType.COMMUNITY_CHANNEL_CREATE, callback, filter, **kwargs) 22 | -------------------------------------------------------------------------------- /swibots/bots/handlers/channel_deleted_handler.py: -------------------------------------------------------------------------------- 1 | from typing import TYPE_CHECKING, Optional, TypeVar 2 | from swibots.api.community.events import ChannelDeletedEvent 3 | from swibots.bots.filters.filter import Filter 4 | 5 | from swibots.bots import BotContext 6 | from .event_handler import EventHandler 7 | from swibots.types import EventType 8 | from swibots.utils.types import HandlerCallback 9 | 10 | if TYPE_CHECKING: 11 | pass 12 | 13 | ResType = TypeVar("ResType") 14 | 15 | 16 | class ChannelDeletedHandler(EventHandler): 17 | def __init__( 18 | self, 19 | callback: HandlerCallback[BotContext[ChannelDeletedEvent], ResType], 20 | filter: Optional[Filter] = None, 21 | **kwargs, 22 | ): 23 | super().__init__(EventType.COMMUNITY_CHANNEL_DELETE, callback, filter, **kwargs) 24 | -------------------------------------------------------------------------------- /swibots/bots/handlers/channel_updated_handler.py: -------------------------------------------------------------------------------- 1 | from typing import TYPE_CHECKING, Optional, TypeVar 2 | from swibots.api.community.events import ChannelUpdatedEvent 3 | from swibots.bots.filters.filter import Filter 4 | 5 | from swibots.bots.handlers import BaseHandler 6 | from swibots.bots import BotContext 7 | from .event_handler import EventHandler 8 | from swibots.types import EventType 9 | from swibots.utils.types import HandlerCallback 10 | 11 | if TYPE_CHECKING: 12 | pass 13 | 14 | ResType = TypeVar("ResType") 15 | 16 | 17 | class ChannelUpdatedHandler(EventHandler): 18 | def __init__( 19 | self, 20 | callback: HandlerCallback[BotContext[ChannelUpdatedEvent], ResType], 21 | filter: Optional[Filter] = None, 22 | **kwargs, 23 | ): 24 | super().__init__(EventType.COMMUNITY_CHANNEL_UPDATE, callback, filter, **kwargs) 25 | -------------------------------------------------------------------------------- /swibots/bots/handlers/community_updated_handler.py: -------------------------------------------------------------------------------- 1 | from typing import TYPE_CHECKING, Optional, TypeVar 2 | from swibots.api.community.events import CommunityUpdatedEvent 3 | from swibots.bots.filters.filter import Filter 4 | 5 | from swibots.bots import BotContext 6 | from .event_handler import EventHandler 7 | from swibots.types import EventType 8 | from swibots.utils.types import HandlerCallback 9 | 10 | ResType = TypeVar("ResType") 11 | 12 | 13 | class CommunityUpdatedHandler(EventHandler): 14 | def __init__( 15 | self, 16 | callback: HandlerCallback[BotContext[CommunityUpdatedEvent], ResType], 17 | filter: Optional[Filter] = None, 18 | **kwargs, 19 | ): 20 | super().__init__(EventType.COMMUNITY_UPDATE, callback, filter, **kwargs) 21 | -------------------------------------------------------------------------------- /swibots/bots/handlers/group_created_handler.py: -------------------------------------------------------------------------------- 1 | from typing import TYPE_CHECKING, Optional, TypeVar 2 | from swibots.api.community.events import GroupCreatedEvent 3 | from swibots.bots.filters.filter import Filter 4 | 5 | from swibots.bots import BotContext 6 | from .event_handler import EventHandler 7 | from swibots.types import EventType 8 | from swibots.utils.types import HandlerCallback 9 | 10 | if TYPE_CHECKING: 11 | pass 12 | 13 | ResType = TypeVar("ResType") 14 | 15 | 16 | class GroupCreatedHandler(EventHandler): 17 | def __init__( 18 | self, 19 | callback: HandlerCallback[BotContext[GroupCreatedEvent], ResType], 20 | filter: Optional[Filter] = None, 21 | **kwargs, 22 | ): 23 | super().__init__(EventType.COMMUNITY_GROUP_CREATE, callback, filter, **kwargs) 24 | -------------------------------------------------------------------------------- /swibots/bots/handlers/group_deleted_handler.py: -------------------------------------------------------------------------------- 1 | from typing import TYPE_CHECKING, Optional, TypeVar 2 | from swibots.api.chat.events import MessageEvent 3 | from swibots.api.community.events import GroupDeletedEvent 4 | from swibots.bots.filters.filter import Filter 5 | 6 | from swibots.bots.handlers import BaseHandler 7 | from swibots.bots import BotContext 8 | from .event_handler import EventHandler 9 | from swibots.types import EventType 10 | from swibots.utils.types import HandlerCallback 11 | 12 | if TYPE_CHECKING: 13 | pass 14 | 15 | ResType = TypeVar("ResType") 16 | 17 | 18 | class GroupDeletedHandler(EventHandler): 19 | def __init__( 20 | self, 21 | callback: HandlerCallback[BotContext[GroupDeletedEvent], ResType], 22 | filter: Optional[Filter] = None, 23 | **kwargs, 24 | ): 25 | super().__init__(EventType.COMMUNITY_GROUP_DELETE, callback, filter, **kwargs) 26 | -------------------------------------------------------------------------------- /swibots/bots/handlers/group_updated_handler.py: -------------------------------------------------------------------------------- 1 | from typing import TYPE_CHECKING, Optional, TypeVar 2 | from swibots.api.chat.events import MessageEvent 3 | from swibots.api.community.events import GroupUpdatedEvent 4 | from swibots.bots.filters.filter import Filter 5 | 6 | from swibots.bots.handlers import BaseHandler 7 | from swibots.bots import BotContext 8 | from .event_handler import EventHandler 9 | from swibots.types import EventType 10 | from swibots.utils.types import HandlerCallback 11 | 12 | if TYPE_CHECKING: 13 | pass 14 | 15 | ResType = TypeVar("ResType") 16 | 17 | 18 | class GroupUpdatedHandler(EventHandler): 19 | def __init__( 20 | self, 21 | callback: HandlerCallback[BotContext[GroupUpdatedEvent], ResType], 22 | filter: Optional[Filter] = None, 23 | **kwargs, 24 | ): 25 | super().__init__(EventType.COMMUNITY_GROUP_UPDATE, callback, filter, **kwargs) 26 | -------------------------------------------------------------------------------- /swibots/bots/handlers/inline_query_handler.py: -------------------------------------------------------------------------------- 1 | from typing import TYPE_CHECKING, Optional, TypeVar 2 | from swibots.api.chat.events import InlineQueryEvent 3 | from swibots.bots.filters.filter import Filter 4 | 5 | from swibots.bots.handlers import BaseHandler 6 | from swibots.bots import BotContext 7 | from .event_handler import EventHandler 8 | from swibots.types import EventType 9 | from swibots.utils.types import HandlerCallback 10 | 11 | if TYPE_CHECKING: 12 | pass 13 | 14 | ResType = TypeVar("ResType") 15 | 16 | 17 | class InlineQueryHandler(EventHandler): 18 | def __init__( 19 | self, 20 | callback: HandlerCallback[BotContext[InlineQueryEvent], ResType], 21 | filter: Optional[Filter] = None, 22 | **kwargs, 23 | ): 24 | super().__init__(EventType.INLINE_QUERY, callback, filter, **kwargs) 25 | 26 | async def should_handle(self, context: BotContext[InlineQueryEvent]) -> bool: 27 | return await super().should_handle(context) 28 | -------------------------------------------------------------------------------- /swibots/bots/handlers/member_joined_handler.py: -------------------------------------------------------------------------------- 1 | from typing import TYPE_CHECKING, Optional, TypeVar 2 | from swibots.api.community.events import MemberJoinedEvent 3 | from swibots.bots.filters.filter import Filter 4 | 5 | from swibots.bots import BotContext 6 | from .event_handler import EventHandler 7 | from swibots.types import EventType 8 | from swibots.utils.types import HandlerCallback 9 | 10 | if TYPE_CHECKING: 11 | pass 12 | 13 | ResType = TypeVar("ResType") 14 | 15 | 16 | class MemberJoinedHandler(EventHandler): 17 | def __init__( 18 | self, 19 | callback: HandlerCallback[BotContext[MemberJoinedEvent], ResType], 20 | filter: Optional[Filter] = None, 21 | **kwargs, 22 | ): 23 | super().__init__(EventType.COMMUNITY_MEMBER_JOIN, callback, filter, **kwargs) 24 | -------------------------------------------------------------------------------- /swibots/bots/handlers/member_left_handler.py: -------------------------------------------------------------------------------- 1 | from typing import TYPE_CHECKING, Optional, TypeVar 2 | from swibots.api.community.events import MemberLeftEvent 3 | from swibots.bots.filters.filter import Filter 4 | 5 | from swibots.bots import BotContext 6 | from .event_handler import EventHandler 7 | from swibots.types import EventType 8 | from swibots.utils.types import HandlerCallback 9 | 10 | if TYPE_CHECKING: 11 | pass 12 | 13 | ResType = TypeVar("ResType") 14 | 15 | 16 | class MemberLeftHandler(EventHandler): 17 | def __init__( 18 | self, 19 | callback: HandlerCallback[BotContext[MemberLeftEvent], ResType], 20 | filter: Optional[Filter] = None, 21 | **kwargs, 22 | ): 23 | super().__init__(EventType.COMMUNITY_MEMBER_LEAVE, callback, filter, **kwargs) 24 | -------------------------------------------------------------------------------- /swibots/bots/handlers/message_handler.py: -------------------------------------------------------------------------------- 1 | from typing import TYPE_CHECKING, Optional, TypeVar 2 | from swibots.api.chat.events import MessageEvent 3 | from swibots.bots.filters.filter import Filter 4 | 5 | from swibots.bots.handlers import BaseHandler 6 | from swibots.bots import BotContext 7 | from .event_handler import EventHandler 8 | from swibots.types import EventType 9 | from swibots.utils.types import HandlerCallback 10 | 11 | if TYPE_CHECKING: 12 | pass 13 | 14 | ResType = TypeVar("ResType") 15 | 16 | 17 | class MessageHandler(EventHandler): 18 | def __init__( 19 | self, 20 | callback: HandlerCallback[BotContext[MessageEvent], ResType], 21 | filter: Optional[Filter] = None, 22 | outgoing: bool = False, 23 | **kwargs, 24 | ): 25 | self._outgoing = outgoing 26 | super().__init__(EventType.MESSAGE, callback, filter, **kwargs) 27 | 28 | async def should_handle(self, context: BotContext[MessageEvent]) -> bool: 29 | if self._outgoing and not context.event.message.outgoing: 30 | return 31 | return ( 32 | await super().should_handle(context) and context.event.message is not None 33 | ) 34 | -------------------------------------------------------------------------------- /swibots/bots/handlers/unknown_command_handler.py: -------------------------------------------------------------------------------- 1 | import re 2 | from typing import TYPE_CHECKING, Any, Optional, TypeVar 3 | from swibots.bots.filters.filter import Filter 4 | from swibots.types import EventType 5 | 6 | from swibots.utils.types import SCT, HandlerCallback 7 | from swibots.bots.handlers.base_handler import BaseHandler 8 | from swibots.bots.bot_context import BotContext 9 | 10 | if TYPE_CHECKING: 11 | pass 12 | 13 | ResType = TypeVar("ResType") 14 | 15 | 16 | class UnknownCommandHandler(BaseHandler): 17 | def __init__( 18 | self, 19 | callback: HandlerCallback[BotContext[Any], ResType], 20 | filter: Optional[Filter] = None, 21 | **kwargs, 22 | ): 23 | super().__init__(callback, filter, **kwargs) 24 | 25 | async def should_handle(self, context: BotContext[Any]) -> bool: 26 | if ( 27 | context.event.type == EventType.COMMAND 28 | and context.event.message is not None 29 | ): 30 | return True 31 | return False 32 | -------------------------------------------------------------------------------- /swibots/bots/handlers/user_banned_handler.py: -------------------------------------------------------------------------------- 1 | from typing import TYPE_CHECKING, Optional, TypeVar 2 | from swibots.api.community.events import UserBannedEvent 3 | from swibots.bots.filters.filter import Filter 4 | 5 | from swibots.bots import BotContext 6 | from .event_handler import EventHandler 7 | from swibots.types import EventType 8 | from swibots.utils.types import HandlerCallback 9 | 10 | if TYPE_CHECKING: 11 | pass 12 | 13 | ResType = TypeVar("ResType") 14 | 15 | 16 | class UserBannedHandler(EventHandler): 17 | def __init__( 18 | self, 19 | callback: HandlerCallback[BotContext[UserBannedEvent], ResType], 20 | filter: Optional[Filter] = None, 21 | **kwargs, 22 | ): 23 | super().__init__(EventType.COMMUNITY_USER_BAN, callback, filter, **kwargs) 24 | -------------------------------------------------------------------------------- /swibots/responses.py: -------------------------------------------------------------------------------- 1 | from typing import List, Optional 2 | from .base.switch_object import SwitchObject 3 | from .api.community.models import QuestCategory, Quest 4 | from .utils.types import JSONDict 5 | 6 | 7 | class CommunityQuestResponse(SwitchObject): 8 | def __init__( 9 | self, categories: List[QuestCategory] = None, quests: List[Quest] = None 10 | ): 11 | super().__init__() 12 | self.categories = categories 13 | self.quests = quests 14 | 15 | def from_json(self, data: JSONDict = None) -> "CommunityQuestResponse": 16 | if data is not None: 17 | self.quests = [ 18 | QuestCategory.build_from_json(quest) for quest in data.get("quests") 19 | ] 20 | self.categories = [ 21 | QuestCategory.build_from_json(category) 22 | for category in data.get("availableCategories") 23 | ] 24 | return self 25 | -------------------------------------------------------------------------------- /swibots/utils/__init__.py: -------------------------------------------------------------------------------- 1 | from .rest_client import RestClient 2 | from .ws import * 3 | from .types import * 4 | from urllib.parse import urlparse 5 | 6 | 7 | def isUrl(text): 8 | """Validate, if text is url.""" 9 | parse = urlparse(text) 10 | return parse.netloc and parse.scheme 11 | -------------------------------------------------------------------------------- /swibots/utils/ws/__init__.py: -------------------------------------------------------------------------------- 1 | from .asyncstomp import * 2 | from .common import * 3 | -------------------------------------------------------------------------------- /swibots/utils/ws/asyncstomp/__init__.py: -------------------------------------------------------------------------------- 1 | from .async_ws_client import AsyncWsClient 2 | from .async_ws_subscription import AsyncWsSubscription 3 | 4 | __all__ = ["AsyncWsClient", "AsyncWsSubscription"] 5 | -------------------------------------------------------------------------------- /swibots/utils/ws/asyncstomp/async_ws_subscription.py: -------------------------------------------------------------------------------- 1 | from typing import Dict 2 | from swibots.utils.ws.common import WsMessage 3 | 4 | 5 | class AsyncWsSubscription: 6 | def __init__( 7 | self, 8 | client, 9 | destination: str, 10 | sub_id: str, 11 | headers: Dict[str, str] = None, 12 | callback=None, 13 | ): 14 | from .async_ws_client import AsyncWsClient 15 | 16 | self.client: AsyncWsClient = client 17 | self.destination = destination 18 | self.callback = callback 19 | self.sub_id = sub_id 20 | self.headers = headers or {} 21 | 22 | async def start(self): 23 | self.headers["id"] = self.sub_id 24 | self.headers["destination"] = self.destination 25 | await self.client.transmit("SUBSCRIBE", self.headers) 26 | 27 | async def receive(self, message): 28 | if self.callback is not None: 29 | await self.callback(WsMessage(message)) 30 | 31 | async def send(self, body: str, headers: Dict[str, str] = None): 32 | await self.client.send(self.destination, headers or {}, body) 33 | 34 | async def unsubscribe(self): 35 | await self.client.unsubscribe(self.sub_id) 36 | -------------------------------------------------------------------------------- /swibots/utils/ws/common/__init__.py: -------------------------------------------------------------------------------- 1 | from .ws_frame import WsFrame 2 | from .ws_message import WsMessage 3 | 4 | __all__ = ["WsMessage", "WsFrame"] 5 | -------------------------------------------------------------------------------- /swibots/utils/ws/common/ws_message.py: -------------------------------------------------------------------------------- 1 | class WsMessage: 2 | def __init__(self, raw): 3 | self.raw = raw 4 | self.headers = raw.headers 5 | self.body = raw.body 6 | self.command = raw.command 7 | self.destination = raw.headers.get("destination") 8 | self.subscription = raw.headers.get("subscription") 9 | self.message_id = raw.headers.get("message-id") 10 | self.ack = raw.headers.get("ack") 11 | self.nack = raw.headers.get("nack") 12 | --------------------------------------------------------------------------------