2008-09-16 8 views
58

Nếu tôi muốn gửi thư không qua SMTP, nhưng thay vì qua sendmail, có thư viện nào cho python đóng gói quá trình này không?Gửi thư qua sendmail từ python

Tốt hơn, có thư viện nào trừu tượng toàn bộ lựa chọn 'sendmail -versus- smtp' không?

Tôi sẽ chạy tập lệnh này trên một loạt các máy chủ Unix, chỉ một số trong số đó đang nghe trên máy chủ cục bộ: 25; một vài trong số này là một phần của các hệ thống nhúng và không thể được thiết lập để chấp nhận SMTP.

Là một phần của Thực hành tốt, tôi thực sự muốn thư viện tự chăm sóc các lỗ hổng tiêu đề - vì vậy, chỉ cần bỏ một chuỗi đến popen('/usr/bin/sendmail', 'w') là gần hơn với kim loại hơn tôi muốn.

Nếu câu trả lời là 'đi viết một thư viện,' như vậy đi ;-)

Trả lời

97

Tiêm tiêu đề không phải là yếu tố trong cách bạn gửi thư, đó là yếu tố trong cách bạn tạo thư. Kiểm tra gói email, xây dựng thư với điều đó, serialise nó, và gửi nó đến /usr/sbin/sendmail sử dụng subprocess mô-đun:

from email.mime.text import MIMEText 
from subprocess import Popen, PIPE 

msg = MIMEText("Here is the body of my message") 
msg["From"] = "[email protected]" 
msg["To"] = "[email protected]" 
msg["Subject"] = "This is the subject." 
p = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE) 
p.communicate(msg.as_string()) 
+0

Hoàn hảo. Vấn đề khái niệm của tôi đã tách biệt việc xây dựng và gửi email. Cảm ơn! – Nate

+3

tốt đẹp, nó đã giúp tôi ngày hôm nay, sau 5 năm của câu trả lời :) – Peter

+10

Bạn cũng nên sử dụng tham số '-oi' để sendmail. Điều này sẽ dừng một '.' đơn trong thư của bạn từ khi kết thúc sớm email. –

3

Đó là khá phổ biến để chỉ cần sử dụng lệnh sendmail từ Python sử dụng os.popen

Cá nhân, cho các kịch bản i didn 't viết bản thân mình, tôi nghĩ rằng chỉ cần sử dụng giao thức SMTP là tốt hơn, vì nó sẽ không yêu cầu cài đặt nói một bản sao sendmail để chạy trên cửa sổ.

https://docs.python.org/library/smtplib.html

+0

SMTP không hoạt động trên ~ hộp nix sử dụng những thứ như [DMA] (https: // github. com/corecode/dma), cung cấp sendmail, nhưng không nghe trên cổng 25 ... –

-6

Câu trả lời đơn giản nhất là smtplib, bạn có thể tìm tài liệu về nó here.

Tất cả những gì bạn cần làm là định cấu hình sendmail cục bộ của mình để chấp nhận kết nối từ máy chủ cục bộ, điều mà có thể nó đã làm theo mặc định. Chắc chắn, bạn vẫn đang sử dụng SMTP để chuyển, nhưng đó là sendmail cục bộ, về cơ bản giống như sử dụng công cụ dòng lệnh.

+7

Câu hỏi cho biết "Nếu tôi muốn gửi thư không qua SMTP, nhưng thay vì gửi qua email ..." – S19N

+1

Chương trình của bạn sẽ bị chậm trễ trong trường hợp không có kết nối hoặc độ trễ đến máy chủ SMTP. Sử dụng sendmail bạn chuyển tin nhắn tới MTA và chương trình của bạn vẫn tiếp tục. –

30

Đây là hàm python đơn giản sử dụng sendmail unix để gửi thư.

def sendMail(): 
    sendmail_location = "/usr/sbin/sendmail" # sendmail location 
    p = os.popen("%s -t" % sendmail_location, "w") 
    p.write("From: %s\n" % "[email protected]") 
    p.write("To: %s\n" % "[email protected]") 
    p.write("Subject: thesubject\n") 
    p.write("\n") # blank line separating headers from body 
    p.write("body of the mail") 
    status = p.close() 
    if status != 0: 
      print "Sendmail exit status", status 
+0

chức năng python thực sự tốt đẹp! – aphex

+0

+1 - chỉ là những gì tôi đang tìm kiếm! –

+0

tuyệt vời, ví dụ đơn giản +1 –

3

Câu hỏi này là rất cũ, nhưng nó đáng giá để lưu ý rằng có một cấu trúc tin nhắn và e hệ thống gửi thư được gọi là Marrow Mailer (trước đây là TurboMail) đã có sẵn từ trước khi thông báo này được yêu cầu.

Nó hiện đang được chuyển để hỗ trợ Python 3 và được cập nhật như một phần của bộ Marrow.

+0

Liên kết turboMail không hoạt động, một năm sau – TankorSmash

+2

Bây giờ, nó được gọi là marrow.mailer. https://github.com/marrow/marrow.mailer – amcgregor

+0

+1 cho Marrow Mailer. Tôi đã thử nó, và nó làm cho nó rất dễ dàng để gửi thư thông qua smpt, sendmail, vv, và cũng cung cấp xác nhận rất tốt. Bởi vì Marrow Mailer là "một thư viện tốt trừu tượng toàn bộ lựa chọn 'sendmail -versus- smtp', tôi cảm thấy điều này trả lời câu hỏi ban đầu là tốt nhất. – tjklemz

-3

Tôi chỉ tìm kiếm xung quanh cho các điều tương tự và tìm thấy một ví dụ điển hình trên trang web Python: http://docs.python.org/2/library/email-examples.html

Từ trang web đề cập:

# Import smtplib for the actual sending function 
import smtplib 

# Import the email modules we'll need 
from email.mime.text import MIMEText 

# Open a plain text file for reading. For this example, assume that 
# the text file contains only ASCII characters. 
fp = open(textfile, 'rb') 
# Create a text/plain message 
msg = MIMEText(fp.read()) 
fp.close() 

# me == the sender's email address 
# you == the recipient's email address 
msg['Subject'] = 'The contents of %s' % textfile 
msg['From'] = me 
msg['To'] = you 

# Send the message via our own SMTP server, but don't include the 
# envelope header. 
s = smtplib.SMTP('localhost') 
s.sendmail(me, [you], msg.as_string()) 
s.quit() 

Lưu ý rằng điều này đòi hỏi rằng bạn có sendmail/mailx thiết lập chính xác để chấp nhận các kết nối trên "localhost". Điều này hoạt động trên máy Mac, Ubuntu và Redhat của tôi theo mặc định, nhưng bạn có thể muốn kiểm tra lại nếu bạn gặp phải bất kỳ sự cố nào.

+0

Điều này vẫn đang sử dụng 'localhost' thông qua giao thức SMTP. Và một số người dùng không muốn mở cổng 21, thậm chí không chỉ trên máy chủ cục bộ. – mbirth

6

Câu trả lời của Jim không hoạt động đối với tôi trong Python 3.4.Tôi đã phải bổ sung thêm một universal_newlines=True lập luận để subrocess.Popen()

from email.mime.text import MIMEText 
from subprocess import Popen, PIPE 

msg = MIMEText("Here is the body of my message") 
msg["From"] = "[email protected]" 
msg["To"] = "[email protected]" 
msg["Subject"] = "This is the subject." 
p = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE, universal_newlines=True) 
p.communicate(msg.as_string()) 

Nếu không có sự universal_newlines=True tôi nhận được

TypeError: 'str' does not support the buffer interface