penpot/backend/src/app/tasks/sendmail.clj
2020-08-18 19:32:11 +02:00

101 lines
3.4 KiB
Clojure

;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; This Source Code Form is "Incompatible With Secondary Licenses", as
;; defined by the Mozilla Public License, v. 2.0.
;;
;; Copyright (c) 2020 UXBOX Labs SL
(ns app.tasks.sendmail
(:require
[clojure.data.json :as json]
[clojure.tools.logging :as log]
[postal.core :as postal]
[app.common.data :as d]
[app.common.exceptions :as ex]
[app.config :as cfg]
[app.metrics :as mtx]
[app.util.http :as http]))
(defmulti sendmail (fn [config email] (:sendmail-backend config)))
(defmethod sendmail "console"
[config email]
(let [out (with-out-str
(println "email console dump:")
(println "******** start email" (:id email) "**********")
(println " from: " (:from email))
(println " to: " (:to email "---"))
(println " reply-to: " (:reply-to email))
(println " subject: " (:subject email))
(println " content:")
(doseq [item (:content email)]
(when (= (:type item) "text/plain")
(println (:value item))))
(println "******** end email "(:id email) "**********"))]
(log/info out)))
(defmethod sendmail "sendgrid"
[config email]
(let [apikey (:sendmail-backend-apikey config)
dest (mapv #(array-map :email %) (:to email))
params {:personalizations [{:to dest
:subject (:subject email)}]
:from {:email (:from email)}
:reply_to {:email (:reply-to email)}
:content (:content email)}
headers {"Authorization" (str "Bearer " apikey)
"Content-Type" "application/json"}
body (json/write-str params)]
(try
(let [response (http/send! {:method :post
:headers headers
:uri "https://api.sendgrid.com/v3/mail/send"
:body body})]
(when-not (= 202 (:status response))
(log/error "Unexpected status from sendgrid:" (pr-str response))))
(catch Throwable error
(log/error "Error on sending email to sendgrid:" (pr-str error))))))
(defn- get-smtp-config
[config]
{:host (:smtp-host config)
:port (:smtp-port config)
:user (:smtp-user config)
:pass (:smtp-password config)
:ssl (:smtp-ssl config)
:tls (:smtp-tls config)})
(defn- email->postal
[email]
{:from (:from email)
:to (:to email)
:subject (:subject email)
:body (d/concat [:alternative]
(map (fn [{:keys [type value]}]
{:type (str type "; charset=utf-8")
:content value})
(:content email)))})
(defmethod sendmail "smtp"
[config email]
(let [config (get-smtp-config config)
email (email->postal email)
result (postal/send-message config email)]
(when (not= (:error result) :SUCCESS)
(ex/raise :type :sendmail-error
:code :email-not-sent
:context result))))
(defn handler
{:app.tasks/name "sendmail"}
[{:keys [props] :as task}]
(sendmail cfg/config props))
(mtx/instrument-with-summary!
{:var #'handler
:id "tasks__sendmail"
:help "Timing of sendmail task."})