ljmerza / ha-email-sensor

Email Sensor for collecting tracking numbers from over 40 providers.
MIT License
90 stars 24 forks source link

Extract Amazon OTP (One-Time-Password) for delivery #60

Open snickers2k opened 11 months ago

snickers2k commented 11 months ago

For the ones not knowing what i'm talking about: Amazon has a new Policy for expensive items, requiring a One-Time-Password at the door.

Is your feature request related to a problem? Please describe.

Amazon sends OTPs only to the main Amazon-Account owner. Everyone else in the household does not have it. Also is a pain in the ass to search for that OTP (mostly on email, because sometimes sms not even works) while the delivery-driver is waiting at the door.

Describe the solution you'd like Extraction of the One-Time-Password with HA-email-sensor -> showing that one on a HA-Display near the door.

Additional context Amazon: Secure Delivery with a One-Time Password

It literally drives people crazy (like me) Reddit

snickers2k commented 11 months ago

this is what chatgpt gave me 😅 (i'm no coder)

import logging
import re

from bs4 import BeautifulSoup
from ..const import EMAIL_ATTR_BODY, EMAIL_ATTR_SUBJECT

_LOGGER = logging.getLogger(__name__)
ATTR_AMAZON = 'amazon'
EMAIL_DOMAIN_AMAZON = 'amazon.com'

def parse_amazon(email):
    """Parse Amazon tracking numbers or OTPs."""
    tracking_numbers = []
    otp = None

    soup = BeautifulSoup(email[EMAIL_ATTR_BODY], 'html.parser')

    order_number_match = re.search('Your Amazon(?:Smile)? order #(.*?) has shipped|Ihre Amazon(?:Smile)?-Bestellung #(.*?) wurde versandt', email[EMAIL_ATTR_SUBJECT])

    # If it's a shipment notification email, find the tracking link
    if order_number_match:
        order_number = order_number_match.group(1)
        linkElements = soup.find_all('a')
        for linkElement in linkElements:
            if re.search(r'track package|Sendung verfolgen', linkElement.text, re.IGNORECASE):
                link = linkElement.get('href')
                if order_number not in [x['tracking_number'] for x in tracking_numbers]:
                    tracking_numbers.append({
                        'link': link,
                        'tracking_number': order_number
                    })
    else:
        # If it's not a shipment notification email; check for OTP in both German and English
        if 'Einmal-Passwort' in email[EMAIL_ATTR_SUBJECT] or 'one-time password' in email[EMAIL_ATTR_SUBJECT].lower():
            otp_match = re.search(r'Ihr Einmal-Passwort lautet (\d{6})|Your one-time password is (\d{6})', email[EMAIL_ATTR_BODY])
            if otp_match:
                otp = otp_match.group(1)

    return {
        'tracking_numbers': tracking_numbers,
        'otp': otp
    }

# Example usage of the function
email_example_1 = {
    EMAIL_ATTR_BODY: "Your Amazon.com order #123456 has shipped.",
    EMAIL_ATTR_SUBJECT: "Your Amazon.com order #123456 has shipped"
}
result_1 = parse_amazon(email_example_1)
print(result_1)

email_example_2 = {
    EMAIL_ATTR_BODY: "Ihr Einmal-Passwort lautet 123456.",
    EMAIL_ATTR_SUBJECT: "Ihr Amazon.de Einmal-Passwort"
}
result_2 = parse_amazon(email_example_2)
print(result_2)