how to use aws ses sendmail in yii2? - php

<?php
namespace api\models;
require '../../vendor/autoload.php';
use Yii;
use Aws\Ses\SesClient;
class Mail
{
public function sendSesEmail($to, $subject, $body="", $bodyHtml="")
{
try
{
$client = SesClient::factory(array(
'version' => 'latest',
'region' => 'us-east-1',
'credentials' => array(
'key' => '**********',
'secret' => '**********',
),
));
$emailSentId = $client->sendEmail(array(
// Source is required
'Source' => 'test#test.com',
// Destination is required
'Destination' => array(
'ToAddresses' => array($to)
),
// Message is required
'Message' => array(
// Subject is required
'Subject' => array(
// Data is required
'Data' => 'SES Testing',
'Charset' => 'UTF-8',
),
// Body is required
'Body' => array(
'Text' => array(
// Data is required
'Data' => 'My plain text email',
'Charset' => 'UTF-8',
),
'Html' => array(
// Data is required
'Data' => '<b>My HTML Email</b>',
'Charset' => 'UTF-8',
),
),
),
'ReplyToAddresses' => array( 'replyTo#email.com' ),
'ReturnPath' => 'bounce#email.com'
));
return $emailSentId;
}
catch (SesException $exec)
{
echo $exec->getmessage();
}
}
}
?>
Getting this error when i use send mail function:
Aws\Ses\Exception\SesException
Error executing "SendEmail" cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)
↵
Caused by: GuzzleHttp\Exception\RequestException
cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)

Related

How to send an email through AWS simple email service(ses) using signature version 4 in PHP

Currently I'm sending email through AWS SDK SES signature 3 and got an email from Amazon to upgrade it to SES signature version 4. But where to add signature in AWS SDK? below is the current code that is being used to send emails.
<?php
//SES
$SESCredentials = array(
'key' => awsSESAccessKey,
'secret' => awsSESSecretKey
);
$SESClient = new SesClient([
// 'profile' => 'default',
'version' => AWS_SDK_VERSION,
'region' => AWS_REGION,
'http' => [
'verify' => AWS_CERT_PATH
],
'credentials' => $SESCredentials
]);
$result = $SESClient->sendEmail([
'Destination' => [
'ToAddresses' => $recipient_emails
],
'ReplyToAddresses' => [$sender_email],
'Source' => $sender_email,
'Message' => [
'Body' => [
'Html' => [
'Charset' => $char_set,
'Data' => $html_body
]
],
'Subject' => [
'Charset' => $char_set,
'Data' => $subject,
]
]
]);
?>
You can use this package as it supports signature 4
https://github.com/daniel-zahariev/php-aws-ses
$signature_version = SimpleEmailService::REQUEST_SIGNATURE_V4;
$ses = new SimpleEmailService('AccessKey', 'SecretKey', $region_endpoint,
$trigger_error, $signature_version);
$m->addTo('Recipient Name <recipient#example.com>');
$m->setFrom('Sender <user#example.com>');
$m->setSubject('Hello, world!');
$m->setMessageFromString('This is the message body.');
$ses = new SimpleEmailService('AccessKey', 'SecretKey');
print_r($ses->sendEmail($m));

sending email using zend/mail

I want to send an email using zend/mail in zend framework 2.
I already have some code but i don't know where to put it, and also not how to trigger this.
$mail = new Mail\Message();
$mail->setBody('This is the text of the email.');
$mail->setFrom('email#hotmail.be', 'email');
$mail->addTo('email#hotmail.be', 'email');
$mail->setSubject('Dit is een email verzonden van de computer');
$transport = new Mail\Transport\Sendmail('-freturn_to_email#hotmail.be');
$transport->send($mail);
I still new at Zend framework 2.
Can anybody help me with this?
I would advice you to take a look at Soflomo\Mail. Note, I am the author of Soflomo mail, but it helps you a lot with sending mails. It eases the config and dependency hassle.
Put "soflomo/mail": "~0.3" in your composer.json file and run the following command:
php composer.phar update soflomo/mail
Next, enable the module Soflomo\Mail in your application.config.php. When you use Zend\Mvc, you will have a controller/action which should trigger the email. For the most simplified use case, you can do this:
public function doAction()
{
// some of your logic
$service = $this->getServiceLocator()->get('Soflomo\Mail\Service\MailService');
$service->send(array(
'to' => 'email#hotmail.be',
'to_name' => 'email',
'from' => 'email#hotmail.be',
'from_name' => 'email',
'subject' => 'Dit is een email verzonden van de computer',
'template' => 'mail/message/default'
));
}
Now Soflomo\Mail sends a message by rendering a template and use that as message text. Here I defined a message mail/message/default so create that file (e.g. module/Application/view/mail/message/default.phtml) with this content:
This is the text of the email.
The last thing to do is to configure how Soflomo/Mail sends the message. Your question uses Sendmail, so I am using this as well in this example. Create a configuration file in config/autoload , e.g. config/autoload/soflomo_mail.global.php which contains the following content:
return array(
'soflomo_mail' => array(
'transport' => array(
'type' => 'sendmail',
),
),
);
If you want to switch to e.g. GMail as transport layer, replace above config with:
return array(
'soflomo_mail' => array(
'transport' => array(
'type' => 'smtp',
'options' => array(
'name' => 'gmail.com',
'host' => 'smtp.gmail.com',
'port' => 587,
'connection_class' => 'login',
'connection_config' => array(
'ssl' => 'tls',
'username' => '%USERNAME%',
'password' => '%PASSWORD%',
),
),
'variables' => array(
'username' => '',
'password' => '',
),
),
),
);
And create a new file config/autoload/soflomo_mail.local.php:
return array(
'soflomo_mail' => array(
'transport' => array(
'variables' => array(
'username' => 'my-address#gmail.com',
'password' => '1234secure7890',
),
),
),
);
I guess Hotmail would be similar to GMail.
You can use this within the zend directory,
$mail = new Zend_Mail();
$mail->setBodyText('This is the text of the mail.');
$mail->setFrom('somebody#example.com', 'Some Sender');
$mail->addTo('somebody_else#example.com', 'Some Recipient');
$mail->setSubject('TestSubject');
$mail->send();

