I need to reply to incoming emails including the attachment they contain.
I wrote this code, but for some reason when I check my debug log and mandrill API logs the attachment isn't included into the request.
Where's my fault?
if ($message['attachments'])
{
$mail=
[
'html' => $mail->msg->html,
'text' => $mail->msg->text,
'subject' => $mail->msg->subject,
'from_email' => 'test#test.com',
'from_name' => $mail->msg->from_name,
'to' => [
[
'email' => 'test#test.com',
'name' => 'test#test.com',
'type' => 'to'
]
],
'headers' => [
'Reply-To' => $mail->msg->from_email
],
];
//just some sample data for testing
foreach ($message['attachment'] as $attachment)
{
$mail['attachments']['name'] ='sample.png';
$mail['attachments']['type'] ='image/png';
$mail['attachments']['content'] ='iVBORw0KGgoAAAANSUhEUgAAABwAAAASCAMAAAB/2U7WAAAABlBMVEUAAAD///+l2Z/dAAAASUlEQVR4XqWQUQoAIAxC2/0vXZDrEX4IJTRkb7lobNUStXsB0jIXIAMSsQnWlsV+wULF4Avk9fLq2r8a5HSE35Q3eO2XP1A1wQkZSgETvDtKdQAAAABJRU5ErkJggg==';
}
$async = false;
$ip_pool = 'Main Pool';
$v = var_export( $mail, true);
file_put_contents('phplog.txt', 'gesendet: ' . $v, FILE_APPEND);
$result = $mandrill->messages->send($mail, $async, $ip_pool, $send_at);
}
Below line looks suspicious. If you check https://mandrillapp.com/api/docs/messages.html here. You can clearly see attachments is a multidimensional array.
//just some sample data for testing
foreach ($message['attachment'] as $attachment)
{
$mail['attachments']['name'] ='sample.png';
$mail['attachments']['type'] ='image/png';
$mail['attachments']['content'] ='iVBORw0KGgoAAAANSUhEUgAAABwAAAASCAMAAAB/2U7WAAAABlBMVEUAAAD///+l2Z/dAAAASUlEQVR4XqWQUQoAIAxC2/0vXZDrEX4IJTRkb7lobNUStXsB0jIXIAMSsQnWlsV+wULF4Avk9fLq2r8a5HSE35Q3eO2XP1A1wQkZSgETvDtKdQAAAABJRU5ErkJggg==';
}
At least it should be like following, but still you don't use $attachment in your code. But the correct usage like following.
foreach ($message['attachment'] as $key => $attachment)
{
$mail['attachments'][$key]['name'] ='sample.png';
$mail['attachments'][$key]['type'] ='image/png';
$mail['attachments'][$key]['content'] ='iVBORw0KGgoAAAANSUhEUgAAABwAAAASCAMAAAB/2U7WAAAABlBMVEUAAAD///+l2Z/dAAAASUlEQVR4XqWQUQoAIAxC2/0vXZDrEX4IJTRkb7lobNUStXsB0jIXIAMSsQnWlsV+wULF4Avk9fLq2r8a5HSE35Q3eO2XP1A1wQkZSgETvDtKdQAAAABJRU5ErkJggg==';
}
If you want to try in more clear way please use as following :
$attachment = [];
$attachment['name'] ='sample.png';
$attachment['type'] ='image/png';
$attachment['content'] ='iVBORw0KGgoAAAANSUhEUgAAABwAAAASCAMAAAB/2U7WAAAABlBMVEUAAAD///+l2Z/dAAAASUlEQVR4XqWQUQoAIAxC2/0vXZDrEX4IJTRkb7lobNUStXsB0jIXIAMSsQnWlsV+wULF4Avk9fLq2r8a5HSE35Q3eO2XP1A1wQkZSgETvDtKdQAAAABJRU5ErkJggg==';
$mail['attachments'][] = $attachment;
UPDATED ACCORDING TO COMMENT :
things look fine, just change your if statement if ($message['attachments']) to if (is_array($message['attachments']) && count($message['attachments']) > 1) then after if statment place $message['attachments'] = array_values($message['attachments']);
so loop like the following one. Just pay attention to $attachment I added to semantic keys to it, you can change according to your needs. I don't know where is your source you getting file, static or file upload etc. I added as an example.
foreach ($message['attachment'] as $key => $attachment)
{
$mail['attachments'][$key]['name'] =$attachment['fileName'];
$mail['attachments'][$key]['type'] =$attachment['mimeType'];
$mail['attachments'][$key]['content'] = chunk_split(base64_encode(file_get_contents($attachment['filePath']))); ;
}
Related
I have written a custom Drupal 8 module that will send article notifications to our Mailchimp subscribers.
Problem
Currently, the module loops over each of the article 'tags' and sends out a separate campaign for each. Consequently, if someone is subscribed two of an article's tags, they will receive two emails.
Solution
Instead, I'd like each person to receive a maximum of one email notification. I think that the best way to achieve this is to create a dynamic segment. Similar to the query posted here. However, I have been getting various errors, and can't find much help here and here.
Code
<?php
function mailchimp_notification_process(EntityInterface $node)
{
global $base_url;
$settings = Settings::get('mailchimp_audience');
$content = (object) array(
'subject_line' => 'XXX',
'title' => 'Notification',
'from_name' => 'XXX',
'reply_to' => 'noreply#gmail.com'
);
$template_content = [
'html' => [
'value' => '<table align="center" border="0" cellpadding="0" cellspacing="0" height="100%" width="100%" id="bodyTable">email content removed for brevity</table>',
'format' => 'mailchimp_campaign'
]
];
$mc_campaign = mailchimp_get_api_object('MailchimpCampaigns');
$lists = mailchimp_campaign_get_list_segments($settings, NULL);
if (
$node->isPublished() &&
($node->bundle() == 'article' || $node->bundle() == 'resource') &&
$node->field_send_notification->getString() == 1 &&
isset($node->field_send_notification_to->entity)
) {
$all_tags = [];
// loop over each of the loops to send notifications to
foreach ($node->field_send_notification_to as $category) {
$tags = array_filter($lists, function ($list) use ($category) {
return $list->name == $category->entity->getName();
});
if ($tags && is_array($tags)) {
$tags = reset($tags);
array_push($all_tags, $tags->id);
\Drupal::logger('mailchimp_notification')->notice('all_tags: ' . json_encode($all_tags));
}
}
$recipients = (object) [
'list_id' => $settings,
'segment_opts' => [
'match' => 'all',
'conditions' => [
[
'condition_type' => 'Tags',
'field' => 'tags-123',
'op' => 'interestcontainsall',
'value' => $all_tags,
]
]
]
];
\Drupal::logger('mailchimp_notification')->notice('recipients: ' . json_encode($recipients));
$campaign_id = mailchimp_campaign_save_campaign($template_content, $recipients, $content, "", "");
if ($campaign_id) {
$mc_campaign->send($campaign_id);
}
}
}
The 2nd foreach should send to each new_token->mob .but it sends to one and then stops.what am doing wrong?
My code is :
foreach($new_tokens as $new_tokenss)
{
foreach($new_tokenss as $new_token)
{
$message = "Message";
$message_encoded = urlencode($message);
$postData = array(
'authkey' => \Config::get('procedures.msg91.authKey'),
'mobiles' => $new_token->mob,
'message' => $message_encoded,
'sender' => \Config::get('procedures.msg91.senderId'),
'route' => \Config::get('procedures.msg91.route')
);
$curl = new \anlutro\cURL\cURL;
$curl->post(\Config::get('procedures.msg91.api_url'), $postData);
return 'New emergency patient';
}
}
return 'New emergency patient';
This like makes the function to return the above mentioned value and thus break the for loop.
I want to be able to send an automated email to all my users with the top 5 projects of my application. I wanna do this with a cron job on my server.
I have constructed my function in my Marketing class. I created an artisan command but I just have no idea if my method will work. I have no idea how I can get the data in my variables to send in the mail.
I am not sure if my variable $name, $email, $projects will work in the mail and if the mail will actually be sent every month. I just don't think this code will work. And I don't have time to wait a month to test it out :p
My SendNewslettterCommand:
public function handle()
{
foreach(User::all() as $user)
{
$name = $user->name;
$email = $user->email;
$projects = "a query to find top 5 projects of the week";
$Marketing = new Marketing;
$Marketing->sendNewsletter($name, $email, $projects);
}
}
My sendNewsletter function in my Marketing class:
public function sendNewsletter($name, $email, $projects)
{
// In template content you write your dynamic content if you use <mc:edit> tags.
$template_content = [];
$message = array(
'subject' => 'SP*RK - TOP 5 projecten van de maand!',
'from_email' => 'noreply#spark.com',
'from_name' => 'SP*RK',
'to' => array(
array(
'email' => $email,
'name' => $name,
'type' => 'to'
)
),
'merge_vars' => array(
array(
'rcpt' => $email,
'vars' => array(
array(
'name' => 'NAME',
'content' => $name
),
array(
'name' => 'PROJECTS',
'content' => $projects
)
)
)
)
);
MandrillMail::messages()->sendTemplate('newsletter', $template_content, $message);
}
If this is all correct my next steps would be to register my command in artisan by editing app/start/artisan.php and adding:
Artisan::add(new SendNewsletterCommand);
After this I should my command to my crontab
Is this correct or not?
I am trying to insert the name, email, company, phone and country from the array into the email message, but all I get is an empty email.
The subject, to and from all works, but I am not getting the message in the email.
Can anyone tell me what I am doing wrong?
<? php
public function contact_mail() {
$data = array(
'name' => $this->input->post('name'),
'email' => $this->input->post('email'),
'company' => $this->input->post('company'),
'phone' => $this->input->post('phone'),
'country' => $this->input->post('country')
);
$success = $this->data->save_contact_info($data);
if ($success) {
$data = array('success_message' => 'Thank you. We\'ll be in touch.');
$this->load->view('ajax/json', array('json' => $data));
$this->load->library('email');
$config['mailtype'] = 'html';
$this->email->initialize($config);
$this->email->from("noreply#example.com", "Example Notification Service");
$this->email->to(array('mha#example.com'));
$this->email->subject('Contact form');
$this->email->message($data);
$this->email->send();
}
else {
$this->load->view('ajax/error', array('error_msg' => 'Please fill out all fields.'));
}
}
?>
Change this line:
$this->load->view('ajax/json', array('json' => $data));
to this:
$view = $this->load->view('ajax/json', array('json' => $data));
Then instead of sending $data through which is just an array, you send through $view which is the HTML that includes the array.
Also, you're using $data to get all of the POST variables, but then use data later to set a flash message.
I'm not sure whether you mean to overwrite $data or not, but it's always best to keep the variable names different for different things.
I am using sync (local driver) for pushing up a queue in a update method of EmailCampaignController, which uses another method of the same controller named emailQueue
like this
Queue::push('EmailNewsletterController#emailQueue', array('campaign_id' => $campaign_id));
The emailQueue uses a foreach loop which runs correctly for once after that it gives error as if the $campaign_id is undefined
here is the emailQueue method
public function emailQueue($job, $data) {
// Queue Starts here
$emailCampaign = EmailCampaign::find($data['campaign_id']);
$emailCampaign->status = 'In Progress';
$emailCampaign->last_activity = Carbon::now();
$emailCampaign->save();
$data = $emailCampaign->emailCampaignNewsletter;
$contacts = $emailCampaign->contactList->contacts;
foreach ($contacts as $contact) {
$emailBody = [
'message' => [
'subject' => $data['email_title'],
'html' => $data['email_body'],
'from_email' => $data['from_email'],
'to' => [['email' => $contact['email_address']]]
]
];
$response = Mandrill::request('messages/send', $emailBody);
EmailCampaignRecord::create([
'email_campaign_id' => $data['campaign_id'],
'mandrill_email_id' => $response[0]->_id,
'status' => $response[0]->status,
'to_email' => $contact['email_address']
]);
$contact->last_activity = Carbon::now();
$contact->save();
}
$emailCampaign->status = 'Sent';
$emailCampaign->save();
$job->delete();
// Ends here
}
What am I doing wrong here? why is it not working like a normal loop ?
The problem was with email_campaign_id to be null because $data['campaign_id'] was null the correct foreign key was $data['email_campaign_id'] that's what stopped the process - I should have tested it before putting it in the queue
after changing the code
EmailCampaignRecord::create([
'email_campaign_id' => $data['campaign_id'],
'mandrill_email_id' => $response[0]->_id,
'status' => $response[0]->status,
'to_email' => $contact['email_address']
]);
to
EmailCampaignRecord::create([
'email_campaign_id' => $data['email_campaign_id'],
'mandrill_email_id' => $response[0]->_id,
'status' => $response[0]->status,
'to_email' => $contact['email_address']
]);
the problem was solved