V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
leiuu
V2EX  ›  程序员

docker 中发送 html 格式邮件的问题

  •  
  •   leiuu · 2020-01-08 17:39:05 +08:00 · 1861 次点击
    这是一个创建于 1817 天前的主题,其中的信息可能已经有所发展或是发生改变。

    请教大家一个困扰我许久的问题。

    使用 sendmail 发送 html 邮件。

    方法如下:

    function sendHtmlMailViaSendmail()
    {
     
    	mailto="$1"
    	subject="$2"
    	content="$3"
    
    	(
    		echo "To:$mailto"
    		echo "From: [email protected]"
    		echo "Content-Type:text/html;charset=UTF-8"
    		echo "Subject:$subject"
    		echo
    		cat $content
    	) | sendmail -t
    }
    
    sendHtmlMailViaSendmail [email protected] "这是主题" /tmp/report.html 
    

    这样可以发出去邮件,但是会被目标邮件服务器拦截或者标记为垃圾。

    google 一顿之后发现通过外部的 smtp 服务器发出,如腾讯的 「 smtp.exmail.qq.com 」,就不会被识别为垃圾邮件。

    依照这个去更新 senmail 设置: https://tecadmin.net/sendmail-to-relay-emails-through-gmail-stmp/。

    结果 sendmail 无法启动,显示端口被占用,服务无法启动。

    怀疑是 docker 和外部的宿主机冲突导致。

    Job for sendmail.service failed because a configured resource limit was exceeded. See "systemctl status sendmail.service" and "journalctl -xe" for details.
    
    daemon MTA: problem creating SMTP socket
    NOQUEUE: SYSERR(root): opendaemonsocket: daemon MTA: cannot bind: Address already in use
    daemon MTA: problem creating SMTP socket
    NOQUEUE: SYSERR(root): opendaemonsocket: daemon MTA: cannot bind: Address already in use
    daemon MTA: problem creating SMTP socket
    sendmail.service never wrote its PID file. Failing.
    Failed to start Sendmail Mail Transport Agent.
    Unit sendmail.service entered failed state.
    sendmail.service failed.
    

    请问大家有没有好的解决这个问题的方法, 或者其他方法用来在 docker 中发送走外部 smtp 的 html 格式的邮件。

    第 1 条附言  ·  2020-01-09 18:34:20 +08:00

    解决了,用 python 的 email 还是很方便的。

    写一个python email client(sendmail.py ):

    
    import sys
    import os
    import time
    import smtplib
    from email.mime.text import MIMEText
    from email.header import Header
    
    def sendMail(mail_sender, mail_host, mail_host_port, mail_user, mail_pass, mail_receivers, mail_subject,
                 mail_body_file):
        with open(mail_body_file, "r") as f:
            text = f.readlines()
    
        text = ''.join(text)
    
        message = MIMEText(text, 'html', 'utf-8')
    
        message['From'] = mail_sender
        message['Subject'] = Header(mail_subject, 'utf-8')
        mail_receivers = mail_receivers.split(",")
        message['To'] = ";".join(mail_receivers)
    
        try:
            smtp_obj = smtplib.SMTP_SSL(mail_host, mail_host_port, local_hostname="optaim.com")
            smtp_obj.set_debuglevel(0)
            smtp_obj.login(mail_user, mail_pass)
            smtp_obj.sendmail(mail_sender, mail_receivers, message.as_string())
        except Exception, e:
            print "Error: 无法发送邮件", e
    
    
    if len(sys.argv) != 4:
        print "Error: %s input parameters: %s .\n" % (sys.argv[0], sys.argv)
        sys.exit(1)
    print "Run: %s input parameters: %s .\n" % (sys.argv[0], sys.argv)
    
    mail_sender = "[email protected]"
    mail_host = "smtp.exmail.qq.com"
    mail_host_port = 465
    mail_user = "[email protected]"
    mail_pass = "123456"
    mail_receivers = sys.argv[1]
    mail_subject = sys.argv[2]
    mail_body_file = sys.argv[3]
    
    sendMail(mail_sender, mail_host, mail_host_port, mail_user, mail_pass, mail_receivers, mail_subject, mail_body_file)
    
    

    使用方法:

    python sendmail.py "[email protected]" "这是主题" "/tmp/xxx.html"
    
    cloverzrg2
        1
    cloverzrg2  
       2020-01-08 18:55:10 +08:00
    mritd
        2
    mritd  
       2020-01-08 19:34:09 +08:00 via iPhone
    🤔如果你尝试在 docker 里折腾 systemd 的那些玩意,那么本身就是错误行为
    julyclyde
        3
    julyclyde  
       2020-01-09 10:35:40 +08:00
    嘿,简直是……

    1 是否被判定为垃圾邮件,完全取决于收件方的策略
    2 你可以做一些事,但是不一定有效;你参考的资料也不一定对
    3 你用外部 smtp 发的话,额外还收到发件 smtp 服务的策略管制

    4 你用 docker,给自己添加了别的社会制度不存在的问题,然后尝试去解决它,浪费时间
    julyclyde
        4
    julyclyde  
       2020-01-09 10:36:09 +08:00
    5 这事和 *html 格式* 这一点,也没啥关系
    wd
        5
    wd  
       2020-01-09 10:44:00 +08:00
    给你个建议,你写一个用来发邮件的 python 程序,这个程序里面直接连接你的 smtp 服务器发邮件。这样你就不用搞 sendmail 了,sendmail 我目测你一时搞不定。
    leiuu
        6
    leiuu  
    OP
       2020-01-09 11:44:47 +08:00
    @cloverzrg2 没错用的就是这个
    @mritd 😢
    @julyclyde 发非 html 邮件,用 mail 命令,改一下默认的 mail.rc 配置就可以走外部 smtp。起码保证能收到。😂。
    如果不走外部的 smtp,次数 /频率超过一个值后,直接收不到了。

    @wd sendmail 配置改起来太麻烦了,哈哈哈,确实一时搞不定。python script 是可以的,但由于项目里脚本太多了都用的 mail 命令,替换起来也比较麻烦。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2645 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 09:39 · PVG 17:39 · LAX 01:39 · JFK 04:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.