gmail api strait forward way to get sender email - php

I’m having problems getting the sender's email address,
$single_message = $gmail->users_messages->get('me', $msg_id);
"from" usually yields the senders name
To get the email address I have this code
if($partes->getName() == 'Authentication-Results')
{
$outh_res = $partes->getValue();
if(strpos($outh_res, 'smtp.mailfrom=') !== false)
{
$bits = explode('smtp.mailfrom=',$outh_res);
$mail = $bits[1];
if(strpos($mail, ';') !== false)
{
$bits = explode(';',$mail);
$mail = str_replace('"', '',$bits[0]);
}
}
}
That always gives me an email, but when the sender is behind mail chimp (or their own servers (postfix)) for example: bounces+2063633-785c-info=myemail.com#sg1.senderemail.com
In the best case I receive #sendermail.com (from gmail itself I know its info#sendermail.com) so it's useless
In some cases
if($partes->getName() == 'Reply-To')
{
$other_mail = str_replace('"', '',$partes->getValue());
}
Gives me a helpful email others just the senders name
as suggested in github php gmail api issue # 521 and other places
$only_header = $gmail->users_messages->get('me',$msg_id, ['format' => 'metadata', 'metadataHeaders' => ['To','X-Original-To','X-Original-From','From','Reply-To','Subject']]);
It gives exactly the same info.
Is there any way that the api gives me exactly the sender email address even if it's behind mail chimp or other 3rd party sender?
There's a similar answer Get sender email from gmail-api, I already loop the headers and tried zingzinco's answer.
Edit: Thanks to Joey Tawadrous;
Php code:
if($partes->getName() == 'From')
{
$raw_from = $partes->getValue();
if(strpos($raw_from, '<') !== false)
{
$bit = explode('<',$raw_from);
$bit2 = explode('>',$bit[1]);
$final_email = $bit2[0];
$sender_name = str_replace('"', '',$bit[0]);
}
else
{
$sender_name = limpiarm(str_replace('"', '',$raw_from));
}
}

var email = '';
var messageFrom = _.where(message.payload.headers, {name: 'From'})[0].value;
if(messageFrom.includes('<')) {
var fromObj = messageFrom.split('<');
email = fromObj[1];
fromObj = email.split('>');
email = fromObj[0];
}
return email;

Related

Error when no mail is inserted in form, using phpmailer

