Sending Emails via Api

Mailto.wiki supports sharing Confluence pages as emails via a REST API. If you have some programming knowledge, you can automate the process of sending emails and schedule recurring emails. The API offers the same features as the graphical user interface (the EMAIL button).

This guide will walk you through the necessary steps to set up the REST API and explain, in general, how to perform the REST requests.

We also provide you with ready-to-use code snippets for: Bash, PowerShell, Python, NodeJS, PHP, and Java.

These examples are for Confluence Server and Confluence Data Center. On Confluence Cloud the REST API works differently: Documentation for Confluence Cloud

Step 0: Ensure the “share by email” button is activated

To use the API for sending emails, the share as email button must be activated and sending emails needs to be enabled. Please ensure it is activated by going to the mailto.wiki configuration page, clicking on the “Replies/Share” tab, and scrolling down to “Enable share by email button.” Make sure that the checkbox is checked. You can find more information on the share as email button here.

Image

Step 1: Credentials

Confluence Server and Data Center support Basic Auth with username and password. For more information please read: https://developer.atlassian.com/server/jira/platform/basic-authentication/. You can use your own user or create and use a low permission user that has access to the pages that you want to share. Write down your username, password and the url to your confluence instance:

CONFLUENCE_URL='https://<your-instance-url>/'
PASSWORD='<The password of your confluence user>'
USERNAME='<The user name of your confluence user>'

Step 2: Obtain the page ID

You will need the ID for the page or blog post that you want to share via email. To get it navigate in Confluence to the content that you want to share and then:

1. click on the ellipses (…) at the top-right of the page

2. select Page Information from the menu

5. The URL in the address bar will change and you can get the page ID from the URL


Now that you have your credentials and the page ID, you can jump right into the code snippets for your programming language below. Currently, we have ready-to-use examples for Bash, PowerShell, Python, NodeJS, PHP, and Java. Alternatively, you can follow the generic description of the REST process to implement it yourself.

Step 3A: Generic description of the REST process

To send an email, make a POST request to the https://<your-confluence-url>/rest/mailto.wiki/1.0/send-email endpoint with your username and password as basic auth and the email details in the request body.

The request body is a JSON object that includes the page ID, the sender email address (this has to be one of your registered addresses), and the recipients’ email addresses. You can specify up to 25 recipients at once. You can also set a few other options.

POST /rest/mailto.wiki/1.0/send-email HTTP/1.1
Host: <your-confluence.tld>
Authorization: Basic <BASE64 encoded username:password>
Content-Type: application/json
Content-Length: 260

{
    "from": "youremail@example.org",
    "to": [
        "alice@example.org",
        "bob@example.org"
    ],
    "includeComments": true,
    "includeAttachments": false,
    "inlineImages": true,
    "contentId": 851969
}

If everything goes correctly, you should receive a response with a status code of 200 and an empty json object: {}.

Step 3B: Bash

Here is an example of how to send emails using a Bash script. To use it, you will need to have curl installed:

#!/bin/bash

# Your credentials (url, username and password) to access confluence.
CONFLUENCE_URL='https://<your-instance-url>/'
USERNAME='<The user name of your confluence user>'
PASSWORD='<The password of your confluence user>'

# Extra options for sending emails
INCLUDE_COMMENTS="true" # Include comments in emails
INCLUDE_ATTACHMENTS="true" # Include attachments in emails
INLIME_IMAGES="true" # Inline images in emails

set -eu # Stop on errors

# Register error handler
set -o errtrace

function handle_error() {
  echo "[ERROR] An error occurred."
  exit 1
}

trap 'handle_error' ERR


