maxapi-python 1.1.19__tar.gz → 1.1.21__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- maxapi_python-1.1.21/.coderabbit.yaml +6 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/PKG-INFO +37 -54
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/README.md +36 -53
- maxapi_python-1.1.21/examples/example.py +272 -0
- maxapi_python-1.1.21/examples/flt_test.py +51 -0
- maxapi_python-1.1.21/examples/large_file_upload.py +51 -0
- maxapi_python-1.1.21/examples/reg.py +34 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/examples/telegram_bridge.py +30 -46
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/pyproject.toml +4 -1
- maxapi_python-1.1.21/pytest.ini +6 -0
- maxapi_python-1.1.21/redocs/Makefile +20 -0
- maxapi_python-1.1.21/redocs/build.sh +1 -0
- maxapi_python-1.1.21/redocs/make.bat +35 -0
- maxapi_python-1.1.21/redocs/source/_static/logo.svg +13 -0
- maxapi_python-1.1.21/redocs/source/clients.rst +126 -0
- maxapi_python-1.1.21/redocs/source/conf.py +49 -0
- maxapi_python-1.1.21/redocs/source/decorators.rst +6 -0
- maxapi_python-1.1.21/redocs/source/examples.rst +374 -0
- maxapi_python-1.1.21/redocs/source/guides.rst +483 -0
- maxapi_python-1.1.21/redocs/source/index.rst +112 -0
- maxapi_python-1.1.21/redocs/source/installation.rst +151 -0
- maxapi_python-1.1.21/redocs/source/quickstart.rst +246 -0
- maxapi_python-1.1.21/redocs/source/types.rst +8 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/core.py +167 -55
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/crud.py +4 -8
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/files.py +15 -12
- maxapi_python-1.1.21/src/pymax/filters.py +164 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/formatter.py +1 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/interfaces.py +20 -10
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/mixins/__init__.py +3 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/mixins/auth.py +75 -18
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/mixins/channel.py +41 -42
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/mixins/group.py +182 -3
- maxapi_python-1.1.21/src/pymax/mixins/handler.py +291 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/mixins/message.py +311 -80
- maxapi_python-1.1.21/src/pymax/mixins/scheduler.py +28 -0
- maxapi_python-1.1.21/src/pymax/mixins/self.py +194 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/mixins/socket.py +267 -254
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/mixins/user.py +63 -42
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/mixins/websocket.py +145 -136
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/payloads.py +48 -3
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/static/constant.py +4 -2
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/static/enum.py +1 -1
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/types.py +114 -2
- maxapi_python-1.1.19/docs/api.md +0 -480
- maxapi_python-1.1.19/docs/assets/icon.svg +0 -13
- maxapi_python-1.1.19/docs/client.md +0 -286
- maxapi_python-1.1.19/docs/examples.md +0 -418
- maxapi_python-1.1.19/docs/index.md +0 -43
- maxapi_python-1.1.19/docs/methods.md +0 -499
- maxapi_python-1.1.19/docs/types.md +0 -314
- maxapi_python-1.1.19/examples/example.py +0 -166
- maxapi_python-1.1.19/src/pymax/filters.py +0 -47
- maxapi_python-1.1.19/src/pymax/mixins/handler.py +0 -166
- maxapi_python-1.1.19/src/pymax/mixins/self.py +0 -41
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/.github/FUNDING.yml +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/.github/ISSUE_TEMPLATE/refactor.md +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/.github/pull_request_template.md +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/.github/workflows/publish.yml +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/.gitignore +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/.pre-commit-config.yaml +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/LICENSE +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/assets/icon.svg +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/assets/logo.svg +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/mkdocs.yml +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/ruff.toml +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/__init__.py +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/exceptions.py +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/formatting.py +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/mixins/telemetry.py +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/mixins/utils.py +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/models.py +0 -0
- {maxapi_python-1.1.19 → maxapi_python-1.1.21}/src/pymax/navigation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maxapi-python
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.21
|
|
4
4
|
Summary: Python wrapper для API мессенджера Max
|
|
5
5
|
Project-URL: Homepage, https://github.com/ink-developer/PyMax
|
|
6
6
|
Project-URL: Repository, https://github.com/ink-developer/PyMax
|
|
@@ -79,65 +79,47 @@ uv add -U maxapi-python
|
|
|
79
79
|
|
|
80
80
|
```python
|
|
81
81
|
import asyncio
|
|
82
|
+
|
|
82
83
|
from pymax import MaxClient, Message
|
|
84
|
+
from pymax.filters import Filters
|
|
85
|
+
|
|
86
|
+
client = MaxClient(
|
|
87
|
+
phone="+1234567890",
|
|
88
|
+
work_dir="cache", # директория для сессий
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
# Обработка входящих сообщений
|
|
93
|
+
@client.on_message(Filters.chat(0)) # фильтр по ID чата
|
|
94
|
+
async def on_message(msg: Message) -> None:
|
|
95
|
+
print(f"[{msg.sender}] {msg.text}")
|
|
83
96
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
97
|
+
await client.send_message(
|
|
98
|
+
chat_id=msg.chat_id,
|
|
99
|
+
text="Привет, я бот на PyMax!",
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
await client.add_reaction(
|
|
103
|
+
chat_id=msg.chat_id,
|
|
104
|
+
message_id=str(msg.id),
|
|
105
|
+
reaction="👍",
|
|
106
|
+
)
|
|
87
107
|
|
|
88
|
-
# Обработчик входящих сообщений
|
|
89
|
-
@client.on_message()
|
|
90
|
-
async def handle_message(message: Message) -> None:
|
|
91
|
-
print(f"{message.sender}: {message.text}")
|
|
92
108
|
|
|
93
|
-
# Обработчик запуска клиента
|
|
94
109
|
@client.on_start
|
|
95
|
-
async def
|
|
96
|
-
print("Клиент
|
|
110
|
+
async def on_start() -> None:
|
|
111
|
+
print(f"Клиент запущен. Ваш ID: {client.me.id}")
|
|
97
112
|
|
|
98
|
-
# Получение истории
|
|
113
|
+
# Получение истории
|
|
99
114
|
history = await client.fetch_history(chat_id=0)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
# Работа с чатами
|
|
110
|
-
for chat in client.chats:
|
|
111
|
-
print(f"Чат: {chat.title}")
|
|
112
|
-
|
|
113
|
-
# Отправка сообщения
|
|
114
|
-
message = await client.send_message(
|
|
115
|
-
"Привет от PyMax!",
|
|
116
|
-
chat.id,
|
|
117
|
-
notify=True
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
# Редактирование сообщения
|
|
121
|
-
await asyncio.sleep(2)
|
|
122
|
-
await client.edit_message(
|
|
123
|
-
chat.id,
|
|
124
|
-
message.id,
|
|
125
|
-
"Привет от PyMax! (отредактировано)"
|
|
126
|
-
)
|
|
127
|
-
|
|
128
|
-
# Удаление сообщения
|
|
129
|
-
await asyncio.sleep(2)
|
|
130
|
-
await client.delete_message(chat.id, [message.id], for_me=False)
|
|
131
|
-
|
|
132
|
-
# Работа с диалогами
|
|
133
|
-
for dialog in client.dialogs:
|
|
134
|
-
print(f"Диалог: {dialog.last_message.text}")
|
|
135
|
-
|
|
136
|
-
# Работа с каналами
|
|
137
|
-
for channel in client.channels:
|
|
138
|
-
print(f"Канал: {channel.title}")
|
|
139
|
-
|
|
140
|
-
await client.close()
|
|
115
|
+
print("Последние сообщения из чата 0:")
|
|
116
|
+
for m in history:
|
|
117
|
+
print(f"- {m.text}")
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
async def main():
|
|
121
|
+
await client.start() # подключение и авторизация
|
|
122
|
+
|
|
141
123
|
|
|
142
124
|
if __name__ == "__main__":
|
|
143
125
|
asyncio.run(main())
|
|
@@ -145,7 +127,8 @@ if __name__ == "__main__":
|
|
|
145
127
|
|
|
146
128
|
## Документация
|
|
147
129
|
|
|
148
|
-
[
|
|
130
|
+
[GitHub Pages](https://maxapiteam.github.io/PyMax/)
|
|
131
|
+
[DeepWiki](https://deepwiki.com/MaxApiTeam/PyMax)
|
|
149
132
|
|
|
150
133
|
## Лицензия
|
|
151
134
|
|
|
@@ -57,65 +57,47 @@ uv add -U maxapi-python
|
|
|
57
57
|
|
|
58
58
|
```python
|
|
59
59
|
import asyncio
|
|
60
|
+
|
|
60
61
|
from pymax import MaxClient, Message
|
|
62
|
+
from pymax.filters import Filters
|
|
63
|
+
|
|
64
|
+
client = MaxClient(
|
|
65
|
+
phone="+1234567890",
|
|
66
|
+
work_dir="cache", # директория для сессий
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# Обработка входящих сообщений
|
|
71
|
+
@client.on_message(Filters.chat(0)) # фильтр по ID чата
|
|
72
|
+
async def on_message(msg: Message) -> None:
|
|
73
|
+
print(f"[{msg.sender}] {msg.text}")
|
|
61
74
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
75
|
+
await client.send_message(
|
|
76
|
+
chat_id=msg.chat_id,
|
|
77
|
+
text="Привет, я бот на PyMax!",
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
await client.add_reaction(
|
|
81
|
+
chat_id=msg.chat_id,
|
|
82
|
+
message_id=str(msg.id),
|
|
83
|
+
reaction="👍",
|
|
84
|
+
)
|
|
65
85
|
|
|
66
|
-
# Обработчик входящих сообщений
|
|
67
|
-
@client.on_message()
|
|
68
|
-
async def handle_message(message: Message) -> None:
|
|
69
|
-
print(f"{message.sender}: {message.text}")
|
|
70
86
|
|
|
71
|
-
# Обработчик запуска клиента
|
|
72
87
|
@client.on_start
|
|
73
|
-
async def
|
|
74
|
-
print("Клиент
|
|
88
|
+
async def on_start() -> None:
|
|
89
|
+
print(f"Клиент запущен. Ваш ID: {client.me.id}")
|
|
75
90
|
|
|
76
|
-
# Получение истории
|
|
91
|
+
# Получение истории
|
|
77
92
|
history = await client.fetch_history(chat_id=0)
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
# Работа с чатами
|
|
88
|
-
for chat in client.chats:
|
|
89
|
-
print(f"Чат: {chat.title}")
|
|
90
|
-
|
|
91
|
-
# Отправка сообщения
|
|
92
|
-
message = await client.send_message(
|
|
93
|
-
"Привет от PyMax!",
|
|
94
|
-
chat.id,
|
|
95
|
-
notify=True
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
# Редактирование сообщения
|
|
99
|
-
await asyncio.sleep(2)
|
|
100
|
-
await client.edit_message(
|
|
101
|
-
chat.id,
|
|
102
|
-
message.id,
|
|
103
|
-
"Привет от PyMax! (отредактировано)"
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
# Удаление сообщения
|
|
107
|
-
await asyncio.sleep(2)
|
|
108
|
-
await client.delete_message(chat.id, [message.id], for_me=False)
|
|
109
|
-
|
|
110
|
-
# Работа с диалогами
|
|
111
|
-
for dialog in client.dialogs:
|
|
112
|
-
print(f"Диалог: {dialog.last_message.text}")
|
|
113
|
-
|
|
114
|
-
# Работа с каналами
|
|
115
|
-
for channel in client.channels:
|
|
116
|
-
print(f"Канал: {channel.title}")
|
|
117
|
-
|
|
118
|
-
await client.close()
|
|
93
|
+
print("Последние сообщения из чата 0:")
|
|
94
|
+
for m in history:
|
|
95
|
+
print(f"- {m.text}")
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
async def main():
|
|
99
|
+
await client.start() # подключение и авторизация
|
|
100
|
+
|
|
119
101
|
|
|
120
102
|
if __name__ == "__main__":
|
|
121
103
|
asyncio.run(main())
|
|
@@ -123,7 +105,8 @@ if __name__ == "__main__":
|
|
|
123
105
|
|
|
124
106
|
## Документация
|
|
125
107
|
|
|
126
|
-
[
|
|
108
|
+
[GitHub Pages](https://maxapiteam.github.io/PyMax/)
|
|
109
|
+
[DeepWiki](https://deepwiki.com/MaxApiTeam/PyMax)
|
|
127
110
|
|
|
128
111
|
## Лицензия
|
|
129
112
|
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import datetime
|
|
3
|
+
import logging
|
|
4
|
+
from time import time
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
import pymax
|
|
8
|
+
from pymax import MaxClient, Message, ReactionInfo, SocketMaxClient
|
|
9
|
+
from pymax.files import File, Video
|
|
10
|
+
from pymax.payloads import UserAgentPayload
|
|
11
|
+
from pymax.static.enum import AttachType, Opcode
|
|
12
|
+
from pymax.types import Chat
|
|
13
|
+
|
|
14
|
+
phone = "+7903223111"
|
|
15
|
+
headers = UserAgentPayload(device_type="WEB")
|
|
16
|
+
|
|
17
|
+
client = MaxClient(
|
|
18
|
+
phone=phone,
|
|
19
|
+
work_dir="cache",
|
|
20
|
+
reconnect=False,
|
|
21
|
+
logger=None,
|
|
22
|
+
headers=headers,
|
|
23
|
+
)
|
|
24
|
+
client.logger.setLevel(logging.INFO)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@client.on_raw_receive
|
|
28
|
+
async def handle_raw_receive(data: dict[str, Any]) -> None:
|
|
29
|
+
print(f"Raw data received: {data}")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@client.task(seconds=10)
|
|
33
|
+
async def periodic_task() -> None:
|
|
34
|
+
# print(f"Periodic task executed at {datetime.datetime.now()}")
|
|
35
|
+
...
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@client.on_start
|
|
39
|
+
async def handle_start() -> None:
|
|
40
|
+
print(f"Client started as {client.me.names[0].first_name}!")
|
|
41
|
+
|
|
42
|
+
chat_id = -1
|
|
43
|
+
max_messages = 1000
|
|
44
|
+
messages = []
|
|
45
|
+
from_time = int(time() * 1000)
|
|
46
|
+
while len(messages) < max_messages:
|
|
47
|
+
r = await client.fetch_history(
|
|
48
|
+
chat_id=chat_id, from_time=from_time, backward=30
|
|
49
|
+
)
|
|
50
|
+
if not r:
|
|
51
|
+
break
|
|
52
|
+
from_time = r[0].time
|
|
53
|
+
messages.extend(r)
|
|
54
|
+
print(f"First message time: {from_time}, id: {r[0].id}, text: {r[0].text}")
|
|
55
|
+
print(f"Last message time: {from_time}, id: {r[-1].id}, text: {r[-1].text}")
|
|
56
|
+
print(f"Loaded {len(messages)}/{max_messages} messages...")
|
|
57
|
+
# channel = await client.resolve_channel_by_name("fm92")
|
|
58
|
+
# if channel:
|
|
59
|
+
# print(f"Resolved channel by name: {channel.title}, ID: {channel.id}")
|
|
60
|
+
# else:
|
|
61
|
+
# print("Channel not found by name.")
|
|
62
|
+
|
|
63
|
+
# channel = await client.join_channel(link)
|
|
64
|
+
# if channel:
|
|
65
|
+
# print(f"Joined channel: {channel.title}, ID: {channel.id}")
|
|
66
|
+
# else:
|
|
67
|
+
# print("Failed to join channel.")
|
|
68
|
+
# await client.send_message(
|
|
69
|
+
# "Hello! The client has started successfully.",
|
|
70
|
+
# chat_id=2265456546456,
|
|
71
|
+
# notify=True,
|
|
72
|
+
# )
|
|
73
|
+
# folder_update = await client.create_folder(
|
|
74
|
+
# title="My Folder",
|
|
75
|
+
# chat_include=[0],
|
|
76
|
+
# )
|
|
77
|
+
# print(f"Folder created: {folder_update.folder.title}")
|
|
78
|
+
# video_path = "tests2/test.mp4"
|
|
79
|
+
# video_file = Video(path=video_path)
|
|
80
|
+
|
|
81
|
+
# await client.send_message(
|
|
82
|
+
# text="Here is the video you requested.",
|
|
83
|
+
# chat_id=0,
|
|
84
|
+
# attachment=video_file,
|
|
85
|
+
# notify=True,
|
|
86
|
+
# )
|
|
87
|
+
# chat_id = -6970655
|
|
88
|
+
# for chat in client.chats:
|
|
89
|
+
# if chat.id == chat_id:
|
|
90
|
+
# print(f"Found chat: {chat.title}, ID: {chat.id}")
|
|
91
|
+
# members_count = chat.participants_count
|
|
92
|
+
# marker = 0
|
|
93
|
+
# member_list = []
|
|
94
|
+
# while len(member_list) < members_count:
|
|
95
|
+
# await asyncio.sleep(10)
|
|
96
|
+
# r = await client.load_members(
|
|
97
|
+
# chat_id=chat_id,
|
|
98
|
+
# marker=marker,
|
|
99
|
+
# count=200,
|
|
100
|
+
# )
|
|
101
|
+
# members, marker = r
|
|
102
|
+
# member_list.extend(members)
|
|
103
|
+
# print(f"Loaded {len(member_list)}/{members_count} members...")
|
|
104
|
+
# for member in member_list:
|
|
105
|
+
# print(
|
|
106
|
+
# f"Member {member.contact.names[0].first_name}, ID: {member.contact.id}"
|
|
107
|
+
# )
|
|
108
|
+
# r = await client.load_members(chat_id=chat_id, count=50)
|
|
109
|
+
# print(f"Loaded {len(r)} members from chat {chat_id}")
|
|
110
|
+
# member_list, marker = r
|
|
111
|
+
# for member in member_list:
|
|
112
|
+
# print(f"Member {member.contact.names[0].first_name}, ID: {member.contact.id}")
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
# @client.on_reaction_change
|
|
116
|
+
# async def handle_reaction_change(
|
|
117
|
+
# message_id: str, chat_id: int, reaction_info: ReactionInfo
|
|
118
|
+
# ) -> None:
|
|
119
|
+
# print(
|
|
120
|
+
# f"Reaction changed on message {message_id} in chat {chat_id}: "
|
|
121
|
+
# f"Total count: {reaction_info.total_count}, "
|
|
122
|
+
# f"Your reaction: {reaction_info.your_reaction}, "
|
|
123
|
+
# f"Counters: {reaction_info.counters[0].reaction}={reaction_info.counters[0].count}"
|
|
124
|
+
# )
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
# @client.on_chat_update
|
|
128
|
+
# async def handle_chat_update(chat: Chat) -> None:
|
|
129
|
+
# print(f"Chat updated: {chat.id}, new title: {chat.title}")
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
@client.on_message()
|
|
133
|
+
async def handle_message(message: Message) -> None:
|
|
134
|
+
print(
|
|
135
|
+
f"New message in chat {message.chat_id} from {message.sender}: {message.text}"
|
|
136
|
+
)
|
|
137
|
+
# if message.link and message.link.message.attaches:
|
|
138
|
+
# for attach in message.link.message.attaches:
|
|
139
|
+
# print(f"Link attach type: {attach.type}")
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
@client.on_message_edit()
|
|
143
|
+
async def handle_edited_message(message: Message) -> None:
|
|
144
|
+
print(f"Edited message in chat {message.chat_id}: {message.text}")
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
@client.on_message_delete()
|
|
148
|
+
async def handle_deleted_message(message: Message) -> None:
|
|
149
|
+
print(f"Deleted message in chat {message.chat_id}: {message.id}")
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
# async def login_flow_test():
|
|
153
|
+
# await client.connect()
|
|
154
|
+
# temp_token = await client.request_code(phone)
|
|
155
|
+
# code = input("Введите код: ").strip()
|
|
156
|
+
# await client.login_with_code(temp_token, code)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# asyncio.run(login_flow_test())
|
|
160
|
+
|
|
161
|
+
# @client.on_message(filter=Filter(chat_id=0))
|
|
162
|
+
# async def handle_message(message: Message) -> None:
|
|
163
|
+
# print(str(message.sender) + ": " + message.text)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
# @client.on_message_edit()
|
|
167
|
+
# async def handle_edited_message(message: Message) -> None:
|
|
168
|
+
# print(f"Edited message in chat {message.chat_id}: {message.text}")
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
# @client.on_message_delete()
|
|
172
|
+
# async def handle_deleted_message(message: Message) -> None:
|
|
173
|
+
# print(f"Deleted message in chat {message.chat_id}: {message.id}")
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
# @client.on_start
|
|
177
|
+
# async def handle_start() -> None:
|
|
178
|
+
# print(f"Client started successfully at {datetime.datetime.now()}!")
|
|
179
|
+
# print(client.me.id)
|
|
180
|
+
|
|
181
|
+
# await client.send_message(
|
|
182
|
+
# "Hello, this is a test message sent upon client start!",
|
|
183
|
+
# chat_id=23424,
|
|
184
|
+
# notify=True,
|
|
185
|
+
# )
|
|
186
|
+
# file_path = "ruff.toml"
|
|
187
|
+
# file = File(path=file_path)
|
|
188
|
+
# msg = await client.send_message(
|
|
189
|
+
# text="Here is the file you requested.",
|
|
190
|
+
# chat_id=0,
|
|
191
|
+
# attachment=file,
|
|
192
|
+
# notify=True,
|
|
193
|
+
# )
|
|
194
|
+
# if msg:
|
|
195
|
+
# print(f"File sent successfully in message ID: {msg.id}")
|
|
196
|
+
# history = await client.fetch_history(chat_id=0)
|
|
197
|
+
# if history:
|
|
198
|
+
# for message in history:
|
|
199
|
+
# if message.attaches:
|
|
200
|
+
# for attach in message.attaches:
|
|
201
|
+
# if attach.type == AttachType.AUDIO:
|
|
202
|
+
# print(attach.url)
|
|
203
|
+
# chat = await client.rework_invite_link(chat_id=0)
|
|
204
|
+
# print(chat.link)
|
|
205
|
+
# text = """
|
|
206
|
+
# **123**
|
|
207
|
+
# *123*
|
|
208
|
+
# __123__
|
|
209
|
+
# ~~123~~
|
|
210
|
+
# """
|
|
211
|
+
# message = await client.send_message(text, chat_id=0, notify=True)
|
|
212
|
+
# react_info = await client.add_reaction(
|
|
213
|
+
# chat_id=0, message_id="115368067020359151", reaction="👍"
|
|
214
|
+
# )
|
|
215
|
+
# if react_info:
|
|
216
|
+
# print("Reaction added!")
|
|
217
|
+
# print(react_info.total_count)
|
|
218
|
+
# react_info = await client.get_reactions(
|
|
219
|
+
# chat_id=0, message_ids=["115368067020359151"]
|
|
220
|
+
# )
|
|
221
|
+
# if react_info:
|
|
222
|
+
# print("Reactions fetched!")
|
|
223
|
+
# for msg_id, info in react_info.items():
|
|
224
|
+
# print(f"Message ID: {msg_id}, Total Reactions: {info.total_count}")
|
|
225
|
+
# react_info = await client.remove_reaction(
|
|
226
|
+
# chat_id=0, message_id="115368067020359151"
|
|
227
|
+
# )
|
|
228
|
+
# if react_info:
|
|
229
|
+
# print("Reaction removed!")
|
|
230
|
+
# print(react_info.total_count)
|
|
231
|
+
# print(client.dialogs)
|
|
232
|
+
|
|
233
|
+
# if history:
|
|
234
|
+
# for message in history:
|
|
235
|
+
# if message.link:
|
|
236
|
+
# print(message.link.chat_id)
|
|
237
|
+
# print(message.link.message.text)
|
|
238
|
+
# for attach in message.attaches:
|
|
239
|
+
# if attach.type == AttachType.CONTROL:
|
|
240
|
+
# print(attach.event)
|
|
241
|
+
# print(attach.extra)
|
|
242
|
+
# if attach.type == AttachType.VIDEO:
|
|
243
|
+
# print(message)
|
|
244
|
+
# vid = await client.get_video_by_id(
|
|
245
|
+
# chat_id=0,
|
|
246
|
+
# video_id=attach.video_id,
|
|
247
|
+
# message_id=message.id,
|
|
248
|
+
# )
|
|
249
|
+
# print(vid.url)
|
|
250
|
+
# elif attach.type == AttachType.FILE:
|
|
251
|
+
# file = await client.get_file_by_id(
|
|
252
|
+
# chat_id=0,
|
|
253
|
+
# file_id=attach.file_id,
|
|
254
|
+
# message_id=message.id,
|
|
255
|
+
# )
|
|
256
|
+
# print(file.url)
|
|
257
|
+
# print(client.me.names[0].first_name)
|
|
258
|
+
# user = await client.get_user(client.me.id)
|
|
259
|
+
|
|
260
|
+
# photo1 = Photo(path="tests/test.jpeg")
|
|
261
|
+
# photo2 = Photo(path="tests/test.jpg")
|
|
262
|
+
|
|
263
|
+
# await client.send_message(
|
|
264
|
+
# "Hello with photo!", chat_id=0, photos=[photo1, photo2], notify=True
|
|
265
|
+
# )
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
if __name__ == "__main__":
|
|
269
|
+
try:
|
|
270
|
+
asyncio.run(client.start())
|
|
271
|
+
except KeyboardInterrupt:
|
|
272
|
+
print("Client stopped by user")
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
3
|
+
|
|
4
|
+
import pymax
|
|
5
|
+
import pymax.static
|
|
6
|
+
from pymax import MaxClient
|
|
7
|
+
from pymax.filters import Filters
|
|
8
|
+
from pymax.payloads import UserAgentPayload
|
|
9
|
+
from pymax.static.enum import Opcode
|
|
10
|
+
|
|
11
|
+
phone = "+7903223423"
|
|
12
|
+
headers = UserAgentPayload(device_type="WEB")
|
|
13
|
+
|
|
14
|
+
client = MaxClient(
|
|
15
|
+
phone=phone,
|
|
16
|
+
work_dir="cache",
|
|
17
|
+
reconnect=False,
|
|
18
|
+
logger=None,
|
|
19
|
+
headers=headers,
|
|
20
|
+
)
|
|
21
|
+
client.logger.setLevel(logging.DEBUG)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@client.task(seconds=10)
|
|
25
|
+
async def periodic_task() -> None:
|
|
26
|
+
client.logger.info("Periodic task executed")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@client.on_message(Filters.text("test") & ~Filters.chat(0))
|
|
30
|
+
async def handle_message(message: pymax.Message) -> None:
|
|
31
|
+
print(f"New message from {message.sender}: {message.text}")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@client.on_start
|
|
35
|
+
async def on_start():
|
|
36
|
+
print("Client started")
|
|
37
|
+
data = await client._send_and_wait(
|
|
38
|
+
opcode=Opcode.FILE_UPLOAD,
|
|
39
|
+
payload={"count": 1},
|
|
40
|
+
)
|
|
41
|
+
print("File upload response:", data)
|
|
42
|
+
# opcode=pymax.static.enum.Opcode.CHATS_LIST,
|
|
43
|
+
# payload={
|
|
44
|
+
# "marker": 1765721869777,
|
|
45
|
+
# },
|
|
46
|
+
# )
|
|
47
|
+
|
|
48
|
+
# print("Chats list:", data)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
asyncio.run(client.start())
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from pymax import MaxClient
|
|
6
|
+
from pymax.files import File, Video
|
|
7
|
+
|
|
8
|
+
client = MaxClient(phone="+1234567890", work_dir="cache", reconnect=False)
|
|
9
|
+
client.logger.setLevel(logging.INFO)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def create_big_file(file_path: Path, size_in_mb: int) -> None:
|
|
13
|
+
with open(file_path, "wb") as f:
|
|
14
|
+
f.seek(size_in_mb * 1024 * 1024 - 1)
|
|
15
|
+
f.write(b"\0")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@client.on_start
|
|
19
|
+
async def upload_large_file_example():
|
|
20
|
+
await asyncio.sleep(2)
|
|
21
|
+
|
|
22
|
+
file_path = Path("tests2/large_file.dat")
|
|
23
|
+
|
|
24
|
+
if not file_path.exists():
|
|
25
|
+
create_big_file(file_path, size_in_mb=300)
|
|
26
|
+
file_size = file_path.stat().st_size
|
|
27
|
+
client.logger.info(f"File size: {file_size / (1024 * 1024):.2f} MB")
|
|
28
|
+
|
|
29
|
+
file = File(path=str(file_path))
|
|
30
|
+
chat_id = 0
|
|
31
|
+
|
|
32
|
+
client.logger.info("Starting file upload...")
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
await client.send_message(
|
|
36
|
+
chat_id=chat_id,
|
|
37
|
+
text="📎 Вот большой файл",
|
|
38
|
+
attachment=file,
|
|
39
|
+
)
|
|
40
|
+
client.logger.info("File uploaded successfully!")
|
|
41
|
+
|
|
42
|
+
except OSError as e:
|
|
43
|
+
if "malloc failure" in str(e):
|
|
44
|
+
client.logger.error("Memory error - file too large for current memory")
|
|
45
|
+
client.logger.info("Recommendation: Upload smaller files or free up memory")
|
|
46
|
+
else:
|
|
47
|
+
raise
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
if __name__ == "__main__":
|
|
51
|
+
asyncio.run(client.start())
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
|
|
3
|
+
from pymax import MaxClient, Message
|
|
4
|
+
from pymax.filters import Filters
|
|
5
|
+
|
|
6
|
+
client = MaxClient(
|
|
7
|
+
phone="+1234567890",
|
|
8
|
+
work_dir="cache",
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@client.on_message(Filters.chat(0))
|
|
13
|
+
async def on_message(msg: Message):
|
|
14
|
+
print(f"[{msg.sender}] {msg.text}")
|
|
15
|
+
await client.send_message(chat_id=msg.chat_id, text="Привет!")
|
|
16
|
+
await client.add_reaction(
|
|
17
|
+
chat_id=msg.chat_id, message_id=str(msg.id), reaction="👍"
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@client.on_start
|
|
22
|
+
async def on_start():
|
|
23
|
+
print(f"Клиент запущен. Ваш ID: {client.me.id}")
|
|
24
|
+
history = await client.fetch_history(chat_id=0)
|
|
25
|
+
for m in history:
|
|
26
|
+
print(f"- {m.text}")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
async def main():
|
|
30
|
+
await client.start()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
if __name__ == "__main__":
|
|
34
|
+
asyncio.run(main())
|