Skip to main content
Custom provider lets you send email notifications through any provider via webhook. SendGrid is supported as a built-in provider separately; use a custom provider only when you need to route email through another service or your own SMTP bridge.

Pre-requisite

  1. Your webhook endpoint must be accessible over HTTPS. This is essential to ensure the security and integrity of data transmission.
  2. This URL should be publicly accessible from the internet.
  3. Ensure that your endpoint supports the HTTP POST method. Event payloads will be delivered via HTTP POST requests in JSON format.
  4. Configure your endpoint to respond immediately to the CometChat server with a 200 OK response. The response should be sent within 2 seconds of receiving the request.
  5. For security, it is recommended to set up Basic Authentication that is usually used for server-to-server calls. This requires you to configure a username and password. Whenever your webhook URL is triggered, the HTTP Header will contain:
Authorization: Basic <Base64-encoded-credentials>

Add credentials

  1. Click on the ”+ Add Credentials” button.
  2. Enable the provider.
  3. Enter the publically accessible Webhook URL.
  4. It is recommended to enable Basic Authentication.
  5. Enter the username and password.
  6. Enabling the “Trigger only if email address is stored with CometChat” setting requires users’ email addresses to be stored with CometChat using the Update Contact details API. When enabled, the webhook is triggered only for those users. If this setting is disabled, the webhook triggers regardless of whether users’ email addresses are stored with CometChat.
  7. Save the credentials.

How does it work?

The Custom provider is triggered once for an event in one-on-one conversation. In case of notifying the members of a group, the custom provider is triggered once for each user present in that group. For example, if there are 100 members in the group, your webhook will receive 100 HTTP requests. Once for each member of the group.
{
  "trigger": "email-notification-payload-generated",
  "data": {
    "to": {
      "uid": "cometchat-uid-1",
      "email": "andrew-joseph@example.com", // Optional
      "name": "Andrew Joseph"
    },
    "messages": [
      {
        "sender": {
          "uid": "cometchat-uid-4",
          "avatar": "https://assets.cometchat.io/sampleapp/v2/users/cometchat-uid-4.webp",
          "name": "Susan Marie"
        },
        "message": "Are we meeting on this weekend?",
        "messageObject": {CometChat Message Object}, // Present if "Include message object" is enabled. The message object is present for new messages or in case a message was edited
      },
      {
        "sender": {
          "uid": "cometchat-uid-4",
          "avatar": "https://assets.cometchat.io/sampleapp/v2/users/cometchat-uid-4.webp",
          "name": "Susan Marie"
        },
        "message": "📷 Has shared an image",
        "messageObject": {CometChat Message Object}, // Present if "Include message object" is enabled. The message object is present for new messages or in case a message was edited
      }
    ],
    "senderDetails": {
      "uid": "cometchat-uid-4",
      "name": "Susan Marie",
      "avatar": "https://assets.cometchat.io/sampleapp/v2/users/cometchat-uid-4.webp"
    },
    "subject": "New messages from Susan Marie"
  },
  "appId": "app123",
  "region": "us/eu/in",
  "webhook": "custom"
}

Sample server-side code

const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;

app.use(express.json());

// Optional: Basic authentication middleware
const basicAuth = (req, res, next) => {
  const authHeader = req.headers['authorization'];
  if (!authHeader || !authHeader.startsWith('Basic ')) {
    return res.status(401).json({ message: 'Unauthorized' });
  }
  next();
};

const triggerEmailNotification = async (to, data) => {
  let { name, uid, email } = to;
  let { groupDetails, senderDetails, subject } = data;

  if (groupDetails) {
    console.log('Received webhook for group email notification');
  }

  if (senderDetails) {
    console.log('Received webhook for one-on-one email notification');
  }

  if (email == null) {
    // Your implementation to fetch Email ID
    email = await fetchEmailIDFor(uid);
  }

  // Your implementation for sending the email notification
  await sendEmail(email, subject, data.messages);
};

app.post('/webhook', basicAuth, (req, res) => {
  const { trigger, data, appId, region, webhook } = req.body;
  const { to } = data || {};

  if (
    trigger !== 'email-notification-payload-generated' ||
    webhook !== 'custom'
  ) {
    return res.status(400).json({ message: 'Invalid trigger or webhook type' });
  }

  console.log('Received Webhook:', JSON.stringify(req.body, null, 2));

  triggerEmailNotification(to, data)
    .then((result) => {
      console.log(
        'Successfully triggered email notification for',
        appId,
        to.uid,
        result
      );
    })
    .catch((error) => {
      console.error(
        'Something went wrong while triggering email notification for',
        appId,
        to.uid,
        error.message
      );
    });

  res.status(200).json({ message: 'Webhook received successfully' });
});

app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});