# Share a confluence page or blog post via email.
#
# Usage:
#
# Arguments:
#   [arg1] - The page id
#   [arg2] - The email address to send from.
#            This needs to be a @mailto.wiki address registered to your confluence.
#   [arg*] - Email addresses to send the email to.
#
#
# Example:
#    share_confluence_page_as_email 106332217 mycompany@mailto.wiki alice@example.org bob@example.org
function share_confluence_page_as_email {
    page_id="$1"
    from="$2"
    shift 2

    recipients_json='['
    glue=''
    for to in "$@"; do
        recipients_json="${recipients_json}${glue}\"${to}\""
        glue=', '
    done
    recipients_json="$recipients_json]"

    # Send the email
    curl -s -f "${CONFLUENCE_URL}rest/mailto.wiki/1.0/send-email" \
        -X POST \
        -H 'Content-Type: application/json' \
        -u "$USERNAME:$PASSWORD" \
        -d @- >/dev/null <<EOF
{
    "contentId": "$page_id",
    "from": "$from",
    "to": $recipients_json,
    "includeComments": $INCLUDE_COMMENTS,
    "includeAttachments": $INCLUDE_ATTACHMENTS,
    "inlineImages": $INLIME_IMAGES
}
EOF
}

page_id=12345678
from_email="<The email address you want to use as sender>"
to_emails=("bob@example.org" "charlie@example.org")

echo "[INFO] sending an email for page $page_id from $from_email to ${to_emails[@]}"
share_confluence_page_as_email "$page_id" "$from_email" "${to_emails[@]}"

echo "[INFO] done"

Step 3C: PowerShell

Here is an example on how to send emails using a PowerShell script:

$ErrorActionPreference = "Stop"

function Send-Email {
    param(
        [string]$ConfluenceUrl,
        [string]$Username,
        [string]$Password,
        [string]$SenderEmail,
        [string[]]$RecipientEmails,
        [string]$PageId,
        [bool]$IncludeComments = $true,
        [bool]$IncludeAttachments = $false,
        [bool]$InlineImages = $true
    )

    $sendEmailEndpoint = "${ConfluenceUrl}rest/mailto.wiki/1.0/send-email"

    # Send email
    $headers = @{
        "Authorization" = "Basic "+[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("$($Username):$($Password)"))
        "Content-Type" = "application/json"
    }

    $body = @{
        "from" = $senderEmail
        "to" = $recipientEmails
        "includeComments" = $includeComments
        "includeAttachments" = $includeAttachments
        "inlineImages" = $inlineImages
        "contentId" = $pageId
    } | ConvertTo-Json

    $response = Invoke-RestMethod -Uri $sendEmailEndpoint -Method Post -Headers $headers -Body $body -ErrorAction Stop

    Write-Output "Email sent"
}

# Usage example
Send-Email `
    -ConfluenceUrl "https://<your-instance-url>/" `
    -Username "<The user name of your confluence user>" `
    -Password "<The password of your confluence user>" `
    -SenderEmail "<The email address you want to use as sender>" `
    -RecipientEmails @("bob@example.org", "charlie@example.org") `
    -PageId "123456789"

Step 3D: Python

Here is an example on how to send emails using a Python 3 script:

import http.client
import base64
import json
from urllib.parse import urlencode
from urllib.parse import urlparse

class MailtoWikiClient:
    def __init__(self, username, password, confluence_url):
        self.username = username
        self.password = password
        self.confluence_url = confluence_url

    def send_email(self, content_id, from_email, to_emails, include_comments=True, include_attachments=False, inline_images=True):
        url_parts = urlparse(self.confluence_url)

        # Create either an HTTPConnection or an HTTPSConnection based on the scheme
        if url_parts.scheme == 'http':
            conn = http.client.HTTPConnection(url_parts.netloc)
        elif url_parts.scheme == 'https':
            conn = http.client.HTTPSConnection(url_parts.netloc)
        else:
            raise ValueError("Invalid URL scheme. Only 'http' and 'https' are supported.")

        auth_string = f"{self.username}:{self.password}"
        auth_header = base64.b64encode(auth_string.encode()).decode()

        headers = {
            "Authorization": f"Basic {auth_header}",
            "Content-Type": "application/json"
        }

        data = {
            "from": from_email,
            "to": to_emails,
            "includeComments": include_comments,
            "includeAttachments": include_attachments,
            "inlineImages": inline_images,
            "contentId": content_id
        }

        conn.request("POST", f"{url_parts.path}/rest/mailto.wiki/1.0/send-email", headers=headers, body=json.dumps(data))

        response = conn.getresponse()
        if response.status != 200:
            try:
                response_data = json.loads(response.read().decode())
                conn.close()
                raise Exception(f"Request failed with status {response.status}: {response_data.get('error', 'Unknown error')}")
            except:
                pass

            raise Exception(f"Request failed with status {response.status}")

