pythonsmtplib

Python smtplib sending mail using docmd


I currently have an smtplib client using sendmail. I need to trap the message id given to the sent message by the receiving server - and from what I've read here I need to use smtplib's docmd command. What I've worked out so far is fairly easy:

import smtplib
svr = smtplib.SMTP("localhost",26)
r = svr.docmd("ehlo", "me")
r = svr.docmd("mail from:","me@home.com")
r = svr.docmd("rcpt to:","you@work.com")
r = svr.docmd("data","")

But now when I try to do svr.docmd("send","Hello there") it just hangs? Similarly, I assume I should do r = svr.docmd("send",".") to send the terminating "." character to send the mail, and get the server response (in theory including msg id!) as part of the returned tuple?

Would really appreciate it if someone could point me at where I'm going wrong in these final steps?

Or am I completely misunderstanding - is using docmd NOT the way to get the server response when the mail is sent? If I am wrong, what should I be doing instead?


Solution

  • smtplibmodule cannot work like that. It is a higher level library and you should not try to send simple mail with docmd. docmd only helps to pass special commands. You should simply use :

    svr.sendmail('me@home', 'you@work', 'msg')
    

    If you really want to do it the hard way, you should send all the data in only single docmd :

    ...
    r = svr.docmd("data")
    r = svr.docmd("line 1\r\nline 2\r\n.\r\n")
    

    That way it a a complete command that receives its SMTP response

    Edit :

    The return of low-level commands is the content of the SMTP response. The RFC 2821 specifies that this replies consist in a 3 digit number followed by an textual explaination. It can be multiline if the number is followed by a -. But all that is hidden from you by smtplib module. The main point of interest if you use low level commands is first digit from the number :

    1yz   Positive Preliminary reply
    2yz   Positive Completion reply
    3yz   Positive Intermediate reply
    4yz   Transient Negative Completion reply
    5yz   Permanent Negative Completion reply
    

    If it is 4 or 5 the command was rejected, 1,2, or 3 it was successful

    If you use directly sendmail command, if you do not get an exception, the mail was successfuly received by the server and accepted for at least on recipient. The return value is a dictionary, with one entry for each recipient that was refused. Each entry contains a tuple of the SMTP error code and the accompanying error message sent by the server (extract from the module documentation).

    I advice you to use the sendmail command unless you want to learn the SMTP protocol or have other special requirement.