php foreach function should send 1 SMS but it sends 2-3 for each contact.
The code should send invitations through email and SMS. But the contacts are receiving sometimes 2 or three invitation at the same time which gets the SMS to be blocked.
public function handle(QRCodeEmail $mail) {
try {
foreach ($this->event->contacts as $eventContact) {
if($eventContact->pivot->sent_date) {
continue;
}
if($eventContact->email) {
$mail->subject = $this->event->name;
$mail->setEmail($eventContact->email);
$mail->setName($eventContact->first_name . ' ' . $eventContact->last_name);
$mail->send([
'name' => $this->event->name ?? '',
'hostName' => $this->event->host_name ?? '',
'suffix' => $eventContact->suffix,
'firstName' => $eventContact->first_name,
'lastName' => $eventContact->last_name,
'data' => $eventContact->pivot->hash,
]);
}
\Curl::to(env('SMS_GATEWAY_URL'))
->withData([
'username' => env('SMS_GATEWAY_USERNAME'),
'password' => env('SMS_GATEWAY_PASSWORD'),
'message' => $this->generateBodyForSms($eventContact, env('INVITATION_LINK') . $eventContact->pivot->hash),
'numbers' => $eventContact->phone,
'sender' => env('SMS_GATEWAY_SENDER'),
])
->post();
(EventsContacts::find($eventContact->pivot->id))->update([
'sent_date' => Carbon::create()->format('Y-m-d H:i:s')
]);
}
$this->job->delete();
} catch (\Exception $e) {
$this->job->delete();
throw new \Exception($e);
}
}
Some possibilities
Maybe you should try array_unique ( http://php.net/manual/en/function.array-unique.php ) (Check the unique_multidim_array function posted in the comments of array_unique.)
Is it possible that you have mulitple records (with distinct "primary key" with the same number ? Then store phone numbers that have already received the SMS and check against that list before sending a new one.
Maybe your exit condition if($eventContact->pivot->sent_date) doesn't work as inteted.
Related
I want to send email with some accounts to some targets.But when use this code all emails are delivered to first sender account only.
from() just change name of sender in message and it could not change sender account
while(true)
{
$config = array(
'driver' => 'smtp',
'host' => $smtp,
'from' => array('address' => $senders[$p], 'name' =>
$senderName),
'username' => $senders[$p],
'password' => $senderpasses[$p],
'port' => '587',
'encryption' => 'tls'
);
Config::set('mail', $config);
$data = [
'target' => $email[$m],
'text' => $text,
'title' => $title,
'sender' => $senders[$p],
'senderName' => $senderName
];
try {
Mail::send('emails.mail', ['data' => $data], function
($message) use ($data) {
$message->from($data['sender'], $data['senderName']);
$message->to($data['target'])-
>subject($data['titl']);
});
} catch (\Exception $e) {
echo $e->getMessage();
}
$m++;
$p++;
if ($p >= count($senders)) {
$p = 0;
}
if ($m >= count($email)) {
return ($m);
}
}
it send email just with first sender and other users are not used.
Emails are, by definition, sent from a single sender to multiple addresses, so it is not possible to achieve what you are asking for.
You have to send the mail multiple times, one for each sender. May I ask you what is the purpose of this scenario?
I am developing an api using Laravel/Lumen. I have seen very few users are complaining that even though their emails are completely fine, my api response says The email must be a valid email address.
What I have seen is that they are giving a space by mistake after their email like 'noob#user.com '. As a result the email is not accepted by the system. What I'm using in my code so far is:
try {
$this->validate($request, [
'first_name' => 'required|min:3|max:40',
'last_name' => 'required|min:3|max:40',
'email' => 'required|email|unique:clients,email',
'profile_photo' => ''
]);
} catch (ValidationException $e) {
return response()->json($this->clientTransformer->validationFailed($e), 200);
}
I have tried adding the following lines inside the first line of try block but failed to change the $request object property.
try{
$request->email = trim($request->email, ' '); //<= or
$request->email = str_replace(' ', '', $request->email); // <= this line
$this->validate($request, [
'first_name' => 'required|min:3|max:40',
'last_name' => 'required|min:3|max:40',
'email' => 'required|email|unique:clients,email',
'profile_photo' => ''
]);
}
but these arent working. this is passing the exact same email to the validate method. Is there any quick way to do it?
You can use:
$request->replace(array('email' => trim($request->email)));
or
$request->merge(array('email' => trim($request->email)));
Source:
https://laracasts.com/discuss/channels/general-discussion/laravel-5-modify-input-before-validation
I'm having a hard time trying to figure out how to send mails with sendgrid.
this is the code i currently have:
employees controller:
function _sendEmail($id) {
$email = new Email();
try {
$email->from(['coms#me.co' => 'Me'])
->profile('SendGrid')
->to([$id['email'] => $id['full_name']])
->subject("TEST SUBJECT")
->emailFormat("both")
->template('default')
->send('My message');
$this->Flash->success("Message sent.");
} catch (Exception $ex) {
echo 'Exception : ', $ex->getMessage(), "\n";
}
return $this->redirect(['action' => 'index']);
}
I'm working with this plugin I found a few days ago; https://github.com/Iandenh/cakephp-sendgrid... I configured everything as stated in the docs but when I want to send the mail, nothing happens, the function flashes the success message and makes the redirection, but no email is sent.
This is the email transport in the app.php
'EmailTransport' => [
'SendGridEmail' => [
'className' => 'SendGridEmail.SendGrid',
'api_key' => 'API_KEY'
],
and the delivery profile
'Email' => [
'SendGrid' => [
'transport' => 'SendGridEmail',
'template' => 'default',
'layout' => 'default',
'emailFormat' => 'both',
'from' => ['coms#me.co' => 'Me'],
'sender' => ['coms#me.co' => 'Me'],
]
]
I'd really appreciate if someone can point me out any mistake or a possible solution for my problem.
Hi there this might be too late but in case if anyone facing the same issue.
This is working for me
So the first mistake you did is you are using the Email class, with sendgrid you should be using sendgrid Mail method now
I assume you have already installed this package if not go ahead and add it to the composer.json file and update composer
"sendgrid/sendgrid": "~7",
After that you can use sendgrid class for sending emails like shown in example below
protected function sendEmail($to, $subject, $content)
{
$email = new \SendGrid\Mail\Mail();
$email->setFrom(Configure::consume('App.from_email'), Configure::consume('Theme.title'));
$email->setSubject($subject);
$email->addTo($to);
$email->addContent("text/html", 'Your email body');
$sendgrid = new \SendGrid(Configure::consume('App.sendgrid_api_key'));
try {
$response = $sendgrid->send($email);
print $response->statusCode() . "\n";
print_r($response->headers());
print $response->body() . "\n";
} catch (Exception $e) {
echo 'Caught exception: '. $e->getMessage() ."\n";
}
}
You need to replace sendgrid_api_key with your api key. I am using it from my configuration file.
I can find out rejected addresses within swiftmailer from the ->setTo(array(. With the following code:
$mailer = Swift_Mailer::newInstance( ... );
$message = Swift_Message::newInstance( ... )
->setFrom( ... )
->setTo(array(
'receiver#bad-domain.org' => 'Receiver Name',
'other#domain.org' => 'A name',
'other-receiver#bad-domain.org' => 'Other Name'
))
->setBody( ... )
;
// Pass a variable name to the send() method
if (!$mailer->send($message, $failures))
{
echo "Failures:";
print_r($failures);
}
/*
Failures:
Array (
0 => receiver#bad-domain.org,
1 => other-receiver#bad-domain.org
)
*/
Now I want to find out rejected addresses from Cc and Bcc fields too. How can I add similar code? Is there a tutorial or a workaround? There is no example in the swiftmailer tutorial.
You can use a try-catch block where you set the to, cc, and bcc email addresses.
From the manual:
If you add recipients automatically based on a data source that may
contain invalid email addresses, you can prevent possible exceptions
by validating the addresses using Swift_Validate::email($email) and
only adding addresses that validate. Another way would be to wrap your
setTo(), setCc() and setBcc() calls in a try-catch block and handle
the Swift_RfcComplianceException in the catch block.
So you can use the try-catch on $message object:
$message = Swift_Message::newInstance();
$emails = array(
'receiver#bad-domain.org' => 'Receiver Name',
'other#domain.org' => 'A name',
'other-receiver#bad-domain.org' => 'Other Name'
);
// loop through emails and set the individually to catch exceptions
foreach($emails as $email => $name)
{
try {
$message->setTo(array($email => $name));
} catch(Swift_RfcComplianceException $e) {
echo "The email ".$email." seems invalid";
}
}
// And do the same thing with cc and bcc emails
$ccEmails = array(
'receiver#ccemail.org' => 'CC Receiver Name'
);
foreach($ccEmails as $email => $name)
{
try {
$message->setCc(array($email => $name));
} catch(Swift_RfcComplianceException $e) {
echo "The email ".$email." seems invalid";
}
}
You could set the failures to a variable if you depending on how you want to handle them.
Edit: If you have an array of users with separate first and last names you can user the below:
$users = array(
array('email' => 'receiver#bad-domain.org', 'first' => 'Receiver', 'last' => 'Name'),
array('email' => 'other#domain.org', 'first' => 'A', 'last' => 'name'),
array('email' => 'other-receiver#bad-domain.org', 'first' => 'Other', 'last' => 'Name')
);
// loop through users and set the individually to catch exceptions
foreach($users as $user)
{
try {
$message->setTo(array($user['email'] => $user['first'].' '.$user['last']));
} catch(Swift_RfcComplianceException $e) {
echo "The email ".$user['email']." seems invalid";
}
}
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