diff --git a/File.class.php b/File.class.php index fdb9d7e..cc47b1d 100644 --- a/File.class.php +++ b/File.class.php @@ -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); diff --git a/Mail.class.php b/Mail.class.php index 2613edc..e2cd652 100644 --- a/Mail.class.php +++ b/Mail.class.php @@ -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; } diff --git a/Request.class.php b/Request.class.php index 2aa78c8..0255da8 100644 --- a/Request.class.php +++ b/Request.class.php @@ -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)); } } \ No newline at end of file diff --git a/Response.class.php b/Response.class.php new file mode 100644 index 0000000..a3d0560 --- /dev/null +++ b/Response.class.php @@ -0,0 +1,24 @@ +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)); + } +} \ No newline at end of file diff --git a/doc/index.html b/doc/index.html index 1580e18..8434aa8 100644 --- a/doc/index.html +++ b/doc/index.html @@ -519,7 +519,7 @@ data-styled.g140[id="sc-global-kJtbWf1"]{content:"sc-global-kJtbWf1,"}/*!sc*/ 55.627 l 55.6165,55.627 -231.245496,231.24803 c -127.185,127.1864 -231.5279,231.248 -231.873,231.248 -0.3451,0 -104.688, -104.0616 -231.873,-231.248 z - " fill="currentColor">

EXPMail (0.4)

Download OpenAPI specification:Download

A simple endpoint to send email messages

+ " fill="currentColor">

EXPMail (0.5)

Download OpenAPI specification:Download

A simple endpoint to send email messages

sending

Sending out an email

Send out an email

Request Body schema: application/json

Object defining the email message to be sent

subject
string

Subject of the email

@@ -535,14 +535,16 @@ data-styled.g140[id="sc-global-kJtbWf1"]{content:"sc-global-kJtbWf1,"}/*!sc*/
Array of objects (Placeholder)

Array of Placeholder objects. Any occurrences of {PLACEHOLDER_NAME} (name in all caps enclosed with curly brackets) in the email's HTML or plain text will be replaced by value.

config
Array of strings (Config)

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)
key
required
string

API key to authenticate request with

Responses

Request samples

Content type
application/json
{
  • "subject": "string",
  • "html": "string",
  • "htmlurl": "string",
  • "text": "string",
  • "texturl": "string",
  • "sender":
    {
    },
  • "recipients":
    [
    ],
  • "ccs":
    [
    ],
  • "bccs":
    [
    ],
  • "attachments":
    [
    ],
  • "placeholders":
    [
    ],
  • "config":
    [
    ],
  • "key": "string"
}

Response samples

Content type
application/json
{
  • "status": "string",
  • "error": "string"
}
+

Request samples

Content type
application/json
{
  • "subject": "string",
  • "html": "string",
  • "htmlurl": "string",
  • "text": "string",
  • "texturl": "string",
  • "sender":
    {
    },
  • "recipients":
    [
    ],
  • "ccs":
    [
    ],
  • "bccs":
    [
    ],
  • "attachments":
    [
    ],
  • "placeholders":
    [
    ],
  • "config":
    [
    ],
  • "key": "string"
}

Response samples

Content type
application/json
{
  • "status": "string",
  • "error": "string",
  • "warning":
    [
    ]
}