Magento - Mailgun plugin not sending email - php

I'm using Magento v1.9.1, with a MailGun plugin installed.
Plugin url:
https://www.magentocommerce.com/magento-connect/mailgun-for-email-delivery.html
Here you can see the MailGun plugin on the admin area:
Then I used the following code to send a test email (test_email.php):
<?php
// Invoke the Magento environment
require_once( 'app/Mage.php' );
Mage::app();
//Getting the Store E-Mail Sender Name.
$senderName = Mage::getStoreConfig('trans_email/ident_general/name');
//Getting the Store General E-Mail.
$senderEmail = Mage::getStoreConfig('trans_email/ident_general/email');
$customerEmail = "<personal_email#hidden_on_purpose>";
$text = "Hello, this is a test.";
//Sending E-Mail to Customers.
$mail = Mage::getModel('core/email')
->setToName($senderName)
->setToEmail($customerEmail)
->setBody($text)
->setSubject('Subject :')
->setFromEmail($senderEmail)
->setFromName($senderName)
->setType('html');
try{
//Confimation E-Mail Send
$mail->send();
}
catch(Exception $error)
{
Mage::getSingleton('core/session')->addError($error->getMessage());
return false;
}
?>
Then the email arrives to me but it is not sent via MailGun. I know that because on the header of the received email is the server where the application lives and on the MailGun log the email is not logged.
I think the MailGun plugin is working on the backend admin area only, but it is not getting called when sending an email with Magento.
I also did a test modifying the file:
./app/code/community/FreeLunchLabs/MailGun/Model/Mailgun.php
by adding the line:
die("Send stopped on file: ./app/code/community/FreeLunchLabs/MailGun/Model/Mailgun.php");
Like:
...
public function send($message) {
die("Send stopped on file: ./app/code/community/FreeLunchLabs/MailGun/Model/Mailgun.php");
$domain = $message->getStore()->getConfig('mailgun/general/domain');
$apiKey = $message->getStore()->getConfig('mailgun/general/key');
$files = null;
if(count($message->getAttachments())) {
foreach($message->getAttachments() as $attachment) {
$files[] = $attachment;
}
}
$sendResponse = $this->mailgunRequest('messages', $domain, $apiKey, $message->getMessage(), Zend_Http_Client::POST, false, $files);
if($message->getStore()->getConfig('mailgun/events/store')) {
Mage::getModel('freelunchlabs_mailgun/email')->saveInitialSend($message, $sendResponse);
}
return $sendResponse;
}
...
But when running the file: test_email.php, the stopped message inside the die(...) on the code above doesn't appear.
Any idea on how to solve/debug this?

Ok, after some try/error experiments I found the answer: that MailGun extension applies only to transactional emails as stated on its description. You cannot send custom emails using MailGun straightforward like on my initial code: test_email.php. If you wanna send some custom email using MailGun you should create a template before and then use that template like in the following code where I created the template with id: 1
<?php
// Invoke the Magento environment
require_once( 'app/Mage.php' );
Mage::app();
$templateId = 1;
$receiveName = "<Your Name Here>";
$receiveEmail = "<your email here>";
$storeId = Mage::app()->getStore()->getStoreId();
$emailTemplate = Mage::getModel("core/email_template")->load($templateId);
$vars = array(
"name" => $receiveName,
"email" => $receiveEmail,
"phone" => "+13052491037",
"comment" => "This is my comment: Hello World!"
);
$emailTemplate->getProcessedTemplate($vars);
/*
echo "<pre>\n";
print_r($emailTemplate);
echo "</pre>\n";
die();
//*/
$emailTemplate->setSenderName(Mage::getStoreConfig("trans_email/ident_general/name", $storeId));
$emailTemplate->setSenderEmail(Mage::getStoreConfig("trans_email/ident_general/email", $storeId));
$emailTemplate->send($receiveEmail, $receiveName, $vars);
?>
Hope this helps somebody.

Related

Bad Request Error while sending sendgrid email using wadeshuler/yii2-sendgrid