I am having trouble with a form, when the user mail is not inserted, it always return the error message "Invalid address: email". I understand $reg_email variable is being used in other functions to send the mail to the user, so I realize I must write a condition that says that when the reg_email variable is empty, it must return a value that wont cause that error. But I dont know how to translate that logic to PHP. What should I do?
<?php
ini_set('display_errors', 1);
session_start();
if($_SESSION['input_flag']) {
unset($_SESSION['input_flag']);
}else{
header('location: /');
}
$path = realpath(dirname(__FILE__) . '') . "/../";
include_once($path.'app_config.php');
include($path.'libs/meta.php');
//設定
require('./jphpmailer.php');
$script = "index.php";
$gtime = time();
$reg_name = isset($_POST['f_name']) ? htmlspecialchars($_POST['f_name']): "";
if (isset($_POST['f_company']) && !empty($_POST['f_company'])) {
$f_company .= "■会社名"."\r\n" . $_POST['f_company'];
}
$f_adress = isset($_POST['f_adress']) ? htmlspecialchars($_POST['f_adress']): "";
$f_select = '';
if (!empty($_POST['select'])) {
foreach ($_POST['select'] as $key => $value) {
$f_select .= "設置されている消防設備"."\r\n" . $_POST['f_select'];
}
}
$f_tel = isset($_POST['f_tel']) ? htmlspecialchars($_POST['f_tel']): "";
// $reg_email = isset($_POST['f_mail']) ? htmlspecialchars($_POST['f_mail']): "";
if (isset($_POST['f_mail']) || !empty($_POST['f_mail'])) {
$reg_email .= "email"."\r\n" . $_POST['f_mail'];
}
$f_select2 = '';
foreach ($_POST['select2'] as $key => $value) {
$f_select2 .= $value."\r\n";
}
$f_request = isset($_POST['f_request']) ? htmlspecialchars($_POST['f_request']): "";
$aMailto = array(
"xxxxxx"
);
$from = "xxxxxx";
$fromname = '';
$subject1 = 'test';
$subject = 'test';
$entry_time = gmdate("Y/m/d H:i:s",time()+9*3600);
$entry_host = gethostbyaddr(getenv("REMOTE_ADDR"));
$entry_ua = getenv("HTTP_USER_AGENT");
$msgBody = "";
$msgBody .= "
■お名前
$reg_name
$f_company
■建物の所在地
$f_adress
$f_select
■お電話番号
$f_tel
$reg_email
■ご希望の連絡方法
$f_select2
■お問い合わせ内容
$f_request
";
//お問い合わせメッセージ送信
$subject = "ホームページからお問い合わせがありました";
$body = "
登録日時:$entry_time
ホスト名:$entry_host
ブラウザ:$entry_ua
ホームページからお問い合わせがありました。
$msgBody
";
//Message for the user
$subject1 = "お問い合わせありがとうございました";
$body1 = "
$reg_name 様
$msgBody
";
// メール送信
mb_language("ja");
mb_internal_encoding("UTF-8");
$fromname = "";
//お客様受け取りメール送信
$email1 = new JPHPmailer();
$email1->addTo($reg_email);
$email1->setFrom($from,$fromname);
$email1->setSubject($subject1);
$email1->setBody($body1);
//if($email1->send()) {};
//Anti spam advanced version 2 start: Don't send blank emails
if( $reg_name <> "" && $reg_email <> "" ) {
//Anti spam advanced version 1 start: The preg_match() is there to make sure spammers can’t abuse your server by injecting extra fields (such as CC and BCC) into the header.
if( $reg_email && !preg_match( "/[\r\n]/", $reg_email) ) {
//Anti spam part1: the contact form start
if($reg_url == ""){
// then send the form to your email
if($email1->Send()) {};
} // otherwise, let the spammer think that they got their message through
//Anti spam part1: the contact form end
}//Anti spam advanced version 1 end
}//Anti spam advanced version 2 end: Don't send blank emails
//メール送信
$email = new JPHPmailer();
for($i = 0; $i < count($aMailto); $i++)
{
$email->addTo($aMailto[$i]);
}
$email->setFrom($reg_email, $reg_name."様");
$email->setSubject($subject);
$email->setBody($body);
//if($email->Send()) {};
//Anti spam advanced version 2 start: Don't send blank emails
if( $reg_name <> "" && $reg_email <> "" ) {
//Anti spam part1: the contact form start
if($reg_url == ""){
// then send the form to your email
if($email->Send()) {};
} // otherwise, let the spammer think that they got their message through
//Anti spam part1: the contact form end
}//Anti spam advanced version 2 end: Don't send blank emails
?>
It's because you're doing this:
$reg_email .= "email"."\r\n" . $_POST['f_mail'];
the word email, followed by a line break, followed by an email address is not itself a valid email address, so will be rejected with the error you're seeing. You're also appending to a variable that has not yet been defined. Do this instead:
$reg_email = $_POST['f_mail'];
I'm also puzzled by this:
$email->addTo($aMailto[$i]);
PHPMailer uses addAddress, not addTo, so unless that's a new method or alias in your JPHPmailer subclass, it's wrong.
Also, don't do this:
$email->setFrom($reg_email, $reg_name."様");
This is forgery and will result in your message being bounced or spam filtered by recipients. Do this instead:
$email->setFrom('myemail#example.com', $reg_name."様");
$email->addReplyTo($reg_email, $reg_name."様");
That is, send from your own address and use the submitter's address as a reply-to.

How to change a pipe-forwarded email's "From" and "To" section in PHP

