I'm trying to get 'email message' from any Email Service Provider, like: yahoo, Gmail, Hotmail. But I can't get it. It's show error message.
Following is my php script..
<?php
if( $mbox = imap_open("{yoursitename.com:110/pop3/notls}INBOX", "username of mailbox",
"password of mailbox")){
$path = "set path here for where the attachments are store";
$check = imap_mailboxmsginfo($mbox);
function getmsg($mbox,$mid) {
global $charset,$htmlmsg,$plainmsg,$attachments,$from,$to,$subj,$timages,$path;
$htmlmsg = $plainmsg = $charset = '';
$attachments = array();
// HEADER
$h = imap_headerinfo($mbox,$mid);
// add code here to get date, from, to, cc, subject...
$date = $h->date;
$from = $h->fromaddress;
$to = $h->toaddress;
$subj = htmlspecialchars($h->Subject);
// BODY
$s = imap_fetchstructure($mbox,$mid);
if (!$s->parts) // simple
getpart($mbox,$mid,$s,0); // pass 0 as part-number
else { // multipart: cycle through each part
foreach ($s->parts as $partno0=>$p)
getpart($mbox,$mid,$p,$partno0+1);
}
}
function getpart($mbox,$mid,$p,$partno) {
// $partno = '1', '2', '2.1', '2.1.3', etc for multipart, 0 if simple
global
$htmlmsg,$plainmsg,$charset,$attachments,$partid,$last_mail_id,$patterns,$pic,
$newstr,$c,$ok,$timages,$subj,$path;
$patterns = array();
$pic = array();
$image=array();
$data = ($partno) ? imap_fetchbody($mbox,$mid,$partno) : imap_body($mbox,$mid);
// simple
if ($p->encoding==4)
$data = quoted_printable_decode($data);
else if ($p->encoding==3)
$data = base64_decode($data);
// PARAMETERS // get all parameters, like charset, filenames of attachments,
etc.
$params = array();
if ($p->parameters)
foreach ($p->parameters as $x)
$params[strtolower($x->attribute)] = $x->value;
if ($p->dparameters)
foreach ($p->dparameters as $x)
$params[strtolower($x->attribute)] = $x->value;
// ATTACHMENT // Any part with a filename is an attachment,
// so an attached text file (type 0) is not mistaken as the message.
if ($params['filename'] || $params['name']) {
$partid = htmlentities($p->id,ENT_QUOTES);
// filename may be given as 'Filename' or 'Name' or both
$filename = ($params['filename'])? $params['filename'] : $params['name'];
// filename may be encoded, so see imap_mime_header_decode()
$attachments[$filename] = $data; // this is a problem if two files have same name
//store id and filename in array
$image[$key] = $filename;
}
//save the attachments in the directory
foreach( $attachments as $key => $val){
$fname = $key;
$fp = fopen("$path/$fname","w");
fwrite($fp, $val);
fclose($fp);
}
// TEXT
if ($p->type==0 && $data) {
// Messages may be split in different parts because of inline attachments,
// so append parts together with blank row.
if (strtolower($p->subtype)=='plain')
$plainmsg .= trim($data)."\n\n";
else
//preg_match_all('/<img[^>]+>/i',$data, $result);
$htmlmsg .= $data."<br><br>";
$charset = $params['charset']; // assume all parts are same charset
}
// There are no PHP functions to parse embedded messages, so this just appends the
raw source to the main message.
else if ($p->type==2 && $data) {
$plainmsg .= $data."\n\n";
}
// SUBPART RECURSION
if ($p->parts) {
foreach ($p->parts as $partno0=>$p2)
getpart($mbox,$mid,$p2,$partno.'.'.($partno0+1)); // 1.2, 1.2.1, etc.
}
}
$attachments = array();
$num_msg = imap_num_msg($mbox);
if($num_msg>0) {
getmsg($mbox,1);
}else {
echo "Sorry!...No Messages in MailBox...<br>";
}
//imap_delete and imap_expunge are used to delete the mail after fetching....Uncomment
it if you want to delete the mail from mailbox
//imap_delete($mbox,1);
//imap_expunge($mbox);
imap_close($mbox);
}else { exit ("Can't connect: " . imap_last_error() ."\n"); echo "FAIL!\n"; };
?>
error message:
Warning: imap_open() [function.imap-open]: Couldn't open stream {yahoo.com:110/pop3
/notls}INBOX in D:\xampp server\xampp\htdocs\practice\php\email.php on line 2
Fatal error: Maximum execution time of 30 seconds exceeded in D:\xampp server\xampp
\htdocs\practice\php\email.php on line 2
Notice: Unknown: Can't connect to yahoo.com,110: Timed out (errflg=1) in Unknown on
line 0
Notice: Unknown: Can't connect to yahoo.com,110: Timed out (errflg=1) in Unknown on
line 0
Notice: Unknown: Can't connect to yahoo.com,110: Timed out (errflg=2) in Unknown on line 0
Can anyone fix it?
Thanks.
As arkascha said, yahoo.com doesn't listen on port 110.
Yahoo's POP3 server is pop.mail.yahoo.com on port 110 (or 995 with SSL) as stated in this Yahoo help article
Related
I face this problem. When i try to open the file list in other server which is 10.200.4.202. The error below appears.
When I try using a local host, the file list can be viewed normally. I think the code is not the error but the server setting is not right.
I used IIS 10.0, PHP 7.3.15
This is what appears on web
status[parsererror] content[SyntaxError: Unexpected token < in JSON at position 0]
and this is the error in f12
Warning:
opendir(\\10.200.4.202\y\1.InspCheckSheet_PDF\log,\\10.200.4.202\y\1.InspCheckSheet_PDF\log): Access is denied. (code: 5) in C:\PGMPIS_Web\public_html\ics_filing\loglist_sub.php on line 68
Warning:
opendir(\\10.200.4.202\y\1.InspCheckSheet_PDF\log): failed to open dir: Bad file descriptor in C:\PGMPIS_Web\public_html\ics_filing\loglist_sub.php
on line 68
{"querytime":"2020-05-14 09:58:50","other_status":"ERR","errmsg":""}
Here's the code
<?php
$dir_log = '\\\\10.200.4.202\\y\\1.InspCheckSheet_PDF\\log';
require_once 'Log.php';
$log = Log::factory('file', 'log/okaspe.log', 'loglist_sub'); //$log->log('teeeeest!');
//$type = $_REQUEST['type'];
try{
// Set query_time
$emsg = "";
$now = new DateTime();
$res['querytime'] = $now->format('Y-m-d H:i:s');
//$res['querytime'] = $now->format('Y-m-d g:i:s A');
// Obtain log file name list → $fn[]
$cnt = $pos = 0;
unset($fn); // clear $fn for safety
if( $dir = opendir($dir_log) ) { // add # infront of opendir by asyraf
while (($file = readdir($dir)) !== false ) {
$pos = strpos ($file, 'main_'); // faster than preg_match() for simple search
if( $pos !== false && $pos == 0) {
$cnt++;
$fn[] = $file;
}
}
closedir($dir);
} else {
throw new Exception("Obtain Log File List failed......");
}
// sort in descending order
rsort($fn); //$log->log( print_r($fn, true) );
//set response
$res['list'] = $fn;
$res['cnt'] = $cnt;
} catch( Exception $e ) {
// Functional Err exception
$res["other_status"] = "ERR";
$res["errmsg" ] = $emsg;
$log->log($e->getMessage(), PEAR_LOG_ERR); // logging
} finally {
//DB disconnect (absolutely and always)
$pdo = null;
// Response in Json
header('Content-Type: application/json; charset=utf-8');
$json = json_encode( $res ); //$log->log($json, PEAR_LOG_ERR);
echo $json;
}
exit;
?>
I am using pdftk library for modify the pdf files. but i am getting the chmod(): Invalid argument error.
Following is my code :
include('fillpdf/createXFDF.php');
$fdf_file = 'fillpdf/acord.fdf';
$acord = array();
$acord['******'] = 'a';
$acord['******'] = 'a';
$pdf_file_url = 'http://localhost/******/fillpdf/Cancellation.pdf';
$fdf = createXFDF( $pdf_file_url, $acord );
// print_r($fdf); die;
if ($fp = fopen($fdf_file, 'w')) {
chmod($fdf, 777);
fwrite($fp, $fdf, strlen($fdf));
$CREATED = TRUE;
} else {
echo 'Unable to create file: ' . $fdf_file . '<br><br>';
$CREATED = FALSE;
}
// var_dump($CREATED); die;
fclose($fp);
$command = '"C:\\Program Files (x86)\\PDFtk\\bin\\pdftk.exe" C:\\xampp\\htdocs\\*******\\fillpdf\\Cancellation.pdf fill_form acord.fdf output C:\\xampp\\htdocs\\*******\\fillpdf\\Cancellation_new.pdf';
exec($command);
I have given all the necessary permission to folder and files. but don't know what is wrong??
Thanks in advance!!!
Why you need to give chmod($fdf,0777); to $fdf. It's not even the file. as per your code the $fdf = createXFDF( $pdf_file_url, $acord ); is calling function and it's not file. so just comment the chmod($fdf,0777); line and check your code is working or not??
Hope it helps!!!
Try like this...For chmod() function first number is always zero.
chmod(file,mode);
The mode parameter consists of four numbers:
1.The first number is always zero
2.The second number specifies permissions for the owner
3.The third number specifies permissions for the owner's user group
4.The fourth number specifies permissions for everybody else
include('fillpdf/createXFDF.php');
$fdf_file = 'fillpdf/acord.fdf';
$acord = array();
$acord['******'] = 'a';
$acord['******'] = 'a';
$pdf_file_url = 'http://localhost/******/fillpdf/Cancellation.pdf';
$fdf = createXFDF( $pdf_file_url, $acord );
// print_r($fdf); die;
if ($fp = fopen($fdf_file, 'w')) {
chmod($fdf,0777);
fwrite($fp, $fdf, strlen($fdf));
$CREATED = TRUE;
} else {
echo 'Unable to create file: ' . $fdf_file . '<br><br>';
$CREATED = FALSE;
}
// var_dump($CREATED); die;
fclose($fp);
$command = '"C:\\Program Files (x86)\\PDFtk\\bin\\pdftk.exe" C:\\xampp\\htdocs\\*******\\fillpdf\\Cancellation.pdf fill_form acord.fdf output C:\\xampp\\htdocs\\*******\\fillpdf\\Cancellation_new.pdf';
exec($command);
I'm trying to create a piece of code that will go into the mailbox and take out the attachments of a specific file. So far I am only able to view if there is an attachment or if there is not an attachment on the e-mail.
But I want it to be able to take the attachments out of the e-mail and then save them to a specified directory. The type of attachment I'm trying to take out is a .jpg
I've tried a bunch of different pieces of code that I've found on google and I've been trying to tailor it to fit into my code, but so far I have been unsuccessful in finding anything that works correctly.
I was wondering if anyone would be able to help me create a piece of code that would be able to take the attachments out of the emails and store them in a directory.
Thanks.
<?php
/* connect to email */
$hostname = '{*****.com:110/pop3}INBOX';
$username = '*****';
$password = '*****';
// try to connect
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to server: ' . imap_last_error());
// grab emails
$emails = imap_search($inbox,'ALL');
// Search for the 39th email, which has an attachment
$count = 39;
// Fetch all the information about an email
$attachment = imap_fetchstructure($inbox, $count);
// find out how may parts the object has
$numparts = count($attachment->parts);
// find if if multipart message
if ($numparts >= 2) {
foreach ($attachment->parts as $part) {
if ($part->disposition == "INLINE") {
// inline message. Show number of lines
printf("Inline message has %s lines<BR>", $part->lines);
} elseif ($part->disposition == "ATTACHMENT") {
// an attachment
echo "Attachment found!";
// print out the file name
echo "Filename: ", $part->dparameters[0]->value;
}
}
}
//}
else {
// only one part so get some useful info
echo "No attachment";
}
imap_close($imap);
?>
Instead of imap_search I used imap_check to retrieve messages overview, and the following worked.
Go over messages found with imap_check, and this is how you extract the binary data of attachment:
$mbox = imap_open( . . . . );
$IMAPobj = imap_check($inbox);
$start = $IMAPobj->Nmsgs-30;
$end = $IMAPobj->Nmsgs;
$result = imap_fetch_overview($inbox,"$start:$end",0);
$count = $end;
foreach ($result as $overview) {
$parts = mail_mime_to_array($inbox, $count);
foreach($parts as $part) {
if(#$part['filename'] || #$part['name'] ) {
$partName = $part['filename'] ? $part['filename'] : $part['name'];
echo "Attachment name is " . basename($partName);
echo "\n";
if(preg_match( . . . write here a regex to detect ".jpg" in $partName . . .)) {
echo "Found file! Extracting binary data...";
$fileContents = $part['data'];
file_put_contents("attachment.jpg", $fileContents);
}
}
}
}
I am piping an email to a program and running some code.
**
I know how to get the "From:" and the "Subject:" but how do I get only the body of the email?
**
#!/usr/bin/php -q
<?
$fd = fopen("php://stdin", "r");
while (!feof($fd)) {
$email .= fread($fd, 1024);
}
fclose($fd);
$lines = explode("\n", $email);
for ($i=0; $i < count($lines); $i++)
{
// look out for special headers
if (preg_match("/Subject:/", $lines[$i], $matches))
{
list($One,$Subject) = explode("Subject:", $lines[$i]);
list($Subject,$Gone) = explode("<", $Subject);
}
etc... HOW DO I GET THE BODY CONTENT OF THE EMAIL?
Basically, you want where the headers end, and to know if it's multipart or not so you can get the right portion(s) of the email.
Here is some information:
parsing raw email in php
Which says that the first double newline should be the beginning of the body of the email.
This page might give you some other ideas (see script below):
http://thedrupalblog.com/configuring-server-parse-email-php-script
#!/usr/bin/php
<?php
// fetch data from stdin
$data = file_get_contents("php://stdin");
// extract the body
// NOTE: a properly formatted email's first empty line defines the separation between the headers and the message body
list($data, $body) = explode("\n\n", $data, 2);
// explode on new line
$data = explode("\n", $data);
// define a variable map of known headers
$patterns = array(
'Return-Path',
'X-Original-To',
'Delivered-To',
'Received',
'To',
'Message-Id',
'Date',
'From',
'Subject',
);
// define a variable to hold parsed headers
$headers = array();
// loop through data
foreach ($data as $data_line) {
// for each line, assume a match does not exist yet
$pattern_match_exists = false;
// check for lines that start with white space
// NOTE: if a line starts with a white space, it signifies a continuation of the previous header
if ((substr($data_line,0,1)==' ' || substr($data_line,0,1)=="\t") && $last_match) {
// append to last header
$headers[$last_match][] = $data_line;
continue;
}
// loop through patterns
foreach ($patterns as $key => $pattern) {
// create preg regex
$preg_pattern = '/^' . $pattern .': (.*)$/';
// execute preg
preg_match($preg_pattern, $data_line, $matches);
// check if preg matches exist
if (count($matches)) {
$headers[$pattern][] = $matches[1];
$pattern_match_exists = true;
$last_match = $pattern;
}
}
// check if a pattern did not match for this line
if (!$pattern_match_exists) {
$headers['UNMATCHED'][] = $data_line;
}
}
?>
EDIT
Here is a PHP extension called MailParse:
http://pecl.php.net/package/mailparse
Somebody has built a class around it called MimeMailParse:
http://code.google.com/p/php-mime-mail-parser/
And here is a blog entry discussing how to use it:
http://www.bucabay.com/web-development/a-php-mime-mail-parser-using-mailparse-extension/
I have set email interception on my server.
following is my email forwarder set on server
testemail#my.server.com,"/home/server/php_pipe_mail.php"
following is my code for php_pipe_mail.php
#!/usr/bin/php -q
<?php
require_once('mimeDecode.php');
include('sql-connect.php');
error_reporting(E_ALL);
ob_start();
$raw_email = '';
if (!$stdin = fopen("php://stdin", "R"))
{
echo "ERROR: UNABLE TO OPEN php://stdin \n";
}
// ABLE TO READ THE MAIL
else
{
while (!feof($stdin))
{
$raw_email .= fread($stdin, 4096);
}
fclose($stdin);
}
$raw_email = preg_replace('/ +/', ' ', $raw_email);
var_dump($raw_email);
$buf = ob_get_contents();
$params['include_bodies'] = true;
$params['decode_bodies'] = true;
$params['decode_headers'] = true;
$params['input'] = $buf;
$params['crlf'] = "\r\n";
//Creating temp file on server
$myFile = "amail.txt";
$fh = fopen($myFile, 'w') or die("can't open file");
fwrite($fh, $buf);
fclose($fh);
//Generating mail structure in object format
$structure = Mail_mimeDecode::decode($params);
$attachment = array();
$mail_date= date( 'Y-m-d H:i:s', strtotime($structure->headers['date']) );
$from = $structure->headers['from'];
$to = $structure->headers['to'];
$subject = htmlentities($structure->headers['subject'],ENT_QUOTES);
if($structure->ctype_primary == "multipart")
{
$body_text = $structure->parts[0]->parts[0]->body;
$body_html = $structure->parts[0]->parts[1]->body;
$x = 0;
//fetch attachment
foreach ($structure->parts as $part) {
// only save if an attachment
if (isset($part->disposition) and ($part->disposition=='attachment')) {
$attachment[$x]["filename"] = $part->d_parameters['filename'];
$attachment[$x]["content_type"] = $part->ctype_primary . "/" . $part->ctype_secondary;
$attachment[$x]["body"] = addslashes($part->body);
$x++;
}
}
}
else
{
$body_text = $structure->parts[0]->body;
$body_html = $structure->parts[1]->body;
}
$qry1 = "insert into mail_buffer(mail_date,mail_from, mail_to,mail_subject,mail_text_body,mail_html_body) Values('". $mail_date ."','".$from."','".$to."','".$subject."','".$body_text."','".$body_html."')";
mysql_query($qry1) or die(mysql_error($con));
$last_id = mysql_insert_id();
if(count($attachment) > 0)
{
for($i=0; $i < count($attachment); $i++)
{
$qry = "insert into mail_attachment(email_id,content_type, file_name,body) Values('". $last_id ."','".$attachment[$i]['content_type']."','".$attachment[$i]['filename']."','".$attachment[$i]['body']."')";
mysql_query($qry) or die(mysql_error($con));
}
}
mysql_close($con);
ob_end_clean();
?>
Now above script works perfectly fine.
I am able to fetch message header, body and attachments and can store them in database without any problems.
When email without attachments come everything works fine and email is delivered to email address I am intercepting.
But following is not working.
When email with attachments comes than email content is being stored in database but email is not delivering to email address I am intercepting and I am getting following error message in bounce back email.
A message that you sent could not be delivered to one or more of its
recipients. This is a permanent error. The following address(es) failed:
pipe to |/home/server/php_pipe_mail.php
generated by testemail#my.server.com
Can anyone help me regarding the matter.
Thanks.
Could it be that, when an attachment is present, your script is echoing something? I have had problems piping emails before, and seen failure messages returned to senders, and they have been due to the piping script producing some kind of output. Maybe your error_reporting(E_ALL); is allowing the script to produce an output - try error_reporting(0);