Webhook Notifications Quick Start

Last updated: 2024-02-28Contributors
Edit this page

Welcome to the RingCentral Platform. RingCentral is the leading unified communications platform. From one system developers can integrate with, or build products around all the ways people communicate today: SMS, voice, fax, chat and meetings.

In this Quick Start, we are going to help you create a Webhook push notifications app using our Push Notifications API, which allows your application receiving notifications on instant SMS message events. Let's get started.

Create an app and obtain credentials

The first thing we need to do is create an app in the RingCentral Developer Console. This can be done quickly by clicking the "Create Notifications App" button below. Just click the button, enter a name and description if you choose, and click the "Create" button. If you do not yet have a RingCentral account, you will be prompted to create one.

Create Webhook App

  1. Login or create an account if you have not done so already.
  2. Go to Console/Apps and click 'Create App' button.
  3. Select "REST API App" under "What type of app are you creating?" Click "Next."
  4. Under "Auth" select "JWT auth flow"
  5. Under "Security" add the following permissions:
    • WebSocket Subscriptions, Read Presence
    • SMS

When you are done, you will be taken to the app's dashboard. Make note of the Client ID and Client Secret. We will be using those momentarily.

Download and edit a .env file

Follow the instructions found in our guide to running Developer Guide code samples. Or:

  1. Download our env-template and save it as a file named .env.
  2. Edit your newly downloaded .env file, setting its variables with the proper values for the app you created above.
    • RC_CLIENT_ID - set to the Client ID of the app you created above
    • RC_CLIENT_SECRET - set to the Client Secret of the app you created above
    • RC_JWT - set to the JWT credential you created for yourself
    • WEBHOOK_DELIVERY_ADDRESS - the full address where notifications will be sent to. If you run the code on your local machine, you can use ngrok service to obtain a tunnel address to your localhost. E.g. https://1058-69-181-202-2.ngrok-free.app

Subscribe for push notification

Select your preferred language below.

Install RingCentral JavaScript SDK

$ npm install ringcentral --save
$ npm install dotenv --save

Run ngrok to create a localhost tunnel

$ ngrok http 5000

Create and edit webhook-server.js

Create a file called webhook-server.js using the contents below.

var http = require('http');
PORT  = 3000

var server = http.createServer(function(req, res) {
  if (req.method == 'POST') {
    if (req.url == "/webhook") {
      if (req.headers.hasOwnProperty("validation-token")) {
        res.setHeader('Content-type', 'application/json');
        res.setHeader('Validation-Token', req.headers['validation-token']);
        res.statusCode = 200;
        res.end();
      } else {
        var body = []
        req.on('data', function(chunk) {
          body.push(chunk);
        }).on('end', function() {
          body = Buffer.concat(body).toString();
          var jsonObj = JSON.parse(body)
          console.log(jsonObj.body);
        });
      }
    }
  }
});

server.listen(PORT);
console.log(`Listening on port ${PORT}`)

Create and edit webhook-notification.js

Create a file called webhook-notification.js using the contents below.

Copy the forwarding address, e.g. https://1058-69-181-202-32.ngrok-free.app, and paste it to your .env file. Or paste it directly into the DELIVERY_ADDRESS variable in the code below.

const RC = require('@ringcentral/sdk').SDK
const path = require('path')
// Remember to modify the path to where you saved your .env file!
require('dotenv').config({ path: path.resolve(__dirname, '../.env') })


// For the purpose of testing the code, we put the deliver address in the environment variable.
// Feel free to set the delivery address directly.
DELIVERY_ADDRESS = process.env.WEBHOOK_DELIVERY_ADDRESS + "/webhook"


// Instantiate the SDK and get the platform instance
var rcsdk = new RC({
    'server':       process.env.RC_SERVER_URL,
    'clientId':     process.env.RC_CLIENT_ID,
    'clientSecret': process.env.RC_CLIENT_SECRET
});
var platform = rcsdk.platform();

/* Authenticate a user using a personal JWT token */
platform.login({ 'jwt':  process.env.RC_JWT })

