Tencent QQ Channel Python SDK
qq-botpy is the official Python SDK for creating bots on Tencent's QQ Channels, providing an easy-to-use and efficient framework for developers. It abstracts the complexities of the QQ Open Platform API, enabling quick development of features like message handling and event listening. The library is actively maintained, with frequent updates; the current stable version is 1.2.1.
Common errors
-
ModuleNotFoundError: No module named 'botpy'
cause You likely installed the wrong package. `pip install botpy` installs a different library.fixRun `pip uninstall botpy` if you installed the incorrect package, then run `pip install qq-botpy`. -
Failed to get access_token: {'error': {'message': 'invalid client', 'type': 'invalid_client'}}cause Your `APP_ID` or `APP_SECRET` is incorrect or missing, or your bot's IP is not whitelisted.fixDouble-check your `APP_ID` and `APP_SECRET` from the QQ Open Platform. Ensure they are correctly passed to `client.run()`. Verify that your server's IP address is whitelisted in the QQ Open Platform settings if applicable. -
Error code: 400 - {'error': {'message': 'invalid message content type:', 'type': 'inv.'}}cause The message content or type being sent is not valid according to the QQ API, or it might be a rate limit issue leading to malformed requests.fixReview the content you are attempting to send. Ensure it adheres to QQ API message format requirements. If sending rich media, ensure the payload is correct. Check for rate limits, as frequent requests can sometimes lead to such errors. -
TypeError: 'NoneType' object is not subscriptable
cause This error often occurs during client startup if `client._ws_ap` is `None` because `self.api.get_ws_url()` timed out or failed to return valid session metadata.fixThis can indicate network issues or a transient API problem with the QQ backend. Check your network connection and ensure your bot's server can reach the QQ API. Consider adding retry logic or increasing the client's timeout setting if available.
Warnings
- breaking Authentication method changed from a single 'token' to 'AppID + AppSecret' in v1.1.5. Older versions using a token will cease to function with new API requirements.
- gotcha Installing `botpy` (without `qq-`) via pip will install a completely different library for StackExchange bots, not the Tencent QQ Channel bot SDK.
- gotcha The minimum required Python version is 3.7+.
- gotcha When replying to an `@` message, `message.content` will include the bot's `@username` prefix (e.g., `@bot_name your message`). This prefix needs to be stripped if you want to process only the user's actual message.
- gotcha QQ bots have rate limits for sending messages. For personal developers, this can be as low as 5 passive replies per minute. Exceeding this limit can result in messages being silently dropped without error.
- gotcha By default, personal developer QQ bots only have channel permissions. To enable group chat functionality, you must explicitly apply for and enable 'group chat' scenarios in the QQ Open Platform backend.
Install
-
pip install qq-botpy
Imports
- Client
import qqbot
import botpy from botpy.types.message import Message
- botpy
import botpy_se
import botpy
Quickstart
import os
import botpy
from botpy.types.message import Message
# Get credentials from environment variables or provide defaults
APP_ID = os.environ.get("QQ_BOT_APP_ID", "YOUR_APP_ID")
APP_SECRET = os.environ.get("QQ_BOT_APP_SECRET", "YOUR_APP_SECRET")
class MyClient(botpy.Client):
async def on_ready(self):
"""Event triggered when the bot is ready."""
print(f"robot 「{self.robot.name}」 on_ready!")
async def on_at_message_create(self, message: Message):
"""Event triggered when the bot receives an @ message."""
# Remove the bot's mention from the message content
user_message_content = message.content.replace(f"<@{self.robot.id}>", "").strip()
if user_message_content:
response_content = f"Hello, {message.author.username}! You said: {user_message_content}"
else:
response_content = f"Hello, {message.author.username}! How can I help you?"
await message.reply(content=response_content)
if __name__ == "__main__":
# Define the intents (events the bot should listen to)
intents = botpy.Intents(public_guild_messages=True)
# Create and run the client
client = MyClient(intents=intents)
client.run(appid=APP_ID, secret=APP_SECRET)