Mail gun Cc header issue - php

Am using this function to sent bulk mail through mail gun
`//sending batch mail
public function BatchMail($subject=null,$body=null, $record=null)
{
# Instantiate the client.
$mg = new Mailgun(MAILGUN_KEY);
$domain = MAILGUN_DOMAIN;
# Next, instantiate a Message Builder object from the SDK, pass in your sending domain
if(!empty($record))
{
$batchMsg = $mg->BatchMessage($domain);
# Define the from address.
$batchMsg->setFromAddress(FROM_EMAIL, array("first"=>FIRST_NAME, "last" => LAST_NAME));
# Define the subject.
$batchMsg->setSubject($subject);
# Define the body of the message.
$batchMsg->setHtmlBody($body);
# Next, let's add a few recipients to the batch job.
foreach ($record as $key => $rec) {
$batchMsg->addToRecipient($rec['email'], array("first" => $rec['fname'], "last" => $rec['lname']));
}
$batchMsg->addCcRecipient("mayname#mycompany.in", array("first" => "Sally", "last" => "Doe"));
$re = $batchMsg->finalize();
$result = $batchMsg->getMessage();
$log = $mg->get("$domain/log");
$respbody = $log->http_response_body;
$result = $mg->get("$domain/stats",array('event' => array('sent', 'opened')));
$resp = $log->http_response_code;
//$event = $mg->get("$domain/events");
$response = array("log"=>$log,"result"=>$result,"body"=>$respbody,"code"=>$resp);
return $response;
}
}`
Here mails are sending properly but I have a problem in my cc mail.
$batchMsg->addCcRecipient("mayname#mycompany.in", array("first" => "Sally", "last" => "Doe"));
This function using for adding CC mails. Mails are delivering properly but the mail reviving with headers like To: mayname#mycompany.in, Cc:mayname#mycompany.in. But the recipients mails are not listing in the headers.
Normally gamil showing recipients in the headers like this
to: test#gmail.com
cc: myname#mycompany.in
Anyone know why mail gun showing issue like this ??

Replace:
foreach ($record as $key => $rec) {
$batchMsg->addToRecipient($rec['email'], array("first" => $rec['fname'], "last" => $rec['lname']));
}
With:
foreach ($record as $key => $rec) {
$batchMsg->addBccRecipient($rec['email'], array("first" => $rec['fname'], "last" => $rec['lname']));
}
Or if you want your recipients to know who else was emailed don't use the batch message builder. See the "To" parameter in the mailgun API documentation for proper formatting.
The batch builder is for sending many distinct emails and not for composing a single email to many different recipients. It's possible that MailGun didn't anticipate you building an email to multiple recipients this way and thus there is no test coverage of this bug. You might try filing a bug report on their github page.
More details about the specification you're trying to implement might lead to a better answer.

Related

Issues sending to multiple emails based on table column data

Here is my code :
// Set the default options for the email
$options = array(
'sender_email' => 'test1#test1.com',
'recipient_email' => 'test2#test2.com',
'subject' => 'subject'
);
// Check the value of the "data1" column in the table
if ($insert['data1'] == 'sample1') {
$options['recipient_email'] = 'test1#test1.com';
} elseif ($insert['data1'] == 'sample2') {
$options['recipient_email'] = 'test2#test1.com';
}
// Send the email using the updated options
$sent_message = Form::sendMail($options);
No matter what I do, the email is always sent to "test2#test1.com". I have written, and rewritten a dozen different ways to the same result. The sendMail() function is based off of the phpmailer found on PHP Form Builder. Is there a better alternate to phpMailer?
I swapped values between emails, I wrote :
$recipientEmail = "email1.email.com";
$options = array(
'sender_email' => 'test1#test1.com',
'recipient_email' => $recipientEmail,
'subject' => 'subject'
);
and wrote a loop that looked at the values of the post data, and changed the $recipientEmail corresponding to that data.

PHP - For each loop does not always do all iterations