platform.on(platform.events.loginSuccess, function(e){
    subscribe_for_notification()
    //read_subscriptions()
});

platform.on(platform.events.loginError, function(e){
    console.log("Unable to authenticate to platform. Check credentials.", e.message)
    process.exit(1)
});

/*
* Create a Webhok notification and subscribe for instant SMS message notification
*/
async function subscribe_for_notification() {
  var bodyParams = {
    eventFilters: ['/restapi/v1.0/account/~/extension/~/message-store/instant?type=SMS'],
    deliveryMode: {
      transportType: "WebHook",
      address: DELIVERY_ADDRESS
    },
    expiresIn: 3600
  }
  try {
    let endpoint = "/restapi/v1.0/subscription"
    var resp = await platform.post(endpoint, bodyParams)
    var jsonObj = await resp.json()
    console.log (`Subscription Id: ${jsonObj.id}`)
    console.log("Ready to receive incoming SMS via WebHook.")
  } catch (e) {
    console.log(e.message);
  }
}

/*
* Read all created subscriptions
*/
async function read_subscriptions(){
  try {
    let endpoint = "/restapi/v1.0/subscription"
    var resp = await platform.get(endpoint)
    var jsonObj = await resp.json()
    if (jsonObj.records.length == 0)
      console.log("No subscription.")
    else {
      for (var record of jsonObj.records){
        console.log(record)
        delete_subscription(record.id)
      }
    }
  } catch (e) {
    console.erlogror(e.message);
  }
}

/*
* Delete a subscription identified by the subscription id
*/
async function delete_subscription(subscriptionId){
  try {
    let endpoint = `/restapi/v1.0/subscription/${subscriptionId}`
    var resp = await platform.delete(endpoint)
    console.log (`Subscription ${subscriptionId} deleted.`)
  } catch (e) {
    console.log(e.message);
  }
}

Run your code

You are almost done. Now run your script. Open 2 terminal windows and run your script in each terminal in the order below:

$ node webhook-server.js
$ node webhook-notification.js

Install RingCentral Python SDK

$ pip install ringcentral python-dotenv

Run ngrok to create a localhost tunnel

$ ngrok http 5000

Create and edit webhook-server.py

Create a file called webhook-server.py using the contents below.

from http.server import BaseHTTPRequestHandler, HTTPServer

class S(BaseHTTPRequestHandler):
    def do_POST(self):
        path = self.path
        if path == "/webhook":
            validationToken = self.headers['Validation-Token']
            if validationToken is not None:
                self.send_response(200)
                self.send_header('Content-type', 'application/json')
                self.send_header('Validation-Token', validationToken)
                return self.end_headers()
            else:
                content_len = int(self.headers.get('Content-Length'))
                payload = self.rfile.read(content_len)
                print (payload)
                return
        else:
            print ("Ignore this")


def run(server_class = HTTPServer, handler_class = S, port=3000):
    server_address = ('localhost', port)
    httpd = server_class(server_address, handler_class)
    print ('Starting server...')
    httpd.serve_forever()

if __name__ == "__main__":
    from sys import argv

if len(argv) == 2:
    run(port=int(argv[1]))
else:
    run()

Create and edit webhook-notification.py

Create a file called webhook-notification.py using the contents below.

Copy the forwarding address, e.g. https://1058-69-181-202-32.ngrok-free.app, and paste it to your .env file. Or paste it directly into the DELIVERY_ADDRESS variable in the code below.

import os, sys, json

from dotenv import load_dotenv
from ringcentral import SDK
load_dotenv()

# For the purpose of testing the code, we put the deliver address in the environment variable.
# Feel free to set the delivery address directly.
DELIVERY_ADDRESS= os.environ.get('WEBHOOK_DELIVERY_ADDRESS') + "/webhook"