I am currently working on a yii2 application and I have integrated wadeshuler/yii2-sendgrid plugin in my application to send emails through it.
I have setup a dynamic template with a template id in my sendgrid account. Here is the code I am using to test sendgrid integration with my app.
public function actionTest()
{
$mailer = Yii::$app->mailer;
$message = $mailer->compose()
->setTo('umair#****.com') // or just $user->email
->setFrom(['alerts#example.com' => 'Alerts'])
->setReplyTo('noreply#example.com')
->setSubject('Hey -username-, Read This Email')
->setHtmlBody('Dear -username-,<br><br>My HTML message here')
->setTextBody('Dear -username-,\n\nMy Text message here')
->setTemplateId('******')
->addSubstitution('-username-', 'Umair Ashraf')
->send();
if ($message === true) {
echo 'Success!';
echo '<pre>' . print_r($mailer->getRawResponses(), true) . '</pre>';
} else {
echo 'Error!<br>';
echo '<pre>' . print_r($mailer, true) . '</pre>';
echo '<pre>' . print_r($mailer->getErrors(), true) . '</pre>';
}
}
Here is the response code printed
Error!
{"code":400,"headers":["HTTP/1.1 400 Bad Request","Server: nginx","Date: Fri, 27 Dec 2019 13:31:27 GMT","Content-Type: application/json","Content-Length: 238","Connection: keep-alive","Access-Control-Allow-Origin: https://sendgrid.api-docs.io","Access-Control-Allow-Methods: POST","Access-Control-Allow-Headers: Authorization, Content-Type, On-behalf-of, x-sg-elas-acl","Access-Control-Max-Age: 600","X-No-CORS-Reason: https://sendgrid.com/docs/Classroom/Basics/API/cors.html","",""],"body":"{\"errors\":[{\"message\":\"Substitutions may not be used with dynamic templating\",\"field\":\"personalizations.0.substitutions\",\"help\":\"http://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/errors.html#message.personalizations.substitutions\"}]}"}
Array
(
[0] => Bad Request!
)
As you can see it says that substitutions may not be used with dynamic templating, but I will be needing to substitute these variable inorder to use templates correclty. How to fix this using the code?
I had to remove wadeshuler/yii2-sendgrid plugin as it didn't support the latest features and updates in the sendgrid liberary. I installed the latest sendgrid plugin. I also made a component named SendGridManager to route all the emails through it in my application.
Here is my function inside the component SendgridManager
public function email($from , $to, $substitution, $templateId, $senderName = NULL,
$toName = NULL, $attachment = NULL)
{
$response = '';
$email = new \SendGrid\Mail\Mail();
$email->setFrom($from,$senderName);
$email->addTo($to , $toName, $substitution);
$email->setTemplateId($templateId);
if(!empty($attachment))
{
$email->addAttachment(
$attachment
);
}
$sendgrid = new \SendGrid($this->apiKey);
try {
$response = $sendgrid->send($email);
} catch (Exception $e) {
echo 'Caught exception: '. $e->getMessage(). "\n";
}
return $response;
}

How to send custom message before, proxy session send actual message

