netflix-clicker/mail_server.py
2024-03-31 19:48:36 +08:00

57 lines
2.0 KiB
Python

from aiosmtpd.controller import Controller
import quopri
from loguru import logger
import re
from browser import PrimaryLocationClicker, TravelVerificationClicker
import asyncio
from line_notifier import LineNotifier
URL_PATTERN = re.compile(b'"(https://www.netflix.com/account/update-primary-location.*?)"', re.DOTALL)
VERIFY_URL_PATTERN = re.compile(b'"(https://www.netflix.com/account/travel/verify.*?)"', re.DOTALL)
notifier = LineNotifier()
class NetflixHandler:
async def handle_RCPT(self, session, envelope, address, rcpt_options):
if 'netflix_clicker' not in address:
logger.info(f'Rejected mail from {envelope.mail_from}')
return '550 not relaying to that domain'
envelope.rcpt_tos.append(address)
logger.info(f'Accepted mail from {envelope.mail_from}')
return '250 OK'
async def handle_DATA(self, session, envelope, *args):
data = quopri.decodestring(
envelope.content.decode('utf8', errors='replace')
)
if urls := URL_PATTERN.findall(data):
with PrimaryLocationClicker() as browser:
url = urls[0]
logger.info(f'Found Update link: {url}')
try:
browser.click(url.decode())
except Exception as e:
logger.error(e)
elif urls := VERIFY_URL_PATTERN.findall(data):
with TravelVerificationClicker() as browser:
url = urls[0]
logger.info(f'Found Travel Verification link: {url}')
code = browser.get_code(url)
notifier.notify(f'代碼為 {code}')
elif 'google' in envelope.mail_from:
logger.info(data)
return '250 Message accepted for delivery'
server = Controller(handler=NetflixHandler, hostname='0.0.0.0', port=1025)
server.start()
logger.info('Netflix-clicker start.')
while True:
try:
asyncio.run(asyncio.sleep(3))
except KeyboardInterrupt:
server.stop()