1 of 35

Universal Acceptance (UA) Micro-Learning Module: Module 9- Programming in Email Address Internationalization(EAI) Using Python.

Instructor Guide

1st Edition.

���© 2024 Creative Commons License - Attribution 4.0 International (CC BY 4.0).

Universal Acceptance

2 of 35

Programming in EAI UA Micro-Learning Module Objectives.

  • The micro-learning module covers fundamentals of EAI programming, including validation, encoding, parsing, and handling of internationalized email addresses.
  • At the end of this module, students should be able to:
    • Learn techniques and best practices for handling non-ASCII characters in email subject line, header line, attachments and email body contents using UTF-8 encoding;
    • Discover libraries and APIs available for handling SMTP interactions with EAI support in programming languages;
    • Learn how to send emails with Non-ASCII email addresses using Python's smtplib and IDNA encoding;
    • Explore techniques for validating internationalized email addresses with confirmation links to ensure email delivery across languages;
    • Learn parsing internationalized email addresses, including decoding the local and domain parts correctly; and
    • Understand the EAI-specific considerations for setting up email mailbox names, including character encoding and validation.

| 2

3 of 35

Note About the Utilization of Unicode String Literals :

  • The Unicode string literals utilized in the code examples necessitate input methods, whether virtual or physical keyboards, suited to the script from which the literals are derived. In the event that these input methods are unavailable, alternatives such as language translation tools can be used.
  • Throughout the module, Unicode string literals derived from various scripts have been used in the examples code, spanning from lesser-known to more widely used ones. This approach aims to broaden learners' exposure to a diverse range of scripts..
  • The module provides the meanings of Unicode string literals used in the example codes in English, along with their transliterations, to aid learners in accurately pronouncing them.
  • Instructors are free to use Unicode literal strings derived from a script of their choice rather than the ones included in the examples code.

| 3

4 of 35

EAI programming: Handling Non-ASCII Characters in Emails.

  • When it comes to handling UTF-8/non-ASCII characters in email communication there needs to be considerations such as the following:
    • Character Encoding: Use UTF-8 as the character encoding scheme throughout the email communication process.
    • Subject Line: ensure that it is properly encoded using the MIME encoded-word syntax.
    • Header Fields: any non-ASCII characters in email headers should be encoded using the MIME encoded-word syntax.
    • Email Body Text: to handle non-ASCII characters in the email body text, ensure that the email content is encoded using UTF-8.
    • Attachments: When dealing with attachments, it is essential to handle the encoding of filenames and content correctly.
    • Testing and Validation: it is crucial to thoroughly test your EAI programming implementation to ensure compatibility across various email clients, servers, and platforms.

| 4

5 of 35

EAI Programming: Handling Subject and Header Lines with UTF-8/Non-ASCII Characters(1/2):

  • When handling subject lines with UTF-8/non-ASCII characters in EAI programming, it's important to ensure proper encoding and decoding.
    • The following are some considerations:
      • Character Encoding: ensure that the subject and header lines support the necessary character encoding, typically UTF-8, to handle non-ASCII characters.
      • MIME Encoded-Word Syntax:

Example1: MIME Encoded-Word Syntax Representing the Arabic Word “Marhaba”:

In the example above:

      • UTF-8 is the character set.
      • Q indicates Quoted-Printable encoding.
      • =D9=85=D8=B1=D8=AD=D8=A8=D8=A7 is the Quoted-Printable encoded representation of the Arabic greeting word ""مرحبا" in UTF-8. Each non-ASCII character is represented by an equal sign "=" followed by two hexadecimal digits.
      • Subject and Header Lines Length: Be aware that using non-ASCII characters in the subject and header lines may affect the length of the subject line.

=?UTF-8?Q?مرحبا?=

| 5

6 of 35

EAI Programming: Handling Subject and Header Lines with UTF-8/Non-ASCII Characters(2/2):

      • Encoding the Subject and Header Lines: be aware that using non-ASCII characters in the subject and header lines may affect the length of the subject line.
      • Testing and Validation: thoroughly test the behavior of the subject and header lines with different scenarios involving non-ASCII characters.

| 6

7 of 35

Example: Code Snippet for Handling Subject Line with UTF-8/non-ASCII Characters in Python:

import smtplib

from email.mime.text import MIMEText

from email.mime.multipart import MIMEMultipart

from email.header import Header

from email.utils import formataddr

# Define sender and recipient email addresses

sender_email = 'your_sender_email@example.com' # Replace with your sender's email address

