So I'm trying to figure out how to send an email to an address for example, something#whatever.com and instead of the e-mail going to there it would be instead sent or forwarded to a script that I create to read the contents of the email and store the contents into a database. Any suggestions on how to do it in PHP?
Thanks!
Here's some code you could use to get you going:
// set user to check
$strUser = "username";
$strPassword = "password";
// open
$hMail = imap_open ("{mail.yourdomain.com:143/notls}INBOX", "$strUser", "$strPassword");
// get headers
$aHeaders = imap_headers( $hMail );
// get message count
$objMail = imap_mailboxmsginfo( $hMail );
// process messages
for( $idxMsg = 1; $idxMsg <= $objMail->Nmsgs; $idxMsg++ )
{
// get header info
$objHeader = imap_headerinfo( $hMail, $idxMsg );
// get from object array
$aFrom = $objHeader->from;
// process headers
for( $idx = 0; $idx < count($aFrom); $idx++ )
{
// get object
$objData = $aFrom[ $idx ];
// get email from
$strEmailFrom = $objData->mailbox . "#" . $objData->host;
// do some stuff here
}
// delete message
imap_delete( $hMail, $idxMsg );
}
// expunge deleted messages
imap_expunge( $hMail );
// close
imap_close( $hMail );
Two options:
1) If you have access to the shell on the recipient email server, you can set up a rule to fire a script (like via procmail or the like) whenever a new message is received.
2) You can allow the email to drop into the mailbox as normal, then write your PHP script to access the mailbox via IMAP, pull the new messages, process them, then delete them. And then run the thing by cron every few minutes.
Related
I spend the best part of today trying to create a message with PHP via IMAP in Exchange which I can open in my mail client, edit and send.
I can create a message in the Draft folder (or any other folder), I can set the FLAGGED flag using the UID, but I cannot set the message to Draft. I create the message with imap_append and set the flags with imap_setflag_full.
Either the setting of the \Draft flag is ignored or the \Draft flag is not the same as creating a message with the mail client and not sending it.
Is the first the case and am I overlooking something? Or is the later the case and am I expecting something IMAP / Exchange does not support?
Who has the experience to answer this?
As requested by cnd (base code without checks and validations):
// Create connection with the mail box
$this->o_mailbox = imap_open($o_company->draftbox, $o_company->username, $o_company->password);
// Create header
$a_header["from"] = $o_company->name.' <'.$o_company->address.'>';
$a_header["to"] = $s_to_name.' <'.$s_to_email.'>';
if(isset($s_cc)) $a_header["cc"] = $s_cc;
$a_header["subject"] = $s_subject;
// Add multipart to body
$a_body[0]["type"] = TYPEMULTIPART;
$a_body[0]["subtype"] = "mixed";
// Add content to body
$a_body[1]["type"] = TYPETEXT;
$a_body[1]["subtype"] = "html";
$a_body[1]["charset"] = "utf-8";
$a_body[1]["disposition.type"] = "inline";
$a_body[1]["description"] = "";
$a_body[1]["contents.data"] = str_replace('[BODY]', $s_message, $o_company->template);
// Loop trough the attachment
foreach ($a_attachments as $a_attachment) {
$a_part["type"] = TYPEAPPLICATION;
$a_part["encoding"] = ENCBINARY;
$a_part["subtype"] = "pdf";
$a_part["disposition.type"] = "attachment";
$a_part["description"] = $a_attachment['name'];
$a_part['disposition'] = array ('filename' => $a_attachment['name']);
$a_part['type.parameters'] = array('name' => $a_attachment['name']);
$a_part["contents.data"] = $a_attachment['data'];
$a_body[] = $a_part;
}
// Create message in the draft box
$o_message = imap_mail_compose($a_header, $a_body);
$b_result = imap_append($this->o_mailbox, $o_company->draftbox, $o_message);
I have been trying to setup up a system with this functionality:
Send email to my server
Server pipes email to php script
Php script parses email getting subject and body
Get phone number from subject of email and send text with email body
I have found an email parser here: https://github.com/daniele-occhipinti/php-email-parser
I think I have setup it up correctly but I do not know how to test it besides just sending an email. But I cannot see what my script echos at that point. Also when I do send the email I know something is not working because the text does not send via twilio. What am I doing wrong?
Here is the code:
#!/usr/bin/php -q
<?php
require_once '../resources/Twilio/autoload.php';
use Twilio\Rest\Client;
require('config.php');
// Retrieve Email
require_once("../resources/PlancakeEmailParser.php");
$email = "php://stdin";
$emailParser = new PlancakeEmailParser(file_get_contents($email));
$subject = $emailParser->getSubject();
$text = $emailParser->getPlainBody();
$number = preg_replace('/[^0-9]/', '', $subject);
$phone = "+".$number;
// After this I send the message via Twilio
You are piping the input so you probably need to buffer the stream to ensure you have received all the data before you try and process it.
Something like this:
$dataIn = fopen('php://stdin', 'r');
if ($dataIn) {
$email = '';
while($line = fgets($dataIn)) {
$email .= $line;
}
fclose($dataIn);
}
I'm currently building a php scripts which fetches the email from a server using imap functions and stores the details in the database.
My problem is I dont know how to identify new mails from old mails that already exists.
and how to get reply mails sent to the mail
use the UID message to determine the last message, you have to store the last UID in the table
$uidsArray = imap_sort($imapConnection, SORTARRIVAL, 1, SE_UID);
if ($uidsArray) {
// read UID last message, XEmailUID - table(mailbox, lastuid mailbox)
$lastUIDObject = new XEmailUID();
$lastUIDObject->setImap($mailbox->getId().'/'.$mailboxRef);
if (!$lastUIDObject->select()) {
$lastUIDObject->insert();
}
$uidMax = 0;
foreach ($uidsArray as $uid) {
if ($uid < $lastUIDObject->getUid()) {
continue;
}
if ($uid >= $uidMax) {
$uidMax = $uid;
}
// your function
$this->_readIMAPMessage(
$imapConnection,
$uid,
$mailboxRef
);
}
if ($uidMax > 0) {
$lastUIDObject->setUid($uidMax);
$lastUIDObject->update();
}
}
I am using this code to send email to my list using my server.
after a while as my list of email is large, the script get timeout.
is there a solution to this problem?
other thing i don't want to overload the server. Is there a code i can add to my script to load each email with a time between each line?
here is the php script i am using
<?php
$emailaddress = file("email-list.txt"); // load from a flat file, assuming 1 email per line in the file
$emailsubject = "[title] title of my email";
$emailbody = file_get_contents("email-content.html");
$fromaddress = "my#3emailserver.com";
$i = count($emailaddress);
$z = 0;
// here we check how many email address's we have, if its is 0, then we don't start the email function
if ($i != 0)
{// start if
// Lets loop until we reach the count from email address arrar
while ($i != $z)
{// start while
// here we send the email to the varables from above, using the email array incrament
mail($emailaddress[$z], $emailsubject, $emailbody, "From: " .$fromaddress. "\nX-Mailer: PHP 4.x");
// lets echo out that the email was sent
echo $z + 1 . " out of " . $i . " emails sent. (" . $emailaddress[$z] . ")<br>";
// increment the array one, so we get a new email address from the array
++$z;
}// end while
}//end if
else
{//start else
// we echo out that no emails where found in the array and end the script
echo "Warning: No emails in array.";
}// end else
?>
use
// sleep for 10 seconds
sleep(10);
after mail fire.
By default in php.ini, max_execution_time is set to 30 seconds. (check this in your php.ini)
Use set_time_limit function to alter that time (0=NOLIMIT):
set_time_limit(0);
Or use ini_set function:
ini_set('max_execution_time', 0);
I'm trying to build a small webmail app. When I read all the emails in inbox I want to show for each mail if it has attachments. This works, but the problem is that it takes to long to do that, about 0.5 secs for 1Mb email attach. Multiply that with all emails in inbox that have big attach files :|
My question is: How to check if an email has attach withouth loading the whole email ? Is that possible ?
Bellow is the code I'm using now:
function existAttachment($part)
{
if (isset($part->parts))
{
foreach ($part->parts as $partOfPart)
{
$this->existAttachment($partOfPart);
}
}
else
{
if (isset($part->disposition))
{
if ($part->disposition == 'attachment')
{
echo '<p>' . $part->dparameters[0]->value . '</p>';
// here you can create a link to the file whose name is $part->dparameters[0]->value to download it
return true;
}
}
}
return false;
}
function hasAttachments($msgno)
{
$struct = imap_fetchstructure($this->_connection,$msgno,FT_UID);
$existAttachments = $this->existAttachment($struct);
return $existAttachments;
}
To check whether the email has attachment, use $structure->parts[0]->parts.
$inbox = imap_open($mailserver,$username, $password, null, 1, ['DISABLE_AUTHENTICATOR' => 'PLAIN']) or die(var_dump(imap_errors()));
$unreadEmails = imap_search($inbox, 'UNSEEN');
$email_number = $unreadEmails[0];
$structure = imap_fetchstructure($inbox, $email_number);
if(isset($structure->parts[0]->parts))
{
// has attachment
}else{
// no attachment
}
imap_fetchstructure does fetch the whole email content in order to analyze it. Sadly there is no other way to check for attachment.
Maybe you can use the message size info from imap_headerinfo to get a prediction if the message will have attachments.
Another way is to fetch the emails in an regular interval in the background and store them with their content and UID for later lookup in a database. You need to do that later anyway when you want so search for specific messages. (You do not want to scan the while imap account when searching for "dinner")