#
# Create a Webhok notification and subscribe for instant SMS message notification
#
def subscribe_for_notification():
    try:
        eventFilters = ['/restapi/v1.0/account/~/extension/~/message-store/instant?type=SMS']
        bodyParams = {
            'eventFilters' : eventFilters,
            'deliveryMode': {
                'transportType': 'WebHook',
                'address': DELIVERY_ADDRESS
            },
            'expiresIn': 3600
        }
        endpoint = "/restapi/v1.0/subscription"
        resp = platform.post(endpoint, bodyParams)
        jsonObj = resp.json()
        print (f"Subscription id: {jsonObj.id}")
        print ("Ready to receive incoming SMS via WebHook.")
    except Exception as e:
        print ("Webhook creation failed.")
        print(f"An exception was thrown: {e}")


#
# Read all created subscriptions
#
def read_subscriptions():
    try:
        endpoint = "/restapi/v1.0/subscription"
        resp = platform.get(endpoint)
        jsonObj = resp.json_dict()
        if jsonObj['records'].count == 0:
            print ("No subscription.")
        else:
            for record in jsonObj['records']:
                print(json.dumps(record, indent=2, sort_keys=True))
                delete_subscription(record['id'])
    except Exception as e:
        print(f"An exception was thrown: {e}")

#
# Delete a subscription identified by the subscription id
#
def delete_subscription(subscriptionId):
    try:
        endpoint = f"/restapi/v1.0/subscription/{subscriptionId}"
        resp = platform.delete(endpoint)
        print (f"Subscription {subscriptionId} deleted.")
    except Exception as e:
        print(f"An exception was thrown: {e}")

# Instantiate the SDK and get the platform instance
rcsdk = SDK( os.environ.get('RC_CLIENT_ID'),
             os.environ.get('RC_CLIENT_SECRET'),
             os.environ.get('RC_SERVER_URL') )
platform = rcsdk.platform()

# Authenticate a user using a personal JWT token
def login():
    try:
      platform.login( jwt=os.environ.get('RC_JWT') )
      subscribe_for_notification()
      #read_subscriptions()
    except Exception as e:
      sys.exit("Unable to authenticate to platform. Check credentials." + str(e))

login()

Run your code

You are almost done. Now run your script. Open 2 terminal windows and run your script in each terminal in the order below: Note: Running the demo code requires Python 3.x

$ python3 webhook-server.py
$ python3 webhook-notification.py

Install RingCentral PHP SDK

$ curl -sS https://getcomposer.org/installer | php
$ php composer.phar require ringcentral/ringcentral-php vlucas/phpdotenv

Run ngrok to create a localhost tunnel

$ ngrok http 5000

Create and edit webhook-server.php

Create a file called webhook-server.php using the contents below.

<?php
$v = isset($_SERVER['HTTP_VALIDATION_TOKEN']) ? $_SERVER['HTTP_VALIDATION_TOKEN'] : '';
if (strlen($v) > 0) {
    header("Validation-Token: {$v}");
}

$jsonStr = file_get_contents('php://input');
$jsonObj = json_decode($jsonStr, TRUE);
var_dump($jsonObj);
?>

Create and edit webhook-notification.php

Create a file called webhook-notification.php using the contents below.

Copy the forwarding address, e.g. https://1058-69-181-202-32.ngrok-free.app, and paste it to your .env file. Or paste it directly into the $DELIVERY_ADDRESS variable in the code below.

<?php
// Remember to modify the path to where you installed the RingCentral SDK and saved your .env file!
require('./../vendor/autoload.php');
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . './../');
$dotenv->load();

// For the purpose of testing the code, we put the deliver address in the environment variable.
// Feel free to set the delivery address directly.
$DELIVERY_ADDRESS= $_ENV['WEBHOOK_DELIVERY_ADDRESS'] . "/webhook-server.php?webhook";

# Instantiate the SDK and get the platform instance
$rcsdk = new RingCentral\SDK\SDK( $_ENV['RC_CLIENT_ID'],
                                  $_ENV['RC_CLIENT_SECRET'],
                                  $_ENV['RC_SERVER_URL'] );
$platform = $rcsdk->platform();