When Customer replies to proxy service reserved number then proxy hit an OutOfSessionCallbackUrl(if a session is not active).
That URL will come to my code below.
public function response()
{
$to = $_POST['To'];
$from = $_POST['From'];
$from = substr($from, 2);
$body = $_POST['Body'];
$twilio = new Client($this->sid, $this->token);
$response=$this->db->get_where('contact_management as cm
,proxy_service as ps',
array('mobile'=>$from,'company_mobile'=>$to,'sc.sms_template_id<>'=>0))
->row_array();
$number = trim($response['country_code'].$response['mobile_number']);
//Here I'm sending a response
header("content-type:application/json");
?>
{
"uniqueName": "<?php echo rand();?>",
"ttl":"64800",
"mode": "voice-and-message",
"participantIdentifier":"<?php echo $number;?>"
}
<?php
}
This will create a session between SMS sender and returned number(company) and send the message of the sender to the company. I want to send a custom message before Twilio proxy send actual message to the company.
Thanks.
Twilio developer evangelist here.
Currently you are using the out of session callback in order to create a session, but you want to send a message before you forward on the incoming message.
To do this, you won't be able to respond with the JSON to create a session. Instead, you should create the session manually using the session API. Once you have created a session you can then send your initial message by creating an interaction on the participant you want to send the message to. You can then follow up by using the same API to forward the original message. And finally you still need to respond to the webhook. Since you handled all the message sending manually, you can return an empty TwiML <Response/> to signify that you need Twilio to take no further part.
Let me know if that helps at all.
Here Are the complete Description.
I have add Twilio number as reserved in proxy service and set the proxy service OutOfSessionCallbackUrl.When this URL reach my code then the magic happens,
public function response()
{
$to = $_POST['To'];
$from = $_POST['From'];
$twilio = new Client($this->sid, $this->token);
$response=$this->db->get_where('contact_management ,proxy_service,
array('mobile'=>$from,'company_mobile'=>$to))->row_array();
$service_sid=$response['service_sid'];
$session = $twilio->proxy->v1->services($service_sid)->sessions
->create(array("uniqueName" => rand(),"ttl"=>"64800"));
$session_sid = $session->sid;
$participant1 = $twilio->proxy->v1->services($service_sid)
->sessions($session_sid)->participants->create($_POST['From'], // identifier
array("friendlyName" => $response['f_name'],"proxyIdentifier"=>$to));
$from_id = $participant1->proxyIdentifier;
$participant2 = $twilio->proxy->v1->services($service_sid)
->sessions($session_sid)->participants
->create($response['country_code'].$response['mobile_number'], // identifier
array("friendlyName" => $response['first_name']));
$to_id = $participant2->proxyIdentifier;
$to_sid = $participant2->sid;
$body = $response['campaign_name']."\n";
$body .= $_POST['Body'];
$message_interaction = $twilio->proxy->v1->services($service_sid)
->sessions($session_sid)
->participants($to_sid)
->messageInteractions
->create(array("body" => $body));
header("content-type:text/xml");
?>
<Response />
<?php
}

Email using cron and including attachment to email from moodle

