jetrauserapi 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. jetrauserapi-1.0.0/CHANGELOG.md +23 -0
  2. jetrauserapi-1.0.0/LICENSE +21 -0
  3. jetrauserapi-1.0.0/MANIFEST.in +12 -0
  4. jetrauserapi-1.0.0/PKG-INFO +67 -0
  5. jetrauserapi-1.0.0/README.md +36 -0
  6. jetrauserapi-1.0.0/examples/01_send_to_user.py +33 -0
  7. jetrauserapi-1.0.0/examples/02_send_to_group.py +32 -0
  8. jetrauserapi-1.0.0/examples/03_send_to_saved.py +31 -0
  9. jetrauserapi-1.0.0/examples/04_list_groups.py +43 -0
  10. jetrauserapi-1.0.0/examples/05_list_users.py +43 -0
  11. jetrauserapi-1.0.0/examples/06_get_history.py +36 -0
  12. jetrauserapi-1.0.0/examples/07_listen_messages.py +44 -0
  13. jetrauserapi-1.0.0/examples/08_echo_bot.py +42 -0
  14. jetrauserapi-1.0.0/examples/09_command_bot.py +61 -0
  15. jetrauserapi-1.0.0/examples/10_auto_reply.py +57 -0
  16. jetrauserapi-1.0.0/examples/README.md +10 -0
  17. jetrauserapi-1.0.0/examples/login.py +162 -0
  18. jetrauserapi-1.0.0/jetrauserapi/__init__.py +7 -0
  19. jetrauserapi-1.0.0/jetrauserapi/client.py +548 -0
  20. jetrauserapi-1.0.0/jetrauserapi/config.py +12 -0
  21. jetrauserapi-1.0.0/jetrauserapi/database.py +112 -0
  22. jetrauserapi-1.0.0/jetrauserapi/high_level.py +519 -0
  23. jetrauserapi-1.0.0/jetrauserapi/message.py +62 -0
  24. jetrauserapi-1.0.0/jetrauserapi/session.py +75 -0
  25. jetrauserapi-1.0.0/jetrauserapi/tl_builder.py +105 -0
  26. jetrauserapi-1.0.0/jetrauserapi.egg-info/PKG-INFO +67 -0
  27. jetrauserapi-1.0.0/jetrauserapi.egg-info/SOURCES.txt +32 -0
  28. jetrauserapi-1.0.0/jetrauserapi.egg-info/dependency_links.txt +1 -0
  29. jetrauserapi-1.0.0/jetrauserapi.egg-info/requires.txt +2 -0
  30. jetrauserapi-1.0.0/jetrauserapi.egg-info/top_level.txt +1 -0
  31. jetrauserapi-1.0.0/pyproject.toml +35 -0
  32. jetrauserapi-1.0.0/requirements.txt +2 -0
  33. jetrauserapi-1.0.0/setup.cfg +4 -0
  34. jetrauserapi-1.0.0/setup.py +30 -0
