1
from OpenSSL.SSL import SSLv3_METHOD, TLSv1_METHOD

from twisted.mail.smtp import ESMTPSenderFactory
from twisted.python.usage import Options, UsageError
from twisted.internet.ssl import ClientContextFactory
from twisted.internet.defer import Deferred
from twisted.internet import reactor


def sendmail(
    authenticationUsername, authenticationSecret,
    fromAddress, toAddress,
    messageFile,
    smtpHost="email-smtp.us-east-1.amazonaws.com", smtpPort=587
    ):
    """
    @param authenticationUsername: The username with which to authenticate.
    @param authenticationSecret: The password with which to authenticate.
    @param fromAddress: The SMTP reverse path (ie, MAIL FROM)
    @param toAddress: The SMTP forward path (ie, RCPT TO)
    @param messageFile: A file-like object containing the headers and body of
    the message to send.
    @param smtpHost: The MX host to which to connect.
    @param smtpPort: The port number to which to connect.

    @return: A Deferred which will be called back when the message has been
    sent or which will errback if it cannot be sent.
    """

    # Create a context factory which only allows SSLv3 and does not verify
    # the peer's certificate.
    contextFactory = ClientContextFactory()
    contextFactory.method = TLSv1_METHOD

    resultDeferred = Deferred()

    senderFactory = ESMTPSenderFactory(
        authenticationUsername,
        authenticationSecret,
        fromAddress,
        toAddress,
        messageFile,
        resultDeferred,
        contextFactory=contextFactory,heloFallback=True
        )

    reactor.connectTCP(smtpHost, smtpPort, senderFactory)

    return resultDeferred

注: SSLv3 と TLSv1 の両方を試したので、両方ともインポートされますが、それは問題ではありません。私が取得し続けるエラーはこれです。トレースバック:

2013-05-23 01:19:17+0800 [ESMTPSender,client] SMTP Client retrying server. Retry: 5
2013-05-23 01:19:20+0800 [ESMTPSender,client] SMTP Client retrying server. Retry: 4
2013-05-23 01:19:22+0800 [ESMTPSender,client] SMTP Client retrying server. Retry: 3
2013-05-23 01:19:25+0800 [ESMTPSender,client] SMTP Client retrying server. Retry: 2
2013-05-23 01:19:28+0800 [ESMTPSender,client] SMTP Client retrying server. Retry: 1
2013-05-23 01:19:30+0800 [ESMTPSender,client] Failed to deliver mail [Failure instance: Traceback (failure with no frames): <class 'twisted.mail.smtp.TLSError'>: 454 Could not complete the SSL/TLS handshake
2013-05-23 01:19:30+0800 [ESMTPSender,client] <<< 250-AUTH PLAIN LOGIN
2013-05-23 01:19:30+0800 [ESMTPSender,client] <<< 250 Ok
2013-05-23 01:19:30+0800 [ESMTPSender,client] >>> STARTTLS
2013-05-23 01:19:30+0800 [ESMTPSender,client] <<< 454 TLS not available due to temporary reason: TLS already active
2013-05-23 01:19:30+0800 [ESMTPSender,client]
2013-05-23 01:19:30+0800 [ESMTPSender,client] ]
2013-05-23 01:19:30+0800 [ESMTPSender,client] Stopping factory <twisted.mail.smtp.ESMTPSenderFactory instance at 0x2119950>

Amazon Ses はラッパーと TLS をサポートしていますが、ポートは異なります。GMail の動作と同様です。

ContextFactory を完全に削除しようとしました。エラーは同じです。

私のシステムや認証などではないことを確認するためにsmtplibを試しました。正常に動作します。

正直、私はツイストを完全には理解していないので、ばかげたことをしているかもしれません。上記のコードは他の場所の例と似ており、動作するはずです。ところで、テスト後にctrl-cするだけなので、reactor.stop()を呼び出しません。手がかりはありますか?

完了のための更新: 上記のメソッドを次のように呼び出します

sendmail('username','password',from, to,StringIO.StringIO(mail)).addCallbacks(self.delivered, self.failed)
4

1 に答える 1