Laravel 5.1 Newsletter every month with cronjob - php

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?

Related

Sendinblue PHP API - multiple recipients only sends to last in array

I am trying to send emails to multiple recipients using SendinBlue's API v3 Php Library (https://github.com/sendinblue/APIv3-php-library).
The following code, I think, it set up correctly - in that the code goes down printing the $result part of the code, meaning there was no exception.
However, when testing sending to multiple recipients, only the email address that's the last one in the array (person2#exampe.com in the code below) receives the email.
If I flip the to array contents around, so that person1#example.com appears last in the array, then only that address receives the email.
This is the sample code:
// ####################################################
// Sendinblue Email
// ####################################################
$config = SendinBlue\Client\Configuration::getDefaultConfiguration()->setApiKey('api-key', $send_in_blue_api_key);
$apiInstance = new SendinBlue\Client\Api\TransactionalEmailsApi(
new GuzzleHttp\Client(),
$config
);
$sendSmtpEmail = new \SendinBlue\Client\Model\SendSmtpEmail();
$sendSmtpEmail['subject'] = 'Mulitple Recipients Email Test';
$sendSmtpEmail['htmlContent'] = $html;
$sendSmtpEmail['sender'] = array('name' => 'Test Messages', 'email' => 'messages#example.com');
$sendSmtpEmail['to'] = array(
array('email' => 'person1#example.com', 'name' => 'Bugs Bunny'
, 'email' => 'person2#example.com', 'name' => 'Daffy Duck')
);
$sendSmtpEmail['replyTo'] = array('email' => 'sender#example.com', 'name' => 'Reply Name');
try {
$result = $apiInstance->sendTransacEmail($sendSmtpEmail);
print_r($result);
} catch (Exception $e) {
$send_error = $e->getMessage();
print_r($send_error);
}
I tried changing the to array from:
$sendSmtpEmail['to'] = array(
array('email' => 'person1#example.com', 'name' => 'Bugs Bunny'
, 'email' => 'person2#example.com', 'name' => 'Daffy Duck')
);
To:
$sendSmtpEmail['to'] = array('email' => 'person1#example.com', 'name' => 'Bugs Bunny'
, 'email' => 'person2#example.com', 'name' => 'Daffy Duck');
But, the API returns this, which I think means the way I'm defining the multiple recipients in the to array is correct:
[400] Client error: `POST https://api.sendinblue.com/v3/smtp/email` resulted in a `400 Bad Request` response:
{"code":"invalid_parameter","message":"to is not valid"}
I wondered if there is any way around this issue?
You have to make an array of arrays. Each array should have email and name key:
Short array syntax:
$sendSmtpEmail['to'] = [
['email' => 'person1#example.com', 'name' => 'Bugs Bunny'],
['email' => 'person2#example.com', 'name' => 'Daffy Duck'],
];
Equivalent to:
$sendSmtpEmail['to'] = array(
array('email' => 'person1#example.com', 'name' => 'Bugs Bunny'),
array('email' => 'person2#example.com', 'name' => 'Daffy Duck'),
);

Laravel schedule don´t send email

i´m trying to send an email from the schedule of laravel, all the API configuration works in controllers, but in schedule not
public function handle()
{
$lateLoans = ReaderRecord::where('estado', 'atraso')->get();
$stolenLoan = ReaderRecord::where('estado', 'robo')->get();
foreach ($lateLoans as $lateLoan)
{
$loanDate = new Carbon($lateLoan['entrega']);
$today = Carbon::today();
$mailData = [
'title' => 'Informe de préstamo',
'name' => $lateLoan->reader['nombre'],
'lastName' => $lateLoan->reader['apellido_paterno'],
'book' => $lateLoan->record->book['titulo'],
'idBook' => $lateLoan->record['id'],
'days' => $loanDate->diffInDays($today),
'endDate' => $lateLoan['entrega']
];
$email = $lateLoan->reader['email'];
$name = $lateLoan->reader['nombre'];
Mail::send('mail.loan.late', $mailData, function($message) use (&$email, &$name) {
$message->to($email, $name)->subject('Atraso de entrega de préstamo');
});
}
}
I don´t know why, but the solution was this
https://github.com/yabacon/paystack-php/wiki/cURL-error-60:-SSL-certificate-problem:-unable-to-get-local-issuer-certificate-(see-http:--curl.haxx.se-libcurl-c-libcurl-errors.html)
download the file https://curl.haxx.se/ca/cacert.pem
edit the php.ini and add this
curl.cainfo = your\absolute\path\cacert.pem

foreach loop not working with laravel queue

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

Laravel: How to Queue mails to send later