// Authenticate a user using a personal JWT token
try {
  $platform->login( [ "jwt" => $_ENV['RC_JWT'] ] );
  subscribe_for_notification();
  //read_subscriptions();
} catch (\RingCentral\SDK\Http\ApiException $e) {
  exit("Unable to authenticate to platform. Check credentials. " . $e->message . PHP_EOL);
}

/*
* Create a Webhok notification and subscribe for instant SMS message notification
*/
function subscribe_for_notification(){
  global $platform, $DELIVERY_ADDRESS;
  try {
      $bodyParams = array(
          'eventFilters' => array(
              '/restapi/v1.0/account/~/extension/~/message-store/instant?type=SMS'
          ),
          'deliveryMode' => array(
              'transportType' => "WebHook",
              'address' => $DELIVERY_ADDRESS
          ),
          'expiresIn' => 3600 );
      $endpoint = "/restapi/v1.0/subscription";
      $resp = $platform->post($endpoint, $bodyParams);
      print_r ("Subscription Id: " . $resp->json()->id . PHP_EOL);
      print_r ("Ready to receive incoming SMS via WebHook.");
  } catch (Exception $e) {
      print_r ("Exception: " . $e->getMessage());
  }
}

/*
* Read all created subscriptions
*/
function read_subscriptions(){
  global $platform;
  try {
      $endpoint = "/restapi/v1.0/subscription";
      $resp = $platform->get($endpoint);
      if (count($resp->json()->records) == 0)
        print_r ("No subscription");
      else {
        foreach ($resp->json()->records as $record) {
          print_r (json_encode($record, JSON_PRETTY_PRINT) . PHP_EOL);
          delete_subscription($record->id);
        }
      }
  } catch (Exception $e) {
      print_r ("Exception: " . $e->getMessage());
  }
}

/*
* Delete a subscription identified by the subscription id
*/
function delete_subscription($subscriptionId){
  global $platform;
  try {
      $endpoint = "/restapi/v1.0/subscription/" . $subscriptionId;
      $resp = $platform->delete($endpoint);
      print_r ("Subscription " . $subscriptionId . " deleted.");
  } catch (Exception $e) {
      print_r ("Exception: " . $e->getMessage());
  }
}

Run your code

You are almost done. Now run your script. Open 2 terminal windows and run your script in each terminal in the order below:

$ php -S localhost:5000
$ php webhook-notification.php

Install RingCentral Ruby SDK

$ gem install ringcentral-sdk
$ gem install dotenv
$ gem install sinatra

Run ngrok to create a localhost tunnel

$ ngrok http 5000

Create and edit webhook-server.rb

Create a file called webhook-server.rb using the contents below.

require 'sinatra'
set :port, 5000
post '/webhook' do
    status 200
    headers('Content-Type' => 'application/json')
    headers('Validation-Token' => request.env['HTTP_VALIDATION_TOKEN'])
    if request.env['HTTP_VALIDATION_TOKEN']
      request.body.rewind
    end
    body = request.body.read
    puts body
    # do whatever with body
    body 'OK'
end

Create and edit webhook-notification.rb

Create a file called webhook-notification.rb using the contents below.

Copy the forwarding address, e.g. https://1058-69-181-202-32.ngrok-free.app, and paste it to your .env file. Or paste it directly into the DELIVERY_ADDRESS variable in the code below.

require 'ringcentral'
require 'dotenv'
# Remember to modify the path to where you saved your .env file!
Dotenv.load("./../.env")

# For the purpose of testing the code, we put the deliver address in the environment variable.
# Feel free to set the delivery address directly.
DELIVERY_ADDRESS = ENV['WEBHOOK_DELIVERY_ADDRESS'] + "/webhook"

#
# Create a Webhok notification and subscribe for instant SMS message notification
#
def subscribe_for_notification()
  begin
    eventFilters = ['/restapi/v1.0/account/~/extension/~/message-store/instant?type=SMS']
    bodyParams = {
      eventFilters: eventFilters,
      deliveryMode: {
        transportType: 'WebHook',
        address: DELIVERY_ADDRESS
      },
      expiresIn: 3600
    }
    endpoint = "/restapi/v1.0/subscription"
    resp = $platform.post(endpoint, payload: bodyParams)
    if (resp.status == 200)
      puts (resp.body)
      puts ("Subscription id: " + resp.body['id'])
      puts ("Ready to receive incoming SMS via WebHook.")
    else
      puts ("Webhook creation failed.")
      puts (resp.body)
    end
  rescue StandardError => e
    puts e
  end
