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";
}
}
Related
I working with framework Yii2 and I want send mail with Mailing. 1 email address sent successfully but array email address sent fail and Show error message:
Exception 'Swift_RfcComplianceException' with message 'Address in mailbox given [xxx#gmail.com,xxx#gmail.com] does not comply with RFC 2822, 3.6.2.'
My code send mail:
Yii::$app->mailer->setTransport([
'class' => 'Swift_SmtpTransport',
'host' => 'smtp.gmail.com',
'username' => $valueEmailSystem->username_mail,
'password' => $valueEmailSystem->password_mail,
'port' => $valueEmailSystem->port,
'encryption' => 'tls',
]);
$message = Yii::$app->mailer->compose();
$message->setFrom([$valueEmailSystem->username_mail => 'TEST']);
$str = implode(',', (array)$modelUser);
$message->setBcc($str);
$message->setSubject('Xác nhận yêu cầu');
$strUserName = implode(',', (array)User::getNameById($pk));
foreach ($valueContent as $key => $item) {
$reValue = str_replace("[hoten]",$strUserName,$item->value);
$message->setHtmlBody($reValue);
}
$message->send();
Help me! Thank all.
The problem is that you are imploding the addresses into one string. The setBcc() method accepts one address as string or multiple addresses as array, for example like that:
$message->setBcc(['first#example.com', 'second#example.com']);
Or if you want to specify names
$message->setBcc([
'first#example.com' => 'First Person',
'second#example.com' => 'Second Person',
]);
Documentation of method.
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?
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.
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 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.