@@ -0,0 +1,23 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [1.0.0] - 2026-10-25
6
+
7
+ ### Added
8
+ - Initial release
9
+ - Login with phone number and OTP
10
+ - Send and receive text messages in private chats (PV)
11
+ - Send and receive text messages in groups
12
+ - Get list of dialogs (users and groups)
13
+ - Local SQLite database for message history
14
+ - Auto-reconnect on connection loss
15
+ - Event handlers (`on_message`, `on_ready`)
16
+ - Auto-detection of peer type (user vs group)
17
+ - 10 ready-to-run examples
18
+
19
+ ### Known Limitations
20
+ - Sending media is blocked by the server
21
+ - Deleting messages is blocked by the server
22
+ - Group management is blocked by the server
23
+ - Message history from server is blocked
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ali VEX
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,12 @@
1
+ include README.md
2
+ include LICENSE
3
+ include requirements.txt
4
+ include CHANGELOG.md
5
+
6
+ recursive-include jetrauserapi *.py
7
+ recursive-include examples *.py
8
+ recursive-include examples *.md
9
+
10
+ exclude data/*
11
+ exclude archive/*
12
+ exclude *.bin
@@ -0,0 +1,67 @@
1
+ Metadata-Version: 2.4
2
+ Name: jetrauserapi
3
+ Version: 1.0.0
4
+ Summary: A Python library for interacting with Jetra Messenger (User Account)
5
+ Home-page: https://github.com/YOUR_USERNAME/JetraUserAPI
6
+ Author: Ali VEX
7
+ Author-email: Ali VEX <your-email@example.com>
8
+ License: MIT
9
+ Project-URL: Homepage, https://github.com/YOUR_USERNAME/JetraUserAPI
10
+ Project-URL: Repository, https://github.com/YOUR_USERNAME/JetraUserAPI
11
+ Project-URL: Issues, https://github.com/YOUR_USERNAME/JetraUserAPI/issues
12
+ Keywords: jetra,messenger,api,client,telethon
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Development Status :: 4 - Beta
20
+ Classifier: Intended Audience :: Developers
21
+ Classifier: Topic :: Communications :: Chat
22
+ Requires-Python: >=3.10
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: websockets>=10.0
26
+ Requires-Dist: pycryptodome>=3.15.0
27
+ Dynamic: author
28
+ Dynamic: home-page
29
+ Dynamic: license-file
30
+ Dynamic: requires-python
31
+
32
+ # JetraUserAPI
33
+
34
+ [![Python](https://img.shields.io/badge/Python-3.10%2B-blue)](https://www.python.org/)
35
+ [![License](https://img.shields.io/badge/License-MIT-green)](LICENSE)
36
+
37
+ A Python library for interacting with **Jetra Messenger** using user accounts.
38
+
39
+ Inspired by [Telethon](https://github.com/LonamiWebs/Telethon), JetraUserAPI provides a simple and clean API for automating Jetra Messenger.
40
+
41
+ ## Features
42
+
43
+ - Login with phone number and OTP
44
+ - Send and receive text messages in private chats (PV)
45
+ - Send and receive text messages in groups
46
+ - Get list of dialogs (users and groups)
47
+ - Local SQLite database for message history
48
+ - Auto-reconnect on connection loss
49
+ - Event handlers (`on_message`, `on_ready`)
50
+ - Auto-detection of peer type (user vs group)
51
+ - Clean async/await API
52
+
53
+ ## Limitations
54
+
55
+ The Jetra server blocks several operations for web clients:
56
+
57
+ - Sending media (photos, videos, files)
58
+ - Deleting messages
59
+ - Group management (ban, admin)
60
+ - Message history from server
61
+
62
+ ## Installation
63
+
64
+ ```bash
65
+ git clone https://github.com/YOUR_USERNAME/JetraUserAPI.git
66
+ cd JetraUserAPI
67
+ pip install -e .
@@ -0,0 +1,36 @@
1
+ # JetraUserAPI
2
+
3
+ [![Python](https://img.shields.io/badge/Python-3.10%2B-blue)](https://www.python.org/)
4
+ [![License](https://img.shields.io/badge/License-MIT-green)](LICENSE)
5
+
6
+ A Python library for interacting with **Jetra Messenger** using user accounts.
7
+
8
+ Inspired by [Telethon](https://github.com/LonamiWebs/Telethon), JetraUserAPI provides a simple and clean API for automating Jetra Messenger.
9
+
10
+ ## Features
11
+
12
+ - Login with phone number and OTP
13
+ - Send and receive text messages in private chats (PV)
14
+ - Send and receive text messages in groups
15
+ - Get list of dialogs (users and groups)
16
+ - Local SQLite database for message history
17
+ - Auto-reconnect on connection loss
18
+ - Event handlers (`on_message`, `on_ready`)
19
+ - Auto-detection of peer type (user vs group)
20
+ - Clean async/await API
21
+
22
+ ## Limitations
23
+
24
+ The Jetra server blocks several operations for web clients:
25
+
26
+ - Sending media (photos, videos, files)
27
+ - Deleting messages
28
+ - Group management (ban, admin)
29
+ - Message history from server
30
+
31
+ ## Installation
32
+
33
+ ```bash
34
+ git clone https://github.com/YOUR_USERNAME/JetraUserAPI.git
35
+ cd JetraUserAPI
36
+ pip install -e .
@@ -0,0 +1,33 @@
1
+ """
2
+ Send a message to a specific user (PV).
3
+
4
+ Usage:
5
+ python 01_send_to_user.py
6
+ """
7
+ import sys
8
+ import os
9
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
10
+
11
+ import asyncio
12
+ from jetrauserapi import JetraClient
13
+ from jetrauserapi.config import DEFAULT_SESSION_FILE, DEFAULT_DB_FILE
14
+
15
+
16
+ async def main():
17
+ client = JetraClient(DEFAULT_SESSION_FILE, DEFAULT_DB_FILE)
18
+
19
+ # start() now waits until client is fully ready
20
+ await client.start()
21
+
22
+ user_id = 1780245516
23
+ message = "Hello from JetraUserAPI!"
24
+
25
+ print(f"Sending to user {user_id}...")
26
+ await client.send_message(user_id, message, peer_type="user")
27
+ print("Message sent successfully!")
28
+
29
+ await client.stop()
30
+
31
+
32
+ if __name__ == "__main__":
33
+ asyncio.run(main())
@@ -0,0 +1,32 @@
1
+ """
2
+ Send a message to a group.
3
+
4
+ Usage:
5
+ python 02_send_to_group.py
6
+ """
7
+ import sys
8
+ import os
9
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
10
+
11
+ import asyncio
12
+ from jetrauserapi import JetraClient
13
+ from jetrauserapi.config import DEFAULT_SESSION_FILE, DEFAULT_DB_FILE
14
+
15
+
16
+ async def main():
17
+ client = JetraClient(DEFAULT_SESSION_FILE, DEFAULT_DB_FILE)
18
+
19
+ await client.start()
20
+
21
+ group_id = 2017
22
+ message = "Hello group!"
23
+
24
+ print(f"Sending to group {group_id}...")
25
+ await client.send_message(group_id, message, peer_type="group")
26
+ print("Message sent successfully!")
27
+
28
+ await client.stop()
29
+
30
+
31
+ if __name__ == "__main__":
32
+ asyncio.run(main())
@@ -0,0 +1,31 @@
1
+ """
2
+ Send a message to Saved Messages (yourself).
3
+
4
+ Usage:
5
+ python 03_send_to_saved.py
6
+ """
7
+ import sys
8
+ import os
9
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
10
+
11
+ import asyncio
12
+ from jetrauserapi import JetraClient
13
+ from jetrauserapi.config import DEFAULT_SESSION_FILE, DEFAULT_DB_FILE
14
+
15
+
16
+ async def main():
17
+ client = JetraClient(DEFAULT_SESSION_FILE, DEFAULT_DB_FILE)
18
+
19
+ await client.start()
20
+
21
+ message = "Note to self: buy milk"
22
+
23
+ print("Sending to Saved Messages...")
24
+ await client.send_to_saved(message)
25
+ print("Message sent successfully!")
26
+
27
+ await client.stop()
28
+
29
+
30
+ if __name__ == "__main__":
31
+ asyncio.run(main())
@@ -0,0 +1,43 @@
1
+ """
2
+ List all your groups.
3
+
4
+ Usage:
5
+ python 04_list_groups.py
6
+ """
7
+ import sys
8
+ import os
9
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
10
+
11
+ import asyncio
12
+ from jetrauserapi import JetraClient
13
+ from jetrauserapi.config import DEFAULT_SESSION_FILE, DEFAULT_DB_FILE
14
+
15
+
16
+ async def main():
17
+ client = JetraClient(DEFAULT_SESSION_FILE, DEFAULT_DB_FILE)
18
+
19
+ @client.on_ready
20
+ async def on_ready():
21
+ groups = await client.get_groups()
22
+
23
+ print(f"\nYou are a member of {len(groups)} groups:\n")
24
+ for i, g in enumerate(groups, 1):
25
+ print(f" {i}. {g['title']}")
26
+ print(f" ID: {g['peer_id']}")
27
+
28
+ await client.start()
29
+
30
+ try:
31
+ while True:
32
+ await asyncio.sleep(1)
33
+ except (KeyboardInterrupt, asyncio.CancelledError):
34
+ pass
35
+ finally:
36
+ await client.stop()
37
+
38
+
39
+ if __name__ == "__main__":
40
+ try:
41
+ asyncio.run(main())
42
+ except KeyboardInterrupt:
43
+ print("\nGoodbye!")
@@ -0,0 +1,43 @@
1
+ """
2
+ List all your user contacts.
3
+
4
+ Usage:
5
+ python 05_list_users.py
6
+ """
7
+ import sys
8
+ import os
9
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
10
+
11
+ import asyncio
12
+ from jetrauserapi import JetraClient
13
+ from jetrauserapi.config import DEFAULT_SESSION_FILE, DEFAULT_DB_FILE
14
+
15
+
16
+ async def main():
17
+ client = JetraClient(DEFAULT_SESSION_FILE, DEFAULT_DB_FILE)
18
+
19
+ @client.on_ready
20
+ async def on_ready():
21
+ users = await client.get_users()
22
+
23
+ print(f"\nYou have {len(users)} users in your dialogs:\n")
24
+ for i, u in enumerate(users, 1):
25
+ print(f" {i}. {u['title']}")
26
+ print(f" ID: {u['peer_id']}")
27
+
28
+ await client.start()
29
+
30
+ try:
31
+ while True:
32
+ await asyncio.sleep(1)
33
+ except (KeyboardInterrupt, asyncio.CancelledError):
34
+ pass
35
+ finally:
36
+ await client.stop()
37
+
38
+
39
+ if __name__ == "__main__":
40
+ try:
41
+ asyncio.run(main())
42
+ except KeyboardInterrupt:
43
+ print("\nGoodbye!")
@@ -0,0 +1,36 @@
1
+ """
2
+ Get message history from local database.
3
+
4
+ Usage:
5
+ python 06_get_history.py
6
+ """
7
+ import sys
8
+ import os
9
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
10
+
11
+ import asyncio
12
+ from jetrauserapi import JetraClient
13
+ from jetrauserapi.config import DEFAULT_SESSION_FILE, DEFAULT_DB_FILE
14
+
15
+
16
+ async def main():
17
+ client = JetraClient(DEFAULT_SESSION_FILE, DEFAULT_DB_FILE)
18
+ await client.start()
19
+
20
+ print("\nLast 10 messages from all chats:\n")
21
+ history = client.get_history(limit=10)
22
+
23
+ for msg in history:
24
+ print(f" [{msg['peer_type']}] From {msg['from_id']}: {msg['text']}")
25
+
26
+ print("\n\nLast 5 messages from group 2017:\n")
27
+ history = client.get_history(peer_id=2017, limit=5)
28
+
29
+ for msg in history:
30
+ print(f" {msg['text']}")
31
+
32
+ await client.stop()
33
+
34
+
35
+ if __name__ == "__main__":
36
+ asyncio.run(main())
@@ -0,0 +1,44 @@
1
+ """
2
+ Listen for all incoming messages and print them.
3
+
4
+ Usage:
5
+ python 07_listen_messages.py
6
+ """
7
+ import sys
8
+ import os
9
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
10
+
11
+ import asyncio
12
+ from jetrauserapi import JetraClient
13
+ from jetrauserapi.config import DEFAULT_SESSION_FILE, DEFAULT_DB_FILE
14
+
15
+
16
+ async def main():
17
+ client = JetraClient(DEFAULT_SESSION_FILE, DEFAULT_DB_FILE)
18
+
19
+ @client.on_message
20
+ async def on_message(message):
21
+ peer_label = "PV" if message.is_private else "Group"
22
+
23
+ print(f"\n[{peer_label}]")
24
+ print(f" From: {message.from_id}")
25
+ print(f" Time: {message.date_str}")
26
+ print(f" Text: {message.text}")
27
+
28
+ print("Listening for messages... Press Ctrl+C to stop.")
29
+ await client.start()
30
+
31
+ try:
32
+ while True:
33
+ await asyncio.sleep(1)
34
+ except (KeyboardInterrupt, asyncio.CancelledError):
35
+ pass
36
+ finally:
37
+ await client.stop()
38
+
39
+
40
+ if __name__ == "__main__":
41
+ try:
42
+ asyncio.run(main())
43
+ except KeyboardInterrupt:
44
+ print("\nGoodbye!")
@@ -0,0 +1,42 @@
1
+ """
2
+ Echo bot: replies with the same message it receives.
3
+
4
+ Usage:
5
+ python 08_echo_bot.py
6
+ """
7
+ import sys
8
+ import os
9
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
10
+
11
+ import asyncio
12
+ from jetrauserapi import JetraClient
13
+ from jetrauserapi.config import DEFAULT_SESSION_FILE, DEFAULT_DB_FILE
14
+
15
+
16
+ async def main():
17
+ client = JetraClient(DEFAULT_SESSION_FILE, DEFAULT_DB_FILE)
18
+
19
+ @client.on_message
20
+ async def on_message(message):
21
+ print(f"Received: {message.text}")
22
+ reply = f"Echo: {message.text}"
23
+ await client.send_message(message.peer_id, reply)
24
+ print(f"Replied: {reply}")
25
+
26
+ print("Echo bot is running... Press Ctrl+C to stop.")
27
+ await client.start()
28
+
29
+ try:
30
+ while True:
31
+ await asyncio.sleep(1)
32
+ except (KeyboardInterrupt, asyncio.CancelledError):
33
+ pass
34
+ finally:
35
+ await client.stop()
36
+
37
+
38
+ if __name__ == "__main__":
39
+ try:
40
+ asyncio.run(main())
41
+ except KeyboardInterrupt:
42
+ print("\nGoodbye!")
@@ -0,0 +1,61 @@
1
+ """
2
+ A bot that responds to specific commands like /start, /help, /ping.
3
+
4
+ Usage:
5
+ python 09_command_bot.py
6
+ """
7
+ import sys
8
+ import os
9
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
10
+
11
+ import asyncio
12
+ from jetrauserapi import JetraClient
13
+ from jetrauserapi.config import DEFAULT_SESSION_FILE, DEFAULT_DB_FILE
14
+
15
+
16
+ async def main():
17
+ client = JetraClient(DEFAULT_SESSION_FILE, DEFAULT_DB_FILE)
18
+
19
+ @client.on_message
20
+ async def on_message(message):
21
+ text = message.text.strip().lower()
22
+
23
+ if text == "/start":
24
+ reply = "Hello! I am a Jetra bot.\nUse /help to see commands."
25
+ await client.send_message(message.peer_id, reply)
26
+
27
+ elif text == "/help":
28
+ reply = (
29
+ "Available commands:\n"
30
+ "/start - Start the bot\n"
31
+ "/help - Show this message\n"
32
+ "/ping - Test bot response\n"
33
+ "/time - Show current time"
34
+ )
35
+ await client.send_message(message.peer_id, reply)
36
+
37
+ elif text == "/ping":
38
+ await client.send_message(message.peer_id, "pong")
39
+
40
+ elif text == "/time":
41
+ import datetime
42
+ now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
43
+ await client.send_message(message.peer_id, f"Current time: {now}")
44
+
45
+ print("Command bot is running... Press Ctrl+C to stop.")
46
+ await client.start()
47
+
48
+ try:
49
+ while True:
50
+ await asyncio.sleep(1)
51
+ except (KeyboardInterrupt, asyncio.CancelledError):
52
+ pass
53
+ finally:
54
+ await client.stop()
55
+
56
+
57
+ if __name__ == "__main__":
58
+ try:
59
+ asyncio.run(main())
60
+ except KeyboardInterrupt:
61
+ print("\nGoodbye!")
@@ -0,0 +1,57 @@
1
+ """
2
+ Auto-reply bot with keyword-based responses.
3
+
4
+ Usage:
5
+ python 10_auto_reply.py
6
+ """
7
+ import sys
8
+ import os
9
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
10
+
11
+ import asyncio
12
+ from jetrauserapi import JetraClient
13
+ from jetrauserapi.config import DEFAULT_SESSION_FILE, DEFAULT_DB_FILE
14
+
15
+
16
+ # Keyword-based responses
17
+ RESPONSES = {
18
+ "hello": "Hi there! How can I help you?",
19
+ "hi": "Hello!",
20
+ "bye": "Goodbye! See you later.",
21
+ "thanks": "You're welcome!",
22
+ "ping": "pong",
23
+ "how are you": "I'm just a bot, but I'm doing great!",
24
+ }
25
+
26
+
27
+ async def main():
28
+ client = JetraClient(DEFAULT_SESSION_FILE, DEFAULT_DB_FILE)
29
+
30
+ @client.on_message
31
+ async def on_message(message):
32
+ text_lower = message.text.strip().lower()
33
+
34
+ # Find matching response
35
+ for keyword, response in RESPONSES.items():
36
+ if keyword in text_lower:
37
+ await client.send_message(message.peer_id, response)
38
+ print(f"Auto-replied to '{message.text}' with '{response}'")
39
+ break
40
+
41
+ print("Auto-reply bot is running... Press Ctrl+C to stop.")
42
+ await client.start()
43
+
44
+ try:
45
+ while True:
46
+ await asyncio.sleep(1)
47
+ except (KeyboardInterrupt, asyncio.CancelledError):
48
+ pass
49
+ finally:
50
+ await client.stop()
51
+
52
+
53
+ if __name__ == "__main__":
54
+ try:
55
+ asyncio.run(main())
56
+ except KeyboardInterrupt:
57
+ print("\nGoodbye!")
@@ -0,0 +1,10 @@
1
+ # JetraUserAPI Examples
2
+
3
+ Short, ready-to-run examples for the JetraUserAPI library.
4
+
5
+ ## Prerequisites
6
+
7
+ You must be logged in first:
8
+
9
+ ```bash
10
+ python login.py