In addition to the built-in mailerutility, SØAD can integrate with third-party email providers such as Mailgun, SendGrid, or Amazon SES. These services provide reliable delivery and advanced features beyond simple SMTP.
The following recipe demonstrates how to send email through the SendGrid API using a Jetty HttpClient (implemented as a singleton). The same approach can be applied to other REST-based providers by adjusting the endpoint, authentication, and parameters.
fromutilsimportrender,Logfromorg.eclipse.jetty.clientimportHttpClient,WWWAuthenticationProtocolHandlerfromorg.eclipse.jetty.clientimportStringRequestContentfromjava.util.concurrent.locksimportReentrantLockfromjava.util.functionimportConsumerimportjson# this class is shared across transactionsclassHttpClientProvider:_client=None_lock=ReentrantLock()defget_client(self):# Double-checked locking to be safe under concurrencyifself._clientisNone:self._lock.lock()try:ifself._clientisNone:client=HttpClient()client.start()# Disable default auth handler - if you have auth issue with mail APIclient.getProtocolHandlers().remove(WWWAuthenticationProtocolHandler.NAME)self._client=clientfinally:self._lock.unlock()returnself._clientclassHeadersConsumer(Consumer):defaccept(self,fields):# Prefer env var or secure config for API keyapi_key=System.getenv("MAIL_API_KEY")fields.add("Authorization","Bearer "+api_key)fields.add("Content-Type","application/json")classMail_sender(object):defsend(self,ctx):api_url="https://api.sendgrid.com/v3/mail/send"fr="[email protected]"to="[email protected]"subject="Test Email"content="Hello, this is a test email."try:client=HttpClientProvider.get_client()client_request=client.POST(api_url)client_request.headers(HeadersConsumer())mail_data={"personalizations":[{"to":[{"email":to}]}],"from":{"email":fr},"subject":subject,"content":[{"type":"text/plain","value":content}]}body=json.dumps(mail_data)client_request.body(StringRequestContent("application/json",body))client_response=client_request.send()Log.info(ctx,"Mail API response: %s"%client_response.getContentAsString())exceptExceptionase:Log.error(ctx,"Mail API error: %s"%str(e))