Enable message notification service
The message notification service can inform your server of Agora product events through HTTP/HTTPS protocol requests. This service integrates some events of the Cloud Recording, Media Push and Media Pull products. You can use this service by providing configuration information to Agora.
Contact support@agora.io enable the message notification service with the following information:
- HTTP/HTTPS server address (URL) to receive notification callbacks.
- The product that you want to use the notification service.
- Events that you want to be notified, see Cloud Recording Event Type.
- Set whether or not to enable the notification Retry option. If you enable this option, the notification server resends the notification callback up to three times after it fails to send the first notification callback in the following situations:
- Your server does not respond in 10 seconds.
- The HTTP status code received from your server is not 200.
After the configuration is completed, the message notification service will take effect after 5 minutes. Therefore, your server needs to respond to the notification server immediately. The response body
must be in JSON format.
After configuring the message notification service, we will automatically generate the secret
. The secret
is a string type key
that can be used to generate a signature. You need to save this key
for signature verification. See Signature verification for details.
The notification callback is sent to your server as an HTTP/HTTPS POST request with the body
in JSON format. The character encoding is UTF-8.
The header
of the notification callback contains the following fields:
Field Name | Value |
---|
Content-Type | application/json |
Agora-Signature | The signature generated by Agora using the secrect key and the HMAC/SHA1 algorithm. You need to use the secret key and HMAC/SHA1 algorithm to verify the signature value. See Signature verification for details. |
Agora-Signature-V2 | The signature generated by Agora using the secrect key and the HMAC/SHA256 algorithm. You need to use the secret key and HMAC/SHA256 algorithm to verify the signature value. See Signature verification for details. |
The body
of the notification callback contains the following fields:
We generate the key
directly. After using the HMAC/SHA1 and HMAC/SHA256 algorithms, we generate the Agora-Signature
and Agora-Signature-V2
. You can use the saved key
to verify Agora-Signature
with the HMAC/SHA1 algorithm or verify Agora-Signature-V2
with the HMAC/SHA256 algorithm.
The signature verification sample code is as follows:
_9# !-*- coding: utf-8 -*-
_9# Get the raw request body of the notification callback to calculate the signature. request_body in the following code is a binary byte array before deserialization and not a dictionary after deserialization.
_9request_body = '{"eventMs":1560408533119,"eventType":10,"noticeId":"4eb720f0-8da7-11e9-a43e-53f411c2761f","notifyMs":1560408533119,"payload":{"a":"1","b":2},"productId":1}'
_9signature = hmac.new(secret, request_body, hashlib.sha1).hexdigest()
_9print(signature) # 033c62f40f687675f17f0f41f91a40c71c0f134c
_9# !-*- coding: utf-8 -*-
_9# Get the raw request body of the notification callback to calculate the signature. request_body in the following code is a binary byte array before deserialization and not a dictionary after deserialization.
_9request_body = '{"eventMs":1560408533119,"eventType":10,"noticeId":"4eb720f0-8da7-11e9-a43e-53f411c2761f","notifyMs":1560408533119,"payload":{"a":"1","b":2},"productId":1}'
_9signature2 = hmac.new(secret, request_body, hashlib.sha256).hexdigest()
_9print(signature2) # 6d3320c60b11101395b7fc8f9068748808a0aa1bfa064438e39d1bc2c7d74d99
_6const crypto = require('crypto')
_6// Get the raw request body of the notification callback to calculate the signature. requestBody in the following code is a binary byte array before deserialization, not an object after deserialization.
_6const requestBody = '{"eventMs":1560408533119,"eventType":10,"noticeId":"4eb720f0-8da7-11e9-a43e-53f411c2761f","notifyMs":1560408533119,"payload":{"a":"1","b":2},"productId":1}'
_6const secret = 'secret'
_6const signature = crypto.createHmac('sha1', secret).update(requestBody, 'utf8').digest('hex')
_6console.log(signature) // 033c62f40f687675f17f0f41f91a40c71c0f134c
_6const crypto = require('crypto')
_6// Get the raw request body of the notification callback to calculate the signature. requestBody in the following code is a binary byte array before deserialization, not an object after deserialization.
_6const requestBody = '{"eventMs":1560408533119,"eventType":10,"noticeId":"4eb720f0-8da7-11e9-a43e-53f411c2761f","notifyMs":1560408533119,"payload":{"a":"1","b":2},"productId":1}'
_6const secret = 'secret'
_6const signature2 = crypto.createHmac('sha256', secret).update(requestBody, 'utf8').digest('hex')
_6console.log(signature2) // 6d3320c60b11101395b7fc8f9068748808a0aa1bfa064438e39d1bc2c7d74d99
_36import javax.crypto.Mac;
_36import javax.crypto.SecretKey;
_36import javax.crypto.spec.SecretKeySpec;
_36public class HmacSha {
_36 // Convert an encrypted byte array into a hex string.
_36 public static String bytesToHex(byte[] bytes) {
_36 StringBuffer sb = new StringBuffer();
_36 for (int i = 0; i < bytes.length; i++) {
_36 String hex = Integer.toHexString(bytes[i] & 0xFF);
_36 if (hex.length() < 2) {
_36 return sb.toString();
_36 // Use the HMAC/SHA1 algorithm and get the encrypted hex string.
_36 public static String hmacSha1(String message, String secret) {
_36 SecretKeySpec signingKey = new SecretKeySpec(secret.getBytes(
_36 "utf-8"), "HmacSHA1");
_36 Mac mac = Mac.getInstance("HmacSHA1");
_36 mac.init(signingKey);
_36 byte[] rawHmac = mac.doFinal(message.getBytes("utf-8"));
_36 return bytesToHex(rawHmac);
_36 } catch (Exception e) {
_36 throw new RuntimeException(e);
_36 public static void main(String[] args) {
_36 // Get the raw request body of the notification callback to calculate the signature. request_body in the following code is a binary byte array before deserialization and not an object after deserialization.
_36 String request_body = "{\"eventMs\":1560408533119,\"eventType\":10,\"noticeId\":\"4eb720f0-8da7-11e9-a43e-53f411c2761f\",\"notifyMs\":1560408533119,\"payload\":{\"a\":\"1\",\"b\":2},\"productId\":1}";
_36 String secret = "secret";
_36 System.out.println(hmacSha1(request_body, secret)); //033c62f40f687675f17f0f41f91a40c71c0f134c
_36import javax.crypto.Mac;
_36import javax.crypto.SecretKey;
_36import javax.crypto.spec.SecretKeySpec;
_36public class HmacSha {
_36 // Convert an encrypted byte array into a hex string.
_36 public static String bytesToHex(byte[] bytes) {
_36 StringBuffer sb = new StringBuffer();
_36 for (int i = 0; i < bytes.length; i++) {
_36 String hex = Integer.toHexString(bytes[i] & 0xFF);
_36 if (hex.length() < 2) {
_36 return sb.toString();
_36 // Use the HMAC/SHA256 algorithm and get the encrypted hex string.
_36 public static String hmacSha256(String message, String secret) {
_36 SecretKeySpec signingKey = new SecretKeySpec(secret.getBytes(
_36 "utf-8"), "HmacSHA256");
_36 Mac mac = Mac.getInstance("HmacSHA256");
_36 mac.init(signingKey);
_36 byte[] rawHmac = mac.doFinal(message.getBytes("utf-8"));
_36 return bytesToHex(rawHmac);
_36 } catch (Exception e) {
_36 throw new RuntimeException(e);
_36 public static void main(String[] args) {
_36 // Get the raw request body of the notification callback to calculate the signature. request_body in the following code is a binary byte array before deserialization and not an object after deserialization.
_36 String request_body = "{\"eventMs\":1560408533119,\"eventType\":10,\"noticeId\":\"4eb720f0-8da7-11e9-a43e-53f411c2761f\",\"notifyMs\":1560408533119,\"payload\":{\"a\":\"1\",\"b\":2},\"productId\":1}";
_36 String secret = "secret";
_36 System.out.println(hmacSha256(request_body, secret)); //033c62f40f687675f17f0f41f91a40c71c0f134c
- Your server does not receive messages in the same order as events occur.
- For the reliability of the notification callbacks, the notification server may send at least two notification callbacks when the event occurs. Hence, your server should be able to handle duplicate messages.