Use a simple IBM Cloud Functions action to send out emails via SMTP. Pass in the SMTP server configuration and the email using JSON objects. For ease of use, bind the server configuration to the action and only pass in the email to send.
The following screenshot shows an email based on this sample properties.
See the blog post A Serverless Function for Sending Emails on IBM Cloud for some background and more links.
Use the IBM Cloud CLI and the Cloud Functions plugin to deploy the action. Log in to IBM Cloud, set the namespace and then run:
ibmcloud fn deploy -m Cloudmailer.yaml
Copy over smtp_config.sample.json to, e.g., smtp_config.sendgrid.json. Then adapt the file (see SMTP server configuration) and use it to set the SMTP configuration as default:
ibmcloud fn action update cloudmailer/sendEmail -P smtp_config.sendgrid.json
Be aware that typically the port 25 is blocked. Many email providers are using ports like 465 or 587.
Instead of using the IBM Cloud CLI, you can also go to the IBM Cloud Functions portal and create the action there. Use the source from smtp_email.js for the action.
Go into the tf directory. You may want to adapt the provider configuration file to match your overall environment. Either change tf/variables.tf or better override some values in a separate terraform.tfvars file. There, you may want to set the IBM Cloud API key to use and change the SMTP server configuration. Set the variable server_config similar to shown in the file variables.tf, e.g., for SendGrid:
server_config= <<EOF
[
{
"key":"server",
"value": {
"host": "smtp.sendgrid.net",
"port" : 465,
"id": "apikey",
"password": "your-api-key"
}
}
]
EOF
Then, initialize Terraform the usual way with terraform init
, check that everything will be applied ok by terraform plan
. Finally, to deploy, run:
terraform apply
It will create a new IAM namespace in IBM Cloud Functions and the action sendEmail in the package cloudmailer.
To expose the action as secured web action, see the comments in tf/variables.tf. See the section on exposing the sendMail action as web action below for further details.
To send an email, invoke the action and pass in the JSON object with the email properties. Use email.sample.json and copy it over to a new file, e.g., email.blog.json. Edit it to your needs like shown. The email can include plain text in the text property, an HTML version in the html property or both.
Once you or your app have composed an email object, send the email by invoking the action using the IBM Cloud CLI:
ibmcloud fn action invoke cloudmailer/sendEmail -r -P email.json
To send out an email using another SMTP server configuration, you can pass in both the server config and the email properties:
ibmcloud fn action invoke cloudmailer/sendEmail -r -P email.json -P smtp_config.myserver.json
You can invoke the sendMail action via API. For testing, use the tool curl. See the documentation for sample code in some programming languages. Calling an API function requires a valid IBM Cloud IAM access token. In the following example, we first obtain the token and assign its value to an environment variable. Thereafter, we use the token for a curl to send a POST request to invoke the action. The email properties are passed in from a file.
export TOKEN=$(ibmcloud iam oauth-tokens --output json | jq -r .iam_token)
curl -X POST --url 'https://us-south.functions.cloud.ibm.com/api/v1/namespaces/04a49bd4-xxxx-xxxx-xxxx-07be0c9b732b/actions/cloudmailer/sendEmail?blocking=true&result=true' -H 'Accept: application/json' -H "Authorization: $TOKEN" -H 'content-type: application/json' -d @email.json
Another option is to turn the action into a web action. See the IBM Cloud Functions documentation on web actions for details. You should secure the web action with one of the offered methods, so that only authorized users can send emails.
Once deployed, you can test the REST API using curl. A call would look like this with the email read from a file again:
curl -X POST https://us-south.functions.appdomain.cloud/api/v1/web/d1ee1c70-xxxx-yyyy-zzzz5-000a41115d3e/cloudmailer/sendEmail.json -H "X-Require-Whisk-Auth: your-web-secret" -H "Content-Type: application/json" --data @email_to_send.json
Some notes on common scenarios.
SMTP / email setup differs depending on your provider. If your provider allows API keys instead of username / password, go with API keys. You may also create a dedicated email account to send out emails. The typical structure for your smtp_config.json looks like this:
{
"server": {
"host": "smtp.example.com",
"port" : 465,
"id": "yourname@example.com",
"password": "your-password"
}
}
IBM Cloud integrates with SendGrid for email delivery. You can sign up for SendGrid, then use its SMTP service with the action from this repository. See the SendGrid documentation or the IBM Cloud Email Delivery documentation for details.
To send emails, create an API key with at least Mail Send privileges. The SMTP configuration, e.g., smtp_config.sendgrid.json would then look similar to this:
{
"server": {
"host": "smtp.sendgrid.net",
"port" : 465,
"id": "apikey",
"password": "your-api-key"
}
}