recipient_email = 'recipient_email@example.com' # Replace with the recipient's email address

# Create a MIME message

msg = MIMEMultipart('alternative')

# Set the subject line with non-ASCII characters

subject = 'Subject with Non-ASCII Characters: 你好, Hello'

msg['Subject'] = Header(subject, 'utf-8').encode()

| 7

8 of 35

EAI Programming: Handling Email Body with UTF-8/Non-ASCII Characters(½):

  • Handling email bodies with UTF-8 or non-ASCII characters in EAI programming:
    • Set the Content-Type and Character Encoding.
      • Code Snippet in Python:

    • Encode the Email Body:
      • Code Snippet in Python:

message['Content-Type'] = 'text/plain; charset=utf-8'

email_body = '你好, Hello'

encoded_body = email_body.encode('utf-8')

| 8

9 of 35

EAI Programming: Handling Email Body with UTF-8/Non-ASCII Characters(2/2):

  • Handling email bodies with UTF-8 or non-ASCII characters in EAI programming:
    • Create a MIMEText Object and Set the Content
      • Code Snippet in Python:

    • Send the Email:
      • Code Snippet in Python:

from email.mime.text import MIMEText

text_part = MIMEText(encoded_body, 'plain', 'utf-8')

message.attach(text_part)

import smtplib

with smtplib.SMTP('smtp.example.com') as server: # Replace with your SMTP server details

server.send_message(message)

| 9

10 of 35

EAI Programming: Full Python Code for Handling Subject Line, Header Line and Email Body with UTF-8/Non-ASCII Characters (1/2):

import smtplib

from email.mime.text import MIMEText

# Define sender and recipient email addresses

sender_email = 'your_sender_email@example.com' # Replace with your sender's email address

recipient_email = 'recipient_email@example.com' # Replace with the recipient's email address

# Create a MIMEText message with internationalized text

message_text = """

Hello,

This is an example of internationalized email body text.

It includes non-ASCII characters like مرحبًا,ሀሎ,ආයුබෝවන්, 你好

(Arabic, Ethiopic, Sinhala and Chinese for "Hello").

Feel free to add more internationalized content as you like.

Best regards,

Your Name

"""

| 10

11 of 35

EAI Programming: Full Python Code for Handling Subject Line, Header Line and Email Body with UTF-8/Non-ASCII Characters (2/2):

msg = MIMEText(message_text, 'plain', 'utf-8')

# Establish an SMTP connection and send the email

smtp_server = 'your_smtp_server.com' # Replace with your SMTP server address

smtp_port = 587 # Replace with the appropriate port

smtp_username = 'your_smtp_username' # Replace with your SMTP username

smtp_password = 'your_smtp_password' # Replace with your SMTP password

msg['From'] = sender_email

msg['To'] = recipient_email

msg['Subject'] = 'Internationalized Email Body Text'

try:

server = smtplib.SMTP(smtp_server, smtp_port)

server.starttls()

server.login(smtp_username, smtp_password)

server.sendmail(sender_email, [recipient_email], msg.as_string())

server.quit()

print("Email sent successfully.")

except Exception as e:

print("Email sending failed:", str(e))

| 11

12 of 35

EAI Programming: Handling Attachments with UTF-8/Non-ASCII Characters:

  • Handling email attachments with UTF-8 or non-ASCII characters in EAI programming:
    • Attachment Encoding: when attaching a file with UTF-8 or non-ASCII characters, it's important to use the appropriate encoding to preserve the character integrity.
    • Filename Encoding: if the attachment has a filename that includes non-ASCII characters, it needs to be properly encoded.
    • Content-Type and Content-Disposition Headers: When including an attachment, you need to set the appropriate Content-Type and Content-Disposition headers.
    • MIME Types: Attachments are typically included in an email using the multipart format, where the email body and attachments are encapsulated in MIME parts.

| 12

13 of 35

Example: Code Snippets for Parts of the Python code for Handling Attachments in UTF-8:

  • Importing Libraries:

import smtplib

from email.mime.multipart import MIMEMultipart

from email.mime.text import MIMEText

from email.mime.base import MIMEBase

from email import encoders

  • Defining Email Configuration:

# Defining Email Configuration

sender_email = 'تجربة-بريد-الكتروني@تجربة-القبول-الشامل.موريتانيا'

recipient_email = '电子邮件测试@普遍适用测试.我爱你'

message = MIMEMultipart()

| 13

14 of 35