Currently, I have the following problem:
I have created a WordPress environment that sends personalized emails to subscribers based on their preferences. This has worked for quite some time but for a couple of months, we are experiencing some inconsistencies. These inconsistencies are as followed:
Once in a while, the foreach loop for sending the emails stops in the middle of its execution. For example, we have a newsletter with 4000 subscribers. Once in a while, the program randomly stops its sending procedure at around 2500 emails. When this happens, there are literally no signs of any errors and there is also nothing to be seen in the debug log.
I have tried the following things to fix the issue:
Different sender; we switched from Sendgrid to SMTPeter (Dutch SMTP service)
Delays; we have tried whether placing a wait after x number of emails would have any impact because there might be too many requests per minute, but this was not the case.
Disable plugins; For 5 weeks we thought we had found the problem. WordFence seemed to be the problem, unfortunately, the send function stopped again last week and this did not appear to be causing the problems. Just to show how unstable it really is. It can go well for 5 weeks and then not for 2 weeks.
Rewriting of functions
Logging, we write values ​​to a txt file after every important step to keep track of where the send function stops. This is just to see which users have received an email and which still need to receive it so that we can continue sending it from there.
Debug log, the annoying thing is that even when we have the wp_debug on, nothing comes up that indicates a cause of crashing.
To schedule the sender I use the WP_Cron to run the task in the background. From there the following function is triggered;
Below, the code I wrote in stripped format. I removed all the $message additions as this is just HTML with some variables of ACF for the email. I translated it so it's easier to understand.
<?php
function send_email($edition_id, $post)
{
require_once('SMTPeter.php'); //Init SMTPeter Sender
$myfile = fopen("log.txt", "a") or die("Unable to open file!"); //Open custom logfile
$editionmeta = get_post_meta($edition_id); //Get data of edition
$users = get_users();
$args = array(
'post_type' => 'articles',
'post_status' => 'publish',
'posts_per_page' => -1,
'order' => 'asc',
'meta_key' => 'position',
'orderby' => 'meta_value_num',
'meta_query' => array(
array(
'key' => 'edition_id',
'value' => $edition_id,
'compare' => 'LIKE',
),
),
);
$all_articles = new WP_Query($args); // Get all articles of edition
$i = 0; // Counter users interrested in topic
$j = 0; // Counter sent emails
foreach ($users as $user) { //Loop over all users <---- This is the loop that not always finishes all itterations
$topic_ids = get_field('topicselect_', 'user_' . $user->ID);
$topic_id = $editionmeta['topic_id'][0];
if (in_array($editionmeta['topic_id'][0], $topic_ids)) { // Check if user is interrested in topic.
$i++; // Counter interrested in topic +1.
// Header info
$headerid = $editionmeta['header_id'][0];
$headerimage = get_field('header_image', $headerid);
$headerimagesmall = get_field('header_image_small', $headerid);
// Footer info
$footerid = $editionmeta['footer_id'][0];
$footer1 = get_field('footerblock_1', $footerid);
$footer2 = get_field('footerblock_2', $footerid);
$footer3 = get_field('footerblock_3', $footerid);
$message = '*HTML header newsletter*'; // First piece of content email
if ($all_articles->have_posts()) :
$articlecount = 0; // Set article count to check for empty newsletters
while ($all_articles->have_posts()) : $all_articles->the_post();
global $post;
$art_categories = get_the_category($post->ID); // Get categories of article
$user_categories = get_field('user_categories_', 'user_' . $user->ID); // Get categories user is interrested in
$user_cats = array();
foreach ($user_categories as $user_category) {
$user_cats[] = $user_category->name; // right format for comparison
}
$art_cats = array();
foreach ($art_categories as $art_category) {
$art_cats[] = $art_category->name; // right format for comparison
}
$catcheck = array_intersect($user_cats, $art_cats); // Check if 1 of the article's categories matches one of a user's categories
if (count($catcheck) > 0) { // The moment the array intersect count is greater than 0 (at least 1 category matches), the article is added to the newsletter.
$message .= "*Content of article*"; // Append article to content of newsletter
$articlecount++;
}
endwhile;
endif;
if ($articlecount > 0) { //As soon as the newsletter contains at least 1 article, it will be sent.
$j++; //Sent email counter.
$mailtitle = $editionmeta['mail_subject'][0]; // Title of the email
$sender = new SMTPeter("*API Key*"); // Class SMTPeter sender
$output = $sender->post("send", array(
'recipients' => $user->user_email, // The receiving email address
'subject' => $mailtitle, // MIME's subject
'from' => "*Sender*", // MIME's sending email address
'html' => $message,
'replyto' => "*Reply To*",
'trackclicks' => true,
'trackopens' => true,
'trackbounces' => true,
'tags' => array("$edition_id")
));
error_log(print_r($output, TRUE));
fwrite($myfile, print_r($output, true));
}
}
}
fclose($myfile);
}
All I want to know is the following;
Why can't my code run the foreach completely, every time? I mean, it's quite frustrating to see that it sometimes works like a charm, and the next time it could get stuck again.
Some things I thought about but did not yet implement:
Rewrite parts of the function into separate functions. Retrieving the content and setting up the HTML for the newsletter could be done in a different function. Besides the fact that it would obviously be an improvement for cleaner code, I just wonder if this could actually be the problem.
Can a foreach crash due to a fwrite trying to write to a file that is already being written to? So does our log cause the function to not run properly? (Concurrency, but is this a thing in PHP with its workers?)
Could the entire sending process be written in a different way?
Thanks in advance,
Really looking forward to your feedback and findings

