自己的临时邮件:Telegram bot

通常,人们希望借助新的工具和功能来尝试和实现一些我以前从未做过的不太普通的事情。 以自动电报形式创建我的临时邮件服务的想法对我来说似乎很有趣。

一点背景
不久前,我从常规托管服务器迁移到了VPS,碰巧一个月或更长时间之后,我又不得不迁移到另一个VPS。 在这两种情况下,我都拥有最便宜的资费计划和Ubuntu 16.04。 自从我上次遇到大学的终端设备以来,这完全是没有经验,所以我使用了DigitalOcean提供的出色的分步说明来配置我的VPS(其中有些已经翻译成俄语,对于像我这样还不够的人来说)会英语)。 是的,我的第一个VPS是在DO上,我不得不再次移动,主要是因为其IP地址的一部分属于ILV的分配范围。 重复了几次LAMP设置过程后,我有点习惯了VPS终端,作为其进一步开发的一部分,我决定切换到不寻常的实验-例如创建我自己的临时邮件服务。

我已经在后端积累了经验,尤其是在PHP MySQL中创建电报机器人的过程中,但是却收到了“给我自己”的电子邮件-这似乎是遥不可及的。 打开有关该主题的各种文章的几个选项卡后,我意识到我什么都不懂。 建议在每个地方使用大量不同的工具,我认为,与在VPS上接收传入电子邮件的任务相比,该工具更适合于功能全面的电子邮件服务。

接收收件箱


第一步,沙盒中的一篇文章对我有很大帮助: habr.com/en/post/260429 。 我提请注意她的负面评价,但这恰恰说明了我感兴趣的地方。 我想得到一个结果,使我可以尽快“感觉”到它,并想到“将来我会做对的”,我去配置sendmail。

然后,我设置了域。 DNS记录:

example.com IN MX 5 mail.example.com
mail.example.com IN A XXX.XX.XXX.XXX (VPS IP地址)

在服务器上,将行@example.com vasya添加@example.com vasya /etc/mail/virtusertable文件中,从而确定将发往****@example.com上任何地址的所有邮件都发送给Vasya。

要使用php-script处理传入的邮件, vasya: "|php -q /home/vasya/mail.php"vasya: "|php -q /home/vasya/mail.php"到文件/etc/aliases vasya: "|php -q /home/vasya/mail.php"

在进行了几次测试并确保将传入邮件传递到php脚本之后,我可以处理它的处理。

以上述方式接收发送到php的原始传入邮件非常简单地在代码中实现:

 $msg = file_get_contents("php://stdin"); 

完全不同的事情是以一种可理解和可访问的方式来分析邮件格式和显示数据。 Google为我提供了几种如何使用PHP解析邮件格式的选项。 我发现的所有库都拖累了其他组件的安装,但是对我来说,其中一个似乎不那么麻烦: github.com/zbateson/mail-mime-parser 。 我唯一需要另外安装的是流行的PHP包管理器-Composer。 当然,在通常的主机上我没有遇到过,但是安装它并进一步连接库以解析邮件并不难。

使用zbateson / mail-mime-parser库处理传入邮件的php脚本的开头看起来像这样:

 <?php require("vendor/autoload.php"); use ZBateson\MailMimeParser\MailMimeParser; use ZBateson\MailMimeParser\Message; $msg = file_get_contents("php://stdin"); $parser = new MailMimeParser(); $message = Message::from($msg); 

由于我认为临时邮件不涉及多个收件人,因此仅接收第一个可能的邮件就足够了:

 $to = $message->getHeader('To'); $email = $to->getAddresses()[0]->getEmail(); 

在变量$ email中,我们具有vasyaorpetya@example.com形式的收件人地址。

要在库中接收传入信件的内容,有适当的方法:

 $from = $message->getHeader('From')->getEmail(); $subject = $message->getHeaderValue('Subject'); $msg_text = $message->getTextContent(); $msg_html = $message->getHtmlContent(); 

电报机器人


电报临时邮件机器人应该首先做什么?

  1. 根据要求发布新的临时电子邮件地址
  2. 在邮件地址有效时发送此电子邮件的收件箱消息
  3. 续订电子邮件地址

在这种情况下以及从许多其他情况下,从Telegram接收更新的一种非常合适的方法是使用Webhook。 只需要带有https的脚本地址。 DO指令中详细介绍了使用Certbot配置ssl域证书。

为了与Telegram Bot API进行交互,我使用了自己的最佳实践。 有人喜欢使用流行的库。 随着许多文章的写作,用按钮向电报发送消息早已成为一种熟悉的事情。

临时电子邮件地址的生成实质上是按顺序输出下一个地址。 我为数据库中的电子邮件地址创建了一个表,其中类型为int且具有自动增量的id唯一地标识了收件人。 将数字转换为另一个数字系统时,会将数字id转换为字符串地址,其中整个拉丁字母都可用作“数字”。 与数字相比,26个字母可以大大减少标识符的长度。 也许我也可以使用大写字母,数字和一些字符来解决问题,以进一步减少发出的地址的长度,但我只留下了小的拉丁字母。

将数字id转换为字符串,反之亦然的函数:

 // $alphabet = explode(",", "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z"); //   @grayfolk: $alphabet = range('a', 'z'); function num2str($n, $a) { // $a -  $b = count($a); $r = 0; $x = ""; while ($n) { $r = $n%$b; $n = ($n-$r)/$b; $x .= $a[$r]; } return strrev($x); } function str2num($s, $a) { $n = 0; $b = count($a); $s = strrev($s); for ($i = 0; $i < strlen($s); $i++) { $n += array_search($s[$i], $a) * pow($b, $i); } return $n; } 

使用临时邮件服务的主要好处之一是没有垃圾邮件。 但是,如果地址顺序正确,则可以列出将要发出的最近地址并成功进行邮寄。 为了解决此问题,我在收件人ID中添加了一些随机字符串。 为了区分id和地址中的随机部分,我决定始终以数字开头。

我们在数据库中随机写入已发行电子邮件地址的行,以及收件人ID,电报中的用户ID和邮箱发出的时间。

看来您甚至不必存储传入的邮件-它们将其发送到电报中就这样。 但是html字母呢? 它们无法显示在聊天消息中。 仍然需要在数据库中记录传入的html消息并在站点上显示它们,并向用户发送包含消息ID和下一个生成的密码的链接。 为了按计划清理数据库,将启动php脚本,以删除一个多小时前收到的传入html消息。

后来,在漫游器的电报中,我添加了将邮箱有效期延长10或60分钟的按钮,以及一个按钮,该按钮使您能够确定在停止接收传入消息之前,他必须生存多少。

由于我们正在与电报中的注册用户打交道,因此您可以提供激活旧邮箱的机会,例如,恢复网站上忘记的密码或进行任何其他需要通过电子邮件进行确认的操作。 发出的邮箱仅在用户需要时才“接受”传入的邮件;在其余时间,可能的垃圾邮件将被忽略。



未来的愿望清单:

  • 创建网络版本[完成]
  • 通过几次单击/命令即可快速更改邮件域(如何?)

参考文献


电报bot:@tmpmailbot

一篇描述sendmail配置的文章

PHP库用于解析电子邮件

Source: https://habr.com/ru/post/zh-CN445988/


All Articles