Sending e-mail manually - Python - python

I'm trying to send an email to an SMTP server but I keep getting errors from the server. It says my commands are unrecognized with status codes like 500 and 501.
Here is my script:
import socket
server_info = ("smtp.gmx.com", 25)
socket = socket.socket()
socket.connect(server_info)
username = raw_input("Enter your username: ")
password = raw_input("Enter your password: ")
recipient = raw_input("Recipient: ")
data = raw_input("Your message: ")
auth = username + "" + password
auth = auth.encode("base64").replace("\n", "")
socket.send("HELO\r\n")
print "EHLO Response: " + socket.recv(1024)
socket.send("AUTH PLAIN "+auth+"\r\n")
print "AUTH Response: " + socket.recv(1024)
socket.send("MAIL FROM:<"+username+">\r\n")
print "MAIL FROM Response: " + socket.recv(1024)
socket.send("RCPT TO:"+recipient+"\r\n")
print "RCPT TO Response: " + socket.recv(1024)
socket.send("RCPT TO:"+recipient+"\r\n")
print "RCPT TO Response: " + socket.recv(1024)
socket.send("DATA\r\n")
print "DATA Response: " + socket.recv(1024)
socket.send(data + "\r\n.\r\n")
print "RAW DATA Response: " + socket.recv(1024)
socket.send("QUIT\r\n")
print "QUIT Response: " + socket.recv(1024)
print "Done."
socket.close()
What is the problem with these command? I wrote them exactly like they should be.
Here is the errors I get from the server:
http://i.gyazo.com/3f5eb3a34cbb0f00510281bccc8d0546.png
P.S I don't want to use smtplib. I would like to send my email manually, for learning purposes

You have a great module to send email messages - smtplib
Usage example:
import smtplib
SMTP_SERVER = 'smtp.gmail.com'
SMTP_PORT = 587
sender = 'example#gmail.com'
password = "password"
recipient = 'example2#gmail.com'
subject = 'Gmail SMTP Test'
body = 'blah blah blah'
body = "" + body + ""
headers = ["From: " + sender,
"Subject: " + subject,
"To: " + recipient,
"MIME-Version: 1.0",
"Content-Type: text/html"]
headers = "\r\n".join(headers)
session = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
session.ehlo()
session.starttls()
session.ehlo()
session.login(sender, password)
session.sendmail(sender, recipient, headers + "\r\n\r\n" + body)
session.quit()
UPD:
If you want to use SSL:
...
session = smtplib.SMTP_SSL_PORT(SMTP_SERVER, SMTP_PORT)
session.ehlo()
session.login(sender, password)
session.sendmail(sender, recipient, headers + "\r\n\r\n" + body)
session.quit()

You're sending "HELO" to start your SMTP session while you should send "EHLO".
The SMTP authentication mechanism is only available if you're using extended SMTP.
Starting your session with HELO tells the servers you're not using extended SMTP, hence it'll reject all authentication commands.

Related

Cant send subject in email - python

when i send an email message like this i cant get the subject get into the message(i get it in the body). what can i do to change it? thank you!
def SendEmailNotHTML(EmailToList,EmailBody,EmailSubject):
mail_from = settings.SMTP_USER
try:
for current_mail_to in EmailToList:
fromaddr = settings.SMTP_USER
toaddrs = current_mail_to
msg = "\r\n".join([
"Subject: {0}".format(EmailSubject),
"",
"{0}".format(EmailBody)
])
print(msg)
my_email = MIMEText(msg, "plain")
username = settings.SMTP_USER
password = settings.SMTP_PASSWORD
server = smtplib.SMTP('smtp.gmail.com:25')
server.ehlo()
server.starttls()
server.login(username,password)
server.sendmail(fromaddr, toaddrs, my_email.as_string())
server.quit()
except Exception as e:
print('cant send email' + str(e))

Difficulty updating e-mail body in python

