Re: Reading emails with PHP

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



John, et al --

[We're going to talk about perl a bit more, albeit comparing and
contrasting with php.  If this should be kicked off of the list,
just let us know.]

...and then Dillon, John said...
% 
% As one who has used php (without classes) but has seen cpan in operation
% (I'd describe it as connecting to the internet from the c: prompt, if using

Heh :-)  Not a bad analogy, though it leaves a lot out.


% Windows) and it's impressive though complicated, only the documentation is a
% bit flat on perl and beginners lists require you to have memorised Learning

Now, now...  I'd hesitate to call the perl doc flat; I haven't even read
it all and I've been playing with perl for years!  There is a *lot* of
documentation available just with the standard perl installation.


% Perl to understand the answers...  I got flamed for mentioning php on a perl

*rofl*  Yes, an expectation of having read some background is there.
It's not nearly so bad as on the DJB utils lists, though!


% beginners list, so I hope php people are not so religious. Though this is

How interesting...  The beginners@xxxxxxxx list isn't religious and it
would certainly be safe to "mention" php in an on-topic post there; where
and what did you mention?  Of course, if you came in and started shooting
off about how php was great and did this and that and perl just sucked
then, yeah, you might get flamed -- on any list :-)


% about perl it is a php-background web person trying to understand it.

Right.


% 
% > The one used here is Mail::DeliveryStatus::BounceParser.
% 
% Where does the perl module reside on the server?  I have my home space, so I

You could put it in your personal perl library or the server perl
library.  In this case I had root access and was installing for the
machine owner and so I put it in /usr/lib/perl5/...


% have seen modules attempting to download onto my computer but would not know
% about doing it on my host server.  Perhaps it is preinstalled on the server

Right.  I wouldn't, either; although there are undoubtedly ways to ftp
into place a module's pieces I've only ever installed from a shell prompt.
I suppose you could write a script to do the install and call it from a
web page :-)


% (a standard module) or I just need to contact my host provider.

You should be able to ask them to install it for you.


% 
% > Once we set up the script to use the module with
% 
% This I understand - the below lines are written in a plain text file and
% saved as a .pl file.

Yep.


% 
% >  ### basic setup	## {{{
...
% >  use Mail::DeliveryStatus::BounceParser ;		# parsing magic
% >  ## }}}
% 
% > catching the mail is literally as easy as
% 
% >  ### catch the input	## {{{
% >  my $bounce = eval { Mail::DeliveryStatus::BounceParser->new ( \*STDIN ) }
% ;
% >  if ( $@ )
% >  {
% >    print "Whoa -- one we actually couldn't handle!\n" ;
% >    exit 255 ;
% >  }	## }}}
% 
% Sorry, lost.  What wakes up this file to notice that an email has bounced

That's the .qmail/.forward thing, so we'll cover it below.


% and execute the second line?  Is it its location on the server?  How does it

It can be located anywhere as long as the MTA/MDA (Mail Transport Agent
and/or Mail Delivery Agent) is told where to go and find it.  Mine is way
away from the home dir of the account calling it.


% realise it has some input, STDIN, to look at?  (Is there a similar concept
% to STDIN in php?)

When I'm whipping out a one-liner to test an example I'm usually lazy and
just use

  echo '...' | php -q

and so that's one way.  I actually don't know how to do the equivalent of

  perl -e 'print "hello, world\n" ;'

which then leads to

  echo "hello, world" | perl -e 'print <STDIN> ;'

in php, so actually passing stdin to a script is a good question.
Perhaps

  fopen("php://stdin",'r') ;

or such as shown in the manual.  Oh, wait -- STDIN is an already-defined
constant that is the same thing, so you just use it :-)  But I still
don't know how to build a script on the command line to use that...


% 
% > through $bounce->reports because it wasn't clear in the man page for the
% > module *blush*.
% 
% For those new to perl, I got as far as
% http://www.perldoc.com/perl5.8.0/pod/perl.html and couldn't find the man

You won't; it's not a stock part of perl but an add-on module.


