简体   繁体   English

Perl - 如何从标题的 FROM 部分获取电子邮件地址?

[英]Perl - How to get the email address from the FROM part of header?

I am trying to set up this script for my local bands newsletter.我正在尝试为我的本地乐队通讯设置此脚本。

Currently, someone sends an email with a request to be added, we manually add it to newsletter mailer I set up.目前,有人发送了一封包含要添加请求的电子邮件,我们手动将其添加到我设置的时事通讯邮件程序中。 (Which works great thanks to help I found here!) (非常感谢我在这里找到的帮助!)

The intent now is to have my script below log into the email account I set up for the list on our server, grab the info to add the email automatically.现在的目的是让下面的脚本登录我为服务器上的列表设置的电子邮件帐户,获取信息以自动添加电子邮件。

I know there are a bunch of apps that do this but, I want to learn myself.我知道有很多应用程序可以做到这一点,但是,我想自己学习。

I already have the "add to list" working when there is an email address returned from the header(from) below BUT, sometimes the header(from) is a name and not the email address ( eg "persons name" is returned from persons name<email@address> but, not the <email@address> .)当从下面的标题(来自)返回一个电子邮件地址时,我已经有“添加到列表”工作,有时标题(来自)是一个名字而不是电子邮件地址( eg "persons name" is returned from persons name<email@address> but, not the <email@address> 。)

Now, I am not set in stone on the below method but, it works famously... to a point.现在,我并没有对下面的方法一成不变,但是,它的效果非常好......在某种程度上。

I read all the docs on these modules and there was nothing I could find to get the darn email in there all the time.我阅读了有关这些模块的所有文档,但始终找不到任何内容来获取该死的电子邮件。

Can someone help me here?有人可以在这里帮助我吗? Verbose examples are greatly appreciated since I am struggling learning Perl.由于我正在努力学习 Perl,因此非常感谢详细示例。

 #!/usr/bin/perl -w
    ##########
    use CGI;
    use Net::IMAP::Simple;
    use Email::Simple;
    use IO::Socket::SSL; #optional i think if no ssl is needed
    use strict;
    use CGI::Carp qw(fatalsToBrowser warningsToBrowser);
    ######################################################
    # fill in your details here
    my $username = '#########';
    my $password = '#############';
    my $mailhost = '##############';
    #######################################################
    print CGI::header();
    # Connect
    my $imap = Net::IMAP::Simple->new($mailhost, port=> 143, use_ssl => 0, ) || die "Unable to connect to IMAP: $Net::IMAP::Simple::errstr\n";
    # Log in
     if ( !$imap->login( $username, $password ) ) {
      print STDERR "Login failed: " . $imap->errstr . "\n";
      exit(64);
     }
    # Look in the INBOX
    my $nm = $imap->select('INBOX');
    # How many messages are there?
    my ($unseen, $recent, $num_messages) = $imap->status();
    print "unseen: $unseen, <br />recent: $recent, <br />total: $num_messages<br />\n\n";
    ## Iterate through unseen messages
     for ( my $i = 1 ; $i <= $nm ; $i++ ) {
         if ( $imap->seen($i) ) {
         my $es = Email::Simple->new( join '', @{ $imap->top($i) } );
         printf( "[%03d] %s\n\t%s\n", $i, $es->header('From'), $es->header('Subject'));
         print "<br />";
         next;
         }## in the long version these are pushed into different arrays for experimenting purposes
       else {
       my $es = Email::Simple->new( join '', @{ $imap->top($i) } );
       printf( "[%03d] %s\n\t%s\n", $i, $es->header('From'), $es->header('Subject'));
       print "<br />";
       }
     }
    # Disconnect
    $imap->quit;
    exit;
use Email::Address;
my @addresses = Email::Address->parse('persons name <email@address>');
print $addresses[0]->address;

The parse method returns an array, so the above way works for me. parse方法返回一个数组,所以上面的方法对我有用。

I'm making this a separate answer because even though this information is hidden in the comments of the accepted answer, it took me all day to figure that out.我将其作为一个单独的答案,因为即使这些信息隐藏在已接受答案的评论中,我也花了一整天的时间才弄明白。

First you need to get the From header using something like Email::Simple.首先,您需要使用 Email::Simple 之类的内容获取 From 标头。 THEN you need to extract the address portion with Email::Address.然后您需要使用Email::Address 提取地址部分。

use Email::Simple;
use Email::Address;

my $email = Email::Simple->new($input);
my $from = $email->header('From');
my @addrs = Email::Address->parse($from);
my $from_address = $addrs[0]->address;    # finally, the naked From address.

Those 4 steps in that order.按顺序执行这 4 个步骤。

The final step is made confusing by the fact that Email::Address uses some voodoo where if you print the parts that Email::Address->parse returns, they will look like simple strings, but they are actually objects .最后一步令人困惑,因为 Email::Address 使用了一些伏都教,如果你打印 Email::Address->parse 返回的部分,它们看起来像简单的字符串,但它们实际上是对象 For example if you print the result of Email::Address->parse like so,例如,如果您像这样打印 Email::Address->parse 的结果,

my @addrs = Email::Address->parse($from);
foreach my $addr (@addrs) { say $addr; }

You will get the complete address as output:您将获得完整的地址作为输出:

"Some Name" <address@example.com>

This was highly confusing when working on this.在处理此问题时,这非常令人困惑。 Granted, I caused the confusion by printing the results in the first place, but I do that out of habit when debugging.当然,我首先打印结果引起了混乱,但我在调试时出于习惯这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM