wintergram-userbot 1.2__tar.gz → 1.3__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.
Files changed (40) hide show
  1. {wintergram_userbot-1.2/wintergram_userbot.egg-info → wintergram_userbot-1.3}/PKG-INFO +3 -2
  2. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/README.md +2 -1
  3. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/pyproject.toml +1 -1
  4. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/__init__.py +1 -1
  5. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/api/functions.py +10 -0
  6. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/api/updates.py +31 -1
  7. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/client.py +47 -1
  8. {wintergram_userbot-1.2 → wintergram_userbot-1.3/wintergram_userbot.egg-info}/PKG-INFO +3 -2
  9. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/MANIFEST.in +0 -0
  10. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/setup.cfg +0 -0
  11. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/api/__init__.py +0 -0
  12. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/crypto/__init__.py +0 -0
  13. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/crypto/aes.py +0 -0
  14. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/crypto/auth_key.py +0 -0
  15. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/crypto/dh.py +0 -0
  16. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/crypto/rsa.py +0 -0
  17. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/crypto/srp.py +0 -0
  18. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/errors.py +0 -0
  19. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/network/__init__.py +0 -0
  20. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/network/connection.py +0 -0
  21. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/network/mtproto.py +0 -0
  22. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/network/transport.py +0 -0
  23. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/session/__init__.py +0 -0
  24. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/session/session.py +0 -0
  25. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/session/storage.py +0 -0
  26. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/tl/__init__.py +0 -0
  27. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/tl/schema_resolver.py +0 -0
  28. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/tl/schemas/__init__.py +0 -0
  29. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/tl/schemas/data/core.json +0 -0
  30. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/tl/schemas/data/latest.json +0 -0
  31. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/tl/schemas/data/v113.json +0 -0
  32. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/tl/schemas/data/v119.json +0 -0
  33. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/tl/schemas/data/v128.json +0 -0
  34. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/tl/schemas/data/v133.json +0 -0
  35. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/tl/serializer.py +0 -0
  36. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot/tl/types.py +0 -0
  37. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot.egg-info/SOURCES.txt +0 -0
  38. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot.egg-info/dependency_links.txt +0 -0
  39. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot.egg-info/requires.txt +0 -0
  40. {wintergram_userbot-1.2 → wintergram_userbot-1.3}/wintergram_userbot.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wintergram-userbot
3
- Version: 1.2
3
+ Version: 1.3
4
4
  Summary: WinterGram Userbot for custom MTProto server
5
5
  Author: WinterGram Team
6
6
  Requires-Python: >=3.8
@@ -122,7 +122,7 @@ history = await client.get_history(chat_id, limit=50)
122
122
  ### Свойства события
123
123
 
124
124
  - `event.id` — ID сообщения
125
- - `event.text` — текст сообщения (bytes или str)
125
+ - `event.text` — текст сообщения (всегда `str`)
126
126
  - `event.date` — время отправки
127
127
  - `event.chat_id` — ID чата
128
128
  - `event.sender_id` — ID отправителя
@@ -130,6 +130,7 @@ history = await client.get_history(chat_id, limit=50)
130
130
  - `event.is_private` — True если личное сообщение
131
131
  - `event.is_channel` — True если сообщение из канала
132
132
  - `event.from_channel` — True если отправлено каналом
133
+ - `event.message` — внутренний dict сообщения (текст тоже `str`)
133
134
 
134
135
  ## Требования
135
136
 
@@ -111,7 +111,7 @@ history = await client.get_history(chat_id, limit=50)
111
111
  ### Свойства события
112
112
 
113
113
  - `event.id` — ID сообщения
114
- - `event.text` — текст сообщения (bytes или str)
114
+ - `event.text` — текст сообщения (всегда `str`)
115
115
  - `event.date` — время отправки
116
116
  - `event.chat_id` — ID чата
117
117
  - `event.sender_id` — ID отправителя
@@ -119,6 +119,7 @@ history = await client.get_history(chat_id, limit=50)
119
119
  - `event.is_private` — True если личное сообщение
120
120
  - `event.is_channel` — True если сообщение из канала
121
121
  - `event.from_channel` — True если отправлено каналом
122
+ - `event.message` — внутренний dict сообщения (текст тоже `str`)
122
123
 
123
124
  ## Требования
124
125
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "wintergram-userbot"
7
- version = "1.2"
7
+ version = "1.3"
8
8
  description = "WinterGram Userbot for custom MTProto server"
9
9
  readme = "README.md"
10
10
  authors = [{name = "WinterGram Team"}]
@@ -4,7 +4,7 @@
4
4
  Поддерживаются слои (layers) от 167 до 228 включительно.