Guys I'm new to python but I made the code below with help of various websites and its working but the issue is its sending separate mails for each ip addresses in sites list. Help me construct mail body with all ip addresses.
ping.py
#!/usr/bin/env python
import smtplib
import pyping
from conf import settings, sites
import time
import datetime
"""Sends an e-mail to the specified recipient."""
sender = settings["monitor_email"]
recipient = settings["recipient_email"]
subject = settings["email_subject"]
headers = ["From: " + sender,
"Subject: " + subject,
"To: " + recipient,
"MIME-Version: 1.0",
"Content-Type: text/html"]
headers = "\r\n".join(headers)
session = smtplib.SMTP(settings["monitor_server"], settings["monitor_server_port"])
session.ehlo()
session.login(settings["monitor_email"], settings["monitor_password"])
ts = time.time()
st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
for site in sites:
checker = pyping.ping(site)
# The site status changed from it's last value, so send an email
if checker.ret_code == 0:
# The site is UP
body = "%s This Server is up %s" % (site, st)
session.sendmail(sender, recipient, headers + "\r\n\r\n" + body)
else:
# The site is Down
body = "%s This Server is down %s" % (site, st)
session.sendmail(sender, recipient, headers + "\r\n\r\n" + body)
session.quit()
This is my conf.py
sites = (
"192.168.1.1",
"192.168.2.1",
"192.168.3.1",
)
settings = {
"recipient_email": 'tomail#domain.com',
"monitor_email": 'frommail#domain.com',
"monitor_password": 'password',
# Leave as it is to use gmail as the server
"monitor_server": 'frommail#domain.com',
"monitor_server_port": 587,
# Optional Settings
"email_subject": 'Server Monitor Alert'
}
I'm getting output as:
Server Monitor Alert
192.168.1.1 This server is up at 2018-04-21
This mail comes successfully to tomail#domain.com but not in a single mail for three ip's it sends three mails with each ip address. Pls help me to send all ip status listed in sites in a single mail.
For example:
temp = []
for site in sites:
checker = pyping.ping(site)
# The site status changed from it's last value, so send an email
if checker.ret_code == 0:
# The site is UP
body = "%s This Server is up %s" % (site, st)
temp.append(body)
else:
# The site is Down
body = "%s This Server is down %s" % (site, st)
temp.append(body)
body = '\n'.join(temp)
session.sendmail(sender, recipient, headers + "\r\n\r\n" + body)

Why is the email not sending to the recipient?

