Targets
- Learn more about SMTP.
- Write an email client based on SMTP.
Steps
- Implement the email client with a programming language.
- Test your email client by sending and receiving mails.
Result
Step 1: Program in Python. Implement a simplefied QQ email client.
emailclient.py
from pwreader import input_pw
import receiver as rcv
import sender as sdr
# Welcome words.
print('Welcome to Wyatt\'s QQ email client!\n')
# Read username and password of the email.
username = input('Username: ')
password = input_pw('Password: ') # a password input method that can replace password characters with asterisks (*)
# Show menu and realize function that user have chosen
while True:
print('\nOption 0: Exit.') # this client provides 3 options for user
print('Option 1: Read emails.')
print('Option 2: Send email.')
opt = int(input('\nYour chosen: '))
if opt == 0:
break
if opt == 1:
rcv.receive(username, password)
if opt == 2:
sdr.send(username, password)
pwreader.py
# Read password and replace password characters with asterisks (*).
def input_pw(text):
import msvcrt
print(text, end='', flush=True)
chars = []
while True:
new_char = msvcrt.getch()
if new_char in b'\r\n':
msvcrt.putch(b'\n')
break
elif new_char == b'\b':
if chars:
chars.pop()
msvcrt.putch(b'\b')
msvcrt.putch(b' ')
msvcrt.putch(b'\b')
else:
chars.append(new_char)
msvcrt.putch(b'*')
return (b''.join(chars)).decode()
receiver.py
import imaplib
import email
# Get all mails of certain user from QQ email.
def receive(username, password):
# Establish connection with email server using IMAP and SSL through port 993.
connection = imaplib.IMAP4_SSL('imap.qq.com', 993)
# Login.
try:
connection.login(username, password) # caution: password here is the authorized code of user's QQ email
print('\nSuccessful login.')
except:
print('\nFail to login.')
return
# Get mails from email server and save them in eml files.
connection.select() # select a mailbox
tpy, mails = connection.search('ALL') # search mailbox for all mails
for num_str in mails[0].split(): # mails[0] is a string recording blank separated mail indexes
try:
typ, mail = connection.fetch(num_str, '(UID BODY.PEEK[])')
content = mail[0][1]
# Store contents of a mail in an eml file.
filename = num_str.decode() + '.eml'
file = open(filename, 'wb')
file.write(content)
file.close()
except:
print('\nSomething wrong with mail No. ' + num_str + '.')
print('\nReception completed, you can surf them in eml files.')
# Disconnect.
connection.close()
sender.py
import smtplib
from mesgreader import input_mesg
from email.mime.text import MIMEText
from email.header import Header
# Write and send an email to a certain email address.
def send(username, password):
# Set up connection with email server using SMTP and SSL through port 465.
connection = smtplib.SMTP_SSL('smtp.qq.com', 465)
# Login.
try:
connection.login(username, password)
print('\nSuccessful login')
except smtplib.SMTPException as exp:
print('\nFail to login:', exp)
return
# Indicate user to write an email.
destination = input('\nDestination email address: ')
subject = input('Email subject: ')
message = input_mesg('Content (ends with string \'-end\'): ', endflag='-end')
# Complete the SMTP message.
message = MIMEText(message, 'plain', 'utf-8')
message['From'] = Header(username) # set header contents
message['To'] = Header(destination)
message['Subject'] = Header(subject)
# Send out.
try:
connection.sendmail(username, destination, message.as_string())
print('\nSuccessful send')
except smtplib.SMTPException as exp:
print('\nFail to send:', exp)
return
# Disconnect.
connection.close()
receiver.py
import imaplib
import email
# Get all mails of certain user from QQ email.
def receive(username, password):
# Establish connection with email server using IMAP and SSL through port 993.
connection = imaplib.IMAP4_SSL('imap.qq.com', 993)
# Login.
try:
connection.login(username, password) # caution: password here is the authorized code of user's QQ email
print('\nSuccessful login.')
except:
print('\nFail to login.')
return
# Get mails from email server and save them in eml files.
connection.select() # select a mailbox
tpy, mails = connection.search('ALL') # search mailbox for all mails
for num_str in mails[0].split(): # mails[0] is a string recording blank separated mail indexes
try:
typ, mail = connection.fetch(num_str, '(UID BODY.PEEK[])')
content = mail[0][1]
# Store contents of a mail in an eml file.
filename = num_str.decode() + '.eml'
file = open(filename, 'wb')
file.write(content)
file.close()
except:
print('\nSomething wrong with mail No. ' + num_str + '.')
print('\nReception completed, you can surf them in eml files.')
# Disconnect.
connection.close()
mesgreader.py
import msvcrt
# Read email body.
def input_mesg(text, endflag='\r'):
print(text)
message = ''
while True:
line = input()
if line == endflag:
break
else:
message += '\n' + line
return message
Step 2: Test clint.