% page for the module.  (I've never been lost in php.net.)  The fact that

Well, could you find the docs for HTML_Client in the php.net php docs?
You'd no doubt at least have to go over to pear.php.net but very probably
have to pull down the tarball, just like with the BounceParser module.


% $bounce->reports gives a $report would be because the object $bounce from: 
%  my $bounce = eval { Mail::DeliveryStatus::BounceParser->new ( \*STDIN ) } ;
% 
% has a 'report' method defined in the module.  The module documentation

Well, a 'reports' (plural!) method, anyway.  My problem was that I didn't
realize I was getting back an array of reports and would need to loop
over it.


% should tell us what this report contains, but it must contain text with the
% bounce report (obviously) including the email address which has bounced.

Yep.


% The line:
% 
%  my $email = $report->get('email') ;
% 
% would then be using a method 'get' as defined in the module to get the email
% address, the argument 'email' must be defined in the module as the email
% address...same with 'std_reason' etc.

Yep.


% 
% execute (as in $ur->execute($email) ;) would work as a method of the module
% we are using because of the syntax '->execute' which I suppose perl sees as
% a method call.  The module will define what happens when we do this.  What

Yep.  That's the DBI module, BTW.


% does 'update user record' mean? - this is the db bit - I realise this is a

That's what I do to the user record in my database.  The USER table has a
zillion fields for our users.  One of them is a status flag field, which
I update.


% loop, is the variable $br accummulating something, why is it redefined below
% in 'my $br = $eteam->prepare($b) ;'?  Why are we connecting to the db after
% the 'execute' if it is updating the db?

I said I glossed over it; the code as shown in the email is actually out
of order, because the BounceParser module was the important thing.  In
the real world, first we connect and prepare and then we [perhaps
repeatedly] execute.  So jump on down again...


% 
...
% >  ### prepare query
% >  my $u = "update eteam.USER set FLAG_CONFIRM = 2 where EMAIL = ?" ;	#
% user status query
% >  my $b = "insert into eteam.MAIL_BOUNCE values (?,?,?,?,?)" ;	# bounce
% mail log query
% >  my $ur = $eteam->prepare($u) ;				# prepare
% query (user)
% >  my $br = $eteam->prepare($b) ;				# prepare
% query (bounce)
% >  ## }}}
% 
% > where the '?' is a placeholder for the values you'll provide at execution
% > time.  
% 
% and how do we provide values at execution time?

Here we have two queries, $u and $b, which will update the USER table and
insert into the MAIL_BOUNCE table, resepectively.  In each query I have
one or more '?' placeholders.

Next we prepare each of those two queries ($u and $b) and get back an
object handle ($ur and $br) for each.  Remember that $eteam is itself a
handle for talking to the eteam DB via the DBI connection.

Finally, in the "loop thru the message" section, we actually put them to
use.  With

  $br->execute($email,$std_reason,$reason,$orig_mid,$date) ;

I have provided five values to insert into the placeholders defined in
the

  $b = ...

line quoted above.


% 
% > So there you have it...  This perl script is only 58 lines long and
% > handles just about every sort of bounce known to man and then goes and
% > updates two DB tables with the info it pulls out.  
% 
% OK.  (58 lines does not translate into thinking time though.)

Of course not -- but, as it turned out, it only took some 10 minutes of
search time, 5 minutes of reading time, 5 minutes of writing time, 20
more minutes of reading time with a bit of thinking/experimenting thrown
in here and there, and then a final 10 minutes of thinking time to write
the rest of the code to get it to work.  It's still less than a minute
per line average ;-)


% 
% > It's called from the
% > apparent sender's .qmail (like .forward) file, which also dumps a copy of
% > the message onto a mail spool for us to review if we ever need to.
% 
% .qmail, .forward file, mail spool are unfamiliar concepts I haven't seen.
% Where 
% can I see touch and smell these things?  The above is a plain text .pl file

On a *NIX host, or a Win host running a *NIX MTA and perhaps MDA.  You
won't see it if you pop your mail down from server with Outhouse; you
might if you use fetchmail to pop and deliver.

On a UNIX/Linux/BSD/... machine running an MTA (ie listening on port 25)
mail that is bound for users on the server will be written to some files
so that it can be read later.  The default file or directory for each
user is generally called a "mail spool".

Sometimes you have an account whose mail should do something other than
just land and wait to be read.  You can direct it with a file in your
home directory (well, that account's home dir) generally named .forward
but perhaps also .qmail (and extensions thereof) for the qmail MTA.  For
all I know Exim and Postfix may have their own custom control files as
well, but everyone can use the .forward file that Sendmail uses.  Think
of forwarding your snail mail, but of course enormously more capable
(like just about anything compared to snail mail :-)

The easiest way to play with this stuff and more is to just set up a *NIX
box at home and start playing with it.  The second easiest way is to read
lots of man pages, but that's a very good approach because you'll find
out ALL about each piece.  Another way is to just beg/buy an account on a
*NIX box and then pester the admin / help staff :-)


% on a server
% with perl installed (as my shared host provider has)...just trying to
% visualise.

No problem, and good for you for digging in!


% 
% > HTH & HAND
% 
% > :-D
% 
% Thanks,
% John
[snip]

There probably isn't the slightest chance that you could avoid having
that gawdawful book of a footer put on your messages, but if you could
I'd sure appreciate it.


HTH & HAND & Happy Holidays

:-D
-- 
David T-G                      * There is too much animal courage in 
(play) davidtg@xxxxxxxxxxxxxxx * society and not sufficient moral courage.
(work) davidtgwork@xxxxxxxxxxxxxxx  -- Mary Baker Eddy, "Science and Health"
http://justpickone.org/davidtg/      Shpx gur Pbzzhavpngvbaf Qrprapl Npg!

Attachment: pgp00087.pgp
Description: PGP signature


[Index of Archives]     [PHP Home]     [PHP Users]     [Postgresql Discussion]     [Kernel Newbies]     [Postgresql]     [Yosemite News]

  Powered by Linux