end

#
# Read all created subscriptions
#
def read_subscriptions()
  begin
    endpoint = "/restapi/v1.0/subscription"
    resp = $platform.get(endpoint)
    if (resp.body['records'].length == 0)
      puts ("No subscription.")
    else
      for record in resp.body['records'] do
        puts JSON.pretty_generate(JSON.parse(record.to_json))
        delete_subscription(record['id'])
      end
    end
  rescue StandardError => e
    puts e
  end
end

#
# Delete a subscription identified by the subscription id
#
def delete_subscription(subscriptionId)
  begin
    endpoint = "/restapi/v1.0/subscription/" + subscriptionId
    resp = $platform.delete(endpoint)
    puts ("Subscription " + subscriptionId + " deleted.")
  rescue StandardError => e
    puts e
  end
end

# Instantiate the SDK and get the platform instance
$platform = RingCentral.new( ENV['RC_CLIENT_ID'], ENV['RC_CLIENT_SECRET'], ENV['RC_SERVER_URL'] )

# Authenticate a user using a personal JWT token
def login()
  begin
    $platform.authorize(jwt: ENV['RC_JWT'])
    subscribe_for_notification()
    #read_subscriptions()
  rescue StandardError => e
    puts ("Unable to authenticate to platform. Check credentials." + e.to_s)
  end
end

login()

Run your code

You are almost done. Now run your script. Open 2 terminal windows and run your script in each terminal in the order below:

$ ruby webhook-server.rb
$ ruby webhook-notification.rb

We use .NET core which is cross-platform. You can get it here.

Create a webhook demo solution

mkdir webhook-demo
cd webhook-demo
dotnet new sln

Create WebHook Server project

mkdir webhook-server
cd webhook-server
dotnet new web

Edit Startup.cs and override its content with code below:

using System;
using System.IO;
using System.Text;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Primitives;

namespace webhooks
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment()) app.UseDeveloperExceptionPage();

            app.Run( async (context) =>
                {
                    context.Request.Headers.TryGetValue("Validation-Token", out StringValues validationToken);
                    context.Response.Headers.Add("Validation-Token", validationToken);
                    if (context.Request.Path == "/webhook" && context.Request.Method == "POST")
                    {
                        using (StreamReader reader = new StreamReader(context.Request.Body, Encoding.UTF8))
                        {
                            var eventPayload = await reader.ReadToEndAsync();
                            Console.WriteLine(eventPayload);
                        }
                    }
                });
        }
    }
}

Run ngrok to create a localhost tunnel

$ ngrok http 5000

Create WebHook Notification Subscription project

Open a new terminal at the "webhook-demo" folder

mkdir setup-webhook
cd setup-webhook
dotnet new console
dotnet add package RingCentral.Net -v "6.0.0"
dotnet add package dotenv.Net

Edit the Program.cs file and override its content with code below. Be sure to copy and paste the .env file to the "setup-webhook" folder

Copy the forwarding address, e.g. https://1058-69-181-202-32.ngrok-free.app, and paste it to your .env file. Or paste it directly into the DELIVERY_ADDRESS variable in the code below.

using System;
using System.Threading.Tasks;
using RingCentral;
using dotenv.net;

namespace setup_webhook
{
    class Program
    {
        static RestClient restClient;
        static string DELIVERY_ADDRESS = "";