GMAIL API - How to process attachments of email when looping through batch request results

"We support the Gmail REST API on Stack Overflow. Google engineers monitor and answer questions with the gmail-api tag.
You should use this tag when asking questions. We aim to answer all questions within a couple of days."
OK so after many frustrating days I found this on the Gmail api support page so here goes.
The short question:
How can I get the attachments for an specific email via the getData() method while looping through $emails from a batch request?
This would be so that when a user loads our inbox they can all the data required to view say 20 messages, instead of having to click on each one and wait for another call to be made which tends to take up to 6 seconds to process.
More Info
I'm trying to upgrade our platform which uses the Gmail API for our Gmail users to manage their inboxes from inside our platform.
I am trying to get all attachments for an email (inline or attached separately) to allow the user to read the email, with any inline images already visible on the page, and also be able to quickly preview any attachments or just download.
I have no issues getting everything I need for a single message.
But as soon as I try to use that code inside a batched request response, I cannot get the attachments out without creating new services and calls for each message.
This really slows everything down as it's making a new call for every email just to get the attachments.
Here's my code:
This is what I am using to get the attachment details out of the relevant part:
public function get_attachment_from_part($service, $emailId, $part) {
//spit_out($service);
//echo 'THIS IS THE FIRST PART:::';
//spit_out($part);
echo $attachmentId = $part->getBody()->getAttachmentId();
echo "<br/>".$filename = $part->getFilename();
echo "<br/>".$mimeType = $part->getMimeType();
echo "<br/>".$partId = $part->getPartId();
$attachment = new stdClass();
$attachment->filename = $filename;
$attachment->displayHeader = 'Content-Type: '.$mimeType;
$attachment->mimeType = $mimeType;
echo "<br/>".$attachment->messageId = $emailId;
$attachment->attachmentId = $attachmentId;
$attachment->partId = $partId;
$file = $service->users_messages_attachments->get('me', $emailId, $attachmentId);
spit_out($file);
$file = $file->getData(); // This fails because the response to $file has nothing in it.
$file = $this->inbox_new_model->decodeBody($file);
$attachment->file = $file;
return $attachment;
}
This is the response I get back when calling the attachments method:
Google_Http_Request Object
(
[batchHeaders:Google_Http_Request:private] => Array
(
[Content-Type] => application/http
[Content-Transfer-Encoding] => binary
[MIME-Version] => 1.0
)
[queryParams:protected] => Array
(
)
[requestMethod:protected] => GET
[requestHeaders:protected] => Array
(
[authorization] => Bearer ya29.Gl0WBEV_MbKok8PAG3YCBtlMI0hMnRsjJ7wCKWPJDAL9nFJlN7TuX8mJICDko-6PuCpsYiqaaVf-NVGzet9SIdPyJ9PZWTsEmlZVHdNOQXn8Kdc1NYOKU5_dNO4QiKU
)
[baseComponent:protected] => https://www.googleapis.com
[path:protected] => /gmail/v1/users/me/messages/15af343839f05824/attachments/ANGjdJ9FYdeQWlu1inYKKPZ6KQZ8G1hkjel1CuOMXKYI8eZNlRl2IjZ8oc_e9TqJ3Q_anX96afyxe6mr3jbZdGnQN0oy-C5uiMi5GMUC-Y_oQgqohgXkG1QcNukKZZ_rgRkqmqLy0O8zcEv2Y5WuOSEeHB9t6iDjmEgWSCy1VXHLmC-3XJVHlHyrCE6-tLHWPvaKf9gdvnuWhyl9XZJ_GdVpvhvJMs8Q5cPwk9jDwuQBw1unHbLqJeZxeGEBYNCH4ri-AuyV048E-3IhFOzfuW-5ST7fDQuhRsBzGKYZax3RDrNQT8mGV3qHXzoISLI
[postBody:protected] =>
[userAgent:protected] =>
[canGzip:protected] =>
[responseHttpCode:protected] =>
[responseHeaders:protected] =>
[responseBody:protected] =>
[expectedClass:protected] => Google_Service_Gmail_MessagePartBody
[accessKey] =>
)
as opposed to this when I use a single request per email:
Google_Service_Gmail_MessagePartBody Object
(
[attachmentId] =>
[data] => ## THE DATA RETURNED HERE IS THE CORRECT FILE AND I CAN DECODE AND USE IT
[size] => 8908
[modelData:protected] => Array
(
)
[processed:protected] => Array
(
)
)
Thanks in advance. Let me know if you need to see any other parts of the code.
Also to note, everything is retrieve successfully while looping through the batch response, it is only attachments which do not actually get returned in the following request and need to have a separate call made to get the actual attachment data:
$service->users_messages->get('me', $messageId, $optParamsGetMsg);