I would like to send emails only to users that have completed a specific course and add a pdf file (a certificate for completing the course) as attachment to the email, and do so at a specific time using moodle cron.
I have looked at some plugins to find out how it's done, but I'm still not sure how exactly I should do this.
I need:
1. to know how I would add an attachment to an email (and which API to use),
2. how I would use cron to send the emails to the desired group at a certain time,
3. how to retrieve users that have completed the course so that I could send emails (with attachment) to them.
Thanks in advance.
(I'm using moodle version 3.0)
This is an overview.
First create a local plugin. For example /local/yourplugin
https://docs.moodle.org/dev/Local_plugins
Then set up a message provider
https://docs.moodle.org/dev/Message_API
defined('MOODLE_INTERNAL') || die();
in local/yourplugin/db/messages.php
$messageproviders = array (
'coursecompleted' => array (
),
Then add an event observer - you will want to respond to the course_completed event
https://docs.moodle.org/dev/Event_2
in /local/yourpluginname/db/events.php
have something like
$observers = array(
array(
'eventname' => '\core\event\course_completed',
'callback' => 'local_yourplugin_observer::course_completed',
),
);
Now add the message code
Add something like this to '/local/message/classes/observer.php'
defined('MOODLE_INTERNAL') || die();
class local_yourplugin_observer {
/**
* Triggered when 'course_completed' event is triggered.
*
* #param \core\event\course_completed $event
* #return bool
*/
public static function course_completed(\core\event\course_completed $event) {
// Your code here.
$message = new \core\message\message();
$message->component = 'local_yourplugin'; // Name of your local plugin.
$message->name = 'coursecompleted'; // Name of message provider.
$message->userfrom = $USER;
$message->userto = $user;
$message->subject = 'message subject 1';
$message->fullmessage = 'message body';
$message->fullmessageformat = FORMAT_MARKDOWN;
$message->fullmessagehtml = '<p>message body</p>';
$message->smallmessage = 'small message';
$message->notification = '0';
$message->contexturl = 'http://GalaxyFarFarAway.com';
$message->contexturlname = 'Context name';
$message->replyto = "random#example.com";
$content = array('*' => array('header' => ' test ', 'footer' => ' test ')); // Extra content for specific processor
$message->set_additional_content('email', $content);
// Create a file instance.
$usercontext = context_user::instance($user->id);
$file = new stdClass;
$file->contextid = $usercontext->id;
$file->component = 'user';
$file->filearea = 'private';
$file->itemid = 0;
$file->filepath = '/';
$file->filename = '1.txt';
$file->source = 'test';
$fs = get_file_storage();
$file = $fs->create_file_from_string($file, 'file1 content');
$message->attachment = $file;
$messageid = message_send($message);
}
}

Swiftmailer breaks down after staging

I'm bringing the (Laravel-based) website for an event that's coming up soon, up to date. Part of this was improving the mailing function, for which I decided to use Mandrill's SMTP with SwiftMailer. Everything worked perfectly while working locally. However, since we pushed everything to a live (well, testing, but on the same server as live) staging area, no mails get sent anymore.
Everything seems to break down after I make a send() command in PHP. Even a simple print command doesn't do anything. There's also no errors being reported, except if I go look in my console, where the request returns a 500 Internal Server Error, without any other errors.
At the moment, these are the function I'm using only to test, which works and sends perfectly on local and then prints, but just gives a white screen on the staging area...
Route::any('test', function()
{
testMail();
//this print works perfectly locally but shows nothing on staging
print ('boe');
});
function testMail(){
$to = array('private#email.address' => 'My Name');
$subject = 'test mail';
$text = "test mail hier";
$htmlTekst = "<b>boe</b><i>spaghetti</i>";
$view = View::make('mailTemplate',
['naam' => 'Jeroen Cuvelier',
'tekst' => $htmlTekst,
'username' => 'my email address',
'password' => 99999,
'siteUrl' => rootUrl(),
'header2' => '']);
$html = $view->render();
sendEmail($text, $html, $to, $subject, "", "");}
function sendEmail($text, $html, $to, $subject, $attachment, $attachmentName)
{
//$subject = 'Subject!';
$from = array('event#email.company' =>'Company event');
/*
SMTP-settings
*/
$transport = Swift_SmtpTransport::newInstance('smtp.mandrillapp.com', 25);
$transport->setUsername('MY_MANDRILL_USERNAME');
$transport->setPassword('MY_MANDRILL_PASSWORD');
$swift = Swift_Mailer::newInstance($transport);
$message = new Swift_Message($subject);
$message->setFrom($from);
$message->setBody($html, 'text/html');
$message->setTo($to);
$message->addPart($text, 'text/plain');
if ($attachment != "")
{
$toAttach = Swift_Attachment::fromPath($attachment);
if ($attachmentName!="")
{
$toAttach->setFilename($attachmentName);
}
$message->attach($toAttach);
}
//neither of these messages print on staging
if ($recipients = $swift->send($message, $failures))
{
echo 'Message successfully sent!';
} else {
echo "There was an error:\n";
print_r($failures);
}
}
Turns out the problem was not in PHP or anything I had done. The server just didn't allow SMTP calls. A call to the company hosting that fixed my issues.

Get transcational email id by name

Does someone know how do I get the id of an email by name set on backend? I have an email created in backend in transactional emails that I want to send it programatically, but the id of it may differ depending on the instance that I'm on (local, live, stage), and I can only provide the same name for it.
I have this:
Mage::getModel('core/email_template')->sendTransactional(
$templateId,
$sender,
$recepientEmail,
$recepientName,
$vars,
$store);
And I need to find out $templateId and I only know that I saved the mail with name "Tests".
You can get email template:
$templateName = “Test”;
$emailTemplate = Mage::getModel('core/email_template')->loadByCode($templateName);
Get id:
$templateId = $emailTemplate->getId();
And then send email on your way:
Mage::getModel('core/email_template')->sendTransactional(
$templateId,
$sender,
$recepientEmail,
$recepientName,
$vars,
$store
);
or use "my" method:
$vars = array('key' => 'value');
$storeId = Mage::app()->getStore()->getStoreId();
$recipientEmail = 'some#email.com';
$recipientName = 'Some Name';
$emailTemplate->setSenderEmail(Mage::getStoreConfig('trans_email/ident_general/email', $storeId));
$emailTemplate->setSenderName(Mage::getStoreConfig('trans_email/ident_general/name', $storeId));
$emailTemplate->send($recipientEmail, $recipientName, $vars);
please check the codes below. any way this is my first answer on stackoverflow.
$templateName = "Tests";
$templateID = Mage::getModel('core/email_template')->loadByCode($templateName)->getId();

Categories