作者 | 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 importPROVIDERS下面是过电子邮件发送短信的方法 , 参数如下:
main.pydefsend_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.pydefsend_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}" withsmtplib.SMTP_SSL( smtp_server, smtp_port, context=ssl.create_default_context ) asemail: 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.pydefsend_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.pydefsend_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 importencodersfrom email.mime.base importMIMEBasefrom email.mime.multipart importMIMEMultipartfrom email.mime.text importMIMETextfrom os.path importbasename接下来 , 我们来写发送电子邮件的函数 。 我们发送的邮件不需要显示主题、收件人和消息 , 但邮件应该包含多个部分:第一部分 , 消息本身;第二部分 , 电子邮件的附件 。
回顾移动提供商列表 , 你可能会注意到一些提供商不支持发送多媒体消息 , 或者使用同一个域名和支持 SMS 的密钥发送短消息和多媒体消息 。
例如 , T-Mobile 没有 MMS 密钥 , 但实际上它支持 MMS 密钥 , 这意味着我们可以使用同一个短信域来 SMS 和 MMS 。 与此同时 , AT&T 既有 SMS 域也有 MMS 域 。 因此 , 你需要根据发送的内容选择合适的域名 。
与上述 email_message 方法类似 , 但这次我们使用 MIMEMultipart 。 此外 , 我们还需要使用 email_message 添加主题、收件人和发件人 。
main.pydefsend_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.pydefsend_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")) withopen(file_path, "rb") asattachment: 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")) withopen(file_path, "rb") asattachment: 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")) withopen(file_path, "rb") asattachment: 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 withsmtplib.SMTP_SSL( smtp_server, smtp_port, context=ssl.create_default_context ) asemail: 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 importPROVIDERS # 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多家知名公司云原生和数字化一手实战经验!
? 程序员挖“洞”致富:发现一个漏洞 , 获赏 1272 万元!
?IntelliJ 平台彻底停用 Log4j 组件!
【sms|如何使用Python通过电子邮件发送短消息】? 40岁开始学习Android开发的我成了一名技术主管
推荐阅读