I am trying to mask emails. Basically give an email to a client like "RandomName#MyDomain.com" and have it forward "MyRealEmail#MyDomain.com".
I am pipe forwarding the emails to a php script on my server, where I want to use the "To" and "From" to find the real recipient of the message and forward the message to them removing any identifiable information from the Sender (From) section.
I can parse almost all the data right now from the header, but my problem is with the body. The html body portion can vary so much from different origins. Outlook have a <html> and <body> section, while Gmail just has <div>s. Regardless, I get these strange "=" signs in my raw email too, in both text and html sections, like <=div>!
I just want to change the "From" and "To" and keep the rest of the email pretty much exactly as it is so it doesn't have anomalies in its text or html section.
How can I do this? Should I just parse the raw email and change the occurrences of the emails? how can I send it then? or should I remake the email using phpmailer or some other class? how can i get the body correct then?
My hosting provider doesn't have MailParse extension installed, since I have seen some solutions on the site using that extension, so I am having to do this using available extensions in PHP 5.5
UPDATE
I managed to figure out the = issue, it was quoted-printable, so now I am calling quoted_printable_decode() to resolve that issue. Still trying to figure the best way to forward the email after altering the header though.
After a lot of failed attempts, finally have a solution I can live with. The host server didn't want to allow MailParse because it was an issue on their shared hosting environment, so I went with Mail_mimeDecode and Mail_MIME PEAR extensions.
// Read the message from STDIN
$fd = fopen("php://stdin", "r");
$input = "";
while (!feof($fd)) {
$input .= fread($fd, 1024);
}
fclose($fd);
$params['include_bodies'] = true;
$params['decode_bodies'] = true;
$params['decode_headers'] = true;
$decoder = new Mail_mimeDecode($input);
$structure = $decoder->decode($params);
// get the header From and To email
$From = ExtractEmailAddress($structure->headers['from'])[0];
$To = ExtractEmailAddress($structure->headers['to'])[0];
$Subject = $structure->headers['subject'];
ExtractEmailAddress uses a solution from "In PHP, how do I extract multiple e-mail addresses from a block of text and put them into an array?"
For the Body I used the following to find the text and html portions:
$HTML = "";
$TEXT = "";
// extract email body details
foreach($structure as $K => $V){
if(is_array($V)){
foreach($V as $KK => $VV){
if(is_object($VV)){
$bodyHTML = false;
$bodyPLAIN = false;
foreach($VV as $KKK => $VVV){
if(!is_array($VVV)){
if($KKK === 'ctype_secondary'){
if($VVV === 'html') { $bodyHTML = true; }
if($VVV === 'plain') { $bodyPLAIN = true; }
}
if($KKK === 'body'){
if($bodyHTML){
$bodyHTML = false;
$HTML .= quoted_printable_decode($VVV);
}
if($bodyPLAIN){
$bodyPLAIN = false;
$TEXT .= quoted_printable_decode($VVV);
}
}
}
}
}
}
}
}
Finally, I had the parts I needed so I used Mail_MIME to get the message out. I do my database lookup logic here and find the real destination and masked From email address using the From and To I extracted from the header.
$mime = new Mail_mime(array('eol' => "\r\n"));
$mime->setTXTBody($TEXT);
$mime->setHTMLBody($HTML);
$mail = &Mail::factory('mail');
$hdrs = array(
'From' => $From,
'Subject' => $Subject
);
$mail->send($To, $mime->headers($hdrs), $mime->get());
I don't know if this will cover all cases of email bodies, but since my system is not using attachments I am ok for now.
Take not of quoted_printable_decode(), that how I fixed the issue with the = in the body.
The only issue is the delay in mail I am having now, but I'll deal with that

How do i look up an email address form its header?