SSL error in CURL call to Twitter API

Below is some code of my controller (dont worry, de keys are fake). Im using the ZendService\Twitter\Twitter module. Almost everything is working only the last error is a bit strange and i can not figure it out:
Unable to enable crypto on TCP connection api.twitter.com: make sure the "sslcafile" or "sslcapath" option are properly set for the environment.
As you can see i the code below of my controller, you can see that both the Verify of Peer and Host are set to false. The adapter is already set to Curl instead of HTTP.
<?php
namespace Twitter\Controller;
use QDCore\Controller\AbstractController;
use Zend\Mvc\MvcEvent;
use Zend\View\Model\JsonModel;
use ZendService\Twitter\Twitter;
class GetController extends AbstractController
{
protected $instance;
public function onDispatch(MvcEvent $e)
{
$config = array(
'access_token' => array(
'token' => '1024003resagsDQGyVC5YZ23423PpBNOwefS',
'secret' => 'oES8Jergewagewahsh2hTqrYGDJo',
),
'oauth_options' => array(
'consumerKey' => 'QY360Nersehr234gg4aV2pw',
'consumerSecret' => 'eEfgdagewa0Hkt4z6nCqHPY1M4wwuubY',
),
'username' => 'myusername',
'http_client_options' => array(
'adapter' => 'Zend\Http\Client\Adapter\Curl',
'curloptions' => array(
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
),
),
);
$this->instance = new Twitter($config);
return parent::onDispatch($e);
}
public function indexAction()
{
$result = new JsonModel(array('message' => 'No valid function call made'));
return $result;
}
public function usertimelineAction()
{
$options = array(
'user_id' => 'myaccountname',
'count' => 30,
);
$twitter = new Twitter($options);
$response = $twitter->statuses->userTimeline();
var_dump($response);
die;
return new JsonModel($response);
}
}
Hope that someone has an idea on how to fix it. My main domain is not running on SSL and is not going to be.
Thanks
NEVER set verify host or peer verification to false, unless you know what you are doing!
You have to point curl to your certification bundle. For Linux (Debian based systems) that is etc/ssl/certs. You could set that as "sslcapath" variable:
'http_client_options' => array(
'adapter' => 'Zend\Http\Client\Adapter\Curl',
'curloptions' => array(
'sslcapath' => '/etc/ssl/certs',
),
),
Because the path varies between systems, it's good to have it as an option set in your config/autoload/global.php file which users could change with a local.php configuration. In your config:
'http_client' => array(
'options' => array(
'sslcapath' => '/etc/ssl/certs',
),
),
Then your code becomes:
public function onDispatch(MvcEvent $e)
{
$app = $e->getApplication();
$sm = $app->getServiceManager();
$cnf = $sm->get('Config');
$config = array(
'access_token' => array(
'token' => '1024003resagsDQGyVC5YZ23423PpBNOwefS',
'secret' => 'oES8Jergewagewahsh2hTqrYGDJo',
),
'oauth_options' => array(
'consumerKey' => 'QY360Nersehr234gg4aV2pw',
'consumerSecret' => 'eEfgdagewa0Hkt4z6nCqHPY1M4wwuubY',
),
'username' => 'myusername',
'http_client_options' => array(
'adapter' => 'Zend\Http\Client\Adapter\Curl',
'curloptions' => $cnf['http_client']['options'],
),
);
$this->instance = new Twitter($config);
return parent::onDispatch($e);
}
I had the same exact problem and found this on Google. I understood I should either disable CURLOPT_SSL_VERIFYHOST and CURLOPT_SSL_VERIFYPEER or specify the correct path to the local certificates, but didn't know how to do that.
This answer has helped me a lot:
$config = array(
'callbackUrl' => 'http://example.com/callback.php',
'siteUrl' => 'http://twitter.com/oauth',
'consumerKey' => 'myConsumerKey',
'consumerSecret' => 'myConsumerSecret'
);
$consumer = new ZendOAuth\Consumer($config);
// this is the key:
$adapter = new \Zend\Http\Client\Adapter\Curl();
$adapter = $adapter->setCurlOption(CURLOPT_SSL_VERIFYHOST, false);
$adapter = $adapter->setCurlOption(CURLOPT_SSL_VERIFYPEER, false);
$httpClient = $consumer->getHttpClient();
$httpClient->setAdapter($adapter);
// now finally fetch a request token
$token = $consumer->getRequestToken();

