我是Python编程的初学者,我想到用Python编写一个电报聊天摘要机器人。我使用了 python-telegram-bot(v20.5) 模块,并主要在 ChatGPT 和其他 AI 的帮助下编写了代码。我正在尝试在本地运行该机器人。当我运行脚本时,没有任何错误或没有任何错误。但是当我尝试在电报中启动机器人时,什么也没有发生。以下是我的代码,请告诉我我做错了什么。
import telegram
from telegram.ext import Updater, CommandHandler, MessageHandler, filters, ConversationHandler, Application
import requests
import datetime
from queue import Queue
import asyncio
# Bot Token
bot = telegram.Bot(token='Correctly pasted my bot token here')
# Create an updater object that will receive updates from Telegram
update_queue = Queue()
updater = Updater(bot=bot, update_queue=update_queue)
# Create an Application object with bot token
application = Application.builder().token('Correctly pasted my bot token here').build()
# Define some constants for the conversation states
CHAT, DATE = range(2)
# Define a function that takes a chat id, a start date and an end date as parameters and returns a summary of the chat messages in that period using the meaningcloud summarization API
def get_summary(chat_id, start_date, end_date):
# Initialize an empty list to store the chat messages
messages = []
# Get the chat history from the bot object using the get_chat_history method
# This method returns a tuple of (messages, next_offset)
# We need to loop until we get all the messages or reach the end date
offset = 0 # The offset is the ID of the first message to be returned
while True:
# Get a batch of 100 messages from the chat history
history = bot.get_chat_history(chat_id, offset=offset)
# Loop through each message in the history
for message in history[0]:
# Get the message date as a datetime object
message_date = message.date
# Check if the message date is within the date range
if start_date <= message_date <= end_date:
# Check if the message has text content
if message.text:
# Append the message text to the messages list
messages.append(message.text)
# If the message date is before the start date, we can break the loop as we have reached the end of the date range
elif message_date < start_date:
break
# If there are no more messages to fetch, we can break the loop as we have reached the end of the chat history
if not history[1]:
break
# Otherwise, we update the offset with the next offset value returned by the get_chat_history method
else:
offset = history[1]
# Join all the messages into a single string with newline characters as separators
text = '\n'.join(messages)
# Check if the text is not empty
if text:
# Make a request to the meaningcloud summarization API using the requests module
# We need to pass our API key, the text to summarize and the number of sentences in the summary as parameters
response = requests.post('https://api.meaningcloud.com/summarization-1.0', data={'key': 'Correctly pasted my meaningcloud API key here', 'txt': text, 'sentences': 5})
# Check if the request was successful by looking at the status code
if response.status_code == 200:
# Parse the response as a JSON object and get the summary field
summary = response.json()['summary']
# Return the summary as a string
return summary
# If the request failed, we return an error message with the status code
else:
return f'Sorry, something went wrong with the meaningcloud summarization API. The status code was {response.status_code}.'
# If the text is empty, we return a message saying that there were no messages in that date range
else:
return 'Sorry, there were no messages in that date range.'
# Define a function that takes an update and a context as parameters and asks the user to choose a chat to summarize from their chat list
def choose_chat(update, context):
# Get all chats that are currently opened by using bot.get_chats() method.
chats = bot.get_chats()
# Initialize an empty list to store chat titles.
chat_titles = []
for chat in chats:
chat_titles.append(chat.title)
update.message.reply_text(f'Please choose one of these chats: {chat_titles}')
return CHAT
# Define a function that takes an update and a context as parameters and asks user to enter a date range to summarize.
def enter_date(update, context):
user_input = update.message.text
if user_input not in chat_titles:
update.message.reply_text(f'Sorry, {user_input} is not a valid chat. Please choose one of these chats: {chat_titles}')
return CHAT
else:
# Get the chat id from the user input by using bot.get_chat() method.
chat = bot.get_chat(user_input)
chat_id = chat.id
# Store the chat id in the user data dictionary for later use.
context.user_data['chat_id'] = chat_id
# Ask the user to enter a date range in the format YYYY-MM-DD - YYYY-MM-DD.
update.message.reply_text('Please enter a date range in the format YYYY-MM-DD - YYYY-MM-DD.')
return DATE
# Define a function that takes an update and a context as parameters and validates the date range input and calls the get_summary function to get the summary of the chat messages in that period.
def summarize(update, context):
# Get the date range input from the user
date_range = update.message.text
# Try to split the date range by the dash character and parse each part as a date object using the datetime module
try:
start_date_str, end_date_str = date_range.split('-')
start_date = datetime.datetime.strptime(start_date_str.strip(), '%Y-%m-%d')
end_date = datetime.datetime.strptime(end_date_str.strip(), '%Y-%m-%d')
# Check if the start date is before or equal to the end date
if start_date <= end_date:
# Store the start date and end date in the user data dictionary for later use
context.user_data['start_date'] = start_date
context.user_data['end_date'] = end_date
# Call the get_summary function to get the summary of the chat messages in that period
summary = get_summary(context.user_data['chat_id'], start_date, end_date)
# Send the summary to the user
update.message.reply_text(summary)
# End the conversation
return ConversationHandler.END
# If the start date is after the end date, we send an error message and ask the user to enter a valid date range again
else:
update.message.reply_text('Sorry, the start date must be before or equal to the end date. Please enter a valid date range.')
return DATE
# If there is an exception while parsing the dates, we send an error message and ask the user to enter a valid date range again
except Exception as e:
update.message.reply_text(f'Sorry, something went wrong while parsing your dates. Please enter a valid date range. The error was: {e}')
return DATE
# Define a function that takes an update and a context as parameters and cancels or restarts the conversation
def cancel(update, context):
# Get the user input
user_input = update.message.text.lower()
# Check if the user input is 'cancel' or 'restart'
if user_input == 'cancel':
# Send a message saying that the conversation is cancelled
update.message.reply_text('OK, I have cancelled this conversation.')
# End the conversation
return ConversationHandler.END
elif user_input == 'restart':
# Send a message saying that the conversation is restarted
update.message.reply_text('OK, I have restarted this conversation.')
# Go back to the first state of choosing a chat
return choose_chat(update, context)
else:
# Send a message saying that the user input is not valid and provide options to cancel or restart
update.message.reply_text('Sorry, I did not understand your input. You can type "cancel" to cancel this conversation or "restart" to restart it.')
return ConversationHandler.END
# Create a conversation handler for the summarization bot
conv_handler = ConversationHandler(
entry_points=[CommandHandler('summarize', choose_chat)],
states={
CHAT: [MessageHandler(filters.Text, enter_date)],
DATE: [MessageHandler(filters.Text, summarize)]
},
fallbacks=[MessageHandler(filters.Text, cancel)]
)
# Add the handler to the application
application.add_handler(conv_handler)
# Start the application
application.run_polling()
尝试在本地运行电报机器人代码,但无法启动机器人。
尝试使用 PTB 文档中的示例,我怀疑 Telegram 是否可以从 TelegramBotAPI 获取聊天历史记录,尝试将消息记录到数据库中,一开始你可以尝试 sqlite3,但在生产模式下我建议使用其他任何东西,例如 MySQL 或PostgreSQL。
变量作用域也很混乱,尝试学习一些关于它的东西,特别是在Python中(关于
local
nonlocal
和global
作用域)