社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

如何使用Python通过电子邮件发送短消息

CSDN • 3 年前 • 470 次点击  
作者 | Alfredo Sequeida    译者 | 弯月
出品 | CSDN(ID:CSDNnews)
首先,我们来熟悉一些相关的概念。SMS(Short Messaging Service,短消息服务)就是文本消息,上限是 160 个字符,通过移动网络发送。MMS(Multimedia Messaging Service,多媒体消息服务)与文本消息基本相同,只不过嵌入了图像、视频或 PDF 文件等多媒体,我也是最近才知道我们可以通过文本消息发送这些多媒体。为了发送免费的文本消息,我们将使用 SMS 网关,但这些网关只是中转服务器,可通过移动网络将消息传递到手机。

发送短信

 
Twilio等解决方案允许你使用他们的 API,通过编程发送文本消息,但需要收费。本文使用的 SMS 和 MMS 网关是免费的,因为我们可以通过电子邮件与它们交互。换句话说,这些网关是由移动提供商架设的,允许我们以电子邮件消息的形式发送文本消息,然后通过 SMS 或 MMS 将消息转发到手机。
下面的列表汇总了美国境内电话提供商的 SMS 和 MMS 电子邮件域名,仅供参考:
providers.pyPROVIDERS = {   "AT&T": {"sms""txt.att.net","mms""mms.att.net""mms_support"True},   "Boost Mobile": {       "sms""sms.myboostmobile.com",       "mms""myboostmobile.com",       "mms_support"True,   },   "C-Spire": {"sms""cspire1.com","mms_support"False},   "Cricket Wireless": {       "sms":"sms.cricketwireless.net ",       "mms""mms.cricketwireless.net",      "mms_support"True,   },   "Consumer Cellular": {"sms":"mailmymobile.net""mms_support"False},   "Google Project Fi": {"sms":"msg.fi.google.com""mms_support"True},   "Metro PCS": {"sms""mymetropcs.com","mms_support"True},   "Mint Mobile": {"sms""mailmymobile.net","mms_support"False},   "Page Plus": {       "sms""vtext.com",       "mms""mypixmessages.com",       "mms_support"True,   },   "Republic Wireless": {       "sms""text.republicwireless.com",       "mms_support"False,   },   "Sprint": {       "sms""messaging.sprintpcs.com",       "mms""pm.sprint.com",       "mms_support"True,   },   "Straight Talk": {       "sms""vtext.com",       "mms""mypixmessages.com",       "mms_support"True,   },   "T-Mobile": {"sms""tmomail.net","mms_support"True},   "Ting": {"sms""message.ting.com","mms_support"False},   "Tracfone": {"sms""""mms":"mmst5.tracfone.com""mms_support"True},   "U.S. Cellular": {       "sms""email.uscc.net",       "mms""mms.uscc.net",       "mms_support"True,   },   "Verizon": {"sms": 


    
"vtext.com","mms": "vzwpix.com", "mms_support": True},   "Virgin Mobile": {       "sms""vmobl.com",       "mms""vmpix.com",       "mms_support"True,   },   "Xfinity Mobile": {       "sms""vtext.com",       "mms""mypixmessages.com",      "mms_support"True,   },}
另外,最近我发现了一个网站,其中包含多个国家/地区的 SMS 网关:https://email2sms.info/。
简单地解释一下,本文中的例子使用的是美国电话号码,一共10个数字。我们可以采用如下形式:电话号码@网管域名(number@gateway-domain.com)。
除了移动提供商提供 SMS 或 MMS 的电子邮件域外,你还需要一个电子邮件提供商,这样才能使用 SMTP 服务器。在本文的示例中,我们将使用 Gmail 及其 SMTP 服务器。因此,你需要一个 Gmail 账号。此外,你还需要设置应用密码,且不设置两步验证,作为登录 SMTP 服务器的方式。
具体的做法,请参见:https://myaccount.google.com/apppasswords。从“应用程序”下拉菜单中选择Email,“设备”下拉菜单中选择“任意设备”,然后就可以获得一个密码,后面我们会使用这个密码来完成 Gmail 的 SMTP 服务器的身份验证。
下面,我们来看一看代码。首先,我们需要导入一些模块:
  • email:用于格式化电子邮件。
  • smtplib:通过 SMTP 服务器发送电子邮件。
  • ssl:连接SMTP 服务器。
  • providers:上面提到的移动提供商的配置。
代码如下:
main.pyimport email, smtplib, sslfrom providers import PROVIDERS
下面是过电子邮件发送短信的方法,参数如下:
main.pydef send_sms_via_email(   number: str,   message: str,   provider: str,   sender_credentials: tuple,   subject: str = "sent using etext",   smtp_server: str = "smtp.gmail.com",   smtp_port: int = 465,):
  • number:字符串类型,发送电子邮件的电话号码。
  • message:字符串类型,实际的消息。
  • provider:字符串类型,移动提供商。
  • sender_credentials:元组类型,发件人凭据,不仅包括发送电子邮件,而且还包括上述我们通过 Google 应用获得的密码。
  • subject:字符串类型,消息主题。注意,有些 SMS 网关不允许发送格式不正确的电子邮件,因此我们在此加入了主题。
  • smtp_server:字符串类型,SMTP服务器。
  • smtp_port:整数类型,SMTP服务器端口。
在这个示例中,我们将使用 Gmail 发送电子邮件,因此默认地址为:smtp.gmail.com。此外,我们还需要知道发送电子邮件的端口。如果你使用的是 Gmail,则无需在意太多,但如果使用的是其他 SMPT 提供商或电子邮件服务器,则需要弄清楚他们使用哪个端口发送电子邮件。在我们的例子中,SMTP 端口为整数类型。
我们首先应该定义的是发件人的电子邮件和密码,下面我们通过发件人凭据中获取这些信息:
main.pydef send_sms_via_email(   number: str,    message: str,   provider: str,   sender_credentials: tuple,   subject: str = "sent using etext",   smtp_server: str = "smtp.gmail.com",   smtp_port: int = 465,):   sender_email, email_password = sender_credentials
如上所述,接收者的电子邮件由电话号码和 SMS 网关的域名组成。此处,为了格式化,我使用了 f 字符串。
main.pydef send_sms_via_email(   number: str,   message: str,   provider: str,   sender_credentials: tuple,   subject: str = "sent using etext",   smtp_server: str = "smtp.gmail.com",   smtp_port: int = 465,):   sender_email, email_password = sender_credentials   receiver_email =f'{number}@{PROVIDERS.get(provider).get("sms")}'
下面,我们来格式化电子邮件。我们创建一个名为 email_messagee 的变量,如上所述,有些提供商不允许发送格式不正确的电子邮件,因此我们不仅需要发送消息内容,还需要指定主题,以及接收方,这里我们将使用 f 字符串。
main.pydef send_sms_via_email(   number: str,   message: str,   provider: str,   sender_credentials: tuple,   subject: str = "sent using etext",   smtp_server: str = "smtp.gmail.com",   smtp_port: int = 465,):   sender_email, email_password = sender_credentials   receiver_email =f'{number}@{PROVIDERS.get(provider).get("sms")}'   email_message =f"Subject:{subject}\nTo:{receiver_email}\n{message}"
为了发送电子邮件,我们需要使用上下文管理器。 简单说明一下,上下文管理器可以让我们完成所有操作后优雅地关闭 SMTP 连接,所以这里我们将使用 smtplib,并使用 SMTP_SSL 创建一个对象,然后利用该实例向 SMTP 服务器发出身份验证:
main.pydef send_sms_via_email(   number: str,   message: str,   provider: str,   sender_credentials: tuple,   subject: str = "sent using etext",   smtp_server: str = "smtp.gmail.com",   smtp_port: int = 465,):   sender_email, email_password = sender_credentials   receiver_email =f'{number}@{PROVIDERS.get(provider).get("sms")}'   email_message =f"Subject:{subject}\nTo:{receiver_email}\n{message}"   with smtplib.SMTP_SSL(       smtp_server, smtp_port, context=ssl.create_default_context()   ) as email:       email.login(sender_email, email_password)       email.sendmail(sender_email, receiver_email, email_message)
下面,我们来发送 SMS 消息!首先快速创建一个 main 方法,然后在这个 main 方法中调用 send_sms_via_email。
main.pydef main():   number = "5623720883"   message = "hello world!"   provider = "T-Mobile"   sender_credentials = ("email@domain.com","password")   send_sms_via_email(number, message, provider, sender_credentials)
我们使用 __name__ 方法运行程序:
if __name__ == "__main__":   main()

发送 MMS 消息

 
下面,我们介绍如何发送 MMS 消息。代码与发送 SMS 消息基本类似,我们从同一段代码入手:
main.pydef send_mms_via_email(   number: str,   message: str,   provider: str,   sender_credentials: tuple,   subject: str = "sent using etext",   smtp_server: str = "smtp.gmail.com",   smtp_port: int = 465,):   sender_email, email_password = sender_credentials   receiver_email =f'{number}@{PROVIDERS.get(provider).get("sms")}'

为了发送 MMS 消息,我们还需要添加三个参数:

  • file_path:由于我们需要一个文件来发送多媒体消息,因此需要再添加一个参数用以表示文件的路径。
  • mime_maintype:多媒体文件的主类型。
  • mime_subtype:多媒体文件的子类型。
具体的代码如下:
main.pydef send_mms_via_email(   number: str,   message: str,   file_path: str,   mime_maintype: str,   mime_subtype: str,   provider: str,   sender_credentials: tuple,   subject: str = "sent using etext",   smtp_server: str = "smtp.gmail.com",   smtp_port: int = 465,): 

此外,我们还需要导入发送 MMS 的工具函数:

main.pyfrom email import encodersfrom email.mime.base import MIMEBasefrom email.mime.multipart importMIMEMultipartfrom email.mime.text import MIMETextfrom os.path import basename

接下来,我们来写发送电子邮件的函数。我们发送的邮件不需要显示主题、收件人和消息,但邮件应该包含多个部分:第一部分,消息本身;第二部分,电子邮件的附件。

回顾移动提供商列表,你可能会注意到一些提供商不支持发送多媒体消息,或者使用同一个域名和支持 SMS 的密钥发送短消息和多媒体消息。
例如,T-Mobile 没有 MMS 密钥,但实际上它支持 MMS 密钥,这意味着我们可以使用同一个短信域来 SMS 和 MMS。与此同时,AT&T 既有 SMS 域也有 MMS 域。因此,你需要根据发送的内容选择合适的域名。
与上述 email_message 方法类似,但这次我们使用 MIMEMultipart。此外,我们还需要使用 email_message 添加主题、收件人和发件人。
main.pydef send_mms_via_email(   number: str,   message: str,   file_path: str,   mime_maintype: str,   mime_subtype: str,   provider: str,   sender_credentials: tuple,   subject: str = "sent using etext",   smtp_server: str = "smtp.gmail.com"   smtp_port: int = 465,):   sender_email, email_password = sender_credentials   receiver_email =f'{number}@{PROVIDERS.get(provider).get("sms")}'   email_message = MIMEMultipart()   email_message["Subject"] = subject   email_message["From"] = sender_email   email_message["To"] = receiver_email

接下来,我们在邮件中添加附件——普通类型(纯文本)。 

main.pydef 


    
send_mms_via_email(   number: str,   message: str,   file_path: str,   mime_maintype: str,   mime_subtype: str,   provider: str,   sender_credentials: tuple,   subject: str = "sent using etext",   smtp_server: str = "smtp.gmail.com",   smtp_port: int = 465,):   sender_email, email_password = sender_credentials   receiver_email =f'{number}@{PROVIDERS.get(provider).get("sms")}'   email_message = MIMEMultipart()   email_message["Subject"] = subject   email_message["From"] = sender_email   email_message["To"] = receiver_email   email_message.attach(MIMEText(message, "plain"))


MIME类型

 
MIME类型是一种文件类型或一种内容类型的声明。在我们的例子中,MIME 文本表明电子邮件的内容是文本。同样,如果想添加此类的附件,则必须指定 MIME类型。


附加文件

 
我们可以通过上下文管理器,在参数中传递的文件路径。然后指定读取类型,在这个例子中,我们需要读取字节。我们可以使用 MIMEBase 指定 MIME 类型的文件。mime_maintype 是主要类型,mime_subtype 是子类型。接着,我们还需要设置内容的有效负载。在这个例子中就是附加文件。为了发送文件,我们需要将其编码为 base64,因此前面我们导入了 encoders,我们需要将媒体编码为 base64。此外,我们还需要添加一个 content-disposition 类型的头部,并在其中指定文件名。然后,将其附加到我们的电子邮件中,就可以像前面一样发送邮件了。
main.pydef send_mms_via_email(   number: str,   message: str,   file_path: str,   mime_maintype: str,   mime_subtype: str,   provider: str,   sender_credentials: tuple,   subject: str = "sent using etext",   smtp_server: str = "smtp.gmail.com",   smtp_port: int = 465,):sender_email, email_password = sender_credentials  receiver_email =f'{number}@{PROVIDERS.get(provider).get("sms")}'   email_message = MIMEMultipart()   email_message["Subject"] = subject   email_message["From"] = sender_email   email_message["To"] = receiver_email   email_message.attach(MIMEText(message, "plain"))   with open(file_path, "rb"as attachment:       part = MIMEBase(mime_maintype, mime_subtype)       part.set_payload(attachment.read())   encoders.encode_base64(part)       part.add_header(            "Content-Disposition",            f"attachment;filename={basename(file_path)}",        )       email_message.attach(part)

最后,我们不能直接发送 MIME 类型的电子邮件,我们必须在上下文管理器之外将其转换为文本。

main.pydef send_mms_via_email(   number: str,   message: str,   file_path: str,   mime_maintype: str,   mime_subtype: str,   provider: str,   sender_credentials: tuple,   subject: str = "sent using etext",   smtp_server: str = "smtp.gmail.com",   smtp_port: int = 465,):   sender_email, email_password = sender_credentials   receiver_email =f'{number}@{PROVIDERS.get(provider).get("sms")}'   email_message = MIMEMultipart()   email_message["Subject"] = subject   email_message["From"] = sender_email   email_message["To"] = receiver_email   email_message.attach(MIMEText(message, "plain"))   with open(file_path, "rb"as attachment:       part = MIMEBase(mime_maintype, mime_subtype)       part.set_payload(attachment.read())       encoders.encode_base64(part)       part.add_header(            "Content-Disposition",            f"attachment;filename={basename(file_path)}",       )       email_message.attach(part)   text = email_message.as_string()
下面的代码与 SMS 几乎一样,只不过我们必须将电子邮件的内容改为刚刚创建的文本。
main.pydef send_mms_via_email(   number: str,   message: str,   file_path: str,   mime_maintype: str,   mime_subtype: str,   provider: str,   sender_credentials: tuple,   subject: str = "sent using etext",   smtp_server: str = "smtp.gmail.com",   smtp_port: int = 465,):   sender_email, email_password = sender_credentials   receiver_email =f'{number}@{PROVIDERS.get(provider).get("sms")}'   email_message = MIMEMultipart()   email_message["Subject"] = subject   email_message["From"] = sender_email   email_message["To"] = receiver_email   email_message.attach(MIMEText(message, "plain"))   with open(file_path, "rb"as attachment:       part = MIMEBase(mime_maintype, mime_subtype)       part.set_payload(attachment.read())       encoders.encode_base64(part)       part.add_header(            "Content-Disposition",            f"attachment;filename={basename(file_path)}",       )       email_message.attach(part)   text = email_message.as_string()   with smtplib.SMTP_SSL(       smtp_server, smtp_port, context=ssl.create_default_context()   ) as email:       email.login(sender_email, email_password)       email.sendmail(sender_email, receiver_email, text)

下面,我们来创建 main 函数。与 SMS 的代码类似,我们只需添加文件路径和 MIME 类型。 为了发送一个 png 图像,我们必须指定 mime_maintype 为 “image”,mime_subtype 为 “png”。

main.pydef main():   file_path = "/path/to/file/file.png"   mime_maintype = "image"   mime_subtype = "png"   number = "5623720883"   message = "hello world!"   provider = "T-Mobile"   sender_credentials = ("email@domain.com","password")   send_mms_via_email(      number,       message,       file_path,       mime_maintype,       mime_subtype,       provider,       sender_credentials,   )if __name__ == "__main__":   main()
同时支持 SMS 和 MMS 的代码如下:
main.pyimport email, smtplib, sslfrom providers import PROVIDERS# used for MMSfrom email import encodersfrom email.mime.base import MIMEBasefrom email.mime.multipart importMIMEMultipartfrom email.mime.text import MIMETextfrom os.path import basenamedef send_sms_via_email(   number: str,   message: str,   provider: str,   sender_credentials: tuple,   subject: str = "sent using etext",   smtp_server: str = "smtp.gmail.com",   smtp_port: int = 465,):   sender_email, email_password = sender_credentials   receiver_email =f'{number}@{PROVIDERS.get(provider).get("sms")}'   email_message =f"Subject:{subject}\nTo:{receiver_email}\n{message}"   with smtplib.SMTP_SSL(       smtp_server, smtp_port, context=ssl.create_default_context()   ) as email:       email.login(sender_email, email_password)       email.sendmail(sender_email, receiver_email, email_message)def send_mms_via_email(   number: str,   message: str,   file_path: str,   mime_maintype: str,   mime_subtype: str,   provider: str,   sender_credentials: tuple,   subject: str = "sent using etext",   smtp_server: str = "smtp.gmail.com",   smtp_port: int = 465,):   sender_email, email_password = sender_credentials   receiver_email =f'{number}@{PROVIDERS.get(provider).get("sms")}'   email_message=MIMEMultipart()   email_message["Subject"] = subject   email_message["From"] = sender_email   email_message["To"] = receiver_email   email_message.attach(MIMEText(message, "plain"))   with open(file_path, "rb") as attachment:       part = MIMEBase(mime_maintype, mime_subtype)       part.set_payload(attachment.read())       encoders.encode_base64(part)       part.add_header(            "Content-Disposition",            f"attachment;filename={basename(file_path)}",       )       email_message.attach(part)   text = email_message.as_string()   with smtplib.SMTP_SSL(       smtp_server, smtp_port, context=ssl.create_default_context()   ) as email:       email.login(sender_email, email_password)       email.sendmail(sender_email, receiver_email, text)def main():   number = "5623720883"   message = "hello world!"   provider = "T-Mobile"   sender_credentials = ("email@domain.com","password")   # SMS   send_sms_via_email(number, message, provider, sender_credentials)   # MMS   file_path = "/path/to/file/file.png"   mime_maintype = "image"   mime_subtype = "png"   send_mms_via_email(       number,       message,       file_path,       mime_maintype,       mime_subtype,       provider,       sender_credentials,   )   if __name__ == "__main__":   main()


常见的 MIME 类型

 
下表是一些常见的 MIME 类型:
参考链接:
https://www.alfredosequeida.com/blog/how-to-send-text-messages-for-free-using-python-use-python-to-send-text-messages-via-email/

新程序员003》正式上市,50余位技术专家共同创作,云原生和数字化的开发者们的一本技术精选图书。内容既有发展趋势及方法论结构,华为、阿里、字节跳动、网易、快手、微软、亚马逊、英特尔、西门子、施耐德等30多家知名公司云原生和数字化一手实战经验!


☞IntelliJ 平台彻底停用 Log4j 组件!
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/127128
 
470 次点击