I was wondering if someone could help me with a problem I have been having some trouble researching related to Laravel and inbound email processing through Mandrill.
Basically I wish to be able to receive emails through Mandrill and store them within my Laravel database. Now i'm not sure if i'm reading through the documentation with the wrong kind of eyes, but Mandrill says it deals with inbound email as well as outbound, however i'm starting to think that Mandrill deals with inbound email details as opposed to the actual inbound email, such as if the message is sent etc.
I've created a new Mandrill account, created an API key, created an inbound domain and corresponding subdomain of my site (e.g. inboundmail.myproject.co.uk), set the MX record and the MX record is showing as valid. From there i have set up a route (e.g. queries#inboundmail.myproject.co.uk), and a corresponding webhook (myproject.co.uk/inboundmail.php) and within this webhook tried a variety of the examples given in the API (https://mandrillapp.com/api/docs/inbound.php.html), such as adding a new route, checking the route and attempting to add a new domain. All of them worked and produced the correct results, so my authentication with Mandrill is not in question, but my real question is is there a specific webhook for dealing with accepting incoming mail messages?
I cant help but feel like an absolute idiot asking this question as i'm sure the answer is either staring me in the face or just not possible through Mandrill.
Thanks in advance.
Thanks to duellsy and debest for their help, in the end i found a script and expanded on it to add the mail to my own database and style / display it accordingly. Hope this helps someone who may have the same trouble:
<?php
require 'mandrill.php';
define('API_KEY', 'Your API Key');
define('TO_EMAIL', 'user#example.com');
define('TO_NAME', 'Foo Bar');
if(!isset($_POST['mandrill_events'])) {
echo 'A mandrill error occurred: Invalid mandrill_events';
exit;
}
$mail = array_pop(json_decode($_POST['mandrill_events']));
$attachments = array();
foreach ($mail->msg->attachments as $attachment) {
$attachments[] = array(
'type' => $attachment->type,
'name' => $attachment->name,
'content' => $attachment->content,
);
}
$headers = array();
// Support only Reply-to header
if(isset($mail->msg->headers->{'Reply-to'})) {
$headers[] = array('Reply-to' => $mail->msg->headers->{'Reply-to'});
}
try {
$mandrill = new Mandrill(API_KEY);
$message = array(
'html' => $mail->msg->html,
'text' => $mail->msg->text,
'subject' => $mail->msg->subject,
'from_email' => $mail->msg->from_email,
'from_name' => $mail->msg->from_name,
'to' => array(
array(
'email' => TO_EMAIL,
'name' => TO_NAME,
)
),
'attachments' => $attachments,
'headers' => $headers,
);
$async = false;
$result = $mandrill->messages->send($message, $async);
print_r($result);
} catch(Mandrill_Error $e) {
// Mandrill errors are thrown as exceptions
echo 'A mandrill error occurred: ' . get_class($e) . ' - ' . $e->getMessage();
// A mandrill error occurred: Mandrill_PaymentRequired - This feature is only available for accounts with a positive balance.
throw $e;
}
?>
Like using webhooks from other mail parsing services, you'll need to make use of
file_get_contents("php://input")
This will give you the raw data from the webhook, which you can then json_decode and work with the results.
Related
can you help me figure out a way to use the email class of CI4 to send an email with an HTML as the message?
in Codeigniter 3 it is simple and goes like this:
$email->message($this->load->view('html_page_to_send_from_view_folder',$data,true));
but in Codeigniter 4 I tried doing this:
$email->setMessage(echo view('html_page_to_send_from_view_folder',$data,true));
It gives out an error:
syntax error, unexpected echo(T_ECHO), expecting ')'
I also tried putting the view in a variable like so:
$echo_page = echo view('html_page_to_send_from_view_folder',$data,true);
$email->setMessage($echo_page);
but it just throws the same error, I was searching all over the internet and the documentation but couldn't find a way to do this. Help please.
I tried this but got no error, and also got no email :'(
$echo_page = view('html_page_to_send_from_view_folder',$data,true);
$email->setMessage($echo_page);
According to this, if you want to use some template as your message body, you should do something like this:
// Using a custom template
$template = view("email-template", []);
$email->setMessage($template);
CodeIgniter 4 documentation states:
setMessage($body)
Parameters: $body (string) – E-mail message body
Returns: CodeIgniter\Email\Email instance (method chaining)
Return type: CodeIgniter\Email\Email
Sets the e-mail message body:
$email->setMessage('This is my message');
Okay I got it now I made it work by adding this code $email->setNewLine("\r\n"); at the end just after the setMessage:
$email->setMessage($my_message);
$email->setNewLine("\r\n");
and also I set the SMTP port 587 instead of 465:
$config['SMTPPort']= 587;
ALSO, for the setMessage, I did it like this:
$my_message = view('html_page_to_send_from_view_folder',["id" => $data['id']]);
$email->setMessage($my_message);
really weird man....
A. Firstly,
Instead of:❌
$echo_page = echo view('html_page_to_send_from_view_folder',$data,true);
Use this:✅
$echo_page = view('html_page_to_send_from_view_folder',$data);
Notice the luck of an echo statement and not passing true as the third argument of the view(...) hepler function.
B. Secondly, to submit HTML-based emails, ensure that you've set the mailType property to html. This can be achieved by using the setMailType() method on the Email instance. I.e:
$email->setMailType('html');
Alternatively, you could set the "mail type" by passing an array of preference values to the email initialize() method. I.e:
public function sendMail(): bool
{
$email = \Config\Services::email();
$email->initialize([
'SMTPHost' => 'smtp.mailtrap.io',
'SMTPPort' => 2525,
'SMTPUser' => '479d7c109ae335',
'SMTPPass' => '0u6f9d18ef3256',
'SMTPCrypto' => 'tls',
'protocol' => 'smtp',
'mailType' => 'html',
'mailPath' => '/usr/sbin/sendmail',
'SMTPAuth' => true,
'fromEmail' => 'from#example.com',
'fromName' => 'DEMO Company Name',
'subject' => 'First Email Test',
]);
$email->setTo('to#example.com');
$email->setMessage(view('blog_view'));
$response = $email->send();
$response ? log_message("error", "Email has been sent") : log_message("error", $email->printDebugger());
return $response;
}
I'm using the AWS SDK for PHP (version 3.52.33, PHP version 7.2.19) and trying to send emails using the Simple Email Service (SES). I have SES configured, and can run the example code successfully. To make my life easier, I wrote a function to send emails (send_email.php):
<?php
// Path to autoloader for AWS SDK
define('REQUIRED_FILE', "/path/to/vendor/autoload.php");
// Region:
define('REGION','us-west-2');
// Charset
define('CHARSET','UTF-8');
// Specify Sender
define('SENDER', 'sender#xxxx.com');
require REQUIRED_FILE;
use Aws\Ses\SesClient;
use Aws\Ses\Exception\SesException;
function send_email($htmlBody,$textBody,$subject,$recipient) {
$access_key = 'accessKey';
$secret_key = 'secretKey';
$ret_array = array('success' => false,
'message' => 'No Email Sent'
);
$client = SesClient::factory(array(
'version' => 'latest',
'region' => REGION,
'credentials' => array(
'key' => $access_key,
'secret' => $secret_key
)
));
try {
$result = $client->sendEmail([
'Destination' => [
'ToAddresses' => [
$recipient,
],
],
'Message' => [
'Body' => [
'Html' => [
'Charset' => CHARSET,
'Data' => $htmlBody,
],
'Text' => [
'Charset' => CHARSET,
'Data' => $textBody,
],
],
'Subject' => [
'Charset' => CHARSET,
'Data' => $subject,
],
],
'Source' => SENDER,
]);
$messageId = $result->get('MessageId');
$ret_array['success'] = true;
$ret_array['message'] = $messageId;
echo("Email sent! Message ID: $messageId" . "\n");
} catch (SesException $error) {
echo("The email was not sent. Error message: " . $error->getAwsErrorMessage() . "\n");
$ret_array['message'] = $error->getAwsErrorMessage();
}
return $ret_array;
}
This works when called from a simple testing script (test.php) in a terminal:
<?php
ini_set('display_errors','On');
error_reporting(E_ALL | E_STRICT);
require_once './send_email.php';
$email = 'test#email.com';
$htmlbody = 'test';
$txtbody = 'test';
$subject = 'test email';
$success = send_email($htmlbody,$txtbody,$subject,$email);
I get output like:
[~]$ php test.php
Email sent! Message ID: 0101016c8d665369-027be596-f8da-4410-8f09-ff8d7f87181b-000000
which is great. However, I'm doing this to send automated emails from a website (new user registration, password resets, ...) and when I try to use send_email from within a larger script I get a ~%50 success rate (when using a constant email address). Either it works and everything is fine, or it fails without an error message:
The email was not sent. Error message:
I know that an exception is being thrown, as I'm ending up in the catch statement, but I don't know how to get more information about what went wrong since there isn't a message associated with the exception. I've tried expanding what I look for in the catch block:
<snip>
catch (SesException $error) {
echo("The email was not sent. Error message: " . $error->getAwsErrorMessage() . "\n");
$ret_array['message'] = $error->getAwsErrorMessage();
$ret_array['errorCode'] = $error->getAwsErrorCode();
$ret_array['type'] = $error->getAwsErrorType();
$ret_array['response'] = $error->getResponse();
$ret_array['statusCode'] = $error->getStatusCode();
$ret_array['isConnectionError'] = $error->isConnectionError();
}
but when it fails everything is NULL except isConnectionError = false. Anecdotally, it is totally random -- I haven't been able to discern a pattern at all as to when it works and when it fails.
One other potentially relevant note: if I loop the email sending so a new user gets 10 emails, either they all succeed or they all fail.
So, does anyone have any suggestions as to what might be going wrong, or other steps I could take to help diagnose why this is happening?
For anyone running in to a similar issue in the future, I eventually came up with two solutions:
Initially, I gave up hope on the AWS SDK and switched to using PHPMailer which avoided the issue (though I believe at the cost of a loss in performance).
The real issue (I'm fairly certain now) was a mismatch in the versions of PHP between my CLI and what the webserver was providing. This question got me thinking about how that might be the issue. By updating the version of cURL and PHP that the webserver was using, I resolved the issue.
Twilio tells me Error - 52182 Messaging Service not specified, so I obviously don't understand how to specificy if, even though I thought I did. The body of the Twilio debugger says Messaging service SID must be specified
I've not found anything that has helped so far on stack, so I'm chancing a question. The same goes for the Twilio docs.
$recipients = [];
foreach ($userIds as $userId) {
$user = Craft::$app->users->getUserById($userId);
$number = !empty($user->mobil);
if ($number) {
try {
$number = $twilio->lookups->v1->phoneNumbers($user->mobil)->fetch(['countryCode' => 'NO'])->phoneNumber;
$recipients[] = '{"binding_type":"sms", "address":"'.$number.'"}';
} catch (\Exception $e) {
continue;
}
}
}
$twilio = new Client('xxx', 'xxx');
$service = $twilio->notify->v1->services->create();
$twilio->notify->services($service->sid)
->notifications->create([
"toBinding" => $recipients,
"body" => $body
]);
I thought I was specifying the service sid here $twilio->notify->services($service->sid), but apparently I'm not.
Previously I would send one SMS at a time in a loop, but that times out due to a growing list of subscribers.
Thank you for shedding any light on this.
I found this guide on youtube: https://www.youtube.com/watch?v=EMOYY58jyKk which seems to have solved my issues, it's not for PHP but the steps were pretty much the same.
In any case, my final code ended up like so
$notifySid = 'ISxxxx';
// Bulk send the SMS
$notification = $twilio->notify->v1->services($notifySid)
->notifications->create([
"toBinding" => $recipients,
"body" => $body
]);
I am developing code that sends an email from our website through Infusionsoft API & XMLRPC.
Here my code:
$email = $user_rec['email'];
$contactID=$user_rec['client_infusionid'];
echo $contactID;
$Subject = 'Your reset password request at GIC Deal Finders';
$From = $this->GetFromAddress();
$link = 'http://dashboard.gicdealfinders.info/resetpwd.php?email='.
urlencode($email).'&code='.
urlencode($this->GetResetPasswordCode($email));
$htmlBody ='Hello '.$user_rec["name"].'<br/><br/>'.
'There was a request to reset your password at GIC Deal Finders<br/>'.
'Please click the link below to complete the request: <br/>'.$link.'<br/><br/>'.
'<br/>'.
'Regards,<br/>'.
'Toyin Dawodu, MBA<br/>'.
'Founder and Chief Relationship Officer';
$clients = new xmlrpc_client("https://ze214.infusionsoft.com/api/xmlrpc");
$clients->return_type = "phpvals";
$clients->setSSLVerifyPeer(FALSE);
###Build a Key-Value Array to store a contact###
$emailI = array(
'contactList' => $contactID,
'fromAddress' => $From,
'toAddress' => $email,
'ccAddresses' => 'admin#gicdealfinders.info',
'bccAddresses' =>'abhilashrajr.s#gmail.com',
'contentType' => 'HTML',
'subject' => $Subject,
'htmlBody' => $htmlBody,
'textBody' => 'test');
//$check=$myApp->sendEmail($clist,"Test#test.com","~Contact.Email~", "","","Text","Test Subject","","This is the body");
###Set up the call###
$calls = new xmlrpcmsg("APIEmailService.sendEmail", array(
php_xmlrpc_encode($this->infusion_api), #The encrypted API key
php_xmlrpc_encode($emailI) #The contact array
));
###Send the call###
$results = $clients->send($calls);
//$conID = $results->value();
/*###Check the returned value to see if it was successful and set it to a variable/display the results###*/
if(!$results->faultCode()) {
return true;
} else {
print $results->faultCode() . "<BR>";
print $results->faultString() . "<BR>";
return false;
}
The captured error shows:
-1
No method matching arguments: java.lang.String, java.util.HashMap
Can anyone check my code and show me a way to fix it?
As the returned error says, the wrong parameters are sent to Infusionsoft API.
The list of acceptable parameters is provided in Infusionsoft API documentation.
First of all, you need to add your API key as the first value in $emailI array.
Also, Infusionsoft API expects the second parameter to be a list of Contact IDs, which means the second parameter $contactID must be sent from php side as an array.
The following code shows the fixes:
$emailI = array(
'yourApiKey',
array($contactID),
$From,
$email,
'admin#gicdealfinders.info',
'abhilashrajr.s#gmail.com',
'HTML',
$Subject,
$htmlBody,
'test'
);
$calls = new xmlrpcmsg(
"APIEmailService.sendEmail",
array_map('php_xmlrpc_encode', $emailI)
);
Please also notice, that if you have more then just one or two Infusionsoft API calls in your code, it's advisable to use API Helper Libraries. Also you may find another wrappers for Infusionsoft API at github.com if current official Helper Libraries don't work for you.
I'm using this plugin in a CakePHP Application. Everything seems to work except sending emails.
I have the following code in AppController.php
function afterPaypalNotification($txnId)
{
//Here is where you can implement code to apply the transaction to your app.
//for example, you could now mark an order as paid, a subscription, or give the user premium access.
//retrieve the transaction using the txnId passed and apply whatever logic your site needs.
$transaction = ClassRegistry::init('PaypalIpn.InstantPaymentNotification')->findById($txnId);
$this->log($transaction['InstantPaymentNotification']['id'], 'paypal');
//Tip: be sure to check the payment_status is complete because failure
// are also saved to your database for review.
if ($transaction['InstantPaymentNotification']['payment_status'] == 'Completed')
{
//Yay! We have monies!
ClassRegistry::init('PaypalIpn.InstantPaymentNotification')->email(array(
'id' => $txnId,
'subject' => 'Thanks!',
'message' => 'Thank you for the transaction!'
));
}
else
{
//Oh no, better look at this transaction to determine what to do; like email a decline letter.
ClassRegistry::init('PaypalIpn.InstantPaymentNotification')->email(array(
'id' => $txnId,
'subject' => 'Failed!',
'message' => 'Please review your transaction'
));
}
}
But the data returned from Paypal is saved in the instant_payment_notifications table but for some reason the emails are not sent. Has anybody tried this plugin before and did the email fonctionality work?
Do I need to enable email.php in app/Config for the emails to work? I read somewhere on Cake's website that I don't need that file for emails to work, so I guess that's not where the problem is.
Any help will be appreciated.
Thanks.
In CakePhp 2.5 you should use CakeEmail
Create the file /app/Config/email.php with the class EmailConfig. The /app/Config/email.php.default has an example of this file.
Add following line in /app/Controller/AppController.php before class declaration
App::uses('CakeEmail', 'Network/Email');
In afterPaypalNotification function replace
ClassRegistry::init('PaypalIpn.InstantPaymentNotification')->email(array(
'id' => $txnId,
'subject' => 'Thanks!',
'message' => 'Thank you for the transaction!'
));
with (fast e-mail, no style)
CakeEmail::deliver('customer#example.com', 'Thanks!', 'Thank you for the transaction!', array('from' => 'you#example.com'));
or
$Email = new CakeEmail();
$Email->template('email_template', 'email_layout')
->emailFormat('html')
->to('customer#example.com')
->from('you#domain.com')
->viewVars(array('id' => $txnId))
->send();
Email template goes to /app/View/Emails/html/email_template.ctp
Email layouts goes to /app/View/Layouts/Emails/html/email_layout.ctp