5
5
  """
6
6
 
7
- __version__ = "1.2"
7
+ __version__ = "1.3"
8
8
 
9
9
  from .client import WinterGramClient
10
10
  from .errors import (
@@ -183,6 +183,16 @@ class Functions:
183
183
  """users.getUsers([InputUser...])."""
184
184
  return await self.conn.rpc("users.getUsers", {"id": ids})
185
185
 
186
+ async def resolve_username(self, username: str):
187
+ """contacts.resolveUsername - ищет пользователя по @юзернейму.
188
+
189
+ Returns:
190
+ contacts.ResolvedPeer с полями peer, users, chats
191
+ """
192
+ return await self.conn.rpc("contacts.resolveUsername", {
193
+ "username": (username or "").strip().lstrip("@"),
194
+ })
195
+
186
196
  # ------------------------------------------------------------------ #
187
197
  # отправка / история
188
198
  # ------------------------------------------------------------------ #
@@ -27,6 +27,15 @@ def _as_dict(obj):
27
27
  return dict(obj)
28
28
 
29
29
 
30
+ def _as_text(value):
31
+ """TL-строки приходят как bytes - приводим к str."""
32
+ if value is None:
33
+ return ""
34
+ if isinstance(value, (bytes, bytearray)):
35
+ return bytes(value).decode("utf-8", "replace")
36
+ return str(value)
37
+
38
+
30
39
  class Event:
31
40
  """Базовое событие."""
32
41
 
@@ -37,6 +46,27 @@ class Event:
37
46
  def raw_dict(self):
38
47
  return _as_dict(self.raw)
39
48
 
49
+ @property
50
+ def message(self):
51
+ """Внутренний dict сообщения (updateNewMessage.message и т.п.).
52
+
53
+ Для updateShort* апдейтов, где сообщение лежит прямо в update,
54
+ возвращается сам update. Текст нормализован в str.
55
+ """
56
+ d = _as_dict(self.raw)
57
+ inner = d.get("message")
58
+ # у updateNew* поле message - вложенный dict, у updateShort* - строка
59
+ if isinstance(inner, (dict, TLObject)):
60
+ m = _as_dict(inner)
61
+ if isinstance(m.get("message"), (bytes, bytearray)):
62
+ m = dict(m)
63
+ m["message"] = _as_text(m["message"])
64
+ return m
65
+ if isinstance(inner, (bytes, bytearray)):
66
+ d = dict(d)
67
+ d["message"] = _as_text(inner)
68
+ return d
69
+
40
70
 
41
71
  class NewMessage(Event):
42
72
  """Новое сообщение.
@@ -48,7 +78,7 @@ class NewMessage(Event):
48
78
  sender_id=None, out=False, from_channel=False):
49
79
  super().__init__(raw)
50
80
  self.id = id
51
- self.text = text
81
+ self.text = _as_text(text)
52
82
  self.date = date
53
83
  self.chat_id = chat_id
54
84
  self.sender_id = sender_id
@@ -778,13 +778,59 @@ class WinterGramClient:
778
778
  return self.functions.input_peer_self()
779
779
  return await self.resolve_peer(peer)
780
780
 
781
+ async def resolve_username(self, username):
782
+ """Ищет пользователя по юзернейму (с @ или без) через contacts.resolveUsername.
783
+
784
+ Args:
785
+ username: "@nick" или "nick"
786
+
787
+ Returns:
788
+ InputPeer текущей эры
789
+
790
+ Raises:
791
+ WinterGramError: если юзернейм не найден
792
+ """
793
+ name = (username or "").strip().lstrip("@")
794
+ if not name:
795
+ raise WinterGramError("empty username")
796
+
797
+ _, result = await self.functions.resolve_username(name)
798
+
799
+ peer = result.get("peer") or {}
800
+ users = result.get("users") or []
801
+ chats = result.get("chats") or []
802
+
803
+ if "user_id" in peer:
804
+ target_id = peer.get("user_id")
805
+ user = next((u for u in users if u.get("id") == target_id), None)
806
+ if user is None and users:
807
+ user = users[0]
808
+ if user is None or user.get("access_hash") is None:
809
+ raise WinterGramError("no access_hash for @%s" % name)
810
+ self.storage.store_peer(user["id"], user["access_hash"], "user")
811
+ return self.functions.input_peer_user(user["id"], user["access_hash"])
812
+
813
+ if "chat_id" in peer:
814
+ return self.functions.input_peer_chat(peer["chat_id"])
815
+
816
+ if "channel_id" in peer:
817
+ target_id = peer.get("channel_id")
818
+ chat = next((c for c in chats if c.get("id") == target_id), None)
819
+ access_hash = (chat or {}).get("access_hash", 0)
820
+ self.storage.store_peer(target_id, access_hash, "channel")
821
+ return self.functions.input_peer_channel(target_id, access_hash)
822
+
823
+ raise WinterGramError("username @%s not found" % name)
824
+
781
825
  async def resolve_peer(self, peer):
782
826
  """Пиринг в InputPeer текущей эры (по возможности через кэш)."""
783
827
  if isinstance(peer, str):
784
828
  low = peer.lower()
785
829
  if low in ("me", "self"):
786
830
  return self.functions.input_peer_self()
787
- raise RPCError(0, "username resolution not supported; pass id or 'me'")
831
+ if low.startswith("@") or peer[:1].isalpha() or "_" in peer:
832
+ return await self.resolve_username(peer)
833
+ raise RPCError(0, "pass id, 'me' or @username")
788
834
  peer_id = int(peer)
789
835
  cached = self.storage.get_peer(abs(peer_id)) if self.storage._db else None
790
836
  access_hash = cached[0] if cached else 0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wintergram-userbot
3
- Version: 1.2
3
+ Version: 1.3
4
4
  Summary: WinterGram Userbot for custom MTProto server
5
5
  Author: WinterGram Team
6
6
  Requires-Python: >=3.8
@@ -122,7 +122,7 @@ history = await client.get_history(chat_id, limit=50)
122
122
  ### Свойства события
123
123
 
124
124
  - `event.id` — ID сообщения
125
- - `event.text` — текст сообщения (bytes или str)
125
+ - `event.text` — текст сообщения (всегда `str`)
126
126
  - `event.date` — время отправки
127
127
  - `event.chat_id` — ID чата
128
128
  - `event.sender_id` — ID отправителя
@@ -130,6 +130,7 @@ history = await client.get_history(chat_id, limit=50)
130
130
  - `event.is_private` — True если личное сообщение
131
131
  - `event.is_channel` — True если сообщение из канала
132
132
  - `event.from_channel` — True если отправлено каналом
133
+ - `event.message` — внутренний dict сообщения (текст тоже `str`)
133
134
 
134
135
  ## Требования
135
136