        static async Task Main(string[] args)
        {
            DotEnv.Load();

            // For the purpose of testing the code, we put the deliver address in the environment variable.
            // Feel free to set the delivery address directly.
            DELIVERY_ADDRESS = Environment.GetEnvironmentVariable("WEBHOOK_DELIVERY_ADDRESS") + "/webhook";

            try
            {
                // Instantiate the SDK
                restClient = new RestClient(
                    Environment.GetEnvironmentVariable("RC_CLIENT_ID"),
                    Environment.GetEnvironmentVariable("RC_CLIENT_SECRET"),
                    Environment.GetEnvironmentVariable("RC_SERVER_URL"));

                // Authenticate a user using a personal JWT token
                await restClient.Authorize(Environment.GetEnvironmentVariable("RC_JWT"));
                await subscribe_for_notification();
                //await read_subscriptions();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        /*
        * Create a Webhok notification and subscribe for instant SMS message notification
        */
        static private async Task subscribe_for_notification()
        {
            try
            {
                var bodyParams = new CreateSubscriptionRequest();
                bodyParams.eventFilters = new[] { "/restapi/v1.0/account/~/extension/~/message-store/instant?type=SMS" };
                bodyParams.deliveryMode = new NotificationDeliveryMode()
                {
                    transportType = "WebHook",
                    address = DELIVERY_ADDRESS
                };
                bodyParams.expiresIn = 3600;

                var resp = await restClient.Restapi().Subscription().Post(bodyParams);
                Console.WriteLine("Subscription Id: " + resp.id);
                Console.WriteLine("Ready to receive incoming SMS via WebHook.");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        /*
        * Read all created subscriptions
        */
        static private async Task read_subscriptions()
        {
            try
            {
                var resp = await restClient.Restapi().Subscription().List();
                if (resp.records.Length == 0)
                {
                    Console.WriteLine("No subscription.");
                }
                else
                {
                    foreach (var record in resp.records)
                    {
                        Console.WriteLine(JsonConvert.SerializeObject(record));
                        await delete_subscription(record.id);
                    }
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        /*
        * Delete a subscription identified by the subscription id
        */
        static private async Task delete_subscription(String subscriptionId)
        {
            try
            {
                var resp = await restClient.Restapi().Subscription(subscriptionId).Delete();
                Console.WriteLine("Subscription " + subscriptionId + " deleted.");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}

Run your code

You are almost done. Now run your scripts.

At the webhook-server terminal, run:

dotnet run

At the setup-webhook terminal, run:

dotnet run

Create a WebhookServer project (using Eclipse IDE)

  • Create a new Java project
  • Select the Gradle Project wizard
  • Enter project name "WebhookServer"
  • Open the build.gradle file and add the dependencies to the project as shown below:

dependencies {
    // ...
    implementation 'org.eclipse.jetty.aggregate:jetty-all:9.4.51.v20230217'
    implementation: 'javax.servlet:javax.servlet-api:4.0.1'
}
We use jetty-all version 9.4.x for our server. You can get a different version here if you want to.

Create a new Java Class

Select "File -> New -> Class" to create a new Java class named "WebhookServer"

Edit the WebhookServer.java with code below:

package WebhookServer;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;

public class WebhookServer extends AbstractHandler
{
    @Override
    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
    {
        response.setStatus(HttpServletResponse.SC_OK);
        response.setHeader("Validation-Token", request.getHeader("Validation-Token"));
        if (request.getMethod() == "POST")
        {
            String body = request.getReader().lines().collect( java.util.stream.Collectors.joining(System.lineSeparator()) );
            System.out.println(body);
        }
        response.getWriter().println("OK");
        baseRequest.setHandled(true);
    }

    public static void main( String[] args ) throws Exception
    {
        Server server = new Server(5000);
        server.setHandler(new WebhookServer());
        server.start();
        server.join();
    }
}

Create a Java project (using Eclipse IDE)

  • Create a new Java project
  • Select the Gradle Project wizard
  • Enter project name "WebHookNotification"
  • Open the build.gradle file and add the RingCentral Java SDK to the project as shown below:
dependencies {
    // ...
    compile 'com.ringcentral:ringcentral:3.0.0'
}
  • On Eclipse menu, select "Run" and choose the "Run Configurations" and in the dialog, select your project and select the "Environments" tab then enter the following variables:

    • RC_CLIENT_ID
    • RC_CLIENT_SECRET
    • RC_SERVER_URL
    • RC_JWT
    • WEBHOOK_DELIVERY_ADDRESS
  • Right-click the project in the Package Explorer and choose "Refresh Gradle Project" under the "Gradle" sub-menu

Create a new Java Class

Select "File -> New -> Class" to create a new Java class named "WebHookNotification"

package WebHookNotification;

public class WebHookNotification {

  public static void main(String[] args) {
    // TODO Auto-generated method stub

  }
}

Edit the file "WebHookNotification.java".

Run ngrok to create a localhost tunnel

$ ngrok http 5000

Copy the forwarding address, e.g. https://1058-69-181-202-32.ngrok-free.app, and paste it to your .env file. Or paste it directly into the DELIVERY_ADDRESS variable in the code below.

package WebHookNotification;

import java.io.IOException;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;

import com.ringcentral.*;
import com.ringcentral.definitions.*;

public class WebHookNotification {
    static RestClient restClient;
    static String DELIVERY_ADDRESS = "";
    public static void main(String[] args) {
      var obj = new WebHookNotification();
      try {
        // Instantiate the SDK
        restClient = new RestClient(System.getenv("RC_CLIENT_ID"), System.getenv("RC_CLIENT_SECRET"), System.getenv("RC_SERVER_URL"));

        // Authenticate a user using a personal JWT token
        restClient.authorize(System.getenv("RC_JWT"));

        // For the purpose of testing the code, we put the deliver address in the environment variable.
        // Feel free to set the delivery address directly.
        DELIVERY_ADDRESS = System.getenv("WEBHOOK_DELIVERY_ADDRESS") + "/webhook";

        obj.create_webhook_subscription();
        // obj.read_subscriptions;
      } catch (RestException e) {
        System.out.println(e.getMessage());
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    /*
    * Create a Webhok notification and subscribe for instant SMS message notification
    */
    private void create_webhook_subscription() throws RestException, IOException {
      try {
        var bodyParams = new CreateSubscriptionRequest();
        bodyParams.eventFilters = new String[] { "/restapi/v1.0/account/~/extension/~/message-store/instant?type=SMS" };
        bodyParams.deliveryMode = new NotificationDeliveryMode();
        bodyParams.deliveryMode.transportType = "WebHook";
        bodyParams.deliveryMode.address = DELIVERY_ADDRESS;

        bodyParams.expiresIn(3600L);

        var resp = restClient.restapi().subscription().post(bodyParams);
        System.out.println("Subscription Id: " + resp.id);
        System.out.println("Ready to receive incoming SMS via WebHook.");
      }catch(RestException e) {
        System.out.println(e.getMessage());
      }
    }
    /*
    * Read all created subscriptions
    */
    private void read_subscriptions()  throws RestException, IOException {
      try {
        var resp = restClient.restapi().subscription().list();
        if (resp.records.length == 0) {
          System.out.println("No subscription.");
        } else {
          for (var record : resp.records) {
            String jsonStr = new Gson().toJson(record, new TypeToken<Object>(){}.getType());
            System.out.println(jsonStr);
            delete_subscription(record.id);
          }
        }

      }catch(RestException e) {
        System.out.println(e.getMessage());
      }
    }
    /*
    * Delete a subscription identified by the subscription id
    */
    private void delete_subscription(String subscriptionId)  throws RestException, IOException {
      try {
        var resp = restClient.restapi().subscription(subscriptionId).delete();
        System.out.println("Subscription Id: " + subscriptionId + " deleted.");
      }catch(RestException e) {
        System.out.println(e.getMessage());
      }
    }
}

Now first run the WebhookServer app, then run the WebHookNotification app from Eclipse.

Test the app

  • Now you can send an SMS message to the extension's phone number to see how you'll receive the notification.
  • After testing your webhook subscription creation, feel free to edit the webhook-notification.xx file by comment out the subscribe_for_notification() function call and uncomment the next line read_subscriptions() to test reading and deleting subscriptions.