I'm currently using cPanel on my server side and i've tried all the tutorials online that show how to pipe all your emails to Laravel project, I did find one tutorial that works on Laravel 4 but unfortunately it didn't work for me on Laravel 5.0:
http://www.sitepoint.com/piping-emails-laravel-application/
I've set up my cPanel "default address" to a php handler file but since i'm working with Laravel I can't get this file to work with the app classes and do stuff for my customers (like send notifications, save email information on the database, etc...)
please let me know if there is a nice clean way to accomplish that.
BTW, I need all the emails on this domain to go to my php handler not from one address only, because each one of my customers got his own email address
I ended up creating a free account on mandrill and they are posting all my incoming emails to one of my routes.. than, I've created a controller to handle the incoming emails from mandrill and i can do whatever I need in there...Thats the best way to do It...I'm getting and processing emails in less than 2 seconds. That's amazing.
I've added the mandrill MX records to a subdomain of mine and now I gave all my customers an email address with this subdomain on it "username#inbox.mydomain.com"
This is my route:
Route::post('inbound/message', 'MailController#inboundMessages');
and this is my controller example:
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Carbon\Carbon;
class MailController extends Controller
{
/**
* main function to receive incoming email from mandrill POST request
* #param JSON $request Mandrill Object in JSON format
* #return string
*/
public function inboundMessages(Request $request){
if(isset($request['mandrill_events'])){
$messageJson = json_decode($request['mandrill_events']);
$message = $messageJson[0]->msg;
$email = [
"to" => $message->email,
"from" => $message->from_email,
"name" => isset($message->from_name) ? $message->from_name : "No Name",
"subject" => isset($message->subject) ? $message->subject : "No Subject",
"content" => isset($message->text) ? $message->text : "",
"content_html" => isset($message->html) ? $message->html : ""
];
//do whatever you want with your $email
}
}
}
hope it helps :) Good luck
Related
I want to fetch all emails in inbox and store them in realtime but the way i m doing it is a little bit wrong :
it's something like this:
class Kernel extends ConsoleKernel
...
$schedule->call(function () {
// connect using credentials
//get all emails
//copy emails
//delete emails when they get copied correctly
})->everyMinute(); // repeat
this Guarantees that the emails in the database will not be copied because the emails are no longer in the inbox .
But now we have a case where we need to keep these messages so we replaced this with :
// connect using credentials
//get all emails
//filter only unseen
//copy emails
//mark these emails as seen
But the problem of all of these solution is that we get emails .
The solution we did is working but added another problem of reloading same emails over and over .
I reread the Documentation and found this
possible solution :
Using events that triggers in the entire package and capture the new event witch gets triggered when a new email is received.
In this example i found some useful methods and classes .
class CustomMessageNewEvent extends Webklex\PHPIMAP\Events\MessageNewEvent {
/**
* Create a new event instance.
* #var \Webklex\PHPIMAP\Message[] $messages
* #return void
*/
public function __construct($messages) {
$this->message = $messages[0];
echo "New message: ".$this->message->subject."\n";
}
}
But i m not sure how to implement them in Laravel , juste where and how should i register / capture this `new` Event !
**Especially that we have multiple Client instances not only one ( foreach user ... )**
Thank you so much for reading all this and hopefully people find this question useful.
When I've done similar tasks in the past I've used the Message-ID defined in the email spec to identify each email uniquely.
You can use your IMAP library to get a list of emails with their Message-IDs, then compare those Message-IDs to your database. Just make sure you add a new field to your Email model (or whatever you've called it) to store the Message-ID.
during the conception of my web site using laravel 7 I found some troubles when I wanted to customize my laravel customize my Laravel email verification message.
first, I went to this file "C:\xampp\htdocs\clinique_juridique\vendor\laravel\framework\src\Illuminate\Auth\Notifications\VerifyEmail.php",then i translate the sentences that are there .
Here I met two issues, the first one some sentences are not in VerifyEmail.php so I couldn't translate them the second one, I didn't know how to change the style of the message, of course, also I didn't know how to include the logo of my website.
thank you in advance.
So I think you're asking about this specific part of the code (took from Laravel 8 vendor code):
/**
* Build the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
$verificationUrl = $this->verificationUrl($notifiable);
if (static::$toMailCallback) {
return call_user_func(static::$toMailCallback, $notifiable, $verificationUrl);
}
return (new MailMessage)
->subject(Lang::get('Verify Email Address'))
->line(Lang::get('Please click the button below to verify your email address.'))
->action(Lang::get('Verify Email Address'), $verificationUrl)
->line(Lang::get('If you did not create an account, no further action is required.'));
}
First, you may use this class VerifyEmail and method toMail to send this confirmation email to your client, but if you look closer, you can identify that this function is using the Lang class, which can be found at Laravel Localization.
Otherwise, if you want to make it more complex you can create your own class MyVerifyEmail which extends VerifyEmail and recreate toMail method to serve your needs, but I can't think of a scenario where you do this.
Second, if you want to include some personalized style of your mail, try creating a Mailable, with this approach you can use a custom view (of course including a logo).
And finally, I encourage to do not to modify the vendor's directory, because it stores all the libraries that laravel needs to work properly. Instead, extend any class which you may want to modify.
I'm using Laravel 5.3 and the SES driver in order to send my emails.
I've set up my database and routes so that, whenever I send an email that returns as a bounce, I get a notification and add this email to a table of "invalid emails".
Now I need to setup my app so it only sends an email if the email is NOT in this bounce table. It's a check that will be made for every single email sent by this app, with no exceptions.
Is there an easy way to make this check on the email driver, or do I need to change all calls to the Mail facade and check this before sending the email?
I'd suggest creating your own Mailable class which inherits from \Illuminate\Mail\Mailable.
There is a method there called buildRecipients() which looks like this:
/**
* Add all of the recipients to the message.
*
* #param \Illuminate\Mail\Message $message
* #return $this
*/
protected function buildRecipients($message)
{
foreach (['to', 'cc', 'bcc', 'replyTo'] as $type) {
foreach ($this->{$type} as $recipient) {
$message->{$type}($recipient['address'], $recipient['name']);
}
}
return $this;
}
You could hook in to (override) this and add some logic to only add the recipient if he is not on the "blocked" list.
if i want send email with SwiftMailer in symfony then i must in action:
$message = $this->getMailer()->compose(
array('user#gmail.com' => 'user'),
$affiliate->getEmail(),
'Jobeet affiliate token',
body
);
$this->getMailer()->send($message);
but this doesnt working in template and in model (i would like create function for this).
I wouldn't recommend sending mail using a template - put a link in the template and call the action to send the mail ... you can send from a model although again i wouldn't recommend it as using sfContext::getInstance() inside the model is a really bad practice as it makes the model class rely on the context. So, your model class can't be unit tested as it needs a context to work...
You need an instance of the current sfContext to do it ... i would suggest passing it as a parameter when you create the model
It's a MVC question.
Here is the situation:
I am writing an application where I have "groups".
You can invite other persons to your groups by typing their email and clicking "invite".
There are two ways this functionality can be called: a) web interface and b) API
After the mail sending is over I want to report to the user which mails were sent successfully (i.e., if the SMTP send succeeded. Currently, I am not interested in reporting mail bounces).
So, I am thinking how should I design so that there is no code duplication. That is, API and web-interface should share the bulk of the code.
To do this, I can create the method "invite" inside the model "group". So, the API and and the Web-interface can just call:
group->invite($emailList);
This method can send the emails. But the, problem is, then I have to access the mail templates, create the views for the mails, and then send the mails. Which should actually be in the "View" part or at least in the "Controller" part.
What is the most elegant design in this situation?
Note: I am really thinking to write this in the Model. My only doubt is: previously I thought sending mails also as "presentation". Since it is may be considered as a different form of generating output.
Added after edit
I understand that View does not necessarily have to be output to the browser. And that is where my doubt is. Now the problem is, say I have a "task list" in my app. We can assign a task to some folks. Now the "assignTo" method can be called in two situations: 1) While creating the task 2) reassign a task to someone else.
In both cases the new assignee should get the email notification. So if the method "assignTo" is not sending the mail, we have to duplicate the mailing part in two places: "task create controller" and "task reassign controller".
I wanted to avoid this duplication.
The View doesn't necessarily have to be an output to the browser that the user gets to see. It can also be the template that's being emailed. The Controller receives input on what to do, requests the necessary information from the Model, and users the View to output that information. In this case, the View would be the template of the email, and the Controller has the task to email that output.
View: click "invite" (or for the API: send an invite command);
Controller: user clicked "invite", get data from model;
Model: Controller requests data (emails for specific folks or whatnot), return;
Controller: receives data from Model, setup data for the View (template) and email the "View".
After that, return something to the API, or tell the Controller to output a View for the web interface that tells the user that the invite has been processed.
I had same doubts with mailing system in Kohana myself, in the end figured out the best way to do it was like this;
Have one main 'mailer' class ( wrapper ) which will contain methods to send mails, extend it for each separately used mailer classes ( factories );
application/classes/mailer.php:
abstract class Mailer {
protected $from;
protected $to;
protected $cc;
protected $bcc;
protected $subject;
protected $body;
protected $reply_to;
protected $sent_on;
protected $content_type = 'text/html';
protected $headers;
protected $template;
public static function factory($name)
{
$class = 'Mailer_'.$name;
return new $class();
}
public function __construct()
{
return $this;
}
public function send($save = FALSE)
{
// send the email using swift mailer, zend_mail, phpmailer, whatever..
}
protected function save($to, $subject, $body, $headers)
{
}
}
application/classes/mailer/user.php
class Mailer_User extends Mailer {
// Who is sending the mail
protected $from = "users#domain.com";
// Content type of the email
protected $content_type = 'text/html';
public function email_activated($name, $email)
{
$this->to = $email;
$this->subject = 'Your email has been verified';
$this->body = View::factory('mailer/user/email_verified')
->set('name', $name)
->render();
return $this;
}
}
and later on in code use it like factory;
Mailer::factory('user')
->email_activated( $user->username, $user->email)
->send();
sending the email from wherever you want it to.
The API itself is group of all public methods in model - no additional wrapper is needed, because model does all the wrapping itself (and keeps other methods non-public). The application itself should not use another api than the official one is (so you prevent the duplication).
I'd do something like:
sendMail(array $recipients);
sendGroupMail($group_id) not{
sendMail(/*get recipients by group_id*/);
};