├── .env-example
├── .gitignore
├── Dockerfile
├── LICENSE
├── README-RU.md
├── README.md
├── bot
├── __init__.py
├── config
│ ├── __init__.py
│ ├── config.py
│ └── youtube_tasks.py
├── core
│ ├── __init__.py
│ ├── agents.py
│ ├── headers.py
│ ├── registrator.py
│ ├── tapper.py
│ ├── tg_manager.cp310-win_amd64.pyd
│ ├── tg_manager.cpython-310-darwin.so
│ └── tg_manager.cpython-310-x86_64-linux-gnu.so
├── exceptions
│ └── __init__.py
└── utils
│ ├── __init__.py
│ ├── accounts.py
│ ├── file_manager.py
│ ├── launcher.py
│ ├── logger.py
│ └── tg_manager
│ ├── PyrogramSession.cp310-win_amd64.pyd
│ ├── PyrogramSession.cpython-310-darwin.so
│ ├── PyrogramSession.cpython-310-x86_64-linux-gnu.so
│ ├── TGSession.cp310-win_amd64.pyd
│ ├── TGSession.cpython-310-darwin.so
│ ├── TGSession.cpython-310-x86_64-linux-gnu.so
│ ├── TelethonSession.cp310-win_amd64.pyd
│ ├── TelethonSession.cpython-310-darwin.so
│ └── TelethonSession.cpython-310-x86_64-linux-gnu.so
├── cats
├── cat.jpg
├── cat2.jpg
├── cat3.jpg
└── cat4.jpg
├── docker-compose.yml
├── main.py
├── requirements.txt
├── run.bat
└── run.sh
/.env-example:
--------------------------------------------------------------------------------
1 | API_ID=
2 | API_HASH=
3 |
4 |
5 | SLEEP_TIME=
6 | START_DELAY=
7 | AUTO_TASK=
8 | JOIN_TG_CHANNELS=
9 | AVATAR_TASK=
10 | REF_ID=
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .env
2 |
3 | sessions/
4 |
5 | .idea/
6 |
7 | __pycache__
8 |
9 | *.session
10 |
11 | *.cpython-310.pyc
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.10.11-alpine3.18
2 |
3 | WORKDIR app/
4 |
5 | COPY requirements.txt requirements.txt
6 |
7 | RUN pip3 install --upgrade pip setuptools wheel
8 | RUN pip3 install --no-warn-script-location --no-cache-dir -r requirements.txt
9 |
10 | COPY . .
11 |
12 | CMD ["python3", "main.py", "-a", "1"]
13 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README-RU.md:
--------------------------------------------------------------------------------
1 | [](https://t.me/catsgang_bot/join?startapp=IRJ3Ytoz3Cmi8Gac-BXFO)
2 |
3 | ## Рекомендация перед использованием
4 |
5 | # 🔥🔥 Используйте PYTHON 3.10 🔥🔥
6 |
7 | > 🇪🇳 README in english available [here](README.md)
8 |
9 | ## Функционал
10 | | Функционал | Поддерживается |
11 | |--------------------------------------------------|:--------------:|
12 | | Многопоточность | ✅ |
13 | | Поддержка pyrogram .session / telethon .session | ✅ |
14 | | Привязка прокси к сессии | ✅ |
15 | | Привязка User-Agent к сессии | ✅ |
16 | | Авторегистрация в боте | ✅ |
17 | | Авто выполнение заданий | ✅ |
18 |
19 |
20 |
21 | ## [Настройки](https://github.com/Desamod/CatsGangBot/blob/master/.env-example/)
22 | | Настройка | Описание |
23 | |-------------------------|:----------------------------------------------------------:|
24 | | **API_ID / API_HASH** | Данные платформы, с которой запускать сессию Telegram |
25 | | **SLEEP_TIME** | Время сна между циклами (по умолчанию - [7200, 10800]) |
26 | | **START_DELAY** | Задержка между сессиями на старте (по умолчанию - [5, 25]) |
27 | | **AUTO_TASK** | Автовыполнение тасок (по умолчанию - True) |
28 | | **JOIN_CHANNELS** | Авто-подписка на ТГ каналы из тасок (по умолчанию - False) |
29 | | **REF_ID** | Реф. ссылка для регистрации в боте |
30 |
31 | ## Быстрый старт 📚
32 |
33 | Для быстрой установки и последующего запуска - запустите файл run.bat на Windows или run.sh на Линукс
34 |
35 | ## Предварительные условия
36 | Прежде чем начать, убедитесь, что у вас установлено следующее:
37 | - [Python](https://www.python.org/downloads/) **версии 3.10**
38 |
39 | ## Получение API ключей
40 | 1. Перейдите на сайт [my.telegram.org](https://my.telegram.org) и войдите в систему, используя свой номер телефона.
41 | 2. Выберите **"API development tools"** и заполните форму для регистрации нового приложения.
42 | 3. Запишите `API_ID` и `API_HASH` в файле `.env`, предоставленные после регистрации вашего приложения.
43 |
44 | ## Установка
45 | Вы можете скачать [**Репозиторий**](https://github.com/Desamod/CatsGangBot) клонированием на вашу систему и установкой необходимых зависимостей:
46 | ```shell
47 | git clone https://github.com/Desamod/CatsGangBot
48 | cd CatsGangBot
49 | ```
50 |
51 | Затем для автоматической установки введите:
52 |
53 | Windows:
54 | ```shell
55 | run.bat
56 | ```
57 |
58 | Linux:
59 | ```shell
60 | run.sh
61 | ```
62 |
63 | # Linux ручная установка
64 | ```shell
65 | python3 -m venv venv
66 | source venv/bin/activate
67 | pip3 install -r requirements.txt
68 | cp .env-example .env
69 | nano .env # Здесь вы обязательно должны указать ваши API_ID и API_HASH , остальное берется по умолчанию
70 | python3 main.py
71 | ```
72 |
73 | Также для быстрого запуска вы можете использовать аргументы, например:
74 | ```shell
75 | ~/CatsGangBot >>> python3 main.py --action (1/2)
76 | # Or
77 | ~/CatsGangBot >>> python3 main.py -a (1/2)
78 |
79 | # 1 - Запускает кликер
80 | # 2 - Создает сессию
81 | ```
82 |
83 | # Windows ручная установка
84 | ```shell
85 | python -m venv venv
86 | venv\Scripts\activate
87 | pip install -r requirements.txt
88 | copy .env-example .env
89 | # Указываете ваши API_ID и API_HASH, остальное берется по умолчанию
90 | python main.py
91 | ```
92 |
93 | Также для быстрого запуска вы можете использовать аргументы, например:
94 | ```shell
95 | ~/CatsGangBot >>> python main.py --action (1/2)
96 | # Или
97 | ~/CatsGangBot >>> python main.py -a (1/2)
98 |
99 | # 1 - Запускает кликер
100 | # 2 - Создает сессию
101 | ```
102 | ### Использование
103 | При первом запуске бота создайте для него сессию с помощью команды «2». В процессе будет создана папка 'sessions', в которой хранятся все сессии, а также файл accounts.json с конфигурациями.
104 | Если у вас уже есть сессии (pyrogram / telethon), просто поместите их в папку 'sessions' и запустите кликер. В процессе запуска вы сможете настроить использование прокси для каждой сессии.
105 | Юзер-агент создается для каждого аккаунта автоматически.
106 |
107 | Пример того, как должен выглядеть accounts.json:
108 | ```shell
109 | [
110 | {
111 | "session_name": "name_example",
112 | "user_agent": "Mozilla/5.0 (Linux; Android 14) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.165 Mobile Safari/537.36",
113 | "proxy": "type://user:pass:ip:port" # "proxy": "" - если прокси не используется
114 | }
115 | ]
116 | ```
117 |
118 | ### Контакты
119 |
120 | Для поддержки или вопросов, вы можете связаться со мной
121 |
122 | [](https://t.me/desforge_cryptwo)
123 |
124 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://t.me/catsgang_bot/join?startapp=IRJ3Ytoz3Cmi8Gac-BXFO)
2 |
3 | ## Recommendation before use
4 |
5 | # 🔥🔥 Use PYTHON 3.10 🔥🔥
6 |
7 | > 🇷 🇺 README in russian available [here](README-RU.md)
8 |
9 | ## Features
10 | | Feature | Supported |
11 | |----------------------------------------------------|:---------:|
12 | | Multithreading | ✅ |
13 | | Proxy binding to session | ✅ |
14 | | User-Agent binding to session | ✅ |
15 | | Support for pyrogram .session / telethon .session | ✅ |
16 | | Registration in bot | ✅ |
17 | | Auto-tasks | ✅ |
18 | | Daily rewards | ✅ |
19 |
20 |
21 |
22 | ## [Settings](https://github.com/Desamod/CatsGangBot/blob/master/.env-example/)
23 | | Settings | Description |
24 | |-------------------------|:---------------------------------------------------------------------------:|
25 | | **API_ID / API_HASH** | Platform data from which to run the Telegram session (by default - android) |
26 | | **SLEEP_TIME** | Sleep time between cycles (by default - [7200, 10800]) |
27 | | **START_DELAY** | Delay between sessions at start (by default - [5, 25]) |
28 | | **AUTO_TASK** | Auto tasks (default - True) |
29 | | **JOIN_CHANNELS** | Auto-join for tg channels tasks (default - False) |
30 | | **REF_ID** | Ref link for registration |
31 |
32 | ## Quick Start 📚
33 |
34 | To fast install libraries and run bot - open run.bat on Windows or run.sh on Linux
35 |
36 | ## Prerequisites
37 | Before you begin, make sure you have the following installed:
38 | - [Python](https://www.python.org/downloads/) **version 3.10**
39 |
40 | ## Obtaining API Keys
41 | 1. Go to my.telegram.org and log in using your phone number.
42 | 2. Select "API development tools" and fill out the form to register a new application.
43 | 3. Record the API_ID and API_HASH provided after registering your application in the .env file.
44 |
45 | ## Installation
46 | You can download the [**repository**](https://github.com/Desamod/CatsGangBot) by cloning it to your system and installing the necessary dependencies:
47 | ```shell
48 | git clone https://github.com/Desamod/CatsGangBot
49 | cd CatsGangBot
50 | ```
51 |
52 | Then you can do automatic installation by typing:
53 |
54 | Windows:
55 | ```shell
56 | run.bat
57 | ```
58 |
59 | Linux:
60 | ```shell
61 | run.sh
62 | ```
63 |
64 | # Linux manual installation
65 | ```shell
66 | python3 -m venv venv
67 | source venv/bin/activate
68 | pip3 install -r requirements.txt
69 | cp .env-example .env
70 | nano .env # Here you must specify your API_ID and API_HASH, the rest is taken by default
71 | python3 main.py
72 | ```
73 |
74 | You can also use arguments for quick start, for example:
75 | ```shell
76 | ~/CatsGangBot >>> python3 main.py --action (1/2)
77 | # Or
78 | ~/CatsGangBot >>> python3 main.py -a (1/2)
79 |
80 | # 1 - Run clicker
81 | # 2 - Creates a session
82 | ```
83 |
84 | # Windows manual installation
85 | ```shell
86 | python -m venv venv
87 | venv\Scripts\activate
88 | pip install -r requirements.txt
89 | copy .env-example .env
90 | # Here you must specify your API_ID and API_HASH, the rest is taken by default
91 | python main.py
92 | ```
93 |
94 | You can also use arguments for quick start, for example:
95 | ```shell
96 | ~/CatsGangBot >>> python main.py --action (1/2)
97 | # Or
98 | ~/CatsGangBot >>> python main.py -a (1/2)
99 |
100 | # 1 - Run clicker
101 | # 2 - Creates a session
102 | ```
103 |
104 | ### Usages
105 | When you first launch the bot, create a session for it using the 'Creates a session' command. It will create a 'sessions' folder in which all accounts will be stored, as well as a file accounts.json with configurations.
106 | If you already have sessions (pyrogram / telethon), simply place them in a folder 'sessions' and run the clicker. During the startup process you will be able to configure the use of a proxy for each session.
107 | User-Agent is created automatically for each account.
108 |
109 | Here is an example of what accounts.json should look like:
110 | ```shell
111 | [
112 | {
113 | "session_name": "name_example",
114 | "user_agent": "Mozilla/5.0 (Linux; Android 14) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.165 Mobile Safari/537.36",
115 | "proxy": "type://user:pass:ip:port" # "proxy": "" - if you dont use proxy
116 | }
117 | ]
118 | ```
119 |
120 | ### Contacts
121 |
122 | For support or questions, you can contact me
123 |
124 | [](https://t.me/desforge_cryptwo)
125 |
126 |
127 |
128 |
--------------------------------------------------------------------------------
/bot/__init__.py:
--------------------------------------------------------------------------------
1 | __version__ = '1.0'
2 |
--------------------------------------------------------------------------------
/bot/config/__init__.py:
--------------------------------------------------------------------------------
1 | from .config import settings
2 |
--------------------------------------------------------------------------------
/bot/config/config.py:
--------------------------------------------------------------------------------
1 | from pydantic_settings import BaseSettings, SettingsConfigDict
2 |
3 |
4 | class Settings(BaseSettings):
5 | model_config = SettingsConfigDict(env_file=".env", env_ignore_empty=True)
6 |
7 | API_ID: int
8 | API_HASH: str
9 |
10 | SLEEP_TIME: list[int] = [7200, 10800]
11 | START_DELAY: list[int] = [5, 25]
12 | AUTO_TASK: bool = True
13 | JOIN_TG_CHANNELS: bool = False
14 | AVATAR_TASK: bool = True
15 | CATS_PATH: str = 'cats'
16 | REF_ID: str = 'IRJ3Ytoz3Cmi8Gac-BXFO'
17 | DISABLED_TASKS: list[str] = ['INVITE_FRIENDS', 'TON_TRANSACTION', 'BOOST_CHANNEL', 'ACTIVITY_CHALLENGE', 'CONNECT_WALLET']
18 |
19 |
20 | settings = Settings()
21 |
--------------------------------------------------------------------------------
/bot/config/youtube_tasks.py:
--------------------------------------------------------------------------------
1 | YOUTUBE_TASKS: dict[str, str] = {
2 | "Boost Your Cats Earnings!": 'dildo',
3 | "Futures Trading PART 1": 'AIRNODE',
4 | "Futures Trading PART 2": 'WEI',
5 | "FREE Crypto": 'dip',
6 | "How To Make 10x On Crypto": 'ABSTRACT',
7 | "How To Make 10x On Crypto PART 2": 'AUCTION',
8 | "How To Make 10x On Crypto PART 3": 'AUDIT',
9 | "Earn $1000 Just by Listening To Music!": 'BAG',
10 | "Make Money Online For Free": 'AFFILIATE',
11 | "GET RICH NOW": 'BAKERS',
12 | "How to Stay Productive": 'ALTCOIN',
13 | "Start From ZERO": 'ALPHA',
14 | "Productivity Tips!": 'BAKING',
15 | "Make $100,000 in 6 Months": 'MAINNET',
16 | "Easy Crypto Airdrops": 'MARKET',
17 | "Job Without a Degree ": 'LAMBO',
18 | "Learned to Code !": 'LEDGER',
19 | "Pinterest Affiliate Marketing ": 'BITSTREAM',
20 | "GET FREE MONEY NOW!": 'OPTION',
21 | "Start Earning Now!": 'BOTS',
22 | "EARN $30 PER WORD": 'BLOCK',
23 | "Make $5,000+ Per MONTH": 'BITCOINER',
24 | "Amazon Success!": 'OPTION',
25 | "Top Shocking Ways": 'ASSET',
26 | "Change Your Life!": 'BOUNTY',
27 | "FREE Money From Rich People!": 'BASKET',
28 | "BLOCKCHAIN TIPS": 'BRIDGES',
29 | "Earn on YouTube Anonymously!": 'CIPHER',
30 | "Maximize Your Savings ": 'DUMPING',
31 | "Make Money on YouTube!": 'CHARGEBACK',
32 | "Earn Cash Back": 'CRYPTOJACKING',
33 | "Save Money on Shopping": 'COORDINATOR',
34 | "Sell Your Photos Online": 'CONSENSUS',
35 | "How to Reupload Free Videos?": 'CASH',
36 | "BUSINESS WITH 100$": 'CRYPTOLOGY',
37 | "EARN FROM HOME": 'CRYPTOJACKING',
38 | "PASSIVE INCOME": 'CRYPTOGRAPHY',
39 | "Small Business Ideas!!": 'CRYPTOASSET',
40 | "Videos Legally for YouTube Profit": 'CUSTODIAN',
41 | "Money on YouTube": 'DEFLATION',
42 | "How Blockchain ACTUALLY Work": 'DIGITAL',
43 | "Earn Money with Amazon!!!": 'DIFFICULTY',
44 | "Legally Reupload Videos": 'CRYPTOLOGY',
45 | "Earn Online by Reuploading": 'CURRENCY',
46 | "Blockchain Demystified": 'DRIVECHAIN',
47 | "Amazon Success": 'DEFI',
48 | "Protect Your Investments!": 'DUMP',
49 | "Avoid Losing Money": 'CROWDLOAN',
50 | "CRYPTO SCAMS": 'CORRECTION',
51 | "Reupload FREE videos": 'CRYPTOLOGY',
52 | "EARN Money!": 'CURRENCY',
53 | "YouTube Niches for Earning Big!": "DELISTING"
54 | }
55 |
56 |
--------------------------------------------------------------------------------
/bot/core/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Desamod/CatsGangBot/727358b283daa514d25ee11188ab47f1ed9a5296/bot/core/__init__.py
--------------------------------------------------------------------------------
/bot/core/agents.py:
--------------------------------------------------------------------------------
1 | import random
2 | import re
3 |
4 | existing_versions = {
5 | 116: [
6 | '116.0.5845.172',
7 | '116.0.5845.164',
8 | '116.0.5845.163',
9 | '116.0.5845.114',
10 | '116.0.5845.92'
11 | ],
12 | 117: [
13 | '117.0.5938.154',
14 | '117.0.5938.141',
15 | '117.0.5938.140',
16 | '117.0.5938.61',
17 | '117.0.5938.61',
18 | '117.0.5938.60'
19 | ],
20 | 118: [
21 | '118.0.5993.112',
22 | '118.0.5993.111',
23 | '118.0.5993.80',
24 | '118.0.5993.65',
25 | '118.0.5993.48'
26 | ],
27 | 119: [
28 | '119.0.6045.194',
29 | '119.0.6045.193',
30 | '119.0.6045.164',
31 | '119.0.6045.163',
32 | '119.0.6045.134',
33 | '119.0.6045.134',
34 | '119.0.6045.66',
35 | '119.0.6045.53'
36 | ],
37 | 120: [
38 | '120.0.6099.230',
39 | '120.0.6099.210',
40 | '120.0.6099.194',
41 | '120.0.6099.193',
42 | '120.0.6099.145',
43 | '120.0.6099.144',
44 | '120.0.6099.144',
45 | '120.0.6099.116',
46 | '120.0.6099.116',
47 | '120.0.6099.115',
48 | '120.0.6099.44',
49 | '120.0.6099.43'
50 | ],
51 | 121: [
52 | '121.0.6167.178',
53 | '121.0.6167.165',
54 | '121.0.6167.164',
55 | '121.0.6167.164',
56 | '121.0.6167.144',
57 | '121.0.6167.143',
58 | '121.0.6167.101'
59 | ],
60 | 122: [
61 | '122.0.6261.119',
62 | '122.0.6261.106',
63 | '122.0.6261.105',
64 | '122.0.6261.91',
65 | '122.0.6261.90',
66 | '122.0.6261.64',
67 | '122.0.6261.43'
68 | ],
69 | 123: [
70 | '123.0.6312.121',
71 | '123.0.6312.120',
72 | '123.0.6312.119',
73 | '123.0.6312.118',
74 | '123.0.6312.99',
75 | '123.0.6312.80',
76 | '123.0.6312.41',
77 | '123.0.6312.40'
78 | ],
79 | 124: [
80 | '124.0.6367.179',
81 | '124.0.6367.172',
82 | '124.0.6367.171',
83 | '124.0.6367.114',
84 | '124.0.6367.113',
85 | '124.0.6367.83',
86 | '124.0.6367.82',
87 | '124.0.6367.54'
88 | ],
89 | 125: [
90 | '125.0.6422.165',
91 | '125.0.6422.164',
92 | '125.0.6422.147',
93 | '125.0.6422.146',
94 | '125.0.6422.113',
95 | '125.0.6422.72',
96 | '125.0.6422.72',
97 | '125.0.6422.53',
98 | '125.0.6422.52'
99 | ],
100 | 126: [
101 | '126.0.6478.122',
102 | '126.0.6478.72',
103 | '126.0.6478.71',
104 | '126.0.6478.50'
105 | ],
106 | 130: [
107 | "130.0.6669.0",
108 | "130.0.6669.1",
109 | "130.0.6669.2",
110 | "130.0.6670.0",
111 | "130.0.6674.2",
112 | "130.0.6675.0",
113 | "130.0.6675.1",
114 | "130.0.6676.0",
115 | "130.0.6676.1",
116 | "130.0.6677.0",
117 | "130.0.6677.1",
118 | "130.0.6677.2",
119 | "130.0.6678.0",
120 | "130.0.6678.1",
121 | "130.0.6679.0",
122 | "130.0.6679.1",
123 | "130.0.6679.2",
124 | "130.0.6679.3",
125 | "130.0.6680.0",
126 | "130.0.6680.1",
127 | "130.0.6680.2",
128 | "130.0.6681.0",
129 | "130.0.6681.1",
130 | "130.0.6682.0",
131 | "130.0.6682.1",
132 | "130.0.6682.2",
133 | "130.0.6682.3",
134 | "130.0.6683.0",
135 | "130.0.6683.1",
136 | "130.0.6683.2",
137 | "130.0.6683.3"
138 | ],
139 | 131: [
140 | "131.0.6724.0",
141 | "131.0.6724.1",
142 | "131.0.6724.2",
143 | "131.0.6725.0",
144 | "131.0.6725.1",
145 | "131.0.6725.2",
146 | "131.0.6725.3",
147 | "131.0.6726.0",
148 | "131.0.6726.1",
149 | "131.0.6726.2",
150 | "131.0.6727.0",
151 | "131.0.6727.1",
152 | "131.0.6728.0",
153 | "131.0.6728.1",
154 | "131.0.6729.0",
155 | "131.0.6729.1",
156 | "131.0.6730.0",
157 | "131.0.6730.1",
158 | "131.0.6731.0",
159 | "131.0.6731.1",
160 | "131.0.6732.0",
161 | "131.0.6732.1",
162 | "131.0.6733.0",
163 | "131.0.6733.1",
164 | "131.0.6734.0"
165 | ],
166 | 132: [
167 | "132.0.6779.0",
168 | "132.0.6779.1",
169 | "132.0.6780.0",
170 | "132.0.6780.1",
171 | "132.0.6781.0",
172 | "132.0.6781.1",
173 | "132.0.6782.0",
174 | "132.0.6782.1",
175 | "132.0.6783.0",
176 | "132.0.6783.1",
177 | "132.0.6784.0",
178 | "132.0.6784.1",
179 | "132.0.6784.2",
180 | "132.0.6785.0",
181 | "132.0.6785.1",
182 | "132.0.6786.0",
183 | "132.0.6786.1",
184 | "132.0.6787.0",
185 | "132.0.6787.1",
186 | "132.0.6788.0",
187 | "132.0.6788.1",
188 | "132.0.6789.0",
189 | "132.0.6789.1",
190 | "132.0.6789.2",
191 | "132.0.6790.0",
192 | "132.0.6790.1",
193 | "132.0.6790.2"
194 | ],
195 | 133: [
196 | "133.0.6835.0",
197 | "133.0.6835.1",
198 | "133.0.6835.2",
199 | "133.0.6835.3",
200 | "133.0.6835.4",
201 | "133.0.6836.0",
202 | "133.0.6836.1",
203 | "133.0.6837.0",
204 | "133.0.6837.1",
205 | "133.0.6838.0",
206 | "133.0.6838.1",
207 | "133.0.6839.0",
208 | "133.0.6839.1",
209 | "133.0.6840.0",
210 | "133.0.6840.1",
211 | "133.0.6841.0",
212 | "133.0.6841.1"
213 | ]
214 | }
215 |
216 | android_versions = ['10', '11', '12', '13', '14', '15']
217 | android_sdks = {
218 | '10': '29',
219 | '11': '30',
220 | '12': '32',
221 | '13': '33',
222 | '14': '34',
223 | '15': '35'
224 | }
225 | manufacturers = ['Samsung', 'Google', 'OnePlus', 'Xiaomi']
226 |
227 | android_devices = {
228 | 'Samsung': [
229 | 'SM-G960F', 'SM-G973F', 'SM-G980F', 'SM-G960U', 'SM-G973U', 'SM-G980U',
230 | 'SM-A505F', 'SM-A515F', 'SM-A525F', 'SM-N975F', 'SM-N986B', 'SM-N981B',
231 | 'SM-F711B', 'SM-F916B', 'SM-G781B', 'SM-G998B', 'SM-G991B', 'SM-G996B',
232 | 'SM-G990E', 'SM-G990B2', 'SM-G990U', 'SM-G990B', 'SM-G990', 'SM-S911B'
233 | ],
234 | 'Google': [
235 | 'Pixel 2', 'Pixel 2 XL', 'Pixel 3', 'Pixel 3 XL', 'Pixel 4', 'Pixel 4 XL',
236 | 'Pixel 4a', 'Pixel 5', 'Pixel 5a', 'Pixel 5 XL', 'Pixel 6', 'Pixel 6 Pro',
237 | 'Pixel 6 XL', 'Pixel 6a', 'Pixel 7', 'Pixel 7 Pro'
238 | ],
239 | 'OnePlus': [
240 | 'IN2010', 'IN2023', 'LE2117', 'LE2123', 'CPH2493', 'NE2213'
241 | 'OnePlus Nord', 'IV2201', 'NE2215', 'CPH2423', 'NE2210',
242 | 'CPH2419'
243 | ],
244 | 'Xiaomi': [
245 | 'Mi 9', 'Mi 10', 'Mi 11', 'Mi 12', 'Redmi Note 8',
246 | 'Redmi Note 9', 'Redmi Note 9 Pro', 'Redmi Note 10',
247 | 'Redmi Note 10 Pro', 'Redmi Note 11', 'Redmi Note 11 Pro', 'Redmi Note 12'
248 | ]}
249 |
250 | telegram_versions = [
251 | '11.0.1', '11.1.0', '11.1.1', '11.1.2', '11.1.3',
252 | '11.2.0', '11.2.1', '11.2.2', '11.2.3', '11.3.0',
253 | '11.3.1', '11.3.2', '11.3.3', '11.3.4', '11.4.0', '11.4.2'
254 | ]
255 |
256 | performance_class = ['AVERAGE', 'HIGH']
257 |
258 |
259 | def generate_random_user_agent(device_type='android', browser_type='chrome'):
260 | firefox_versions = list(range(100, 127)) # Last 10 versions of Firefox
261 |
262 | if browser_type == 'chrome':
263 | major_version = random.choice(list(existing_versions.keys()))
264 | browser_version = random.choice(existing_versions[major_version])
265 | elif browser_type == 'firefox':
266 | browser_version = random.choice(firefox_versions)
267 |
268 | if device_type == 'android':
269 | android_manufacturer = random.choice(manufacturers)
270 | android_device = random.choice(android_devices[android_manufacturer])
271 | android_version = random.choice(android_versions)
272 | telegram_version = random.choice(telegram_versions)
273 | performance_version = random.choice(performance_class)
274 | if browser_type == 'chrome':
275 | return (
276 | f"Mozilla/5.0 (Linux; Android {android_version}; {random.choice([android_device, 'K'])}) AppleWebKit/537.36 "
277 | f"(KHTML, like Gecko) Chrome/{browser_version} Mobile Safari/537.36 Telegram-Android/{telegram_version} "
278 | f"({android_manufacturer} {android_device}; Android {android_version}; "
279 | f"SDK {android_sdks[android_version]}; {performance_version})")
280 | elif browser_type == 'firefox':
281 | return (f"Mozilla/5.0 (Android {android_version}; Mobile; rv:{browser_version}.0) "
282 | f"Gecko/{browser_version}.0 Firefox/{browser_version}.0")
283 |
284 | elif device_type == 'ios':
285 | ios_versions = ['13.0', '14.0', '15.0', '16.0', '17.0', '18.0']
286 | ios_version = random.choice(ios_versions)
287 | if browser_type == 'chrome':
288 | return (f"Mozilla/5.0 (iPhone; CPU iPhone OS {ios_version.replace('.', '_')} like Mac OS X) "
289 | f"AppleWebKit/537.36 (KHTML, like Gecko) CriOS/{browser_version} Mobile/15E148 Safari/604.1")
290 | elif browser_type == 'firefox':
291 | return (f"Mozilla/5.0 (iPhone; CPU iPhone OS {ios_version.replace('.', '_')} like Mac OS X) "
292 | f"AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/{browser_version}.0 Mobile/15E148 Safari/605.1.15")
293 |
294 | elif device_type == 'windows':
295 | windows_versions = ['10.0', '11.0']
296 | windows_version = random.choice(windows_versions)
297 | if browser_type == 'chrome':
298 | return (f"Mozilla/5.0 (Windows NT {windows_version}; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
299 | f"Chrome/{browser_version} Safari/537.36")
300 | elif browser_type == 'firefox':
301 | return (f"Mozilla/5.0 (Windows NT {windows_version}; Win64; x64; rv:{browser_version}.0) "
302 | f"Gecko/{browser_version}.0 Firefox/{browser_version}.0")
303 |
304 | elif device_type == 'ubuntu':
305 | if browser_type == 'chrome':
306 | return (f"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:94.0) AppleWebKit/537.36 (KHTML, like Gecko) "
307 | f"Chrome/{browser_version} Safari/537.36")
308 | elif browser_type == 'firefox':
309 | return (f"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:{browser_version}.0) Gecko/{browser_version}.0 "
310 | f"Firefox/{browser_version}.0")
311 |
312 | return None
313 |
314 |
315 | def is_user_agent_valid(user_agent: str) -> bool:
316 | return 'Telegram-Android' in user_agent
317 |
318 |
319 | def is_latest_tg_version(user_agent: str) -> bool:
320 | tg_version = re.search(r'Telegram-Android/([\d\.]+)', user_agent)
321 | if tg_version:
322 | version = tg_version.group(1)
323 | return version in telegram_versions
324 | return False
325 |
326 |
327 | def get_telegram_custom_params(user_agent: str) -> str | None:
328 | android_device = re.search(r'Android \d+.*?; (.*?)(?=\))', user_agent)
329 | if not android_device:
330 | return None
331 | android_device = android_device.group(1)
332 | android_manufacturer = random.choice(manufacturers) if android_device == 'K' else get_manufacturer(android_device)
333 | if not android_manufacturer:
334 | return None
335 | telegram_version = random.choice(telegram_versions)
336 | performance_version = random.choice(performance_class)
337 | android_version = re.search(r'Android (\d+(\.\d+)*)', user_agent).group(1).split('.')[0]
338 | tg_params = f" Telegram-Android/{telegram_version} " \
339 | f"({android_manufacturer} {android_device}; Android {android_version}; " \
340 | f"SDK {android_sdks[android_version]}; {performance_version})"
341 | return tg_params
342 |
343 |
344 | def get_sec_ch_ua(user_agent: str) -> str:
345 | browser_version = re.search(r'Chrome/(\d+)', user_agent).group(1)
346 | return f'"Android WebView";v="{browser_version}", "Chromium";v="{browser_version}", "Not_A Brand";v="24"'
347 |
348 |
349 | def get_manufacturer(android_device: str) -> str | None:
350 | for brand in android_devices:
351 | for model in android_devices[brand]:
352 | if android_device in model:
353 | return brand
354 | return None
355 |
--------------------------------------------------------------------------------
/bot/core/headers.py:
--------------------------------------------------------------------------------
1 | headers = {
2 | 'Accept': '*/*',
3 | 'Accept-Language': 'ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7',
4 | 'Accept-Encoding': 'br',
5 | 'Content-Type': 'application/json',
6 | 'Connection': 'keep-alive',
7 | 'Origin': 'https://cats-frontend.tgapps.store',
8 | 'Referer': 'https://cats-frontend.tgapps.store/',
9 | 'Sec-Fetch-Dest': 'empty',
10 | 'Sec-Fetch-Mode': 'cors',
11 | 'Sec-Fetch-Site': 'same-origin',
12 | 'Sec-Ch-Ua': '"Google Chrome";v="125", "Chromium";v="125", "Not.A/Brand";v="24"',
13 | 'Sec-Ch-Ua-mobile': '?1',
14 | 'Sec-Ch-Ua-platform': '"Android"',
15 | 'User-Agent': 'Mozilla/5.0 (Linux; Android 14) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.165 Mobile Safari/537.36'
16 | }
--------------------------------------------------------------------------------
/bot/core/registrator.py:
--------------------------------------------------------------------------------
1 | from pyrogram import Client
2 |
3 | from bot.config import settings
4 | from bot.core.agents import generate_random_user_agent
5 | from bot.utils import logger
6 | from bot.utils.file_manager import save_to_json
7 |
8 |
9 | async def register_sessions() -> None:
10 | API_ID = settings.API_ID
11 | API_HASH = settings.API_HASH
12 |
13 | if not API_ID or not API_HASH:
14 | raise ValueError("API_ID and API_HASH not found in the .env file.")
15 |
16 | session_name = input('\nEnter the session name (press Enter to exit): ')
17 |
18 | if not session_name:
19 | return None
20 |
21 | raw_proxy = input("Input the proxy in the format type://user:pass:ip:port (press Enter to use without proxy): ")
22 | session = await get_tg_client(session_name=session_name, proxy=raw_proxy)
23 | async with session:
24 | user_data = await session.get_me()
25 |
26 | user_agent = generate_random_user_agent(device_type='android', browser_type='chrome')
27 | save_to_json(f'sessions/accounts.json',
28 | dict_={
29 | "session_name": session_name,
30 | "user_agent": user_agent,
31 | "proxy": raw_proxy if raw_proxy else None
32 | })
33 | logger.success(f'Session added successfully @{user_data.username} | {user_data.first_name} {user_data.last_name}')
34 |
35 |
36 | async def get_tg_client(session_name: str, proxy: str | None) -> Client:
37 | if not session_name:
38 | raise FileNotFoundError(f"Not found session {session_name}")
39 |
40 | if not settings.API_ID or not settings.API_HASH:
41 | raise ValueError("API_ID and API_HASH not found in the .env file.")
42 |
43 | proxy_dict = {
44 | "scheme": proxy.split(":")[0],
45 | "username": proxy.split(":")[1].split("//")[1],
46 | "password": proxy.split(":")[2],
47 | "hostname": proxy.split(":")[3],
48 | "port": int(proxy.split(":")[4])
49 | } if proxy else None
50 |
51 | tg_client = Client(
52 | name=session_name,
53 | api_id=settings.API_ID,
54 | api_hash=settings.API_HASH,
55 | workdir="sessions/",
56 | plugins=dict(root="bot/plugins"),
57 | proxy=proxy_dict
58 | )
59 |
60 | return tg_client
--------------------------------------------------------------------------------
/bot/core/tapper.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import json
3 | import os
4 | from datetime import datetime, timedelta
5 | from time import time
6 |
7 |
8 | import aiohttp
9 | import brotli
10 | from aiohttp_proxy import ProxyConnector
11 | from better_proxy import Proxy
12 | from bot.config import settings
13 |
14 | from bot.utils import logger
15 | from bot.exceptions import InvalidSession
16 | from .agents import get_sec_ch_ua
17 | from .headers import headers
18 |
19 | from random import randint
20 |
21 | from ..config.youtube_tasks import YOUTUBE_TASKS
22 | from ..utils.file_manager import get_random_cat_image
23 | from ..utils.tg_manager.TGSession import TGSession
24 |
25 |
26 | class Tapper:
27 | def __init__(self, tg_session: TGSession):
28 | self.tg_session = tg_session
29 | self.session_name = tg_session.session_name
30 | self.start_param = ''
31 | self.name = ''
32 |
33 | async def login(self, http_client: aiohttp.ClientSession, retry=0):
34 | try:
35 | response = await http_client.get("https://api.catshouse.club/user",
36 | timeout=aiohttp.ClientTimeout(60))
37 |
38 | if response.status == 404:
39 | response = await http_client.post("https://api.catshouse.club/user/create",
40 | params={"referral_code": self.start_param})
41 | response.raise_for_status()
42 | logger.success(f"{self.session_name} | User successfully registered!")
43 | await asyncio.sleep(delay=2)
44 | return await self.login(http_client)
45 |
46 | response.raise_for_status()
47 | response_bytes = await response.read()
48 | response_text = brotli.decompress(response_bytes)
49 | response_json = json.loads(response_text.decode('utf-8'))
50 | return response_json
51 |
52 | except Exception as error:
53 | if retry < 5:
54 | logger.warning(f"{self.session_name} | Can't logging | Retry attempt: {retry}")
55 | await asyncio.sleep(delay=randint(5, 10))
56 | return await self.login(http_client, retry=retry+1)
57 |
58 | logger.error(f"{self.session_name} | Unknown error when logging: {error}")
59 | await asyncio.sleep(delay=randint(3, 7))
60 |
61 | async def check_proxy(self, http_client: aiohttp.ClientSession, proxy: Proxy) -> None:
62 | try:
63 | response = await http_client.get(url='https://ipinfo.io/ip', timeout=aiohttp.ClientTimeout(20))
64 | ip = (await response.text())
65 | logger.info(f"{self.session_name} | Proxy IP: {ip}")
66 | except Exception as error:
67 | logger.error(f"{self.session_name} | Proxy: {proxy} | Error: {error}")
68 |
69 | async def get_all_tasks(self, http_client: aiohttp.ClientSession, groups: list[str], retry=0):
70 | try:
71 | tasks = []
72 | for group in groups:
73 | response = await http_client.get(f"https://api.catshouse.club/tasks/user?group={group}")
74 | response.raise_for_status()
75 | response_bytes = await response.read()
76 | response_text = brotli.decompress(response_bytes)
77 | tasks_json = json.loads(response_text.decode('utf-8'))
78 | tasks += tasks_json.get('tasks')
79 | await asyncio.sleep(delay=randint(1, 3))
80 | return tasks
81 | except Exception as error:
82 | if retry < 5:
83 | logger.warning(f"{self.session_name} | Can't getting tasks | Retry attempt: {retry}")
84 | await asyncio.sleep(delay=randint(5, 10))
85 | return await self.get_all_tasks(http_client, groups, retry=retry+1)
86 |
87 | logger.error(f"{self.session_name} | Unknown error when getting tasks: {error}")
88 | await asyncio.sleep(delay=3)
89 |
90 | async def processing_tasks(self, http_client: aiohttp.ClientSession):
91 | try:
92 | tasks = await self.get_all_tasks(http_client, ['cats', 'bitget', 'kukoin', 'okx'])
93 | if tasks:
94 | for task in tasks:
95 | if not task['completed'] and not task['isPending'] and task['type'] not in settings.DISABLED_TASKS:
96 | if task['type'] == 'NICKNAME_CHANGE':
97 | if '🐈⬛' in self.tg_session.name:
98 | result = await self.verify_task(http_client, task['id'], endpoint='check')
99 | if result:
100 | logger.info(f"{self.session_name} | Removing 🐈 from nickname")
101 | name = self.tg_session.name.split('🐈⬛')[0]
102 | await self.tg_session.change_tg_nickname(name=name)
103 | else:
104 | logger.info(f"{self.session_name} | Performing {task['title']} task")
105 | cat_name = f'{self.tg_session.name}🐈⬛'
106 | await self.tg_session.change_tg_nickname(name=cat_name)
107 | continue
108 | elif task['type'] == 'SUBSCRIBE_TO_CHANNEL':
109 | if not settings.JOIN_TG_CHANNELS:
110 | continue
111 | url = task['params']['channelUrl']
112 | logger.info(f"{self.session_name} | Performing TG subscription to {url}")
113 | await self.tg_session.join_tg_channel(url)
114 | result = await self.verify_task(http_client, task['id'], endpoint='check')
115 |
116 | elif task['type'] == 'YOUTUBE_WATCH':
117 | logger.info(f'{self.session_name} | Performing Youtube {task["title"]}')
118 | answer = YOUTUBE_TASKS.get(task["title"], None)
119 | if answer:
120 | endpoint = f'complete?answer={answer}'
121 | await asyncio.sleep(delay=randint(30, 60))
122 | result = await self.verify_task(http_client, task['id'], endpoint=endpoint)
123 | else:
124 | logger.warning(f'{self.session_name} | Answer for task {task["title"]} not found')
125 | continue
126 | else:
127 | logger.info(f"{self.session_name} | Performing {task['title']} task")
128 | result = await self.verify_task(http_client, task['id'], endpoint='complete')
129 |
130 | if result:
131 | logger.success(f"{self.session_name} | Task {task['title']} completed! |"
132 | f" Reward: +{task['rewardPoints']} CATS")
133 | else:
134 | logger.info(f"{self.session_name} | Task {task['title']} not completed")
135 |
136 | await asyncio.sleep(delay=randint(5, 10))
137 |
138 | elif task['isPending']:
139 | logger.info(f"{self.session_name} | Task {task['title']} is pending")
140 |
141 | except Exception as error:
142 | logger.error(f"{self.session_name} | Unknown error when processing tasks: {error}")
143 | await asyncio.sleep(delay=3)
144 |
145 | async def verify_task(self, http_client: aiohttp.ClientSession, task_id: str, endpoint: str, retry=0):
146 | try:
147 | response = await http_client.post(f'https://api.catshouse.club/tasks'
148 | f'/{task_id}/{endpoint}', json={}, timeout=aiohttp.ClientTimeout(60))
149 | response.raise_for_status()
150 | response_json = await response.json()
151 | status = response_json.get('success', False) or response_json.get('completed', False)
152 | return status
153 |
154 | except Exception as e:
155 | if retry < 5:
156 | logger.warning(f"{self.session_name} | Can't verify task | Retry attempt: {retry}")
157 | await asyncio.sleep(delay=randint(5, 10))
158 | return await self.verify_task(http_client, task_id, endpoint, retry=retry+1)
159 |
160 | logger.error(f"{self.session_name} | Unknown error while verifying task {task_id} | Error: {e}")
161 | await asyncio.sleep(delay=3)
162 |
163 | async def get_avatar_info(self, http_client: aiohttp.ClientSession, retry=0):
164 | try:
165 | response = await http_client.get('https://api.catshouse.club/user/avatar')
166 | response.raise_for_status()
167 | response_bytes = await response.read()
168 | response_text = brotli.decompress(response_bytes)
169 | response_json = json.loads(response_text.decode('utf-8'))
170 | return response_json
171 |
172 | except Exception as e:
173 | if retry < 5:
174 | logger.warning(f"{self.session_name} | Can't getting avatar info | Retry attempt: {retry}")
175 | await asyncio.sleep(delay=randint(5, 10))
176 | return await self.get_avatar_info(http_client, retry=retry+1)
177 |
178 | logger.error(f"{self.session_name} | Unknown error while getting avatar info | Error: {e}")
179 | await asyncio.sleep(delay=3)
180 |
181 | async def check_available(self, http_client: aiohttp.ClientSession, retry=0):
182 | try:
183 | response = await http_client.get('https://api.catshouse.club/exchange-claim/check-available')
184 | response.raise_for_status()
185 | response_bytes = await response.read()
186 | response_text = brotli.decompress(response_bytes)
187 | response_json = json.loads(response_text.decode('utf-8'))
188 | return response_json
189 |
190 | except Exception as e:
191 | if retry < 5:
192 | logger.warning(f"{self.session_name} | Can't getting airdrop data | Retry attempt: {retry}")
193 | await asyncio.sleep(delay=randint(5, 10))
194 | return await self.check_available(http_client, retry=retry+1)
195 |
196 | logger.error(f"{self.session_name} | Unknown error while getting airdrop data | Error: {e}")
197 | await asyncio.sleep(delay=3)
198 |
199 | def generate_random_string(self, length=8):
200 | characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
201 | random_string = ''
202 | for _ in range(length):
203 | random_index = int((len(characters) * int.from_bytes(os.urandom(1), 'big')) / 256)
204 | random_string += characters[random_index]
205 | return random_string
206 |
207 | async def processing_avatar_task(self, http_client: aiohttp.ClientSession, retry=0):
208 | try:
209 | cat_image = await get_random_cat_image(session_name=self.session_name)
210 | hash_id = self.generate_random_string(length=16)
211 | http_client.headers['Content-Type'] = f'multipart/form-data; boundary=----WebKitFormBoundary{hash_id}'
212 | data = (f'------WebKitFormBoundary{hash_id}\r\n'.encode('utf-8') + cat_image +
213 | f'\r\n------WebKitFormBoundary{hash_id}--\r\n'.encode('utf-8'))
214 | response = await http_client.post('https://api.catshouse.club/user/avatar/upgrade',
215 | data=data)
216 | http_client.headers['Content-Type'] = headers['Content-Type']
217 | response.raise_for_status()
218 | response_bytes = await response.read()
219 | response_text = brotli.decompress(response_bytes)
220 | response_json = json.loads(response_text.decode('utf-8'))
221 | logger.info(
222 | f"{self.session_name} | Avatar task completed! | Reward: +{response_json['rewards']} CATS")
223 | return response_json
224 |
225 | except Exception as e:
226 | if retry < 5:
227 | logger.warning(f"{self.session_name} | Can't processing avatar task | Retry attempt: {retry}")
228 | await asyncio.sleep(delay=randint(5, 10))
229 | return await self.processing_avatar_task(http_client, retry=retry+1)
230 |
231 | logger.error(f"{self.session_name} | Unknown error while processing avatar task | Error: {e}")
232 | await asyncio.sleep(delay=3)
233 |
234 | async def get_user_exchange(self, http_client: aiohttp.ClientSession, retry=0):
235 | try:
236 | response = await http_client.get('https://api.catshouse.club/exchange-claim/user-request')
237 | if response.content_length == 0:
238 | logger.info(f"{self.session_name} | User has not linked a wallet")
239 | return
240 | response.raise_for_status()
241 | response_bytes = await response.read()
242 | response_text = brotli.decompress(response_bytes)
243 | response_json = json.loads(response_text.decode('utf-8'))
244 | return response_json
245 |
246 | except Exception as e:
247 | if retry < 3:
248 | logger.warning(f"{self.session_name} | Can't getting exchange data | Retry attempt: {retry}")
249 | await asyncio.sleep(delay=randint(5, 10))
250 | return await self.get_user_exchange(http_client, retry=retry + 1)
251 |
252 | logger.error(f"{self.session_name} | Unknown error while getting exchange data | Error: {e}")
253 | await asyncio.sleep(delay=3)
254 |
255 | async def run(self, user_agent: str, proxy: str | None) -> None:
256 | access_token_created_time = 0
257 | proxy_conn = ProxyConnector().from_url(proxy) if proxy else None
258 | headers["User-Agent"] = user_agent
259 | headers['Sec-Ch-Ua'] = get_sec_ch_ua(user_agent)
260 |
261 | async with aiohttp.ClientSession(headers=headers, connector=proxy_conn, trust_env=True, auto_decompress=False) as http_client:
262 | if proxy:
263 | await self.check_proxy(http_client=http_client, proxy=proxy)
264 |
265 | token_live_time = randint(3500, 3600)
266 | while True:
267 | try:
268 | sleep_time = randint(settings.SLEEP_TIME[0], settings.SLEEP_TIME[1])
269 | if time() - access_token_created_time >= token_live_time:
270 | tg_web_data = await self.tg_session.get_tg_web_data()
271 | if tg_web_data is None:
272 | continue
273 |
274 | http_client.headers["Authorization"] = "tma " + tg_web_data
275 | user_info = await self.login(http_client=http_client)
276 | if user_info is None:
277 | token_live_time = 0
278 | await asyncio.sleep(randint(1000, 1800))
279 | continue
280 |
281 | access_token_created_time = time()
282 | token_live_time = randint(3500, 3600)
283 |
284 | balance = user_info['totalRewards']
285 | logger.info(f"{self.session_name} | Balance: {balance} CATS")
286 | result = await self.check_available(http_client=http_client)
287 | if result:
288 | logger.info(f'{self.session_name} '
289 | f'| Has free pass: {result.get("hasFreePass")} '
290 | f'| Has OG pass: {result.get("hasOgPass")} '
291 | f'| Has transaction: {result.get("hasTransaction")} '
292 | f'| Is available for Airdrop: {result.get("isAvailable")}')
293 |
294 | exchange = await self.get_user_exchange(http_client=http_client)
295 | if exchange:
296 | logger.info(f"{self.session_name} | "
297 | f"Exchange: {exchange['exchange']} | Address: {exchange['address']}")
298 |
299 | if settings.AUTO_TASK:
300 | await asyncio.sleep(delay=randint(5, 10))
301 | await self.processing_tasks(http_client=http_client)
302 |
303 | if settings.AVATAR_TASK:
304 | avatar_info = await self.get_avatar_info(http_client=http_client)
305 | og_pass = user_info.get('hasOgPass', False)
306 | logger.info(f"{self.session_name} | OG Pass: {og_pass}")
307 | if avatar_info:
308 | attempt_time = None
309 | max_attempts = 3 if og_pass else 1
310 | used_attempts = 0
311 | if avatar_info['attemptTime'] is not None:
312 | attempt_time = avatar_info['attemptTime']
313 | parsed_time = datetime.strptime(attempt_time, '%Y-%m-%dT%H:%M:%S.%fZ').timestamp()
314 | delta_time = datetime.utcnow().timestamp() - parsed_time
315 | next_attempt_time = delta_time - timedelta(hours=24).total_seconds()
316 | used_attempts = avatar_info['attemptsUsed'] if next_attempt_time < 0 else 0
317 | if attempt_time is None or used_attempts < max_attempts:
318 | for attempt in range(max_attempts - used_attempts):
319 | await asyncio.sleep(delay=randint(5, 10))
320 | await self.processing_avatar_task(http_client=http_client)
321 |
322 | elif next_attempt_time < 0:
323 | sleep_time = min(sleep_time, abs(int(next_attempt_time)))
324 |
325 | logger.info(f"{self.session_name} | Sleep {round(sleep_time / 60, 1)} min")
326 | await asyncio.sleep(delay=sleep_time)
327 |
328 | except InvalidSession as error:
329 | raise error
330 |
331 | except Exception as error:
332 | logger.error(f"{self.session_name} | Unknown error: {error}")
333 | await asyncio.sleep(delay=randint(60, 120))
334 |
335 |
336 | async def run_tapper(tg_session: TGSession, user_agent: str, proxy: str | None):
337 | try:
338 | await Tapper(tg_session=tg_session).run(user_agent=user_agent, proxy=proxy)
339 | except InvalidSession:
340 | logger.error(f"{tg_session.session_name} | Invalid Session")
341 |
--------------------------------------------------------------------------------
/bot/core/tg_manager.cp310-win_amd64.pyd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Desamod/CatsGangBot/727358b283daa514d25ee11188ab47f1ed9a5296/bot/core/tg_manager.cp310-win_amd64.pyd
--------------------------------------------------------------------------------
/bot/core/tg_manager.cpython-310-darwin.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Desamod/CatsGangBot/727358b283daa514d25ee11188ab47f1ed9a5296/bot/core/tg_manager.cpython-310-darwin.so
--------------------------------------------------------------------------------
/bot/core/tg_manager.cpython-310-x86_64-linux-gnu.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Desamod/CatsGangBot/727358b283daa514d25ee11188ab47f1ed9a5296/bot/core/tg_manager.cpython-310-x86_64-linux-gnu.so
--------------------------------------------------------------------------------
/bot/exceptions/__init__.py:
--------------------------------------------------------------------------------
1 | class InvalidSession(BaseException):
2 | ...
3 |
--------------------------------------------------------------------------------
/bot/utils/__init__.py:
--------------------------------------------------------------------------------
1 | from .logger import logger
2 | from . import launcher
3 |
4 |
5 | import os
6 |
7 | if not os.path.exists(path="sessions"):
8 | os.mkdir(path="sessions")
9 |
--------------------------------------------------------------------------------
/bot/utils/accounts.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | from bot.core.agents import generate_random_user_agent, is_user_agent_valid, get_telegram_custom_params
4 | from bot.utils import logger
5 | from bot.config import settings
6 | from bot.utils.file_manager import load_from_json, save_to_json, update_ua_json_data
7 |
8 |
9 | class Accounts:
10 | def __init__(self):
11 | self.workdir = "sessions/"
12 | self.api_id = settings.API_ID
13 | self.api_hash = settings.API_HASH
14 |
15 | @staticmethod
16 | def get_available_accounts(sessions: list):
17 |
18 | accounts_from_json = load_from_json('sessions/accounts.json')
19 |
20 | if not accounts_from_json:
21 | raise ValueError("Can't run script | Please, add account/s in sessions/accounts.json")
22 |
23 | available_accounts = []
24 | for session in sessions:
25 | is_session_added = False
26 | for saved_account in accounts_from_json:
27 | if saved_account['session_name'] == session:
28 | if not is_user_agent_valid(saved_account['user_agent']):
29 | tg_params = get_telegram_custom_params(saved_account['user_agent'])
30 | saved_account['user_agent'] = saved_account['user_agent'] + tg_params if tg_params else (
31 | generate_random_user_agent(device_type='android', browser_type='chrome'))
32 | update_ua_json_data(f'sessions/accounts.json', dict_=saved_account)
33 | logger.success(f'{saved_account["session_name"]} | Successfully updated User-Agent data')
34 | available_accounts.append(saved_account)
35 | is_session_added = True
36 | break
37 | if not is_session_added:
38 | logger.warning(f'{session}.session does not exist in sessions/accounts.json')
39 | ans = input(f"Add {session} to accounts.json? (y/N): ")
40 | if 'y' in ans.lower():
41 | raw_proxy = input("Input the proxy in the format type://user:pass:ip:port (press Enter to use without proxy): ")
42 | user_agent = generate_random_user_agent(device_type='android', browser_type='chrome')
43 | new_account = {
44 | "session_name": session,
45 | "user_agent": user_agent,
46 | "proxy": raw_proxy
47 | }
48 | save_to_json(f'sessions/accounts.json', dict_=new_account)
49 | available_accounts.append(new_account)
50 | logger.success(f'Account {session} added successfully')
51 |
52 | return available_accounts
53 |
54 | def pars_sessions(self):
55 | sessions = []
56 | for file in os.listdir(self.workdir):
57 | if file.endswith(".session"):
58 | sessions.append(file.replace(".session", ""))
59 |
60 | logger.info(f"Searched sessions: {len(sessions)}.")
61 | return sessions
62 |
63 | async def get_accounts(self):
64 | sessions = self.pars_sessions()
65 | available_accounts = self.get_available_accounts(sessions)
66 |
67 | if not available_accounts:
68 | raise ValueError("Available accounts not found! Please add accounts in 'sessions' folder")
69 | else:
70 | logger.success(f"Available accounts: {len(available_accounts)}.")
71 |
72 | return available_accounts
73 |
--------------------------------------------------------------------------------
/bot/utils/file_manager.py:
--------------------------------------------------------------------------------
1 | import json
2 | import mimetypes
3 | import os
4 | import random
5 | import aiofiles
6 |
7 | from bot.config import settings
8 | from bot.utils import logger
9 |
10 |
11 | def load_from_json(path: str):
12 | if os.path.isfile(path):
13 | with open(path, encoding='utf-8') as file:
14 | return json.load(file)
15 | else:
16 | with open(path, 'x', encoding='utf-8') as file:
17 | example = {
18 | "session_name": "name_example",
19 | "user_agent": "Mozilla/5.0 (Linux; Android 14) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.165 Mobile Safari/537.36",
20 | "proxy": "type://user:pass:ip:port"
21 | }
22 | json.dump([example], file, ensure_ascii=False, indent=2)
23 | return [example]
24 |
25 |
26 | def save_to_json(path: str, dict_):
27 | if os.path.isfile(path):
28 | with open(path, 'r', encoding='utf-8') as file:
29 | data = json.load(file)
30 |
31 | data.append(dict_)
32 | with open(path, 'w', encoding='utf-8') as file:
33 | json.dump(data, file, ensure_ascii=False, indent=2)
34 | else:
35 | with open(path, 'x', encoding='utf-8') as file:
36 | json.dump([dict_], file, ensure_ascii=False, indent=2)
37 |
38 |
39 | async def get_random_cat_image(session_name: str):
40 | images = [f for f in os.listdir(settings.CATS_PATH) if f.lower().endswith(('.png', '.jpeg', '.jpg'))]
41 | if not images:
42 | logger.warning(f"Please, add cats images in '{settings.CATS_PATH}' folder")
43 | return None
44 |
45 | image = random.choice(images)
46 | logger.info(f"{session_name} | Selected image: {image}")
47 | image_path = os.path.join(settings.CATS_PATH, image)
48 | mime_type = mimetypes.guess_type(image_path)
49 |
50 | async with aiofiles.open(image_path, 'r+b') as file:
51 | data = await file.read()
52 |
53 | image_data = (f'Content-Disposition: form-data; name="photo"; filename="{image}"\r\n'
54 | f'Content-Type: {mime_type}\r\n\r\n').encode('utf-8')
55 | image_data += data
56 | return image_data
57 |
58 |
59 | def update_ua_json_data(path: str, dict_):
60 | if os.path.isfile(path):
61 | with open(path, 'r', encoding='utf-8') as file:
62 | data = json.load(file)
63 |
64 | for session in data:
65 | if session["session_name"] == dict_["session_name"]:
66 | session["user_agent"] = dict_["user_agent"]
67 |
68 | with open(path, 'w', encoding='utf-8') as file:
69 | json.dump(data, file, ensure_ascii=False, indent=2)
70 | else:
71 | with open(path, 'x', encoding='utf-8') as file:
72 | json.dump([dict_], file, ensure_ascii=False, indent=2)
73 |
--------------------------------------------------------------------------------
/bot/utils/launcher.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import argparse
3 | from random import randint
4 | from typing import Any
5 | from better_proxy import Proxy
6 |
7 | from bot.config import settings
8 | from bot.utils import logger
9 | from bot.core.tapper import run_tapper
10 | from bot.core.registrator import register_sessions
11 | from bot.utils.accounts import Accounts
12 | from bot.core.tg_manager import SessionManager
13 |
14 |
15 | start_text = """
16 |
17 | ░█████╗░░█████╗░████████╗░██████╗░██████╗░░█████╗░███╗░░██╗░██████╗░██████╗░░█████╗░████████╗
18 | ██╔══██╗██╔══██╗╚══██╔══╝██╔════╝██╔════╝░██╔══██╗████╗░██║██╔════╝░██╔══██╗██╔══██╗╚══██╔══╝
19 | ██║░░╚═╝███████║░░░██║░░░╚█████╗░██║░░██╗░███████║██╔██╗██║██║░░██╗░██████╦╝██║░░██║░░░██║░░░
20 | ██║░░██╗██╔══██║░░░██║░░░░╚═══██╗██║░░╚██╗██╔══██║██║╚████║██║░░╚██╗██╔══██╗██║░░██║░░░██║░░░
21 | ╚█████╔╝██║░░██║░░░██║░░░██████╔╝╚██████╔╝██║░░██║██║░╚███║╚██████╔╝██████╦╝╚█████╔╝░░░██║░░░
22 | ░╚════╝░╚═╝░░╚═╝░░░╚═╝░░░╚═════╝░░╚═════╝░╚═╝░░╚═╝╚═╝░░╚══╝░╚═════╝░╚═════╝░░╚════╝░░░░╚═╝░░░
23 | by Desamod
24 | Select an action:
25 |
26 | 1. Run bot
27 | 2. Create session
28 | """
29 |
30 |
31 | def get_proxy(raw_proxy: str) -> Proxy:
32 | return Proxy.from_str(proxy=raw_proxy).as_url if raw_proxy else None
33 |
34 |
35 | async def process() -> None:
36 | parser = argparse.ArgumentParser()
37 | parser.add_argument("-a", "--action", type=int, help="Action to perform")
38 | action = parser.parse_args().action
39 |
40 | if not action:
41 | print(start_text)
42 |
43 | while True:
44 | action = input("> ")
45 |
46 | if not action.isdigit():
47 | logger.warning("Action must be number")
48 | elif action not in ["1", "2"]:
49 | logger.warning("Action must be 1 or 2")
50 | else:
51 | action = int(action)
52 | break
53 |
54 | if action == 2:
55 | await register_sessions()
56 | elif action == 1:
57 | accounts = await Accounts().get_accounts()
58 | await run_tasks(accounts=accounts)
59 |
60 |
61 | async def run_tasks(accounts: [Any, Any, list]):
62 | tasks = []
63 | manager = SessionManager(api_id=settings.API_ID,
64 | api_hash=settings.API_HASH,
65 | peer='catsgang_bot',
66 | short_name='join',
67 | start_param=settings.REF_ID)
68 | for account in accounts:
69 | session_name, user_agent, raw_proxy = account.values()
70 | tg_session = await manager.get_tg_session(session_name=session_name, proxy=raw_proxy)
71 | proxy = get_proxy(raw_proxy=raw_proxy)
72 | tasks.append(asyncio.create_task(run_tapper(tg_session=tg_session, user_agent=user_agent, proxy=proxy)))
73 | await asyncio.sleep(delay=randint(settings.START_DELAY[0], settings.START_DELAY[1]))
74 |
75 | await asyncio.gather(*tasks)
76 |
--------------------------------------------------------------------------------
/bot/utils/logger.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from loguru import logger
3 |
4 |
5 | logger.remove()
6 | logger.add(sink=sys.stdout, format="{time:YYYY-MM-DD HH:mm:ss}"
7 | " | {level: <8}"
8 | " | {line}"
9 | " - {message}")
10 | logger = logger.opt(colors=True)
11 |
--------------------------------------------------------------------------------
/bot/utils/tg_manager/PyrogramSession.cp310-win_amd64.pyd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Desamod/CatsGangBot/727358b283daa514d25ee11188ab47f1ed9a5296/bot/utils/tg_manager/PyrogramSession.cp310-win_amd64.pyd
--------------------------------------------------------------------------------
/bot/utils/tg_manager/PyrogramSession.cpython-310-darwin.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Desamod/CatsGangBot/727358b283daa514d25ee11188ab47f1ed9a5296/bot/utils/tg_manager/PyrogramSession.cpython-310-darwin.so
--------------------------------------------------------------------------------
/bot/utils/tg_manager/PyrogramSession.cpython-310-x86_64-linux-gnu.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Desamod/CatsGangBot/727358b283daa514d25ee11188ab47f1ed9a5296/bot/utils/tg_manager/PyrogramSession.cpython-310-x86_64-linux-gnu.so
--------------------------------------------------------------------------------
/bot/utils/tg_manager/TGSession.cp310-win_amd64.pyd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Desamod/CatsGangBot/727358b283daa514d25ee11188ab47f1ed9a5296/bot/utils/tg_manager/TGSession.cp310-win_amd64.pyd
--------------------------------------------------------------------------------
/bot/utils/tg_manager/TGSession.cpython-310-darwin.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Desamod/CatsGangBot/727358b283daa514d25ee11188ab47f1ed9a5296/bot/utils/tg_manager/TGSession.cpython-310-darwin.so
--------------------------------------------------------------------------------
/bot/utils/tg_manager/TGSession.cpython-310-x86_64-linux-gnu.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Desamod/CatsGangBot/727358b283daa514d25ee11188ab47f1ed9a5296/bot/utils/tg_manager/TGSession.cpython-310-x86_64-linux-gnu.so
--------------------------------------------------------------------------------
/bot/utils/tg_manager/TelethonSession.cp310-win_amd64.pyd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Desamod/CatsGangBot/727358b283daa514d25ee11188ab47f1ed9a5296/bot/utils/tg_manager/TelethonSession.cp310-win_amd64.pyd
--------------------------------------------------------------------------------
/bot/utils/tg_manager/TelethonSession.cpython-310-darwin.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Desamod/CatsGangBot/727358b283daa514d25ee11188ab47f1ed9a5296/bot/utils/tg_manager/TelethonSession.cpython-310-darwin.so
--------------------------------------------------------------------------------
/bot/utils/tg_manager/TelethonSession.cpython-310-x86_64-linux-gnu.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Desamod/CatsGangBot/727358b283daa514d25ee11188ab47f1ed9a5296/bot/utils/tg_manager/TelethonSession.cpython-310-x86_64-linux-gnu.so
--------------------------------------------------------------------------------
/cats/cat.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Desamod/CatsGangBot/727358b283daa514d25ee11188ab47f1ed9a5296/cats/cat.jpg
--------------------------------------------------------------------------------
/cats/cat2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Desamod/CatsGangBot/727358b283daa514d25ee11188ab47f1ed9a5296/cats/cat2.jpg
--------------------------------------------------------------------------------
/cats/cat3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Desamod/CatsGangBot/727358b283daa514d25ee11188ab47f1ed9a5296/cats/cat3.jpg
--------------------------------------------------------------------------------
/cats/cat4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Desamod/CatsGangBot/727358b283daa514d25ee11188ab47f1ed9a5296/cats/cat4.jpg
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '1'
2 | services:
3 | bot:
4 | container_name: 'CatsGangBot'
5 | build:
6 | context: .
7 | stop_signal: SIGINT
8 | restart: unless-stopped
9 | command: "python3 main.py -a 1"
10 | volumes:
11 | - .:/app
12 |
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import sys
3 | from contextlib import suppress
4 |
5 | from bot.utils import logger
6 | from bot.utils.launcher import process
7 |
8 |
9 | async def main():
10 | await process()
11 |
12 |
13 | if __name__ == '__main__':
14 | try:
15 | asyncio.run(main())
16 | except KeyboardInterrupt:
17 | logger.warning("Bot stopped by user...")
18 | sys.exit(2)
19 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | aiocfscrape==1.0.0
2 | aiohttp==3.9.3
3 | aiohttp-proxy==0.1.2
4 | aiosignal==1.3.1
5 | annotated-types==0.6.0
6 | async-timeout==4.0.3
7 | attrs==23.2.0
8 | beautifulsoup4==4.12.3
9 | better-proxy==1.1.5
10 | colorama==0.4.6
11 | DateTime==5.5
12 | frozenlist==1.4.1
13 | Js2Py==0.74
14 | loguru==0.7.2
15 | multidict==6.0.5
16 | pyaes==1.6.1
17 | pydantic==2.6.4
18 | pydantic-settings==2.2.1
19 | pydantic_core==2.16.3
20 | pyjsparser==2.7.1
21 | Pyrogram==2.0.106
22 | PySocks==1.7.1
23 | python-dotenv==1.0.1
24 | pytz==2024.1
25 | six==1.16.0
26 | soupsieve==2.5
27 | TgCrypto==1.2.5
28 | typing_extensions==4.11.0
29 | tzdata==2024.1
30 | tzlocal==5.2
31 | websockets==12.0
32 | win32-setctime==1.1.0
33 | yarl==1.9.4
34 | zope.interface==6.4.post2
35 | aiofiles~=24.1.0
36 | Brotli~=1.1.0
37 | opentele~=1.15.1
38 | Telethon~=1.37.0
--------------------------------------------------------------------------------
/run.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | title CatsGangBot
3 | if not exist venv (
4 | echo Creating virtual environment...
5 | python -m venv venv
6 | )
7 |
8 | echo Activating virtual environment...
9 | call venv\Scripts\activate
10 |
11 | if not exist venv\Lib\site-packages\installed (
12 | if exist requirements.txt (
13 | echo installing wheel for faster installing
14 | pip install wheel
15 | echo Installing dependencies...
16 | pip install -r requirements.txt
17 | echo. > venv\Lib\site-packages\installed
18 | ) else (
19 | echo requirements.txt not found, skipping dependency installation.
20 | )
21 | ) else (
22 | echo Dependencies already installed, skipping installation.
23 | )
24 |
25 | if not exist .env (
26 | echo Copying configuration file
27 | copy .env-example .env
28 | ) else (
29 | echo Skipping .env copying
30 | )
31 |
32 | echo Starting the bot...
33 | python main.py
34 |
35 | echo done
36 | echo PLEASE EDIT .ENV FILE
37 | pause
38 |
--------------------------------------------------------------------------------
/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Проверка на наличие папки venv
4 | if [ ! -d "venv" ]; then
5 | echo "Creating virtual environment..."
6 | python3 -m venv venv
7 | fi
8 |
9 | echo "Activating virtual environment..."
10 | source venv/bin/activate
11 |
12 | # Проверка на наличие установленного флага в виртуальном окружении
13 | if [ ! -f "venv/installed" ]; then
14 | if [ -f "requirements.txt" ]; then
15 | echo "Installing wheel for faster installing"
16 | pip3 install wheel
17 | echo "Installing dependencies..."
18 | pip3 install -r requirements.txt
19 | touch venv/installed
20 | else
21 | echo "requirements.txt not found, skipping dependency installation."
22 | fi
23 | else
24 | echo "Dependencies already installed, skipping installation."
25 | fi
26 |
27 | if [ ! -f ".env" ]; then
28 | echo "Copying configuration file"
29 | cp .env-example .env
30 | else
31 | echo "Skipping .env copying"
32 | fi
33 |
34 | echo "Starting the bot..."
35 | python3 main.py
36 |
37 | echo "done"
38 | echo "PLEASE EDIT .ENV FILE"
39 |
--------------------------------------------------------------------------------