How to use SMTP with Apple iCloud Custom Domain

Viewed 678

I would like to use Python's SMTP to send automated emails with a custom domain iCloud+ email address. However, I can't get logged into the SMTP servers. I will always either get "Mailbox does not exist" or "Authentication failed".

From the Apple support pages it seems like you need to use SSL over port 587. Additionally, they want you to generate an "app-specific password" for outside applications. This led me to the following code:

import smtplib, ssl

smtp_server = "smtp.mail.me.com"
port = 587  # For SSL

# Create a secure SSL context
context = ssl.create_default_context()

sender_email = "me@example.com"  # Enter your address
receiver_email = "you@example.com"  # Enter receiver address
password = "some,password" # app specific password from Apple ID settings
message = """\
To: {to}
From: {sender}
Subject: Hello There

This was sent through Python!
""".format(to=receiver_email, sender=sender_email)

with smtplib.SMTP_SSL(smtp_server, port, context=context) as server:
    server.login(sender_email, password)
    # Send email here
    server.sendmail(sender_email, receiver_email, message)

However, this was still giving me a connection error. Only when I changed the last part to use TLS instead would it connect and give me an authentication error. This was taken from this question: SMTP_SSL SSLError: [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:590)

try:
    server = smtplib.SMTP(smtp_server, port)
    server.ehlo() # Can be omitted
    server.starttls(context=context) # Secure the connection
    server.ehlo() # Can be omitted
    server.login(sender_email, password)
    # Send email here
    server.sendmail(sender_email, receiver_email, message)
except Exception as e:
    import traceback
    print(traceback.format_exc())
finally:
    server.quit()

So how can I use my custom domain address with Apple's iCloud+ service with Python's SMTP?

1 Answers

Just before I was going to ask this question, I solved it!

After reading this reddit post, I figured that all custom domain iCloud+ accounts are actually alias of some sort to the main iCloud account. So, I tried logging into my "main" iCloud account. This worked with the above code and sent the email! However, the from was still not my custom domain email address.

This is a somewhat easy fix though, simply modify the "From: <sender>" line in the email body. I'm not sure if this should be done (since it's technicaly faking who you are) but it seems to work. If any email experts know of better ways to do this please comment/answer though! The following code is what I used:

sender_email = "me@icloud.com"       # this is who we actually are
sender = "me@example.com"            # this is who we appear to be (i.e. custom domain email)
receiver_email = "you@example.com"   # this is to who we have sent the email

message = """\
To: {to}
From: {sender}
Subject: Hello There

This was sent through Python!
""".format(to=receiver_email, sender=sender) # this is what changed, we use an alias instead

# ...

server.sendmail(sender_email, receiver_email, message)
Related