# Replace these values with your own
username = "<The username of your confluence user>"
password = "<The password of your confluence user>"
confluence_url = "https://<your-instance-url>/"
from_email = "<The email address you want to use as sender>"
to_emails = ["bob@example.org", "charlie@example.org"]
content_id = "12345678"

# Create MailtoWikiClient instance
client = MailtoWikiClient(username, password, confluence_url)

# Send email
client.send_email(content_id, from_email, to_emails)

print("email sent")

Step 3E: NodeJS

Here is an example on how to send emails using a NodeJS script:

const http = require('http');
const https = require('https');
const querystring = require('querystring');
const { Buffer } = require('buffer');

async function main() {
    const username = '<The username of your confluence user>';
    const password = '<The password of your confluence user>';
    const confluenceUrl = 'https://<your-instance-url>/';

    const emailDetails = {
        from: '<The email address you want to use as sender>',
        to: ["bob@example.org", "charlie@example.org"],
        includeComments: true,
        includeAttachments: false,
        inlineImages: true,
        contentId: '1179649'
    };

    const emailResponse = await sendEmail(confluenceUrl, username, password, emailDetails);

    console.log("Email sent");
}

main().catch(error => {
    console.error('Error:', error.message);
});

function httpRequest(options, requestData) {
    return new Promise((resolve, reject) => {
        const protocol = getProtocol(options.protocol);
        const req = protocol.request(options, res => {
            let data = '';
            res.on('data', chunk => {
                data += chunk;
            });
            res.on('end', () => {
                resolve({
                    status: res.statusCode,
                    data: data
                });
            });
        });

        req.on('error', error => {
            reject(error);
        });

        if (requestData) {
            req.write(requestData);
        }

        req.end();
    });
}

function getProtocol(protocol) {
    return protocol === 'http:' ? http : https;
}

async function sendEmail(confluenceUrl, username, password, emailDetails) {
    const url = `${confluenceUrl}rest/mailto.wiki/1.0/send-email`;
    const authString = `${username}:${password}`;
    const authHeader = `Basic ${Buffer.from(authString).toString('base64')}`;
    const data = JSON.stringify(emailDetails);
    
    const parsedUrl = new URL(confluenceUrl);
    const hostname = parsedUrl.hostname;
    const protocol = parsedUrl.protocol;
    const port = parsedUrl.port || (protocol === 'https:' ? 443 : 80);

    const options = {
        protocol: protocol,
        method: 'POST',
        hostname: hostname,
        port: port,
        path: url,
        headers: {
            'Authorization': authHeader,
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            'Content-Length': data.length
        }
    };

    const response = await httpRequest(options, data);

    if (response.status !== 200) {
        throw new Error('Failed to send email: ' + response.data);
    }

    return
}

Step 3F: PHP

Here is an example on how to send emails using a PHP script. To use it you will need to have the curl extension for PHP installed, which is the case on almost all common hosting providers:

<?php

class MailtoWikiException extends Exception
{
}

class MailtoWikiClient
{
    private $username;
    private $password;
    private $confluenceUrl;

    public function __construct($username, $password, $confluenceUrl)
    {
        $this->username = $username;
        $this->password = $password;
        $this->confluenceUrl = $confluenceUrl;
    }

    public function sendEmail(
        $pageContentId,
        $fromEmail,
        $recipients,
        $includeComments = true,
        $includeAttachments = false,
        $inlineImages = true
    ) {
        $url = "{$this->confluenceUrl}rest/mailto.wiki/1.0/send-email";
        $auth = base64_encode("{$this->username}:{$this->password}");
        $headers = [
            "Authorization: Basic {$auth}",
            'Content-Type: application/json'
        ];
        $emailData = [
            'contentId' => $pageContentId,
            'from' => $fromEmail,
            'to' => $recipients,
            'includeComments' => $includeComments,
            'includeAttachments' => $includeAttachments,
            'inlineImages' => $inlineImages
        ];
        $jsonData = json_encode($emailData);

        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch);
        $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpcode != 200) {
            throw new MailtoWikiException('Failed to send email. HTTP status: ' . $httpcode . ', body: ' . $result);
        }

        return json_decode($result, true);
    }
}