Example: Code Snippets for Parts of the Python code for Handling Attachments in UTF-8- Composing Email Content:

# Composing Email Content

message["From"] = sender_email

message["To"] = recipient_email

message["Subject"] = "Email with Attachment"

message_text = "Hello,\n\n" \

"Please find the attached file.\n\n" \

"Best regards,\n" \

"Your Name\n"

message.attach(MIMEText(message_text, "plain"))

attachment_file = "path/to/attachment"

attachment = open(attachment_file, "rb")

part = MIMEBase("application", "octet-stream")

part.set_payload(attachment.read())

encoders.encode_base64(part)

part.add_header(

"Content-Disposition", f"attachment; filename=attachment_name; filename*=UTF-8''{attachment_file}",)

message.attach(part)

| 14

15 of 35

Example: Code Snippets for Parts of the Python code for Handling Attachments in UTF-8 – Sending Email with Attachment.

# Sending Email with Attachment

smtp_server = "your_smtp_server.com"

smtp_port = 587

smtp_username = "your_smtp_username"

smtp_password = "your_smtp_password"

with smtplib.SMTP(smtp_server, smtp_port) as server:

server.starttls()

server.login(smtp_username, smtp_password)

server.sendmail(sender_email, recipient_email, message.as_string())

print("Email sent successfully.")

| 15

16 of 35

Example: Full Code for Handling Attachments with UTF-8/Non-ASCII Characters in Python(1/3):

import smtplib

from email.mime.multipart import MIMEMultipart

from email.mime.text import MIMEText

from email.mime.base import MIMEBase

from email import encoders

def send_email_with_attachment():

# Define sender and recipient email addresses

sender_email = 'تجربة-بريد-الكتروني@تجربة-القبول-الشامل.موريتانيا' # Replace with your sender's email address

recipient_email = '电子邮件测试@普遍适用测试.我爱你' # Replace with the recipient's email address

# Create a MIMEMultipart object

message = MIMEMultipart()

message["From"] = sender_email

message["To"] = recipient_email

message["Subject"] = "Email with Attachment"

| 16

17 of 35

Example: Full Code for Handling Attachments with UTF-8/Non-ASCII Characters in Python(2/3):

# Add email text

message_text = "Hello,\n\n" \

"Please find the attached file.\n\n" \

"Best regards,\n" \

"Your Name\n"

message.attach(MIMEText(message_text, "plain"))

# Add attachment

attachment_file = "path/to/attachment" # Replace with the path to your attachment file

attachment = open(attachment_file, "rb")

part = MIMEBase("application", "octet-stream")

part.set_payload(attachment.read())

encoders.encode_base64(part)

part.add_header(

"Content-Disposition",

f"attachment; filename=attachment_name; filename*=UTF-8''{attachment_file}",

)

message.attach(part)

| 17

18 of 35

Example: Full Code for Handling Attachments with UTF-8/Non-ASCII Characters in Python(3/3):

# Connect to the SMTP server and send the email

smtp_server = "your_smtp_server.com" # Replace with your SMTP server address

smtp_port = 587 # Replace with the appropriate port

smtp_username = "your_smtp_username" # Replace with your SMTP username

smtp_password = "your_smtp_password" # Replace with your SMTP password

with smtplib.SMTP(smtp_server, smtp_port) as server:

server.starttls()

server.login(smtp_username, smtp_password)

server.sendmail(sender_email, recipient_email, message.as_string())

print("Email sent successfully.")

# Call the function to send the email

send_email_with_attachment()

| 18

19 of 35

Example: Handling Attachments with UTF-8/Non-ASCII Filename in Python:

import email.utils

def handle_attachment(filename):

# Encode the filename using UTF-8

encoded_filename = filename.encode('utf-8')

# Set the Content-Disposition header with the encoded filename

content_disposition = f'attachment; filename="{encoded_filename.decode()}"'

# Create the email attachment object

attachment = email.mime.base.MIMEBase('application', 'octet-stream')

attachment.set_payload(open(filename, 'rb').read())

# Set the Content-Disposition header for the attachment

attachment['Content-Disposition'] = content_disposition

# Encode the attachment as base64

email.encoders.encode_base64(attachment)

return attachment

# Example usage

attachment_filename = "文件名.pdf" # Non-ASCII filename

attachment = handle_attachment(attachment_filename)

| 19

20 of 35

Handling SMTP Interactions with EAI Support: Libraries and APIs:

  • The following are some commonly used libraries and APIs for handling SMTP interactions with EAI support in Python:
    • Python's built-in smtplib module with IDN support:
      • smtplib.
      • Idna.

