### Install python-trueconf-bot using pip Source: https://github.com/trueconf/python-trueconf-bot/blob/master/README.md Install the library using pip. For recommended installation, use uv. ```bash pip install python-trueconf-bot ``` ```bash uv add python-trueconf-bot ``` -------------------------------- ### Install python-trueconf-bot with uv Source: https://github.com/trueconf/python-trueconf-bot/blob/master/README-PyPI.md Use this command to install the library using uv, which is the recommended package installer. ```bash uv add python-trueconf-bot ``` -------------------------------- ### Install python-trueconf-bot with pip Source: https://github.com/trueconf/python-trueconf-bot/blob/master/README-PyPI.md Use this command to install the library using pip. Ensure you have pip installed. ```bash pip install python-trueconf-bot ``` -------------------------------- ### Install Python TrueConf Bot Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/getting-started.md Install the {{product_name}} package from PyPI using pip. This will also install necessary dependencies like websockets and httpx. ```shell pip install {{product_name}} ``` -------------------------------- ### Install python-trueconf-bot Source: https://context7.com/trueconf/python-trueconf-bot/llms.txt Install the library using pip or uv. An optional dependency for enhanced MIME type detection is also available. ```bash pip install python-trueconf-bot ``` ```bash uv add python-trueconf-bot ``` ```bash pip install python-trueconf-bot[python-magic] ``` -------------------------------- ### Basic Router Setup Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/types.md Initializes the router for handling events. No specific type hints are applied here. ```python from trueconf import Router r = Router() @r.added_chat_participant() async def on_added_user(event): ... ``` -------------------------------- ### Install python-magic-bin on Windows Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/files.md Install the python-magic-bin package using pip for Windows systems. ```bash pip install python-magic-bin ``` -------------------------------- ### Example Echo Bot Source: https://github.com/trueconf/python-trueconf-bot/blob/master/README-PyPI.md This example demonstrates a basic echo bot that replies with the message it receives. It requires setting the TOKEN environment variable and configuring the bot with your TrueConf server details. ```python import asyncio from trueconf import Bot, Dispatcher, Router, Message, F, ParseMode from os import getenv router = Router() dp = Dispatcher() dp.include_router(router) TOKEN = getenv("TOKEN") bot = Bot(server="video.example.com", token=TOKEN, dispatcher=dp) @router.message(F.text) async def echo(msg: Message): await msg.answer(f"You says: **{msg.text}**", parse_mode=ParseMode.MARKDOWN) async def main(): await bot.run() if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Set up a Webhook with FastAPI Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/examples/index.md This example demonstrates how to set up a webhook using FastAPI to receive requests from external systems like Zabbix. It includes bot initialization and an endpoint to process incoming data. ```python import asyncio import logging import os from typing import Any from trueconf import Bot from contextlib import asynccontextmanager from fastapi import FastAPI import uvicorn os.makedirs("logs", exist_ok=True) logging.basicConfig( level=logging.DEBUG, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s", filename="logs/bot.log", encoding="utf-8", ) @asynccontextmanager async def lifespan(app: FastAPI): bot_task = asyncio.create_task(bot.run()) yield app = FastAPI(lifespan=lifespan) bot = Bot.from_credentials( server="10.140.1.255", username="echo_bot", password="123tr", verify_ssl=False) @app.post("/send") async def read_root(data: dict[str, Any]): r = await bot.create_personal_chat(user_id="user") r = await bot.send_message(chat_id = r.chat_id, text=str(data)) print(r.message_id) if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=8000) ``` -------------------------------- ### Run and Stop Bot Source: https://context7.com/trueconf/python-trueconf-bot/llms.txt Start the bot's WebSocket connection with `bot.run()`, which blocks until shutdown. Use `bot.shutdown()` for graceful termination. The example shows non-blocking start with custom lifecycle management. ```python import asyncio from trueconf import Bot, Dispatcher dp = Dispatcher() bot = Bot(server="video.example.com", token="JWT_TOKEN", dispatcher=dp) async def main(): # Start without blocking (for custom lifecycle management) await bot.start() print("Bot is running, press Ctrl+C to stop") await bot.stopped_event.wait() # Block until shutdown() is called async def stop_after_delay(): await asyncio.sleep(30) await bot.shutdown() # Graceful shutdown if __name__ == "__main__": asyncio.run(bot.run()) # Preferred: blocks and handles OS signals ``` -------------------------------- ### Create and Delete Chats using `create_group_chat`, `create_channel`, `create_personal_chat`, `delete_chat` Source: https://context7.com/trueconf/python-trueconf-bot/llms.txt Examples for managing chats. Use `create_group_chat`, `create_channel`, or `create_personal_chat` to create new chats, and `delete_chat` to remove existing ones. ```python from trueconf import Router, F from trueconf.types import Message r = Router() @r.message(F.text == "/newgroup") async def create_group(msg: Message): result = await msg._bot.create_group_chat(title="Project Team Alpha") await msg.answer(f"Group created: {result.chat_id}") ``` ```python @r.message(F.text == "/newchannel") async def create_channel(msg: Message): result = await msg._bot.create_channel(title="Company Announcements") await msg.answer(f"Channel created: {result.chat_id}") ``` ```python @r.message(F.text == "/newp2p") async def create_p2p(msg: Message): result = await msg._bot.create_personal_chat(user_id="alice") await msg.answer(f"P2P chat: {result.chat_id}") ``` ```python @r.message(F.text.startswith("/deletechat ")) async def delete_chat(msg: Message): chat_id = msg.text.split(" ", 1)[1].strip() await msg._bot.delete_chat(chat_id=chat_id) await msg.answer(f"Chat {chat_id} deleted.") ``` -------------------------------- ### Basic Command and Message Routers Source: https://context7.com/trueconf/python-trueconf-bot/llms.txt Defines handlers for /start, /help commands and basic message echoing/photo handling. Includes setup for a bot with a dispatcher. ```python from trueconf import Bot, Dispatcher, Router, F from trueconf.types import Message from trueconf.filters import Command dp = Dispatcher() # --- commands_router handlers --- @commands_router.message(Command("start")) async def on_start(msg: Message): await msg.answer("Welcome! Send me any text.") @commands_router.message(Command("help", "info", "about")) async def on_help(msg: Message): await msg.answer("I'm a demo TrueConf bot. Commands: /start, /help") # --- messages_router handlers --- @messages_router.message(F.text) async def on_text(msg: Message): await msg.answer(f"Echo: {msg.text}") @messages_router.message(F.photo) async def on_photo(msg: Message): await msg.reply("Nice photo!") # --- Dynamic router (for stateful conversations) --- @commands_router.message(Command("register")) async def on_register(msg: Message): dynamic_r = Router(name=f"session_{msg.from_user.id}") dp.include_router(dynamic_r) async def collect_name(m: Message): await m.answer(f"Registered as: {m.text}") # Remove this one-shot router afterwards dp.routers[:] = [r for r in dp.routers if r.name != dynamic_r.name] dynamic_r.message(F.from_user.id == msg.from_user.id)(collect_name) await msg.answer("What is your display name?") bot = Bot(server="video.example.com", token="JWT_TOKEN", dispatcher=dp) import asyncio asyncio.run(bot.run()) ``` -------------------------------- ### Router and Dispatcher Setup Source: https://context7.com/trueconf/python-trueconf-bot/llms.txt Organize event handlers using `Router` instances, which can be nested. The `Dispatcher` aggregates all routers and directs incoming events. ```python from trueconf import Bot, Dispatcher, Router, F from trueconf.filters import Command from trueconf.types import Message # Create multiple specialized routers commands_router = Router(name="commands") messages_router = Router(name="messages") admin_router = Router(name="admin") dp = Dispatcher() dp.include_router(commands_router) dp.include_router(messages_router) dp.include_router(admin_router) ``` -------------------------------- ### Install python-magic for MIME type detection Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/files.md Install the python-magic package with dependencies for accurate MIME type detection based on file content. ```shell pip install python-trueconf-bot[python-magic] ``` -------------------------------- ### Initialize Bot with Credentials Source: https://context7.com/trueconf/python-trueconf-bot/llms.txt Use the `from_credentials` class method to authenticate with username and password, obtaining a JWT token automatically. This method is useful for initial setup or when a token needs to be refreshed. ```python import asyncio from trueconf import Bot, Dispatcher, Router, F router = Router() dp = Dispatcher() dp.include_router(router) bot = Bot.from_credentials( server="10.110.2.240", username="echo_bot", password="s3cr3t", dispatcher=dp, verify_ssl=False, # Allow self-signed certificates https=True, ) @router.message(F.text) async def echo(msg): await msg.answer(msg.text) if __name__ == "__main__": asyncio.run(bot.run()) ``` -------------------------------- ### Retrieve Chat Information using `get_chats()`, `get_chat_by_id()`, `get_chat_history()` Source: https://context7.com/trueconf/python-trueconf-bot/llms.txt Examples for fetching chat lists, details of a specific chat, and message history. The `get_chat_history` example prints message IDs, sender IDs, and text content (or '' for non-text messages). ```python from trueconf import Router, F from trueconf.filters import Command from trueconf.types import Message r = Router() @r.message(Command("listchats")) async def list_chats(msg: Message): result = await msg._bot.get_chats(count=10, page=1) lines = [f"{c.chat_id}: {c.title}" for c in result.chats] await msg.answer("Your chats:\n" + "\n".join(lines)) ``` ```python @r.message(Command("chatinfo", magic=F.args.is_not(None))) async def chat_info(msg: Message, command): info = await msg._bot.get_chat_by_id(chat_id=command.args.strip()) await msg.answer(f"Chat: {info.title}\nType: {info.chat_type}\nID: {info.chat_id}") ``` ```python @r.message(Command("history")) async def chat_history(msg: Message): result = await msg._bot.get_chat_history( chat_id=msg.chat_id, count=5, ) for m in result.messages: print(f"[{m.message_id}] {m.from_user.id}: {getattr(m, 'text', '')}") await msg.answer(f"Fetched {len(result.messages)} recent messages.") ``` -------------------------------- ### Install libmagic on Linux Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/files.md Use apt to install the libmagic1 dependency on Debian/Ubuntu based Linux systems. ```bash sudo apt install libmagic1 ``` -------------------------------- ### Install libmagic on macOS Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/files.md Use Homebrew to install the libmagic dependency on macOS systems. ```bash brew install libmagic ``` -------------------------------- ### Handler Priorities Example Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/parse-messages.md Demonstrates how handler priorities affect execution. Only the first handler matching the filter will be triggered. ```python r = Router() @r.message(F.text == "Hello") async def handler1(message): await message.answer("First") @r.message(F.text == "Hello") async def handler2(message): await message.answer("Second") ``` -------------------------------- ### Command Filter Examples Source: https://context7.com/trueconf/python-trueconf-bot/llms.txt Demonstrates various ways to use the Command filter for parsing slash-style commands, including multiple commands, arguments, argument validation, regex matching, and custom prefixes/case insensitivity. ```python import re from trueconf import Router, F from trueconf.filters import Command from trueconf.filters.command import CommandObject from trueconf.types import Message r = Router() # Basic single command @r.message(Command("ping")) async def pong(msg: Message): await msg.answer("pong") # Multiple commands handled by one function @r.message(Command("info", "about", "whoami")) async def info(msg: Message, command: CommandObject): await msg.answer(f"You used: /{command.command}") # Command with mandatory arguments (magic guards missing args) @r.message(Command("echo", magic=F.args.is_not(None))) async def echo_cmd(msg: Message, command: CommandObject): await msg.answer(command.args) # Argument length validation @r.message(Command("upper", magic=F.args.len() > 3)) async def upper_cmd(msg: Message, command: CommandObject): await msg.answer((command.args or "").upper()) # Regex-based command name @r.message(Command(re.compile(r"task_\d+"))) async def task_handler(msg: Message, command: CommandObject): await msg.answer(f"Task command: {command.command}, args: {command.args}") # Case-insensitive, custom prefix @r.message(Command("STOP", prefix="!", ignore_case=True)) async def stop_cmd(msg: Message): await msg.answer("Stopping...") ``` -------------------------------- ### Support Report Bot Example Source: https://context7.com/trueconf/python-trueconf-bot/llms.txt This bot collects messages for a support report, allows cancellation, and submission. It uses dynamic routers for per-user stateful conversation flows. ```python """ Support report bot: /report starts collecting messages, /cancel aborts, /send submits the collected report. """ import asyncio import uuid from trueconf import Bot, Dispatcher, Router, F, Message from trueconf.filters import Command r1 = Router() dp = Dispatcher() dp.include_router(r1) bot = Bot.from_credentials( server="video.example.com", username="support_bot", password="s3cr3t", dispatcher=dp, verify_ssl=False, ) router_sessions: dict = {} message_store: dict = {} async def collect_report_message(msg: Message): if msg.from_user.id in message_store: message_store[msg.from_user.id].append(msg) await msg.answer("Message added to your report.") @r1.message(Command("report")) async def start_report(msg: Message): ticket_id = uuid.uuid4() await msg.answer(f"Ticket #{ticket_id} opened. Send your messages, then /send or /cancel.") session_router = Router(name=str(ticket_id)) dp.include_router(session_router) session_router.message(F.from_user.id == msg.from_user.id)(collect_report_message) router_sessions[msg.from_user.id] = session_router message_store[msg.from_user.id] = [] @r1.message(Command("cancel")) async def cancel_report(msg: Message): uid = msg.from_user.id if uid in router_sessions: dp.routers[:] = [r for r in dp.routers if r.name != router_sessions[uid].name] router_sessions.pop(uid) message_store.pop(uid) await msg.answer("Report cancelled.") else: await msg.answer("No active report found.") @r1.message(Command("send")) async def send_report(msg: Message): uid = msg.from_user.id if uid not in message_store: await msg.answer("No active report.") return messages = message_store.pop(uid) router_sessions.pop(uid, None) # Process/email messages here await msg.answer(f"Report submitted with {len(messages)} messages. Thank you!") if __name__ == "__main__": asyncio.run(bot.run()) ``` -------------------------------- ### Combine Regex Command Filter with MagicFilter Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/filters.md Use a regular expression to match command patterns and MagicFilter to process arguments. This example handles commands like 'echo_123' and ensures arguments are present. ```python @r.message(Command(re.compile(r"echo_\\d+"), magic=F.args)) async def handle_special_echo(message: Message, command: CommandObject): await bot.send_message(chat_id=message.chat_id, text=f"Special: {command.command} -> {command.args}") ``` -------------------------------- ### Combine MagicFilter and Custom Filter Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/filters.md Combine message content checks with custom access rules. This example reacts to the word 'help' only for users in the 'support' group. ```python # Triggers if the text contains "help" # AND the user belongs to the "support" group @r.message(F.text.contains("help"), InGroupFilter(target_group="0003")) async def support_handler(message: Message): await message.answer("The support team has been notified of your request.") ``` -------------------------------- ### Get File Upload Limits Source: https://context7.com/trueconf/python-trueconf-bot/llms.txt Queries the server for currently enforced file upload restrictions (size and extension filters). Requires TrueConf Server 5.5.3+. ```python from trueconf import Router, F from trueconf.types import Message, FSInputFile from trueconf.enums import ParseMode r = Router() @r.message(F.text == "/uploadlimits") async def show_limits(msg: Message): limits = await msg._bot.get_file_info_upload_limits() max_mb = (limits.max_size / 1_000_000) if limits.max_size else "unlimited" await msg.answer( f"**Upload limits:**\n" f"Max size: {max_mb} MB\n" f"Extension mode: {getattr(limits.extensions, 'mode', 'none')} " f"Extensions: {getattr(limits.extensions, 'list', [])}", parse_mode=ParseMode.MARKDOWN, ) ``` -------------------------------- ### MagicFilter Examples Source: https://context7.com/trueconf/python-trueconf-bot/llms.txt Illustrates the use of MagicFilter (F) for creating declarative, chainable filters based on event fields. Covers equality, substring, regex, set membership, logical operators, and custom functions. ```python from trueconf import Router, F from trueconf.types import Message r = Router() # Text equality @r.message(F.text == "hello") async def on_hello(msg: Message): await msg.answer("Hello there!") # Substring check @r.message(F.text.contains("urgent")) async def on_urgent(msg: Message): await msg.answer("Flagging as urgent...") # Starts/ends with @r.message(F.text.startswith("/") | F.text.startswith("!")) async def on_command_like(msg: Message): await msg.answer("Looks like a command") # Regex match @r.message(F.text.regexp(r"ticket-\d+")) async def on_ticket(msg: Message): await msg.answer(f"Found ticket reference in: {msg.text}") # Set membership @r.message(F.from_user.id.in_({"alice", "bob", "carol"})) async def on_admin_user(msg: Message): await msg.answer("Hello, trusted user!") # Nested attribute with AND combination @r.message((F.from_user.id == "alice@myserver") & F.text) async def on_alice_text(msg: Message): await msg.answer(f"Alice says: {msg.text}") # OR combination @r.message(F.photo | F.document) async def on_attachment(msg: Message): await msg.answer("Got a file!") # Custom function filter @r.message(F.text.func(lambda t: t and len(t.split()) > 5)) async def on_long_message(msg: Message): await msg.answer("That's a detailed message!") # Inversion @r.message(~F.text) # matches non-text messages async def on_non_text(msg: Message): await msg.answer("That's not text!") ``` -------------------------------- ### Implement a Support Reporting Bot Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/examples/index.md This bot collects support reports from users. It uses commands like /report to start a new ticket, /cancel to stop it, and /send to submit the collected messages. The bot manages active reports using routers and stores messages in lists. ```python """ Below is the initial scaffold for a bot that collects support reports. - /report creates a router/state to capture and parse messages from a specific user. - /cancel cancels the ticket and removes the user from this state. - /send emails the collected messages — this is where you implement the logic to assemble the email (body + attachments) and send it. You can use built-in modules, and third-party libraries if needed. """ import asyncio import uuid import trueconf from trueconf import * from trueconf.filters import Command r1 = Router() dp = Dispatcher() dp.include_router(r1) router_list_for_report = {} list_message_for_report = {} bot = trueconf.Bot.from_credentials( server="10.110.2.241", username="report_bot", password="123tr", dispatcher=dp, https=True, verify_ssl=False) async def handle_report(msg: Message): if msg.from_user.id in router_list_for_report.keys(): list_message_for_report[msg.from_user.id].append(msg) await msg.answer("The message has been added to the report.") @r1.message(Command("report")) async def on_report(msg: Message): number = uuid.uuid4() # генерация номера обращения с помощью uuid await msg.answer(f"Your ticket number is {number}. All subsequent messages will be added to this ticket.") r = Router(name=str(number)) dp.include_router(r) r.message(F.from_user.id == msg.from_user.id)(handle_report) router_list_for_report.update({msg.from_user.id: r}) list_message_for_report.update({msg.from_user.id: []}) @r1.message(Command("cancel")) async def on_cancel(msg: Message): if msg.from_user.id in router_list_for_report.keys(): for router in dp.routers: if router.name == router_list_for_report[msg.from_user.id].name: dp.routers.remove(router) router_list_for_report.pop(msg.from_user.id) list_message_for_report.pop(msg.from_user.id) await msg.answer("The report has been cancelled.") break else: await msg.answer("You don’t have an active report.") def build_message_and_send_email(messages:list): """ In Python, there are built-in libraries for working with email messages: https://docs.python.org/3/library/email.examples.html Here, you need to take the data from list_message_for_report[msg.from_user.id] and build an email-ready representation: for msg in message: match msg.content_type: case MessageType.TEXT: # You can put the text into the email body case MessageType.ATTACHMENT: # Download the files from TrueConf Server via: # msg.download(dest_path="path/to/file") Once the email is assembled correctly, send it using the smtplib module: https://docs.python.org/3/library/smtplib.html#smtp-example """ @r1.message(Command("send")) async def send_report(msg: Message): if msg.from_user.id in router_list_for_report.keys(): if build_message_and_send_email(list_message_for_report[msg.from_user.id]): await msg.answer("Your request has been successfully submitted to Technical Support.") else: await msg.answer("An error occurred. Please contact the bot developer.") else: await msg.answer("You don’t have an active report.") return if __name__ == "__main__": asyncio.run(bot.run()) ``` -------------------------------- ### Implement a Custom Filter Class Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/filters.md Custom filters must be implemented as classes with a __call__ method that returns True or False. This example checks if a user belongs to a specified group via the server API. ```python from typing import Any class MyFilter: """ This filter checks whether a user belongs to the specified group via the server API. """ def __init__(self, target_group: str): # Store the required group when creating the instance self.target_group = target_group async def __call__(self, event: Any) -> bool: user = getattr(event, "from_user", None) if not user: return False user_id = user.id # Perform the check, for example via an API call user_info: dict = await server_api.get_user(user_id) groups = user_info.get("groups", []) # Make sure to return True or False return any(group.get("id") == self.target_group for group in groups) ``` -------------------------------- ### Set Up Virtual Environment Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/getting-started.md Create and activate a virtual environment to manage project dependencies. Use 'source' on Linux/macOS and '.venv\Scripts\activate' on Windows. ```shell python -m venv .venv source .venv/bin/activate # Linux / macOS .venv\Scripts\activate # Windows PowerShell ``` -------------------------------- ### Initialize Bot with Credentials Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/features.md Create a Bot instance using the from_credentials class method, providing server address, username, and password for authentication. ```python bot = Bot.from_credentials(server, username, password) ``` -------------------------------- ### MagicFilter String Start/End Checks Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/filters.md Checks if a string attribute starts or ends with a specific substring. ```python F.text.startswith("foo") ``` ```python F.text.endswith("bar") ``` -------------------------------- ### Using TrueConf Enums for Message Formatting and File Handling Source: https://context7.com/trueconf/python-trueconf-bot/llms.txt Demonstrates using enums like `ParseMode` for message formatting and `FileReadyState` for checking file availability before downloading. Requires importing `Message` and `Bot`. ```python from trueconf.enums import ( ParseMode, FileReadyState, ChatType, ChatParticipantRole, ) from trueconf import Bot, Router, F from trueconf.types import Message r = Router() @r.message(F.text) async def format_demo(msg: Message): # ParseMode await msg.answer("**Bold** and _italic_", parse_mode=ParseMode.MARKDOWN) # FileReadyState check info = await msg._bot.get_file_info("some_file_id") if info.ready_state == FileReadyState.READY: await msg._bot.download_file_by_id(info.file_id, "./downloads") elif info.ready_state == FileReadyState.NOT_AVAILABLE: await msg.answer("File not available.") # ChatType check chat = await msg._bot.get_chat_by_id(msg.chat_id) if chat.chat_type == ChatType.GROUP: await msg.answer("This is a group chat.") # ChatParticipantRole await msg._bot.change_participant_role( chat_id=msg.chat_id, user_id="bob", role=ChatParticipantRole.ADMIN, ) ``` -------------------------------- ### Initialize Bot with JWT Token Source: https://context7.com/trueconf/python-trueconf-bot/llms.txt Create a bot instance connected to TrueConf Server using a JWT token. Configure connection parameters like SSL verification and retry attempts. ```python import asyncio from os import getenv from trueconf import Bot, Dispatcher, Router, F, ParseMode router = Router() dp = Dispatcher() dp.include_router(router) TOKEN = getenv("TOKEN") # Store securely, e.g. in .env file bot = Bot( server="video.example.com", token=TOKEN, dispatcher=dp, receive_unread_messages=False, # Don't replay unread on connect receive_system_messages=False, # Skip system events (user joins, etc.) verify_ssl=True, # Set False for self-signed certs https=True, ws_max_retries=5, # Give up after 5 failed IP-level retries ws_max_delay=60, # Cap reconnect backoff at 60s debug=False, ) @router.message(F.text) async def echo(msg): await msg.answer(f"You said: {msg.text}") async def main(): await bot.run() if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Initialize Bot with JWT Token Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/features.md Instantiate the Bot class using a pre-obtained JWT token and the server address. Ensure the token is valid for authentication. ```python bot = Bot(server="video.example.com", token="...") ``` -------------------------------- ### Initialize Router and Dispatcher Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/getting-started.md Create instances of Router and Dispatcher. The Dispatcher is used to manage message routing and event handling. ```python r = Router() dp = Dispatcher() # dp.include_router(r) ``` -------------------------------- ### Create BufferedInputFile from File Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/files.md Use the from_file() class method to easily create a BufferedInputFile from a file path. ```python file = BufferedInputFile.from_file("archive.zip") await bot.send_document(chat_id="...", file=file) ``` -------------------------------- ### Download Files using `bot.download_file_by_id()` and `message.document.download()` Source: https://context7.com/trueconf/python-trueconf-bot/llms.txt Demonstrates downloading files from the server. Use `message.document.download()` for direct downloads from message attachments or `bot.download_file_by_id()` to download by file ID, optionally into memory as bytes. ```python from trueconf import Router, F from trueconf.types import Message r = Router() @r.message(F.document) async def handle_document(msg: Message): # Shortcut: download directly from the message attachment path = await msg.document.download(dest_path="./downloads") print(f"Saved to: {path}") ``` ```python @r.message(F.photo) async def handle_photo(msg: Message): # Download into memory (returns bytes if dest_path is omitted) raw_bytes = await msg._bot.download_file_by_id(file_id=msg.photo.file_id) print(f"Photo size in memory: {len(raw_bytes)} bytes") ``` ```python @r.message(F.text.startswith("/getfile ")) async def fetch_by_id(msg: Message): file_id = msg.text.split(" ", 1)[1].strip() saved_path = await msg._bot.download_file_by_id( file_id=file_id, dest_path="./downloads", ) await msg.answer(f"Downloaded: {saved_path}") ``` -------------------------------- ### Command Router Handlers Source: https://context7.com/trueconf/python-trueconf-bot/llms.txt Handles specific commands like /start and /help, providing basic bot interactions. ```APIDOC ## Command Router Handlers ### Description Handles specific commands like /start and /help, providing basic bot interactions. ### Handlers - `on_start`: Responds to the /start command with a welcome message. - `on_help`: Responds to /help, /info, or /about commands with bot information. - `on_register`: Initiates a stateful conversation to register a user's display name. ``` -------------------------------- ### Initialize an Unnamed Router Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/parse-messages.md Create a new Router instance without a specific name. This is useful for simple bots or when router names are not critical for management. ```python from trueconf import Router r = Router() ``` -------------------------------- ### Downloading Files Source: https://context7.com/trueconf/python-trueconf-bot/llms.txt Demonstrates how to download files using `bot.download_file_by_id()` or `message.document.download()`. Files can be saved to disk or loaded into memory as bytes. ```APIDOC ## Downloading Files — `bot.download_file_by_id()` / `message.document.download()` Downloads a file from the server by its ID, either to disk or into memory as bytes. ```python from trueconf import Router, F from trueconf.types import Message r = Router() @r.message(F.document) async def handle_document(msg: Message): # Shortcut: download directly from the message attachment path = await msg.document.download(dest_path="./downloads") print(f"Saved to: {path}") @r.message(F.photo) async def handle_photo(msg: Message): # Download into memory (returns bytes if dest_path is omitted) raw_bytes = await msg._bot.download_file_by_id(file_id=msg.photo.file_id) print(f"Photo size in memory: {len(raw_bytes)} bytes") @r.message(F.text.startswith("/getfile ")) async def fetch_by_id(msg: Message): file_id = msg.text.split(" ", 1)[1].strip() saved_path = await msg._bot.download_file_by_id( file_id=file_id, dest_path="./downloads", ) await msg.answer(f"Downloaded: {saved_path}") ``` ``` -------------------------------- ### Download Document using .download() Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/files.md Use the .download() shortcut method on a message's document attribute to easily save incoming documents. Specify the destination path. ```python @router.message(F.document) async def handle_doc(msg: Message): await msg.document.download(dest_path="document.pdf") ``` -------------------------------- ### Get User Display Name and Bot's Favorites Chat ID Source: https://context7.com/trueconf/python-trueconf-bot/llms.txt Retrieves display names for users and identifies the bot's own personal 'Favorites' chat. Requires TrueConf Server 5.5.3+. ```python from trueconf import Router, F from trueconf.filters import Command from trueconf.filters.command import CommandObject from trueconf.types import Message r = Router() @r.message(Command("whoami")) async def whoami(msg: Message): result = await msg._bot.get_user_display_name(user_id=msg.from_user.id) await msg.answer(f"You are: {result.display_name}") @r.message(Command("myid")) async def myid(msg: Message): # bot.me returns the chat_id of the bot's Favorites/Saved Messages chat favorites_chat_id = await msg._bot.me await msg.answer(f"Bot's favorites chat ID: {favorites_chat_id}") @r.message(Command("servername")) async def server_info(msg: Message): name = await msg._bot.server_name version = await msg._bot.server_version await msg.answer(f"Server: {name}\nVersion: {version}") ``` -------------------------------- ### Send Sticker with FSInputFile Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/files.md Use FSInputFile to send a sticker from the local file system. Ensure the file path is correct. ```python from trueconf.types import FSInputFile await bot.send_sticker( chat_id="a1b2c3d4", file=FSInputFile("stickers/cat.webp") ) ``` -------------------------------- ### Initialize a Named Router Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/parse-messages.md Create a new Router instance with a specific name. Naming routers can help in managing and identifying them, especially when dealing with multiple routers. ```python from trueconf import Router r = Router(name="Router1") ``` -------------------------------- ### Importing All Types Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/reference/Types.md You can import all available types at once for convenience. ```APIDOC from trueconf.types import * ``` -------------------------------- ### Import Required Classes Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/getting-started.md Import core classes like Bot, Dispatcher, Router, and F, along with the Message type for handling incoming messages. ```python from trueconf import Bot, Dispatcher, Router, F from trueconf.types import Message ``` -------------------------------- ### Import Router Class Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/reference/Router.md Import the Router class directly from the trueconf package. ```python from trueconf import Router ``` -------------------------------- ### Download File by ID using bot.download_file_by_id() Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/files.md Use bot.download_file_by_id() for more flexible control over downloading files, providing the file_id and destination path. ```python await bot.download_file_by_id( file_id=msg.document.file_id, dest_path="document.pdf" ) ``` -------------------------------- ### Bulk Add Users to a Channel Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/examples/index.md This script shows how to add multiple users to a TrueConf channel in bulk. It reads user IDs from a file and adds them to a newly created channel, handling potential API errors. ```python from trueconf import Bot from trueconf.exceptions import ApiErrorException import asyncio import logging from pathlib import Path SERVER_ADDR = "" BOT_USERNAME = "" BOT_PASSWORD = "" PATH_LIST_USERS = "" CHANNEL_NAME = "" bot = Bot.from_credentials( server=SERVER_ADDR, username=BOT_USERNAME, password=BOT_PASSWORD, verify_ssl=False, ) Path("logs").mkdir(parents=True, exist_ok=True) logging.basicConfig( level=logging.DEBUG, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s", filename="logs/bot.log", encoding="utf-8", ) async def main(): await bot.start() await bot.connected_event.wait() await bot.authorized_event.wait() resp = await bot.create_channel(title=CHANNEL_NAME) with open(PATH_LIST_USERS, "r") as file: for line in file: user_id = line.strip() if user_id: try: await bot.add_participant_to_chat(resp.chat_id, user_id=user_id, display_history=True) except ApiErrorException as e: if e.code == 309: continue await bot.shutdown() if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Import All Enums Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/reference/Enums.md Import all available enums from the trueconf.enums module at once for convenient access. ```python from trueconf.enums import * ``` -------------------------------- ### Send Document with FSInputFile Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/files.md Use FSInputFile to upload a file from the local file system. Ensure the file path is correct. ```python from trueconf.types import FSInputFile await bot.send_document( chat_id="a1b2c3d4", file=FSInputFile("docs/report.pdf"), caption="📄 Annual report for **2025**", parse_mode=ParseMode.MARKDOWN ) ``` -------------------------------- ### Define Message Handlers with Router and Filters Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/features.md Use the Router to define message handlers. Filters like F.text.startswith and F.document.mime_type can be used to specify conditions for triggering handlers. Requires importing Router, Message, MessageType, and F. ```python from trueconf import Router, Message from trueconf.enums import MessageType from trueconf.filters import F router = Router() @router.message(F.text.startswith("/start")) async def on_start(msg: Message): await msg.answer("Hello! I\'m TrueConf bot 👋") @router.message(F.document.mime_type == "application/pdf") async def on_pdf(msg: Message): await msg.reply("Thanks for the PDF!") ``` -------------------------------- ### Import All Enums Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/enums.md Import all available enums from the trueconf.enums module at once for easy access. ```python from trueconf.enums import * ``` -------------------------------- ### Login/Password Authentication Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/getting-started.md Authenticate your bot using username and password with the `from_credentials` method. This method requests a new token from the server each time it's called. ```python bot = Bot.from_credentials( username="echo_bot", password="123tr", server="10.110.2.240", dispatcher=dp ) ``` -------------------------------- ### Manage Chat Participants with `add_participant_to_chat`, `remove_participant_from_chat`, `change_participant_role`, `get_chat_participants` Source: https://context7.com/trueconf/python-trueconf-bot/llms.txt Code snippets for adding, removing, promoting users, and listing participants in a chat. Note that `add_participant_to_chat` with `display_history=True` and `change_participant_role` require TrueConf Server 5.5.2+. ```python from trueconf import Router, F from trueconf.filters import Command from trueconf.filters.command import CommandObject from trueconf.types import Message from trueconf.enums import ChatParticipantRole r = Router() @r.message(Command("adduser", magic=F.args.is_not(None))) async def add_user(msg: Message, command: CommandObject): result = await msg._bot.add_participant_to_chat( chat_id=msg.chat_id, user_id=command.args.strip(), display_history=True, # Requires TrueConf Server 5.5.2+ ) await msg.answer(f"User added: {result}") ``` ```python @r.message(Command("removeuser", magic=F.args.is_not(None))) async def remove_user(msg: Message, command: CommandObject): await msg._bot.remove_participant_from_chat( chat_id=msg.chat_id, user_id=command.args.strip(), clear_history=False, ) await msg.answer("User removed.") ``` ```python @r.message(Command("promote", magic=F.args.is_not(None))) async def promote_user(msg: Message, command: CommandObject): user_id = command.args.strip() await msg._bot.change_participant_role( # Requires TrueConf Server 5.5.2+ chat_id=msg.chat_id, user_id=user_id, role=ChatParticipantRole.ADMIN, ) await msg.answer(f"{user_id} promoted to admin.") ``` ```python @r.message(Command("participants")) async def list_participants(msg: Message): result = await msg._bot.get_chat_participants( chat_id=msg.chat_id, page_size=20, page_number=1, ) names = [p.user_id for p in result.participants] await msg.answer("Participants:\n" + "\n".join(names)) ``` -------------------------------- ### Basic Command Filter Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/filters.md Use Command("ping") to create a filter that matches the exact command "ping". This is useful for simple command responses. ```python from bots.filters import Command from bots.types import Message @r.message(Command("ping")) async def handle_ping(message: Message): await bot.send_message(chat_id=message.chat_id, text="pong") ``` -------------------------------- ### Import All Types Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/reference/Types.md Import all available types from the trueconf.types library at once. This is a convenient way to access all type definitions. ```python from trueconf.types import * ``` -------------------------------- ### Import Bot Class Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/reference/Bot.md Import the Bot class directly from the trueconf package to use its functionalities. ```python from trueconf import Bot ``` -------------------------------- ### Basic MagicFilter Usage Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/filters.md Demonstrates how to use MagicFilter to check a simple string condition in a message handler. ```python from magic_filter import F @r.message(F.text == "ping") async def ping_handler(message): await message.answer("pong") ``` -------------------------------- ### File Status Check with FileReadyState Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/enums.md Check the ready state of a file using FileReadyState enum before downloading. Handles cases where the file is ready or not available. ```python from trueconf.enums import FileReadyState info = await bot.get_file_info(file_id="abc123") if info.ready_state == FileReadyState.READY: await bot.download_file_by_id(info.file_id, "./downloads") elif info.ready_state == FileReadyState.NOT_AVAILABLE: print("File is not available") ``` -------------------------------- ### Send Files with Different Input Types Source: https://context7.com/trueconf/python-trueconf-bot/llms.txt Send documents, photos, and stickers using `bot.send_document()`, `bot.send_photo()`, and `bot.send_sticker()`. Supports sending files from the filesystem (`FSInputFile`), memory (`BufferedInputFile`), or URLs (`URLInputFile`). Captions can use Markdown. ```python from trueconf import Router, F from trueconf.types import Message, FSInputFile, BufferedInputFile, URLInputFile from trueconf.enums import ParseMode r = Router() @r.message(F.text == "send files") async def send_files(msg: Message): bot = msg._bot # Send a document from the filesystem await bot.send_document( chat_id=msg.chat_id, file=FSInputFile("reports/annual_2025.pdf"), caption="📄 Annual report **2025**", parse_mode=ParseMode.MARKDOWN, ) # Send a photo with preview from bytes in memory with open("photo.jpg", "rb") as f: photo_bytes = f.read() with open("photo_thumb.webp", "rb") as f: thumb_bytes = f.read() await bot.send_photo( chat_id=msg.chat_id, file=BufferedInputFile(file=photo_bytes, filename="photo.jpg"), preview=BufferedInputFile(file=thumb_bytes, filename="thumb.webp"), caption="Team photo 📸", ) # Send a file from a remote URL await bot.send_document( chat_id=msg.chat_id, file=URLInputFile(url="https://example.com/data.csv", filename="data.csv"), caption="CSV export", ) # Send a WebP sticker await bot.send_sticker( chat_id=msg.chat_id, file=FSInputFile("stickers/thumbs_up.webp"), ) ``` -------------------------------- ### Import Dispatcher Class Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/reference/Dispatcher.md Import the Dispatcher class directly from the trueconf package to begin using its functionalities. ```python from trueconf import Dispatcher ``` -------------------------------- ### Sending Files Source: https://context7.com/trueconf/python-trueconf-bot/llms.txt Uploads and sends files using `FSInputFile` (local path), `BufferedInputFile` (in-memory bytes), or `URLInputFile` (remote URL). ```APIDOC ## Sending Files — `bot.send_document()` / `bot.send_photo()` / `bot.send_sticker()` Uploads and sends files using `FSInputFile` (local path), `BufferedInputFile` (in-memory bytes), or `URLInputFile` (remote URL). ```python from trueconf import Router, F from trueconf.types import Message, FSInputFile, BufferedInputFile, URLInputFile from trueconf.enums import ParseMode r = Router() @r.message(F.text == "send files") async def send_files(msg: Message): bot = msg._bot # Send a document from the filesystem await bot.send_document( chat_id=msg.chat_id, file=FSInputFile("reports/annual_2025.pdf"), caption="📄 Annual report **2025**", parse_mode=ParseMode.MARKDOWN, ) # Send a photo with preview from bytes in memory with open("photo.jpg", "rb") as f: photo_bytes = f.read() with open("photo_thumb.webp", "rb") as f: thumb_bytes = f.read() await bot.send_photo( chat_id=msg.chat_id, file=BufferedInputFile(file=photo_bytes, filename="photo.jpg"), preview=BufferedInputFile(file=thumb_bytes, filename="thumb.webp"), caption="Team photo 📸", ) # Send a file from a remote URL await bot.send_document( chat_id=msg.chat_id, file=URLInputFile(url="https://example.com/data.csv", filename="data.csv"), caption="CSV export", ) # Send a WebP sticker await bot.send_sticker( chat_id=msg.chat_id, file=FSInputFile("stickers/thumbs_up.webp"), ) ``` ``` -------------------------------- ### Token-Based Authentication Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/getting-started.md Authenticate your bot using a token. It's recommended to store the token in an environment variable for security. ```python from os import getenv TOKEN = getenv("TOKEN") bot = Bot(server="video.example.com", token=TOKEN, dispatcher=dp) ``` -------------------------------- ### InputFile Type Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/reference/Types.md Abstract base type for input files. ```APIDOC ::: trueconf.types.InputFile options: filters: - "!^_" - "!^__" - "!bot" - "!bind" ``` -------------------------------- ### Bot Class Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/reference/Bot.md The Bot class is the main entry point for interacting with the TrueConf bot API. It allows you to manage bot configurations, handle events, and interact with the TrueConf platform. ```APIDOC ## Class `Bot` Here is the reference information for the `Bot` class, including all its parameters, attributes, and methods. You can import the `Bot` class directly from the `trueconf` package: ```python from trueconf import Bot ``` ::: trueconf.Bot options: filters: - "!^_" - "!^__" ``` -------------------------------- ### Register Router with Dispatcher Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/parse-messages.md Include a created Router instance into the main Dispatcher. The Dispatcher is responsible for managing and routing all incoming updates to the appropriate handlers. ```python from trueconf import Dispatcher dp = Dispatcher() dp.include_router(r) ``` -------------------------------- ### Include Multiple Routers in Dispatcher Source: https://github.com/trueconf/python-trueconf-bot/blob/master/docs/en/learn/parse-messages.md Register several Router instances with a single Dispatcher. This allows for a modular bot structure where different functionalities are handled by separate routers. ```python from trueconf import Bot, Router, Dispatcher r1 = Router() r2 = Router() r3 = Router() r4 = Router() dp = Dispatcher() dp.include_router(r1) dp.include_router(r2) dp.include_router(r3) dp.include_router(r4) bot = Bot(token="JWT-token", dispatcher=dp) ```