I'm currently using the following function to check valid email provider-
function chkEmailProvider($hn, $rt = ''){
if( $rt == '' ) $rt = "MX";
exec("nslookup -type=$rt $hn", $result);
foreach ($result as $line) {
if(eregi("^$hn",$line)) {
return true;
}
}
return false;
}
But don't know how to get email sender details from email header. Could you please help me? How to do that?
Again is that possible to check the availability of an email address?
Looking forward to your valuable solutions..
Thanks in advance.
Many shared hosting environments disable exec. Consdier using checkdnsrr instead
function chkEmailProvider($hn, $rt = ''){
if( $rt == '' ) $rt = "MX";
return checkdnsrr($hn, $rt);
}
As to checking if the email itself is valid... that's difficult without actually sending an email to the server and checking for a bounce (which might earn you a spot on a spam list)

Find E-Mails with an exact e-mail address on an IMAP server using PHP

I want to connect to an IMAP-server and find all E-Mails that were sent to abc#server.tld. I tried:
$mbox = imap_open("{imap.server.tld/norsh}", "imap#server.tld", "5ecure3");
$result = imap_search($mbox, "TO \"abc#server.tld\"", SE_UID);
but this also listed e-Mails that were sent e.g. to 123abc#server.tld. Is it somehow possible to do a search for exact matches?
Short answer: you can't. I didn't find anything in RFC 2060 - Internet Message Access Protocol - Version 4rev1 saying that it can be done.
But, there is a workaround. First fetch all emails that contain abc#server.tld, then iterate through the results and select only the exact matches.
$searchEmail = "abc#server.tld";
$emails = imap_search($mbox, "TO $searchEmail");
$exactMatches = array();
foreach ($emails as $email) {
// get email headers
$info = imap_headerinfo($mbox, $email);
// fetch all emails in the TO: header
$toAddresses = array();
foreach ($info->to as $to) {
$toAddresses[] = $to->mailbox . '#' . $to->host;
}
// is there a match?
if (in_array($searchEmail, $toAddresses)) {
$exactMatches[] = $email;
}
}
Now you have all emails matching abc#server.tld in $exactMatches

Creating a Craigslist Anonymous Email Forwarding Program