Special Characters in Amazon SES

I'm using AWS SDK for PHP (https://github.com/aws/aws-sdk-php) to send emails using Amazon SES.
Here's the code:
<?php
require 'vendor/autoload.php';
use Aws\Ses\SesClient;
$client = SesClient::factory(array(
'key' => 'XXXXXXXXXXXXXXXX',
'secret' => 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
'region' => 'eu-west-1'
));
$result = $client->sendEmail(array(
// Source is required
'Source' => 'Télécom Co <email#address.com>',
// Destination is required
'Destination' => array(
'ToAddresses' => array('Grégory Smith <another_email#address.com>')
),
// Message is required
'Message' => array(
// Subject is required
'Subject' => array(
// Data is required
'Data' => 'The subject',
'Charset' => 'utf-8',
),
// Body is required
'Body' => array(
'Text' => array(
// Data is required
'Data' => 'The message',
'Charset' => 'utf-8',
)
),
)
));
?>
The problem is that in the email clients "Télécom" appears like "T�l�com" and "Grégory" like "Gr�gory".
Are there any solutions for this problem?
Here's the solution:
<?php
require 'vendor/autoload.php';
use Aws\Ses\SesClient;
$client = SesClient::factory(array(
'key' => 'XXXXXXXXXXXXXXXX',
'secret' => 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
'region' => 'eu-west-1'
));
$from_name = base64_encode("Télécom Co");
$from = "=?utf-8?B?$from_name?= <email#address.com>";
$to_name = base64_encode('Grégory Smith');
$to = array("=?utf-8?B?$to_name?= <another_email#address.com>");
$result = $client->sendEmail(array(
// Source is required
'Source' => $from,
// Destination is required
'Destination' => array(
'ToAddresses' => $to
),
// Message is required
'Message' => array(
// Subject is required
'Subject' => array(
// Data is required
'Data' => 'The subject',
'Charset' => 'utf-8',
),
// Body is required
'Body' => array(
'Text' => array(
// Data is required
'Data' => 'The message',
'Charset' => 'utf-8',
)
),
)
));
?>

Deserialize WCF web service request in PHP

I have a WCF web service with a Login operation taking a company name, user name and password as the three parameters. I am trying to create a PHP client app to communicate with this service. No matter what I pass to the Login operation I get the following error:
OperationFormatter encountered an invalid Message body. Expected to find node type 'Element' with name 'Login' and namespace ''. Found node type 'Element' with name 'parameters' and namespace ''
My client app:
<?php
try
{
$client = new SoapClient("https://somewhere.com/DataServiceRxPublic.svc?wsdl");
//$params = array(
// 'parameters' => array(
// 'Param' => array(
// array('Name' => 'loginCompany', 'Value' => 'XXX'),
// array('Name' => 'loginId', 'Value' => 'XXX'),
// array('Name' => 'loginPwd', 'Value' => 'XXX')
//)));
//$params = array(
// 'Login' => array(
// array('Name' => 'loginCompany', 'Value' => 'XXX'),
// array('Name' => 'loginId', 'Value' => 'XXX'),
// array('Name' => 'loginPwd', 'Value' => 'XXX')
//));
//$params = array(
// 'Login' => array(
// 'parameters' => array(
// array('Name' => 'loginCompany', 'Value' => 'XXX'),
// array('Name' => 'loginId', 'Value' => 'XXX'),
// array('Name' => 'loginPwd', 'Value' => 'XXX')
//)));
//$params = array(
// array('Name' => 'loginCompany', 'Value' => 'XXX'),
// array('Name' => 'loginId', 'Value' => 'XXX'),
// array('Name' => 'loginPwd', 'Value' => 'XXX')
//);
$params = array(
'loginCompany' => 'XXX',
'loginId' => 'XXX',
'loginPwd' => 'XXX'
);
$obj->loginCompany = 'XXX';
$obj->loginId = 'XXX';
$obj->loginPwd = 'XXX';
//$result = $client->Login($obj);
//$result = $client->Login($params);
}
catch (Exception $e)
{
print_r($e);
}
}
?>
$params being the different array permutations I've based off several different examples online.
Any help is appreciated.
The error message is telling you that there should have been something named "Login", but was named "parameters".
Go get SoapUI and with your WSDL follow the steps I described here to debug what you are actually sending. If you cannot compare what the service expects vs. what you are sending, this will be way too much trial-and-error.
If you need more external help, we'd need the WSDL resource - without it, nobody knows which request structure is expected.
Turns out I needed to extend the SOAPClient and override the __doRequest() method to replace the mismatched soap headers.
I managed to fix this error by modifying service namespace on server side.
[ServiceContract(Name="Service", Namespace = "https://sample.eu")]
Namespace was empty before.

Categories