如何在aiogram中实现函数仅周五单次执行的功能?
实现AIogram周五领奖指令单次触发功能
要实现每个用户每周五仅能触发一次领奖指令,我们需要记录用户的领奖日期,避免重复触发。以下是具体实现方案:
内存存储版本(简单但重启丢失数据)
这种方式适合测试或临时场景,数据存储在内存中,机器人重启后会重置:
import logging from aiogram import Bot, Dispatcher, executor, types from aiogram.types.message import ContentType from aiogram.types import ReplyKeyboardRemove, \ ReplyKeyboardMarkup, KeyboardButton, \ InlineKeyboardMarkup, InlineKeyboardButton import json from oop import Shop import requests from aiogram.contrib.fsm_storage.memory import MemoryStorage from aiogram.dispatcher import FSMContext from datetime import datetime, date, time # 初始化存储:键为用户ID,值为最后领奖日期 user_last_prize_date = {} @dp.message_handler(text_contains='To get prize') async def get_prize(message: types.Message): user_id = message.from_user.id today = date.today() # 判断是否是周五 if datetime.today().weekday() != 4: await bot.send_message(user_id, 'You can get your prize only on fridays.\nToday is no friday :)') return # 检查用户今天是否已领奖 if user_id in user_last_prize_date and user_last_prize_date[user_id] == today: await bot.send_message(user_id, 'You have already claimed your prize today! Come back next Friday.') else: # 发送领奖成功消息并更新领奖日期 await bot.send_message(user_id, 'You successfully got your prize, come next friday to get one more✅') user_last_prize_date[user_id] = today # 补充Bot和Dispatcher初始化(需替换为你的Token) # API_TOKEN = 'your_bot_token_here' # storage = MemoryStorage() # bot = Bot(token=API_TOKEN) # dp = Dispatcher(bot, storage=storage) if __name__ == '__main__': executor.start_polling(dp, skip_updates=True)
持久化存储版本(数据不丢失)
如果需要机器人重启后仍保留领奖记录,可以使用JSON文件存储数据:
import logging from aiogram import Bot, Dispatcher, executor, types from aiogram.types.message import ContentType from aiogram.types import ReplyKeyboardRemove, \ ReplyKeyboardMarkup, KeyboardButton, \ InlineKeyboardMarkup, InlineKeyboardButton import json from oop import Shop import requests from aiogram.contrib.fsm_storage.memory import MemoryStorage from aiogram.dispatcher import FSMContext from datetime import datetime, date, time # 存储文件路径 STORAGE_FILE = 'prize_records.json' # 加载已有的领奖记录 def load_prize_records(): try: with open(STORAGE_FILE, 'r') as f: data = json.load(f) # 将字符串日期转换为date对象 return {int(user_id): date.fromisoformat(date_str) for user_id, date_str in data.items()} except FileNotFoundError: return {} # 保存领奖记录到文件 def save_prize_records(records): # 将date对象转换为字符串以便JSON存储 data = {str(user_id): date_obj.isoformat() for user_id, date_obj in records.items()} with open(STORAGE_FILE, 'w') as f: json.dump(data, f) # 初始化存储 user_last_prize_date = load_prize_records() @dp.message_handler(text_contains='To get prize') async def get_prize(message: types.Message): user_id = message.from_user.id today = date.today() if datetime.today().weekday() != 4: await bot.send_message(user_id, 'You can get your prize only on fridays.\nToday is no friday :)') return if user_id in user_last_prize_date and user_last_prize_date[user_id] == today: await bot.send_message(user_id, 'You have already claimed your prize today! Come back next Friday.') else: await bot.send_message(user_id, 'You successfully got your prize, come next friday to get one more✅') user_last_prize_date[user_id] = today # 保存到文件 save_prize_records(user_last_prize_date) # 补充Bot和Dispatcher初始化(需替换为你的Token) # API_TOKEN = 'your_bot_token_here' # storage = MemoryStorage() # bot = Bot(token=API_TOKEN) # dp = Dispatcher(bot, storage=storage) if __name__ == '__main__': executor.start_polling(dp, skip_updates=True)
关键逻辑说明
- 日期判断:通过
datetime.today().weekday() == 4确认当前是周五(周一为0,周日为6)。 - 领奖记录检查:通过字典存储用户ID与领奖日期,每次触发时对比当前日期与记录中的日期,判断是否重复领奖。
- 持久化处理:使用JSON文件存储数据,每次更新记录后写入文件,确保机器人重启后数据不丢失。
内容的提问来源于stack exchange,提问作者rayt-right-decision
相关产品推荐
相关产品推荐

