Skip to content

Instantly share code, notes, and snippets.

@DamnedFacts
Last active October 21, 2023 03:44
Show Gist options
  • Save DamnedFacts/9817b6e400a66961725b49099cc6f9da to your computer and use it in GitHub Desktop.
Save DamnedFacts/9817b6e400a66961725b49099cc6f9da to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import argparse
import smtplib
import ssl
import dns.resolver # Required for DNS lookup
from email.mime.text import MIMEText
def get_mx_record(domain):
"""
Retrieve the highest priority MX record for the specified domain.
"""
try:
records = dns.resolver.resolve(domain, 'MX')
except (dns.resolver.NoAnswer, dns.resolver.NXDOMAIN):
print(f"No MX record found for domain {domain}")
return None
records = sorted(records, key=lambda record: record.preference)
return str(records[0].exchange).rstrip('.')
def test_mail(
smtp_server,
smtp_port,
smtp_user,
smtp_password,
from_email,
to_email,
subject="Test email",
body="This is a test email",
use_tls=True,
certfile=None,
keyfile=None,
direct_send=False # Flag for direct sending
):
"""
Send a test email. If direct_send is enabled, it bypasses the specified SMTP server
and sends the email directly to the recipient's domain SMTP server.
"""
if direct_send:
domain = to_email.split('@')[-1]
mx_record = get_mx_record(domain)
if mx_record is None:
return # Exit if we couldn't find an MX record
smtp_server = mx_record
# Setup the email message
msg = MIMEText(body)
msg["Subject"] = subject
msg["From"] = from_email
msg["To"] = to_email
try:
context = ssl.create_default_context()
if certfile and keyfile:
context.load_cert_chain(certfile=certfile, keyfile=keyfile)
with smtplib.SMTP(smtp_server, smtp_port) as server:
server.ehlo() # It's good practice to identify ourselves to the SMTP server.
# If we're not doing direct send or if we're using TLS, start the TLS session
if use_tls or not direct_send:
server.starttls(context=context)
server.ehlo() # Re-identify ourselves over the encrypted connection.
if smtp_user and smtp_password and not direct_send:
server.login(smtp_user, smtp_password)
server.sendmail(from_email, [to_email], msg.as_string())
print("Email sent successfully!")
except Exception as e:
print(f"Failed to send email. Error: {e}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Send a test email.")
parser.add_argument("from_email", help="The email address to send from.")
parser.add_argument("to_email", help="The email address to send to.")
parser.add_argument(
"--smtp_server", help="The SMTP server address.", default="")
parser.add_argument("--smtp_port", type=int,
help="The SMTP server port.", default=25)
parser.add_argument(
"--smtp_user", help="The SMTP server username.", default="")
parser.add_argument("--smtp_password",
help="The SMTP server password.", default="")
parser.add_argument("--subject", help="Email subject.",
default="Test email")
parser.add_argument("--body", help="Email body.",
default="This is a test email.")
parser.add_argument(
"--use_tls", help="Use TLS for the SMTP connection.", action="store_true")
parser.add_argument(
"--certfile", help="Path to the client certificate file.", default="")
parser.add_argument(
"--keyfile", help="Path to the client key file.", default="")
parser.add_argument(
"--direct_send", help="Send email directly to the recipient's SMTP server based on MX lookup.", action="store_true")
args = parser.parse_args()
# If direct_send is active, use_tls is adapted to ensure compatibility with the recipient's server.
use_tls = args.use_tls if not args.direct_send else True
test_mail(
args.smtp_server,
args.smtp_port,
args.smtp_user,
args.smtp_password,
args.from_email,
args.to_email,
args.subject,
args.body,
use_tls,
args.certfile,
args.keyfile,
args.direct_send
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment