How to Send Emails in Python from Scratch in 2024

This article will teach you how to send and receive emails in Python using Google’s SMTP server without using the ‘smtplib’ Python library.

What is SMTP?

SMTP (Simple Mail Transfer Protocol) is a software protocol for sending simple text-based emails. It works by:

  1. Connecting to an SMTP Server
  2. Sending and Receiving Initial Greetings and Commands
  3. Logging into your Gmail Account
  4. Writing and Sending the Subject and Body of the Email

SMTP originated in 1982 with RFC 821, but has now evolved into Extended SMTP (ESMTP) through RFC iterations 821 -> 1869 -> 2821 -> 5321 -> 7504. I will be mostly using RFC 5321 in this article.

How does SMTP work?

SMTP works by:

  1. Connecting to an SMTP server
  2. Sending and Receiving Initial Greetings and Commands
  3. Logging into your Gmail Account
  4. Writing and Sending the Subject and Body of the Email

Here is a graphic I made using Canva:

How to Send an Email in Python

Before starting, we need to import the ‘socket’, ‘ssl’, and ‘base64’ libraries for later:

import socket
import ssl
import base64

First, we must connect to Google’s SMTP server through its IP address. Google’s SMTP server is called “smtp.gmail.com”, and we will use the socket class’s ‘socket’ library to create a TCP connection. We will be connecting to the encrypted, and safe, Port 587 (although traditionally Port 25 was used for SMTP emails in the past, it is HIGHLY recommended NOT to use it because Port 25 is not encrypted and your information will get stolen):

import socket
import ssl
import base64

def main():
   smtp_server = 'smtp.gmail.com'
   ip_address = socket.gethostbyname(smtp_server) #finds the IP address of Google's SMTP server
   smtp_port = 587 #the SSL encrypted connection

   # Establish a TCP connection to the SMTP server
   client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   client_socket.connect((ip_address, smtp_port))

As soon as the above “client_socket.connect((ip_address, smtp_port))” code is executed and correctly connects to the server, the server will send an initial reply to your computer, such as:

220 smtp.gmail.com ESMTP af79cd13be357-7955a81dc14sm304665385a.45 – gsmtp

Where ‘220’ is a positive reply code, ‘smtp.gmail.com’ is the domain name of the SMTP server, ‘ESMTP’ is the version of SMTP this server is running, ‘af79….45’ is the unique ID of this message, and ‘gsmtp’ indicates that this response is from a Google SMTP server.

NOTE: Although the ‘220’ reply code is standardized, each company’s SMTP server has its unique initial reply message.

To receive the initial message from the server, you must call the ‘.recv’ method from your socket that is connected to the SMTP server in this ‘initiate_connection’ method:

import socket
import ssl
import base64

def initiate_connection(client_socket):
	#server sends some of its information when connecting to it via TCP
	print("v-----initiate connection-----v")
	server_greeting = client_socket.recv(1024) #reads in max of 1024 bytes from server
	print(server_greeting.decode()) #decodes received message in bytes into a string
	print("^-----initiate connection-----^")

def main():
   smtp_server = 'smtp.gmail.com'
   ip_address = socket.gethostbyname(smtp_server) #finds the IP address of Google's SMTP server
   smtp_port = 587 #the SSL encrypted connection

   # Establish a TCP connection to the SMTP server
   client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   client_socket.connect((ip_address, smtp_port))

   initiate_connection(client_socket)

You now must enter a

Similar Posts