Skip to main content

Listmonk

Listmonk is self-hosted newsletter and mailing list manager that organizers can use in-house to send out informational emails to participants.

Listmonk can be self-installed on your own server, or it can be quickly and easily set up in the cloud.

Here are some clouds where you can quickly set up the Listmonk system:

Cloud services
One-click deploy on Railway
Deploy on Elestio
Deploy on PikaPod

The Listmonk dashboard looks like this:

splash.png

To connect Listmonk, go to "Club Details" -> "Integrations".

"Club Details" can be found in the bottom left corner.

Under integrations, find Listmonk and click "Connect".

To connect Listmonk, the following fields must be filled out:

After filling out the fields and pressing "Save," the system will attempt to connect to Listmonk and verify that the connection is working.

Once the connection is established, you can choose an email design, and perform the following actions:

  1. Choose the email design that is sent when a membership is successfully paid for.
  2. Perform event synchronization.
  3. Synchronize member emails.
  4. Send a test "Purchase email".

Event synchronization (competitions or challenges)

Every organizer's event creates a new email list in Listmonk, allowing participants to be linked to a specific email list so that the organizer can send emails only to participants of that specific event.

By pressing the "Initialize Full Event Sync" button, all events are created in Listmonk.

All events will be saved in the following format: "Year - Competition Name".

When adding a new participant to Listmonk, the system checks if the specific event has been created; if not, it is created.

Participant synchronization

Each time a purchase is made (membership payment), a request is sent to Listmonk and the participant's email is added. Both the "billing email," which the buyer must fill out, and all emails attached to the participants are added.

Each participant is added to the specific competition list and the following attributes are attached:

  • Events - contains a list of all the events in which the participant has participated.
  • Marketing - contains information about the "marketing" preferences marked during the purchase step.

This information can be used to filter participants and add them to new mailing lists.

For example, to find all participants who have indicated that they wish to receive news, the following query can be used: (subscribers.attribs->'marketing'->>'News')::BOOLEAN = true.

Executing this query will select all participants who have indicated that they wish to receive news.

Initial participant synchronization

To perform the initial participant synchronization, you must press the "Initialize Full data sync with Listmonk" button. Note that this may take longer if the number of participants is large.

Purchase confirmation email

DistantRace sends an automatic email from the system when a participant pays for their entry, but organizers can create their own email design.

It is important to include the following in the email:

  • What is being paid for and the amounts
  • The total amount paid
  • A link to the purchase confirmation

How to create an email and connect it to DistantRace?

  1. Create a purchase confirmation email.

In Listmonk, it is possible to create "Transactional" email designs. Create a new design for purchase confirmation.

Here is a simplified sample for the email:

<!doctype html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
        <base target="_blank">

        <style>
            body {
                background-color: #F0F1F3;
                font-family: 'Helvetica Neue', 'Segoe UI', Helvetica, sans-serif;
                font-size: 15px;
                line-height: 26px;
                margin: 0;
                color: #444;
            }

            pre {
                background: #f4f4f4f4;
                padding: 2px;
            }

            table {
                width: 100%;
                border: 1px solid #ddd;
            }
            table td {
                border-color: #ddd;
                padding: 5px;
            }
            table th {
                border-color: #000;
                padding: 5px;
                text-align: left;
            }

            .wrap {
                background-color: #fff;
                padding: 30px;
                max-width: 525px;
                margin: 0 auto;
                border-radius: 5px;
            }

            .button {
                background: #0055d4;
                border-radius: 3px;
                text-decoration: none !important;
                color: #fff !important;
                font-weight: bold;
                padding: 10px 30px;
                display: inline-block;
            }
            .button:hover {
                background: #111;
            }

            .footer {
                text-align: center;
                font-size: 12px;
                color: #888;
            }
                .footer a {
                    color: #888;
                    margin-right: 5px;
                }

            .gutter {
                padding: 30px;
            }

            img {
                max-width: 100%;
                height: auto;
            }

            a {
                color: #0055d4;
            }
                a:hover {
                    color: #111;
                }
            @media screen and (max-width: 600px) {
                .wrap {
                    max-width: auto;
                }
                .gutter {
                    padding: 10px;
                }
            }
        </style>
    </head>
<body style="background-color: #F0F1F3;font-family: 'Helvetica Neue', 'Segoe UI', Helvetica, sans-serif;font-size: 15px;line-height: 26px;margin: 0;color: #444;">
    <div class="gutter" style="padding: 30px;">&nbsp;</div>
    <div class="wrap" style="background-color: #fff;padding: 30px;max-width: 525px;margin: 0 auto;border-radius: 5px;">
        <p>Hello {{ .Subscriber.Name }}</p>
        <p>
            <strong>Order number: </strong> {{ .Tx.Data.orderNumber }}<br />
            <strong>Created date: </strong> {{ .Tx.Data.createdAt }}<br />
        </p>
        <br />
        <table>
        <tr><th>Name</th><th>Price</th></tr>
        {{range .Tx.Data.products}} <tr><td>{{.title }}</td><td>{{.price}} {{ .Tx.Data.currency }}</td></tr>{{end}} 	
        </table>
        Total price: {{ .Tx.Data.orderSum }} {{ .Tx.Data.currency }}
        <br />
        <p>
            <a href="{{ .Tx.Data.orderUrl }}">Open Order</a>
        </p>
    </div>
    
    <div class="footer" style="text-align: center;font-size: 12px;color: #888;">
        <p>{{ L.T "public.poweredBy" }} <a href="https://listmonk.app" target="_blank" rel="noreferrer" style="color: #888;">listmonk</a></p>
    </div>
</body>
</html>

Visually, this HTML looks like this:

  1. Once the design is prepared, the specific template must be selected at the Listmonk integration with DistantRace:

If the design is not available, press the "Update" button (pressing this button refreshes the list of designs) and reopen the integration.

  1. Once the design is selected and saved, you can test how the design looks by sending a test email. Press the button "Test Order Email (if template is set)".

That's it - from this moment on, if a participant pays for their entry, only your designed email will be sent.

Here is a sample with the information that is sent to Listmonk to send the email:


{
        "subscriber_email": email,
        "template_id": template_id,
        "data": {
            "orderID": "36902",
            "orderNumber": 36902,
            "firstName": first_name,
            "lastName": last_name,
            "cartID": "36902",
            "orderUrl": "https://distantrace.com/en/cart/d5949dac-b7d9-4e93-a874-34946286c006/",
            "currency": "EUR",
            "orderSum": 30.0,
            "createdAt": "2024-05-02 15:50",
            "updatedAt": "2024-05-02 16:36",
            "paymentMethod": "payment with card",
            "paymentStatus": "paid",
            "tags": ["Competition Name"],
            "products": [
                {
                    "cartProductID": 85268,
                    "productID": "607",
                    "variantID": "432",
                    "variantTitle": "Distance Name",
                    "title": "Participant Name - Competition Name, Distance Name, Additional products",
                    "vendor": "Competition Name",
                    "quantity": 1,
                    "price": 15.0,
                },
                {
                    "cartProductID": 85268,
                    "productID": "607",
                    "variantID": "432",
                    "variantTitle": "Distance Name",
                    "title": "Participant Name - Competition Name, Distance Name, Additional products",
                    "vendor": "Competition Name",
                    "quantity": 1,
                    "price": 15.0,
                },
            ],
        },
        "content_type": "html",
    }