// Configuration
$username = '<The user name of your confluence user>';
$password = '<The password of your confluence user>';
$confluenceUrl = 'https://<your-instance-url>/';
$pageContentId = '12345678';
$fromEmail = '<The email address you want to use as sender>';
$recipients = ['alice@example.org', 'bob@example.org'];

try {
    $mailtoWikiClient = new MailtoWikiClient($username, $password, $confluenceUrl);
    $response = $mailtoWikiClient->sendEmail($pageContentId, $fromEmail, $recipients);

    echo "Email sent successfully\n";
} catch (Exception $e) {
    echo "Error: " . $e->getMessage() . "\n";
}

Step 3G: Java

Here is an example of how to send emails using a Java program. The code will work with Java 11 or newer without any additional dependencies. If you want to use it in a production environment, you will probably want to refactor the buildJsonRequestBody method to use a proper JSON library.

import java.io.StringReader;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;

public class MailtoWikiApi {
    private static final boolean DEFAULT_INCLUDE_COMMENTS = true;
    private static final boolean DEFAULT_INCLUDE_ATTACHMENTS = false;
    private static final boolean DEFAULT_INLINE_IMAGES = true;

    private final HttpClient httpClient;
    private final String password;
    private final String username;
    private final String restEndpoint;

    public MailtoWikiApi(String confluenceUrl, String password, String username) {
        httpClient = HttpClient.newHttpClient();
        this.restEndpoint = confluenceUrl + "rest/mailto.wiki/1.0/send-email";
        this.password = password;
        this.username = username;
    }

    public static void main(String[] args) {
        String confluenceUrl = "https://<your-instance-url>/";
        String username = "<The user name of your confluence user>";
        String password = "<The password of your confluence user>";
        MailtoWikiApi api = new MailtoWikiApi(confluenceUrl, password, username);

        String from = "<The email address you want to use as sender>";
        List<String> to = List.of("bob@example.org", "charlie@example.org");

        try {
            api.sendEmail("12345678", from, to);
            System.out.println("Sent email");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void sendEmail (String contentId, String from, List<String> to) throws Exception {
        sendEmail(contentId, from, to, DEFAULT_INCLUDE_COMMENTS, DEFAULT_INCLUDE_ATTACHMENTS, DEFAULT_INLINE_IMAGES);
    }

    private String buildJsonRequestBody(String contentId, String from, List<String> to, boolean includeComments, boolean includeAttachments,
                            boolean inlineImages) {
        // @todo
        // If you use this in a production product you propably want to replace this with a proper json library like org.json or jackson.

        String toJsonString = "[";
        String glue = "";
        for (String sender: to) {
            toJsonString += glue + "\"" + sender.replace("\"", "") + "\"";
            glue = ",";
        }
        toJsonString += "]";

        return "{" + 
            "\"from\":\"" + from.replace("\"", "") + "\"" +
            ",\"to\":" + toJsonString +
            ",\"includeComments\":" + (includeComments ? "true" : "false") +
            ",\"includeAttachments\":" + (includeAttachments ? "true" : "false") +
            ",\"contentId\":\"" + contentId.replace("\"", "") + "\"" +
        "}";
    }

    public void sendEmail(String contentId, String from, List<String> to, boolean includeComments, boolean includeAttachments,
                            boolean inlineImages) throws Exception {
        String requestBody = buildJsonRequestBody(contentId, from, to, includeComments, includeAttachments, inlineImages);

        String auth = username + ":" + password;
        String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(restEndpoint))
            .header("Authorization", "Basic " + encodedAuth)
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(requestBody))
            .build();

        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
        if (response.statusCode() == 200) {

        } else {
            throw new Exception("Error sending email, status Code: " + response.statusCode() + ", body: " + response.body());
        }
    }
}

Conclusion

Using these code snippets, you should be able to integrate sharing Confluence pages via email into your applications, build systems, and cron jobs.

If you need any help with getting things to work, or if you have any suggestions or questions, please do not hesitate to contact the support team at support@mailto.wiki [English, German].