MailChimp API 3.0 Batch update - Always pending, total_operations:0

Trying to update a batch of emails. I think I've tried every way to do this, but my use of DrewM's MailChimp wrapper only returns the following $result content:
Array ( [id] => 1234abcd [status] => pending [total_operations] => 0 [finished_operations] => 0
And so on. No errors, but no operations!
Essentially, my code looks like this, where $emails stores all the emails in an array.
include("MailChimp.php");
include("Batch.php");
$list_id = "1234abcd";
use \DrewM\MailChimp\MailChimp;
use \DrewM\MailChimp\Batch;
$apiKey = 'aslkjf84983hg84938h89gd-us13';
if(!isset($emails)){ // If not sending bulk requests
$MailChimp = new MailChimp($apiKey);
$subscriber_hash = $MailChimp->subscriberHash($email);
$result = $MailChimp->patch("lists/$list_id/members/$subscriber_hash",
array(
'status' => 'subscribed',
)
);
/* SENDING BATCH OF EMAILS */
} else if($emails){
$MailChimp = new MailChimp($apiKey);
$Batch = $MailChimp->new_batch();
$i = 1;
foreach($emails as &$value){
$Batch->post("op".$i, "lists/$list_id/members", [
'email_address' => $value,
'status' => 'subscribed',
]);
$i++;
}
$result = $Batch->execute(); // Send the request (not working I guess)
$MailChimp->new_batch($batch_id); // Now get results
$result = $Batch->check_status();
print_r($result);
}
If anyone can see what I'm not seeing, I'll be very grateful!
Problem solved. After talking with a rep at MailChimp, he helped to find two major problems.
Instead of using a POST method, he said to use PUT, when working with already existing emails. POST is best used for adding emails, while PUT can add and update emails.
So, change
$Batch->post
to
$Batch->put
Secondly, after successfully sending requests and getting errors in the $result, he found they were 405 errors and told me to add the md5 hash to my emails.
So, change
$Batch->post("op".$i, "lists/$list_id/members", [ ...
to
$subscriber_hash = $MailChimp->subscriberHash($value);
$Batch->put("op$i", "lists/$list_id/members/$subscriber_hash", [ ...
And they sent me a MailChimp stocking cap for being a good sport :-)
Veni. Vidi. Vici.

calling an array in a function

I am having a function which has an array in it. I wanted to call that function foo and use the $result indexes (text, html, attachments) in my script. Please help me with this since I am totally new to php. I am trying to call the array to the mail() method. and getting error saying string expected and it id array. How can I insert the array to the relevant mail method.
function foo($a)
{
if (is_resource($b))
{
$result = array
(
'text' => null,
'html' => null,
'attachments' => array(),
);
}
return $result;
}
You cannot pass an array to the mail function as it is expecting just strings. If you want the text of the email to be $result['text'], try
mail ($to, $subject, $result['text']
However, it looks like what are you trying is to have an array populate the attachments and content of an email. There's nothing like that out from the box in PHP. You may have to look for some third parties library. SwiftMailer maybe what you want.

Categories