This is the code I have running, which is supposedly working totally fine, but it is not actually sending the email to the address I specify. It does not have anything to do with the CSV because I have another script doing the same thing and working just fine. The problem is that the email is being placed in the senders inbox... which is weird.
I would rather use this script since it's nicely object oriented and it has all the proper subject fields, etc.
import smtplib
import pandas as pd
class Gmail(object):
def __init__(self, email, password, recepient):
self.email = email
self.password = password
self.recepient = recepient
self.server = 'smtp.gmail.com'
self.port = 465
session = smtplib.SMTP_SSL(self.server, self.port)
session.ehlo
session.login(self.email, self.password)
self.session = session
print('Connected to Gmail account successfully.')
def send_message(self, subject, body):
headers = [
"From: " + self.email,
"Subject: " + subject,
"To: " + self.recepient,
"MIME-Version: 1.0",
"Content-Type: text/html"]
headers = "\r\n".join(headers)
self.session.sendmail(
self.email,
self.email,
headers + "\r\n\r\n" + body)
print('- Message has been sent.')
df = pd.read_csv('test.csv', error_bad_lines=False)
for index, row in df.iterrows():
print('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
comp_name = (row['name'])
print('Email to: ' + comp_name)
rec = (row['email'])
print('Email to: ' + rec)
gm = Gmail('email#gmail.com', 'password', rec)
gm.send_message('email to ' + comp_name, '<b>This is a test<b>')
print('-- Message for ' + rec + ' (' + comp_name + ') is completed.')
print('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
print('*********************************')
print('Finish reading through CSV.')
print('*********************************')
print('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
Let me know if there is something wrong. I would really like this to work.
Just so that you can see it is working, here is the other script I am testing it against (which is poorly formatted) and it is completely functioning properly.
import smtplib
import pandas as pd
df = pd.read_csv('test.csv', error_bad_lines=False)
gmail_user = 'email#gmail.com'
gmail_password = 'password'
for index, row in df.iterrows():
sent_from = gmail_user
to = (row['email'])
subject = 'Important Message'
body = 'Hey, whats up'
rec = (row['email'])
comp_name = (row['name'])
print('Email to: ' + comp_name)
print('Email to: ' + rec)
email_text = """\
From: %s
To: %s
Subject: %s
%s
""" % (sent_from, to, subject, body)
try:
server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
server.ehlo()
server.login(gmail_user, gmail_password)
server.sendmail(sent_from, to, email_text)
server.close()
print ('-- Email sent!')
except:
print ('-- Something went wrong...')
print('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
print('*********************************')
print('Finish reading through CSV.')
print('*********************************')
print('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
You should pass the recipient instead of the sender.
self.session.sendmail(
self.email,
# self.email, <- wrong here
self.recepient,
headers + "\r\n\r\n" + body)

python email sent and received with smtplib has no content

I am sending email with my raspberrypi with python.
I successfully sent and received the message, but the content is missing.
Here is my code
import smtplib
smtpUser = 'myemail#gmail.com'
smtpPass = 'mypassword'
toAdd = 'target#gmail.com'
fromAdd = smtpUser
subject = 'Python Test'
header = 'To: ' + toAdd + '\n' + 'From: ' + fromAdd + '\n' + 'Subject: ' + subject
body = 'From within a Python script'
msg = header + '\n' + body
print header + '\n' + body
s = smtplib.SMTP('smtp.gmail.com',587)
s.ehlo()
s.starttls()
s.ehlo()
s.login(smtpUser,smtpPass)
s.sendmail(fromAdd, toAdd, msg)
s.quit()
Thank you for your attention!
I wrote a wrapper around sending emails in python; it makes sending emails super easy: https://github.com/krystofl/krystof-utils/blob/master/python/krystof_email_wrapper.py
Use it like so:
emailer = Krystof_email_wrapper()
email_body = 'Hello, <br /><br />' \
'This is the body of the email.'
emailer.create_email('sender#example.com', 'Sender Name',
['recipient#example.com'],
email_body,
'Email subject!',
attachments = ['filename.txt'])
cred = { 'email': 'sender#example.com', 'password': 'VERYSECURE' }
emailer.send_email(login_dict = cred, force_send = True)
You can also look at the source code to find how it works.
The relevant bits:
import email
import smtplib # sending of the emails
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
self.msg = MIMEMultipart()
self.msg.preamble = "This is a multi-part message in MIME format."
# set the sender
author = email.utils.formataddr((from_name, from_email))
self.msg['From'] = author
# set recipients (from list of email address strings)
self.msg['To' ] = ', '.join(to_emails)
self.msg['Cc' ] = ', '.join(cc_emails)
self.msg['Bcc'] = ', '.join(bcc_emails)
# set the subject
self.msg['Subject'] = subject
# set the body
msg_text = MIMEText(body.encode('utf-8'), 'html', _charset='utf-8')
self.msg.attach(msg_text)
# send the email
session = smtplib.SMTP('smtp.gmail.com', 587)
session.ehlo()
session.starttls()
session.login(login_dict['email'], login_dict['password'])
session.send_message(self.msg)
session.quit()

Why can't I send emails to multiple recipients with this script?

Why can't I send emails to multiple recipients with this script?
I get no errors nor bouncebacks, and the first recipient does receive the email. None of the others do.
The script:
#!/usr/bin/python
import smtplib
SMTP_SERVER = 'smtp.gmail.com'
SMTP_PORT = 587
recipient = 'email#domain.com; email2#domain.com;'
sender = 'me#gmail.com'
subject = 'the subject'
body = 'the body'
password = "password"
username = "me#gmail.com"
body = "" + body + ""
headers = ["From: " + sender,
"Subject: " + subject,
"To: " + recipient,
"MIME-Version: 1.0",
"Content-Type: text/html"]
headers = "\r\n".join(headers)
session = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
session.ehlo()
session.starttls()
session.ehlo
session.login(username, password)
session.sendmail(sender, recipient, headers + "\r\n\r\n" + body)
session.quit()
Semicolons are not the correct separator for addresses in recipient headers. You must use commas.
EDIT: I see now that you are using the library incorrectly. You're supplying a string which will always be interpreted as a single address. You must supply a list of addresses to send to multiple recipients.
Recipients in the standard header must be separated by commas, not semicolons. I blame Microsoft Outlook for leading people to believe otherwise.
You can, just put the emails in an array, and loop through the array for each email as in:
(my python is rusty... so forgive my syntax)
foreach recipient in recipients
headers = ["From: " + sender, "Subject: " + subject, "To: " + recipient, "MIME-Version: 1.0", "Content-Type: text/html"]
headers = "\r\n".join(headers)
session.sendmail(sender, recipient, headers + "\r\n\r\n" + body)
Change this in your code:
recipient = ['email#domain.com','email2#domain.com']
headers = ",".join(headers)
session.sendmail(sender, recipient.split(","), headers + "\r\n\r\n" + body)
Alternatively
recipient = ', '.join(recipient.split('; '))
if your recipients are a string of semicolon separated addresses.

Categories

Resources