Im trying to use the Mail::queue to send and email, but when I call this function it simple sends the mail, and the response is delayed ... I thought that the point of using Mail::queue was to queue ....
I want the response to came instantly, not having to wait for the email to be sent
for eg
Mail::queue('emails.template', $data, function($message) {
$message->to('somemail#gmail.com');
$message->subject('Notificacion');
});
return Response::json(array('error' => 0, 'message' => 'Ok'));
I want to receive the response without waiting for the mail to be sent.
How can I do that???
What queue driver (app/config/queue.php - 'default' param) are you using? If you're using sync, and haven't set up one of the others, then you're using the synchronous driver, which does exactly what the name says: Runs your queued task as soon as the task is created.
You need to configure an MQ server for Laravel to talk to. You can get a free iron.io account for this, and then you need to configure it, for instance:
'iron' => array(
'driver' => 'iron',
'project' => 'iron-io-project-id',
'token' => 'iron-io-queue-token',
'queue' => 'queue-name',
),
Then when you use Mail::queue() it will push the instruction to iron.io. You'll then have to have another thread listening on the queue - just run php artisan queue:listen and leave it running while messages are pushed to the queue.
/**
* Get all email recipients and include their user details for Mailgun's
* template tags - %recipient.userToken%
*/
private function getRecipients()
{
foreach (User::get() as $user)
{
$this->recipients[$user->email] = [
'id' => $user->id,
'userToken' => $user->user_token,
'first_name' => $user->first_name,
'last_name' => $user->last_name,
'email' => $user->email
];
}
}
private function sendEmail()
{
$subject = 'Demo Subject';
/**
* Data for the Blade template
*/
$data = [
'foo' => 'bar'
];
// Inline the CSS for the email
$inliner = new InlineEmail('emails.some-email', $data);
$content = $inliner->convert();
// Create Emails table entry for this email. Used for Mailgun webhooks
$email = Email::create(['user_id' => $this->userId, 'subject' => $subject, 'email_id' => str_random()]);
// Prepare the email addresses
$emailAddresses = array_column($this->recipients, 'email');
$this->mailgun->sendMessage('demo.org', [
"from" => 'support#demo.org',
"to" => implode(',', $emailAddresses), // Comma separated list of email addresses
"subject" => $subject,
"html" => $content, // Inlined CSS HTML from Blade
"text" => "Plain text message here",
"recipient-variables" => json_encode($this->recipients), // Required for batch sending, matches to recipient details
"v:messageId" => $email->id, // Custom variable used for webhooks
]);
}

Retrieving JSON response using HTTPful library for Laravel

I am currently building a e-mail client (inbound and outbound sending) using Mandrill as the e-mail sending / inbound service and Laravel 3.x.
In order to send messages, I am using the HTTPful bundle with the Mandrill using the following code in my mail/compose POST method.
$url = 'https://mandrillapp.com/api/1.0/messages/send.json';
$data = array(
'key' => '{removedAPIkey}',
'message' => array (
'to' => array( array( "email" => $_to ) ),
'from_name' => Auth::user()->name,
'from_email' => Auth::user()->email,
'subject' => $_subject,
'html' => $_body
),
'async' => true
);
$request = Httpful::post($url)->sendsJson()->body($data)->send();
Link to better formatted code above: http://paste.laravel.com/m79
Now as far as I can tell from the API log, the request is correctly made (with the expected JSON) and a response of the following format is sent back:
[
{
"email": "test#test.com",
"status": "queued",
"_id": "longmessageID"
}
]
However, what I am trying to do is access the response from the request (specifically the _id attribute), which is in JSON. Now as far as I'm aware, the HTTPful class should do this automatically (using json_decode()). However, accessing:
$request->_id;
is not working and I'm not entirely sure how to get this data out (it is required so I can record this for soft-bounce, hard-bounce and rejection messages for postmaster-like functionality)
Any assistance would be appreciated.
Edit
Using the following code, results in the mail being sent but an error returned:
$url = 'https://mandrillapp.com/api/1.0/messages/send.json';
$data = array(
'key' => '{removedAPIkey}',
'message' => array (
'to' => array( array( "email" => $_to ) ),
'from_name' => Auth::user()->name,
'from_email' => Auth::user()->email,
'subject' => $_subject,
'html' => $_body
),
'async' => true
);
$request = Httpful::post($url)->sendsJson()->body($data)->send();
if ( $request[0]->status == "queued" ) {
$success = true;
}
Results in an exception being thrown: Cannot use object of type Httpful\Response as array
I must say, a huge thanks to Aiias for his assistance. I managed to fix this myself (I must have spent hours looking at this). For anyone who wants to know, the HTTPful bundle has a body array, where the response is kept. Therefore, the code below works:
$url = 'https://mandrillapp.com/api/1.0/messages/send.json';
$data = array(
'key' => '{removedAPIkey}',
'message' => array (
'to' => array( array( "email" => $_to ) ),
'from_name' => Auth::user()->name,
'from_email' => Auth::user()->email,
'subject' => $_subject,
'html' => $_body
),
'async' => true
);
$request = Httpful::post($url)->sendsJson()->body($data)->send();
if ( $request->body[0]->status == "queued" ) {
$success = true;
}
Again, huge thanks to Aiias for clearing some major confusion up for me!

Categories