| 20

21 of 35

Example: Sending Emails with EAI Address with Python's smtplib and IDNA(1/4):

  • Import Libraries

import smtplib

from email.mime.text import MIMEText

from email.header import Header

| 21

22 of 35

Example: Sending Emails with EAI Address with Python's smtplib and IDNA(2/4):

  • Define EAI Addresses and Message:

#Define EAI Addresses and Message

def send_multilingual_email(): # Define sender and recipient email addresses

sender_email = "تجربة-بريد-الكتروني@example.com"

recipient_email = "电子邮件测试@example.com"

# Create the email message

message = MIMEText("مرحبًا,ሀሎ,ආයුබෝවන්", "plain", "utf-8")

message["From"] = Header("Sender Name", "utf-8")

message["To"] = Header("Recipient Name", "utf-8")

message["Subject"] = Header("Multilingual Email", "utf-8")

| 22

23 of 35

Example: Sending Emails with EAI Address with Python's smtplib and IDNA(3/4):

  • Connect to the SMTP Server

#Connect to the SMTP Server and Send the Email

smtp_server = "your_smtp_server.com"

smtp_port = 587

smtp_username = "your_smtp_username"

smtp_password = "your_smtp_password"

try:

with smtplib.SMTP(smtp_server, smtp_port) as server:

server.starttls()

server.login(smtp_username, smtp_password)

# Encode email addresses using IDNA (Internationalized Domain Names in Applications)

sender_email_encoded = sender_email.encode("idna").decode("utf-8")

recipient_email_encoded = recipient_email.encode("idna").decode("utf-8")

| 23

24 of 35

Example: Sending Emails with EAI Address with Python's smtplib and IDNA(4/4):

  • Send the Email

# Send the email

server.sendmail(sender_email_encoded, recipient_email_encoded, message.as_string())

print("Email sent successfully.")

except (smtplib.SMTPException, socket.gaierror) as e:

print(f"Error sending email: {str(e)}")

try:

send_multilingual_email()

except Exception as e:

print(f"An error occurred: {str(e)}")

| 24

25 of 35

Ensuring Email Delivery Across Languages: Internationalized Email Address Validation with Confirmation Links:

  • Confirmation link workflow steps for EAI:
    • User Registration.
    • Send Confirmation Email.
    • Send Confirmation Email.
    • Email Verification.
    • Token Validation.
    • Confirmation Page.
    • Email Address Verification Status.

| 25

26 of 35

Ensuring Email Delivery Across Languages: Internationalized Email Address Validation with Confirmation Links(1/4):

  • Confirmation link workflow steps for EAI:
    • User Registration: this step simulates user registration with an internationalized email address:

user_email = '你好@example.com'

confirmation_token = 'unique_token_generated_for_user'

| 26

27 of 35

Ensuring Email Delivery Across Languages: Internationalized Email Address Validation with Confirmation Links(2/4):

    • Send Confirmation Email: This step generates and sends an email with a confirmation link.

import smtplib

from email.mime.text import MIMEText

# Create an email message