The following program is intended to match incoming email aliases with those in the database, and forward the email to the right address, like Craigslist does.
I am now getting this error:
Error: [1] You must provide at least one recipient email address.
in anon-email.php at line number: sending the email
Here is the code:
$mailboxinfo = imap_mailboxmsginfo($connection);
$messageCount = $mailboxinfo->Nmsgs; //Number of emails in the inbox
for ($MID = 1; $MID <= $messageCount; $MID++)
{
$EmailHeaders = imap_headerinfo($connection, $MID); //Save all of the header information
$Body = imap_qprint(imap_fetchbody($connection, $MID, 1)); //The body of the email to be forwarded
$MessageSentToAllArray = $EmailHeaders->to; //Grab the “TO” header
$MessageSentToAllObject = $MessageSentToAllArray[0];
$MessageSentToMailbox = $MessageSentToAllObject->mailbox ."#". $MessageSentToAllObject->host; //Everything before and after the “#” of the recipient
$MessageSentFromAllArray = $EmailHeaders->from; //Grab the “FROM” header
$MessageSentFromAllObject = $MessageSentFromAllArray[0];
$MessageSentFromMailbox = $MessageSentFromAllObject->mailbox ."#". $MessageSentFromAllObject->host; //Everything before and after the “#” of the sender
$MessageSentFromName = $MessageSentFromAllObject->personal; //The name of the person who sent the email
$toArray = searchRecipient($MessageSentToMailbox); //Find the correct person to send the email to
if($toArray == FALSE) //If the alias they entered doesn’t exist…
{
$bounceback = 'Sorry the email in your message does not appear to be correct';
/* Send a bounceback email */
$mail = new PHPMailer(); // defaults to using php “mail()”
$mail -> ContentType = 'text/plain'; //Plain email
$mail -> IsHTML(false); //No HTML
$the_body = wordWrap($bounceback, 70); //Word wrap to 70 characters for formatting
$from_email_address = 'name#domain.com';
$mail->AddReplyTo($from_email_address, "domain.Com");
$mail->SetFrom($from_email_address, "domain.Com");
$address = $MessageSentFromMailbox; //Who we’re sending the email to
$mail->AddAddress($address, $MessageSentFromName);
$mail->Subject = 'Request'; //Subject of the email
$mail->Body = $the_body;
if(!$mail->Send()) //If the mail fails, send to customError
{
customError(1, $mail->ErrorInfo, "anon-email.php", "sending the email");
}
}
else //If the candidate address exists, forward on the email
{
$mail = new PHPMailer(); // defaults to using php “mail()”
$mail -> ContentType = 'text/plain'; //Plain E-mail
$mail -> IsHTML(FALSE); //No HTML
$the_body = wordwrap($Body, 70); //Wordwrap for proper email formatting
$from_email_address = "$MessageSentFromMailbox";
$mail->AddReplyTo($from_email_address);
$mail->SetFrom($from_email_address);
$address = $toArray[1]; //Who we’re sending the email to
$mail->AddAddress($address, $toArray[0]); //The name of the person we’re sending to
$mail->Subject = $EmailHeaders->subject; //Subject of the email
$mail->Body = ($the_body);
if(!$mail->Send()) //If mail fails, go to the custom error
{
customError(1, $mail->ErrorInfo, "anon-email.php", "sending the email");
}
}
/* Mark the email for deletion after processing */
imap_delete($connection, $MID);
}
imap_expunge($connection); // Expunge processes all of the emails marked to be deleted
imap_close($connection);
function searchRecipient() // function to search the database for the real email
{
global $MessageSentToMailbox; // bring in the alias email
$email_addr = mysql_query("SELECT email FROM tbl WHERE source='$MessageSentToMailbox'"); // temp store of the real email
$row = mysql_fetch_array($email_addr); //making temp store of data for use in program
if(empty($row['email']))
{
return FALSE;
}
else /* Else, return find the person's name and return both in an array */
{
$results = mysql_query("SELECT * FROM tbl WHERE email = '$email_addr'"); // temp store of both queries from this function
$row = mysql_fetch_array($results, $email_addr); //making temp store of data for use in program
$name = $row['author']; // taking the author data and naming its variable
return array($name, $email_addr); // this is the name and the real email address to be used in function call
}
}
function customError($errno, $errstr, $file, $line)
{
error_log("Error: [$errno] $errstr in $file at line number: $line",1, "name#domain.com","From: name#domain.com.com");
die();
}
Here is the first thing I would try:
It would appear that your function searchRecipient isn't being passed a parameter. Rather than use the global keyword, I would define it in your function call. Also, mysql_fetch_array does not pass back an associative array, which is what you are using in your next step. I would change that to mysql_fetch_assoc (it's the same thing essentially). There are also a few other minor syntax corrections in this function. Here are my proposed changes to that function. I think this should fix your problem. Or at least get you moving forward.
function searchRecipient($MessageSentToMailbox) // function to search the database for the real email
{
$email_addr = mysql_query("SELECT email FROM tbl WHERE source='$MessageSentToMailbox'"); // temp store of the real email
$row = mysql_fetch_assoc($email_addr); //making temp store of data for use in program
if(empty($row['email']))
{
return FALSE;
}
else /* Else, return find the person's name and return both in an array */
{
$email_addr = $row['email'];
$results = mysql_query("SELECT * FROM tbl WHERE email = '$email_addr'"); // temp store of both queries from this function
$row = mysql_fetch_assoc($results); //making temp store of data for use in program
$name = $row['author']; // taking the author data and naming its variable
return array($name, $email_addr); // this is the name and the real email address to be used in function call
}
}
You could also combine this into one query and make it a little easier. Here is that solution.
function searchRecipient($MessageSentToMailbox)
{
$results = mysql_query("SELECT email, author FROM tbl WHERE source='$MessageSentToMailbox'");
$row = mysql_fetch_assoc($results);
if(empty($row['email']) || empty($row['author'])) return false;
return array($row['email'], $row['author']);
}

Categories