Move response to own class
Implement warning output Implement warning when URL and string provided for HTML/plain Turn allowempty to config key Add option to prefer URL over string for HTML/plain Add user agent to curl requests Update OpenAPI Bump version to 0.5
This commit is contained in:
parent
48087056b5
commit
730ad8c0e1
7 changed files with 97 additions and 37 deletions
|
@ -12,6 +12,7 @@ class File {
|
|||
curl_setopt($ch, CURLOPT_URL, $this->url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $follow);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; KumiSystemsMailer/0.5; +https://expmail.kumi.systems/doc/)");
|
||||
curl_setopt($ch, CURLOPT_HEADER, true);
|
||||
curl_setopt($ch, CURLOPT_NOBODY, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
|
@ -65,6 +66,7 @@ class File {
|
|||
curl_setopt($ch, CURLOPT_URL, $this->url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $follow);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; KumiSystemsMailer/0.5; +https://expmail.kumi.systems/doc/)");
|
||||
curl_setopt($ch, CURLOPT_HEADER, false);
|
||||
curl_setopt($ch, CURLOPT_NOBODY, false);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
|
|
|
@ -12,14 +12,13 @@ class Mail {
|
|||
global $MAIL_HOST, $MAIL_USER, $MAIL_PASS, $MAIL_STARTTLS, $MAIL_SMTPS, $MAIL_PORT;
|
||||
$this->mailer = new PHPMailer(true);
|
||||
$this->mailer->isSMTP();
|
||||
$this->mailer->AllowEmpty = true;
|
||||
$this->mailer->Host = $host ?: $MAIL_HOST;
|
||||
$this->mailer->SMTPAuth = (bool) $MAIL_USER;
|
||||
$this->mailer->Username = $user ?: $MAIL_USER;
|
||||
$this->mailer->Password = $password ?: $MAIL_PASS;
|
||||
$this->mailer->SMTPSecure = $MAIL_STARTTLS ? PHPMailer::ENCRYPTION_STARTTLS : ($MAIL_SMTPS ? PHPMailer::ENCRYPTION_SMTPS : false);
|
||||
$this->mailer->Port = $port ?: ($MAIL_PORT ?: ($MAIL_SMTPS ? 465 : 587));
|
||||
$this->mailer->XMailer = "Kumi Systems Mailer 0.1 (https://kumi.systems/)";
|
||||
$this->mailer->XMailer = "Kumi Systems Mailer 0.5 (https://kumi.systems/)";
|
||||
}
|
||||
|
||||
function add_attachment($content, $filename=null, $cid=null) {
|
||||
|
@ -68,6 +67,10 @@ class Mail {
|
|||
}
|
||||
}
|
||||
|
||||
function allow_empty($boolean) {
|
||||
$this->mailer->AllowEmpty = $boolean;
|
||||
}
|
||||
|
||||
static function FromRequest($req) {
|
||||
$mail = new self();
|
||||
|
||||
|
@ -76,12 +79,14 @@ class Mail {
|
|||
$mail->add_ccs($req->get_ccs());
|
||||
$mail->add_bccs($req->get_bccs());
|
||||
|
||||
$html = $req->prepare_html();
|
||||
$text = $req->prepare_text(!$req->has_config("noconversion"));
|
||||
$html = $req->prepare_html($req->has_config("urlbeforestring"));
|
||||
$text = $req->prepare_text(!$req->has_config("noconversion"), $req->has_config("urlbeforestring"));
|
||||
$mail->add_content($html, $text);
|
||||
|
||||
$mail->add_attachments($req->get_attachments(true, true, $req->has_config("ignoredlfails")));
|
||||
|
||||
$mail->allow_empty($req->has_config("allowempty"));
|
||||
|
||||
return $mail;
|
||||
}
|
||||
|
||||
|
|
|
@ -77,8 +77,15 @@ class Request {
|
|||
return $this->json["config"];
|
||||
}
|
||||
|
||||
function get_html() {
|
||||
if ($this->json["html"]) {
|
||||
function get_html($urlbeforestring=false) {
|
||||
if ($this->json["html"] && $this->json["htmlurl"]) {
|
||||
if ($urlbeforestring) {
|
||||
trigger_error("Both `html` and `htmlurl` provided - using `htmlurl` as `urlbeforestring` config key was also provided", E_USER_WARNING);
|
||||
} else {
|
||||
trigger_error("Both `html` and `htmlurl` provided - using `html`", E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
if ($this->json["html"] && !$urlbeforestring) {
|
||||
$html = $this->json["html"];
|
||||
} else if ($this->json["htmlurl"]) {
|
||||
try {
|
||||
|
@ -87,6 +94,8 @@ class Request {
|
|||
} catch (\Exception $e) {
|
||||
throw new Exception("Could not fetch URL for HTML message: " . $e->getMessage());
|
||||
}
|
||||
} else if ($this->json["html"]) {
|
||||
$html = $this->json["html"];
|
||||
}
|
||||
|
||||
return $html;
|
||||
|
@ -123,8 +132,15 @@ class Request {
|
|||
}
|
||||
}
|
||||
|
||||
function get_text($conversion=true) {
|
||||
if ($this->json["text"]) {
|
||||
function get_text($conversion=true, $urlbeforestring=false) {
|
||||
if ($this->json["text"] && $this->json["texturl"]) {
|
||||
if ($urlbeforestring) {
|
||||
trigger_error("Both `text` and `texturl` provided - using `texturl` as `urlbeforestring` config key was also provided", E_USER_WARNING);
|
||||
} else {
|
||||
trigger_error("Both `text` and `texturl` provided - using `text`", E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
if ($this->json["text"] && !$urlbeforestring) {
|
||||
$text = $this->json["text"];
|
||||
} else if ($this->json["texturl"]) {
|
||||
try {
|
||||
|
@ -133,6 +149,8 @@ class Request {
|
|||
} catch (\Exception $e) {
|
||||
throw new Exception("Could not fetch URL for plain text message: " . $e->getMessage());
|
||||
}
|
||||
} else if ($this->json["text"]) {
|
||||
$text = $this->json["text"];
|
||||
} else if ($conversion) {
|
||||
if ($html=$this->get_html()) {
|
||||
$text = html_entity_decode(
|
||||
|
@ -149,8 +167,8 @@ class Request {
|
|||
return in_array($key, $this->get_config());
|
||||
}
|
||||
|
||||
function prepare_html() {
|
||||
return $this->prepare_string($this->get_html());
|
||||
function prepare_html($urlbeforestring=false) {
|
||||
return $this->prepare_string($this->get_html($urlbeforestring));
|
||||
}
|
||||
|
||||
function prepare_string($string) {
|
||||
|
@ -158,8 +176,8 @@ class Request {
|
|||
return $string;
|
||||
}
|
||||
|
||||
function prepare_text($conversion=true) {
|
||||
return $this->prepare_string($this->get_text($conversion));
|
||||
function prepare_text($conversion=true, $urlbeforestring=false) {
|
||||
return $this->prepare_string($this->get_text($conversion, $urlbeforestring));
|
||||
}
|
||||
|
||||
}
|
24
Response.class.php
Normal file
24
Response.class.php
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
class Response {
|
||||
private $error;
|
||||
private $warnings;
|
||||
|
||||
function handle_warning($warning) {
|
||||
if (!$this->warnings) $this->warnings = array();
|
||||
array_push($this->warnings, $warning);
|
||||
}
|
||||
|
||||
function handle_exception($e) {
|
||||
$this->error = $e->getMessage();
|
||||
$this->respond();
|
||||
}
|
||||
|
||||
function respond() {
|
||||
header('Content-Type: application/json');
|
||||
$response = array("status" => $this->error ? "error" : "success");
|
||||
if ($this->error) $response["error"] = $this->error;
|
||||
if ($this->warnings) $response["warnings"] = $this->warnings;
|
||||
die(json_encode($response));
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -1,7 +1,7 @@
|
|||
openapi: 3.0.0
|
||||
info:
|
||||
description: A simple endpoint to send email messages
|
||||
version: '0.4'
|
||||
version: '0.5'
|
||||
title: EXPMail
|
||||
contact:
|
||||
email: support@kumi.systems
|
||||
|
@ -36,17 +36,18 @@ paths:
|
|||
error:
|
||||
type: string
|
||||
description: 'Error message, only included if an error has occurred'
|
||||
warning:
|
||||
type: array
|
||||
description: 'Array of warning messages generated during the sending process, if any'
|
||||
items:
|
||||
type: string
|
||||
|
||||
servers:
|
||||
- url: 'https://expmail.kumi.live'
|
||||
components:
|
||||
schemas:
|
||||
Config:
|
||||
type: string
|
||||
required:
|
||||
- key
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
Placeholder:
|
||||
type: object
|
||||
required:
|
||||
|
@ -139,8 +140,10 @@ components:
|
|||
type: array
|
||||
description: >
|
||||
Array of `Config` keys to change the default behaviour
|
||||
* `noconversion` - Do not automatically convert HTML to plain text if no plain text message is explicitly given
|
||||
* `allowempty` - Allow messages to have an empty body, would otherwise return an error
|
||||
* `ignoredlfails` - If an attachment fails to download, just leave it out and continue processing the message
|
||||
* `noconversion` - Do not automatically convert HTML to plain text if no plain text message is explicitly given
|
||||
* `urlbeforestring` - If both a string and a URL are given for the HTML or plain text content, prefer URL (else: prefer string)
|
||||
items:
|
||||
$ref: '#/components/schemas/Config'
|
||||
key:
|
||||
|
|
34
sender.php
34
sender.php
|
@ -3,21 +3,27 @@
|
|||
require_once 'config.php';
|
||||
require_once 'Mail.class.php';
|
||||
require_once 'Request.class.php';
|
||||
require_once 'Response.class.php';
|
||||
|
||||
try {
|
||||
$req = new Request(file_get_contents('php://input'));
|
||||
$mail = Mail::FromRequest($req);
|
||||
$mail->send();
|
||||
function handle_exception($e) {
|
||||
global $res;
|
||||
$res->handle_exception($e);
|
||||
}
|
||||
|
||||
$response = array(
|
||||
"status" => "success"
|
||||
);
|
||||
function handle_warning($errno, $errstr) {
|
||||
global $res;
|
||||
if ($res) {
|
||||
$res->handle_warning($errstr);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$response = array(
|
||||
"status" => "error",
|
||||
"error" => "{$e->getMessage()}"
|
||||
);
|
||||
};
|
||||
$res = new Response();
|
||||
|
||||
echo json_encode($response);
|
||||
set_exception_handler("handle_exception");
|
||||
set_error_handler("handle_warning", E_USER_WARNING);
|
||||
|
||||
$req = new Request(file_get_contents('php://input'));
|
||||
$mail = Mail::FromRequest($req);
|
||||
$mail->send();
|
||||
|
||||
$res->respond();
|
||||
|
|
Loading…
Reference in a new issue