msg = MIMEText(f"Click the following link to confirm your email address:

http://example.com/confirm?token={confirmation_token}", 'plain', 'utf-8')

msg['Subject'] = 'Confirm Your Email Address'

msg['From'] = 'noreply@example.com'

msg['To'] = user_email

# Send the email using an SMTP server

smtp_server = 'your_smtp_server.com'

smtp_port = 587

smtp_username = 'your_smtp_username'

smtp_password = 'your_smtp_password'

server = smtplib.SMTP(smtp_server, smtp_port)

server.starttls()

server.login(smtp_username, smtp_password)

server.sendmail('noreply@example.com', [user_email], msg.as_string())

server.quit()

| 27

28 of 35

Ensuring Email Delivery Across Languages: Internationalized Email Address Validation with Confirmation Links(3/4):

    • Token Storage: The confirmation token should be generated and stored in your database

    • Email Verification: This step simulates the user clicking the confirmation link.

database = {

user_email: confirmation_token

}

clicked_token = 'unique_token_generated_for_user'

# Verify the clicked token against the stored token

if clicked_token == database.get(user_email):

print("Email address confirmed.")

else:

print("Confirmation link is invalid.")

database = {

user_email: confirmation_token

}

| 28

29 of 35

Ensuring Email Delivery Across Languages: Internationalized Email Address Validation with Confirmation Links(4/4):

    • Token Validation:
      • The server endpoint specified in the confirmation link processes the request.
      • It extracts the confirmation token from the link and queries the database to find the associated user.
      • If the token and user are found, and the token has not expired, the server marks the user's email address as verified.
    • Confirmation Page:
      • After successful validation, the server may display a confirmation page to the user, thanking them for confirming their email address.
    • Email Address Verification Status:
      • The server can now mark the user's email address as verified in its records.
      • The user is considered to have a verified email address and can use the service accordingly.

| 29

30 of 35

Understanding Multilingual Mailboxes: Parsing Internationalized Email Addresses:

  • The following are key points to consider while parsing internationalized email addresses:
    • Split the Email Address:
      • Split the email address into two parts: the local part and the domain part.
      • The local part is the portion before the "@" symbol, and the domain part is the portion after the "@" symbol.
      • For example, if the email address is " تجربة-بريد-الكتروني@تجربة-القبول-الشامل.موريتاني", splitting it would result in the local part "تجربة-القبول" and the domain part "تجربة-القبول-الشامل.موريتاني".
    • Decode the Domain Part:
    • Decode the Local Part:
    • Validate the Email Address.

| 30

31 of 35

Example: Validating Email Addresses Length Using Python.

import re

def is_valid_email_address(email):

try:

# Validate email address using regular expression

pattern = r'^[\w\.-]+@[\w\.-]+\.\w+$'

if not re.match(pattern, email):

return False

# Check length validation

return len(email) <= 254 and len(email.split('@')[0]) <= 64 and len(email.split('@')[1]) <= 255

except Exception:

return False

# Test the validation

email = 'تجربة-بريد-الكتروني@تجربة-القبول-الشامل.موريتاني'

is_valid = is_valid_email_address(email)

print(f"Is valid email address: {is_valid}")

  • Output:

Is valid email address: True

| 31

32 of 35

EAI-Specific Considerations for Setting Up Email Mailbox Names:

  • Key points to setting up mailbox names for internationalized email addresses
    • EAI Support.
    • Character Encoding.
    • Punycode Encoding.
    • Validation and Display.
    • User Experience Considerations.

| 32

33 of 35

Reference:

[1]. Freed, N., & Borenstein, N. (1996). Multipurpose Internet Mail Extensions (MIME) Part 3: Message Header Extensions for Non-ASCII Text (RFC 2047). Retrieved from [https://www.ietf.org/] on 2023-12-11.

[2]. Klensin, J., & Hildebrand, M. (2008). Internationalized Email Headers (RFC 5335). Retrieved from [https://datatracker.ietf.org/wg/tewg/documents/] on 2023-12-11.

[3]. The Unicode Consortium. (n.d.). Retrieved from https://unicode.org/consortium/] on 2023-12-11.

[4]. Freed, N. (1996). Multipurpose Internet Mail Extensions (MIME) Part 5: Base64 Content-Transfer-Encoding (RFC 2048). Retrieved from http://tools.ietf.org/html/rfc2048: http://tools.ietf.org/html/rfc2048 on 2023-12-11.

[5]. Python, Chardet. (n.d.). Retrieved from https://github.com/chardet/chardet on 2023-12-11.

[6]. Python, Idna. (n.d.). Retrieved from https://pypi.org/project/idna/

[7]. Java, Java Platform, Standard Edition 7 API Specification. (n.d.). Charset class. Retrieved from https://docs.oracle.com/javase/7/docs/api/java/nio/charset/Charset.html on 2023-12-11..

[8]. Hoffman, P., & Dürst, M. (2010, July). Internationalized Domain Names in Applications (IDNA2008) (RFC 5893). Retrieved from https://www.ietf.org/ on on 2023-12-11.

[9]. Python Documentation, (n.d.):https://docs.python.org/: https://docs.python.org/, on 2023-12-11.

| 33

34 of 35

Reference:

[10]. JavaMail, (nd): https://www.oracle.com/java/technologies/javamail-api.html, on 2023-12-11.

[11]. Python, smtplib module, (n.d.): https://docs.python.org/3/library/smtplib.html, on 2023-12-11.

[12]. (Stack Exchange, 2023). What's the best approach to confirm user email address - sending an email-confirm link? Retrieved from https://ux.stackexchange.com/questions/111252/from-a-ux-perspective-when-should-you-send-the-confirm-your-email-message on December 11, 2023.

| 34

35 of 35

Author:

  • Dessalegn Mequanint Yehuala, dessalegn.mequanint@aau.edu.et.

| 35