Pythonanywhere每小时定时任务避免重复发送预订邮件方案咨询
实现方案
核心逻辑
通过本地轻量标记文件记录邮件发送日期,实现当日发送后自动锁定、次日自动重置的效果,适配Pythonanywhere的运行环境,无需额外依赖或数据库。
- 脚本启动时先读取标记文件中存储的上次成功发送邮件的日期
- 若存储日期与当前日期一致,直接终止运行,不再执行后续查询和发送逻辑
- 若日期不一致或标记文件不存在,正常执行订单查询流程
- 邮件发送成功后,将当前日期写入标记文件,完成当日的发送锁定
修正后完整代码
import urllib import sys import json import requests import smtplib import datetime # 标记文件配置,存储上次发送邮件的日期 MARK_FILE = "last_sent_date.txt" today = datetime.date.today().isoformat() # 检查今日是否已发送过邮件 try: with open(MARK_FILE, 'r') as f: last_sent_date = f.read().strip() if last_sent_date == today: print("今日已发送过预订通知,直接退出") exit() except FileNotFoundError: # 标记文件不存在,说明从未发送过,继续执行 pass #email log in variables gmail_user = 'info@XXXXX.com' gmail_password = 'XXXXXXXX' # Create Email mail_from = "info@XXXXX.com" mail_to = 'XXXXX@mtlcz.com' mail_subject = 'New booking from XXXXXXX' base_url = 'https://XXX.XXXXX.co.uk/api/3.0/booking?created_date=TODAY' client_id='XXXXXX' client_secret='XXXXXX' #return a json oject with the bookings data response = requests.get(base_url,auth=(client_id, client_secret)) mycustomer=response.json() #checks if there is a booking for the day if mycustomer['request']['records']==0: print ('no bookings for this date') exit() #if there is a booking continue mytext = None if mycustomer['request']['records']>0: #gets the keys of the booking and turns into booking ids for key in mycustomer['booking/index'].keys(): my_booking_id = key #checks if the tours are bookings delight if "foodie's delight tour" in mycustomer['booking/index'][my_booking_id]['summary']: #extracts the data of the bookings my_customer_email =mycustomer['booking/index'][my_booking_id]['customer_email'] my_customer_name=mycustomer['booking/index'][my_booking_id]['customer_name'] my_payment=mycustomer['booking/index'][my_booking_id]['status_id'] tour_booked=mycustomer['booking/index'][my_booking_id]['summary'] date_booking=mycustomer['booking/index'][my_booking_id]['date_desc'] booking_id=mycustomer['booking/index'][my_booking_id]['booking_id'] # get more info from order ###add this part booking_order_code =mycustomer['booking/index'][my_booking_id]['code'] # 修正原代码缺失的单引号问题 base_url = 'https://XXXXX.XXXXX.co.uk/api/3.0/booking/'+booking_order_code response3 = requests.get(base_url,auth=(client_id, client_secret)) mycustomer3=response3.json() deposit=mycustomer3['booking']['deposit_due'] quantity=mycustomer3['booking']['items']['1']['qty'] mytext=''' Hello, there is a new booking for XXXXX XXXXX, here some details: the booking ID is: '''+ str(booking_id) + ''' The date of event is: ''' + date_booking + ''' The customer email is: ''' + my_customer_email +''' The customer name is: ''' +my_customer_name +''' This cumstomer booked : ''' + tour_booked +''' The status of the payment is ''' + my_payment +''' Deposit owned is '''+deposit+''' People booked on activity '''+quantity+''' A more detailed email will follow Unless indicated above the tours will leave from ''' # 仅当存在符合条件的订单时才发送邮件 if mytext: try: mail_message_body = mytext mail_message = '''\ From: %s To: %s Subject: %s %s ''' % (mail_from, mail_to, mail_subject, mail_message_body) server = smtplib.SMTP_SSL('smtp.XXXXXXX.com', 465) server.login(gmail_user, gmail_password) server.sendmail(mail_from, mail_to, mail_message) server.close() print ('email has been sent') print (mail_message_body) # 发送成功后写入当前日期到标记文件,锁定当日发送 with open(MARK_FILE, 'w') as f: f.write(today) except Exception as e: print ('邮件发送失败:', str(e)) else: print('今日无符合条件的新预订')
补充说明
如果后续业务调整需要支持单日多订单不重复发送,可以将标记文件的存储内容修改为当日已发送的订单ID集合,每日日期变更时清空集合即可,当前需求下仅用日期判断足够使用。
内容的提问来源于stack exchange,提问作者Emilia Delizia
相关产品推荐
相关产品推荐

