Add mailer
This commit is contained in:
parent
fb84bd03d1
commit
2a792c0945
|
@ -0,0 +1,146 @@
|
|||
<?php
|
||||
namespace controllers\internals;
|
||||
|
||||
use Monolog\Handler\StreamHandler;
|
||||
use Monolog\Logger;
|
||||
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
use PHPMailer\PHPMailer\SMTP;
|
||||
use PHPMailer\PHPMailer\Exception;
|
||||
|
||||
/**
|
||||
* Mailing class
|
||||
*/
|
||||
class Mailer extends \descartes\Controller
|
||||
{
|
||||
private $log;
|
||||
private $mail;
|
||||
|
||||
public function __construct ()
|
||||
{
|
||||
$this->log = new Logger('Mailer');
|
||||
$this->log->pushHandler(new StreamHandler(PWD_LOGS . '/mail.log', Logger::DEBUG));
|
||||
|
||||
$this->mail = new PHPMailer(true);
|
||||
$mail->SMTPDebug = SMTP::DEBUG_OFF;
|
||||
$mail->isSMTP();
|
||||
$mail->Host = MAIL['SMTP']['HOST'];
|
||||
$mail->SMTPAuth = true;
|
||||
$mail->Username = MAIL['SMTP']['USER'];
|
||||
$mail->Password = MAIL['SMTP']['PASS'];
|
||||
$mail->Port = MAIL['SMTP']['PORT'];
|
||||
$mail->setFrom(MAIL['FROM']);
|
||||
|
||||
if (MAIL['SMTP']['TLS'])
|
||||
{
|
||||
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send email
|
||||
* @param array $destinations : Destinations address
|
||||
* @param string $subject : Message subject
|
||||
* @param string $message : Message
|
||||
* @param ?string $alt_message : Alt Message if no html support. Null if message is not html.
|
||||
* @param array $attachments : List of path to attachment files
|
||||
* @return bool : false on error, true else
|
||||
*/
|
||||
public function send (array $destinations, string $subject, string $message, ?string $alt_message = null, array $attachments = [])
|
||||
{
|
||||
try
|
||||
{
|
||||
$mail = clone $this->mail;
|
||||
|
||||
foreach ($destinations as $destination)
|
||||
{
|
||||
//Only use bcc to avoid leak
|
||||
$mail->addBCC($destination);
|
||||
}
|
||||
|
||||
foreach ($attachments as $attachment)
|
||||
{
|
||||
$mail->addAttachment($attachment);
|
||||
}
|
||||
|
||||
$mail->Subject = $subject;
|
||||
$mail->Body = $message;
|
||||
|
||||
if ($alt_message)
|
||||
{
|
||||
$mail->isHTML($html);
|
||||
$mail->AltBody = $alt_message;
|
||||
}
|
||||
|
||||
$mail->send();
|
||||
return true;
|
||||
}
|
||||
catch (\Throwable $t)
|
||||
{
|
||||
$this->log->error('Error sending mail : ' . $t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an email body
|
||||
* @param array $settings : [
|
||||
* string 'type' => Internal RaspiSMS email type,
|
||||
* string 'subject' => Email subject,
|
||||
* string 'template' => Email template to use
|
||||
* ?string 'alt_template' => Template to use for alt message, if null ignore
|
||||
* ]
|
||||
*
|
||||
* @param array : Datas to inject into email template
|
||||
*
|
||||
* @return array [
|
||||
* string 'body' => email body
|
||||
* ?string 'alt_body' => email alternative body if needed
|
||||
* ]
|
||||
*/
|
||||
private function generate_body(array $settings, array $datas) : array
|
||||
{
|
||||
//Generate body of email
|
||||
ob_start();
|
||||
$this->render($settings['template'], $datas);
|
||||
$body = ob_get_clean();
|
||||
|
||||
//Generate alt body if needed
|
||||
$alt_body = null;
|
||||
if ($settings['alt_template'] ?? false)
|
||||
{
|
||||
ob_start();
|
||||
$this->render($settings['alt_template'], $datas);
|
||||
$alt_body = ob_get_clean();
|
||||
}
|
||||
|
||||
return [
|
||||
'body' => $body,
|
||||
'alt_body' => $alt_body,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue an email for later sending
|
||||
* @param string $destination : email address to send email to
|
||||
* @param array $settings : Email settings
|
||||
* @param array $datas : Datas to inject into email template
|
||||
* @return bool : true on success, false on error
|
||||
*/
|
||||
public function enqueue (string $destination, string $settings, string $datas) : bool
|
||||
{
|
||||
$response = $this->generate_body($settings, $datas);
|
||||
|
||||
$message = [
|
||||
'destinations' => [$destination],
|
||||
'subject' => $settings['subject'],
|
||||
'body' => $response['body'],
|
||||
'alt_body' => $response['alt_body'],
|
||||
];
|
||||
|
||||
$error_code = null;
|
||||
$queue = msg_get_queue(QUEUE_ID_EMAIL);
|
||||
$success = msg_send($queue, QUEUE_TYPE_EMAIL, $message, true, true, $error_code);
|
||||
return (bool) $success;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of RaspiSMS.
|
||||
*
|
||||
* (c) Pierre-Lin Bonnemaison <plebwebsas@gmail.com>
|
||||
*
|
||||
* This source file is subject to the GPL-3.0 license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace daemons;
|
||||
|
||||
use Monolog\Handler\StreamHandler;
|
||||
use Monolog\Logger;
|
||||
|
||||
/**
|
||||
* Phone daemon class.
|
||||
*/
|
||||
class Mailer extends AbstractDaemon
|
||||
{
|
||||
private $mailer_queue;
|
||||
private $last_message_at;
|
||||
private $bdd;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $phone : A phone table entry
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$name = 'RaspiSMS Daemon Mailer';
|
||||
$logger = new Logger($name);
|
||||
$logger->pushHandler(new StreamHandler(PWD_LOGS . '/daemons.log', Logger::DEBUG));
|
||||
$pid_dir = PWD_PID;
|
||||
$no_parent = false; //Rattach to parent so parent can stop it
|
||||
$additional_signals = [];
|
||||
$uniq = true; //Sender should be uniq
|
||||
|
||||
//Construct the daemon
|
||||
parent::__construct($name, $logger, $pid_dir, $no_parent, $additional_signals, $uniq);
|
||||
|
||||
parent::start();
|
||||
}
|
||||
|
||||
public function run()
|
||||
{
|
||||
$find_message = true;
|
||||
while ($find_message)
|
||||
{
|
||||
//Call message
|
||||
$msgtype = null;
|
||||
$maxsize = 409600;
|
||||
$message = null;
|
||||
|
||||
$error_code = null;
|
||||
$success = msg_receive($this->mailer_queue, QUEUE_TYPE_MAIL, $msgtype, $maxsize, $message, true, MSG_IPC_NOWAIT, $error_code); //MSG_IPC_NOWAIT == dont wait if no message found
|
||||
if (!$success && MSG_ENOMSG !== $error_code)
|
||||
{
|
||||
$this->logger->critical('Error for mailer queue reading, error code : ' . $error_code);
|
||||
$find_message = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$message)
|
||||
{
|
||||
$find_message = false;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->logger->info('Try sending email : ' . json_encode($message));
|
||||
|
||||
$mailer = new \controllers\internals\Mailer();
|
||||
$success = $mailer->send($message['destinations'], $message['subject'], $message['body'], $message['alt_body']);
|
||||
if (!$success)
|
||||
{
|
||||
$this->logger->error('Failed sending email');
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->logger->info('Success sending email');
|
||||
}
|
||||
|
||||
//Send mail every 5 seconds
|
||||
usleep(5 * 1000000);
|
||||
}
|
||||
|
||||
public function on_start()
|
||||
{
|
||||
//Set last message at to construct time
|
||||
$this->mailer_queue = msg_get_queue(QUEUE_ID_MAIL);
|
||||
|
||||
$this->logger->info('Starting Mailer daemon with pid ' . getmypid());
|
||||
}
|
||||
|
||||
public function on_stop()
|
||||
{
|
||||
//Delete queue on daemon close
|
||||
$this->logger->info('Closing queue : ' . QUEUE_ID_MAIL);
|
||||
msg_remove_queue($this->mailer_queue);
|
||||
|
||||
$this->logger->info('Stopping Mailer daemon with pid ' . getmypid());
|
||||
}
|
||||
|
||||
public function handle_other_signals($signal)
|
||||
{
|
||||
$this->logger->info('Signal not handled by ' . $this->name . ' Daemon : ' . $signal);
|
||||
}
|
||||
}
|
|
@ -45,6 +45,10 @@
|
|||
//Queues ids
|
||||
'QUEUE_ID_WEBHOOK' => ftok(__FILE__, 'w'),
|
||||
'QUEUE_TYPE_WEBHOOK' => 3,
|
||||
|
||||
//Queue email
|
||||
'QUEUE_ID_EMAIL' => ftok(__FILE__, 'e'),
|
||||
'QUEUE_TYPE_EMAIL' => 3,
|
||||
|
||||
//User default settings
|
||||
'USER_DEFAULT_SETTINGS' => [
|
||||
|
|
|
@ -5,5 +5,17 @@
|
|||
'DATABASE_NAME' => '%APP_DATABASE_NAME%',
|
||||
'DATABASE_USER' => '%APP_DATABASE_USER%',
|
||||
'DATABASE_PASSWORD' => '%APP_DATABASE_PASS%',
|
||||
|
||||
//Mailer SMTP credentials
|
||||
'MAIL' => [
|
||||
'SMTP' => [
|
||||
'USER' => '%APP_MAIL_SMTP_USER%',
|
||||
'PASS' => '%APP_MAIL_SMTP_PASS%',
|
||||
'HOST' => '%APP_MAIL_SMTP_HOST%',
|
||||
'TLS' => %APP_MAIL_SMTP_TLS% ,
|
||||
'PORT' => %APP_MAIL_SMTP_PORT% ,
|
||||
],
|
||||
'FROM' => '%APP_MAIL_FROM%',
|
||||
],
|
||||
|
||||
];
|
||||
|
|
Loading…
Reference in New Issue