Receive event notifications
A webhook is a user-defined callback over HTTP. You use webhooks to notify your app or back-end system when certain Media Pull events occur. Agora Notifications enables you to subscribe to events and receive notifications about them across multiple product lines.
Understand the tech
Using Agora Console you subscribe to specific events for your project and configure the URL of the webhooks to receive these events. Agora sends notifications of your events to your webhook every time they occur. Your server authenticates the notification and returns 200 Ok
to confirm reception. You use the information in the JSON payload of each notification to give the best user experience to your users.
The following figure illustrates the workflow when Notifications is enabled for the specific Media Pull events you subscribe to:
- A user commits an action that creates an event.
- Notifications sends an HTTPS POST request to your webhook.
- Your server validates the request signature, then sends a response to Notifications within 10 seconds. The response body must be in JSON.
If Notifications receives 200 OK
within 10 seconds of sending the initial notification, the callback is considered successful. If these conditions are not met, Notifications immediately resends the notification. The interval between notification attempts gradually increases. Notifications stops sending notifications after three retries.
Prerequisites
To set up and use Notifications, you must have:
-
A computer with Internet access.
If your network access is restricted by a firewall, call the IP address query API to retrieve the Notifications IP addresses , then configure the firewall to allow these IP addresses.
Handle notifications for specific events
In order to handle notifications for the events you subscribe to, you need to:
Create your webhook
Once Notifications is enabled, Agora SD-RTN™ sends notification callbacks as HTTPS POST
requests to your webhook when events that you are subscribed to occur. The data format of the requests is JSON, the character encoding is UTF-8
, and the signature algorithm is HMAC/SHA1
or HMAC/SHA256
.
For Notifications, a webhook is an endpoint on an HTTP
server that handles these requests. In a production environment you write this in your web infrastructure, for development purposes best practice is to create a simple local server and use a service such as ngrok to supply a public URL that you register with Agora SD-RTN™ when you enable Notifications.
To do this, take the following steps:
-
Set up Go
Ensure you have Go installed on your system. If not, download and install it from the official Go website.
-
Create a Go project for your server
Create a new directory for your project and navigate into it:
In the project directory, create a new file
main.go
. Open the file in your preferred text editor and add the following code: -
Run your Go server
Run the server using the following command:
-
Create a public URL for your server
In this example you use
ngrok
to create a public URL for your server.-
Download and install ngrok. If you have
Chocolatey
, use the following command: -
Add an
authtoken
to ngrok:To obtain an
authToken
, sign up with ngrok. -
Start a tunnel to your local server using the following command:
You see a Forwarding URL and a Web Interface URL in the console. Open the web interface URL in your browser.
-
-
Test the server
Open a web browser and navigate to the public URL provided by
ngrok
to see the root handler response.Use curl, Postman, or another tool to send a
POST
request tohttps://<ngrok_url>/ncsNotify
with the requiredJSON
payload.Example using
curl
:Make sure you replace
ngrok_url
with the forwarding url.Once the HTTP request is successful, you see the following
JSON
payload in your browser:
Enable Notifications
To enable Notifications:
-
Log in to Agora Console. On the Projects tab, locate the project for which you want to enable Notifications and click Configure.
-
In the Features section, locate Notifications, and click Enable.
-
On the configuration page, click on the service for which you want to enable notifications. The item expands to show configuration options.
-
Fill in the following information:
-
Event: Select all the events that you want to subscribe to.
If the selected events generate a high number of queries per second (QPS), ensure that your server has sufficient processing capacity.
-
Receiving Server Region: Select the region where your server that receives the notifications is located. Agora connects to the nearest Agora node server based on your selection.
-
Receiving Server URL Endpoint: The
HTTPS
public address of your server that receives the notifications. For example,https://1111-123-456-789-99.ap.ngrok.io/ncsNotify
.infoFor enhanced security, Notifications no longer supports
HTTP
addresses.-
To reduce the delay in notification delivery, best practice is to activate
HTTP
persistent connection (also calledHTTP
keep-alive) on your server with the following settings:MaxKeepAliveRequests
: 100 or moreKeepAliveTimeout
: 10 seconds or more
-
-
Whitelist: If your server is behind a firewall, check the box here, and ensure that you call the IP address query API to get the IP addresses of the Agora Notifications server and add them to the firewall's allowed IP list.
-
-
Copy the Secret displayed against the product name by clicking the copy icon. You use this secret to Add signature verification.
-
Press Save. Agora performs a health test for your configuration as follows:
-
The Notifications health test generates test events that correspond to your subscribed events, and then sends test event callbacks to your server.
-
After receiving each test event callback, your server must respond within 10 seconds with a status code of
200
. The response body must be in JSON format. -
When the Notifications health test succeeds, read the prompt and press Save Notifications Configuration. After your configuration is saved, the Status of Notifications shows Enabled.
If the Notifications health test fails, follow the prompt on the Agora Console to troubleshoot the error. Common errors include the following:
-
Request timeout (590): Your server does not return the status code
200
within 10 seconds. Check whether your server responds to the request properly. If your server responds to the request properly, contact Agora Technical Support to check if the network connection between the Agora Notifications server and your server is working. -
Domain name unreachable (591): The domain name is invalid and cannot be resolved to the target IP address. Check whether your server is properly deployed.
-
Certificate error (592): The Agora Notifications server fails to verify the SSL certificates returned by your server. Check if the SSL certificates of your server are valid. If your server is behind a firewall, check whether you have added all IP addresses of the Agora Notifications server to the firewall's allowed IP list.
-
Other response errors: Your server returns a response with a status code other than
200
. See the prompt on the Agora Console for the specific status code and error messages.
-
-
Add signature verification
To communicate securely between Notifications and your webhook, Agora SD-RTN™ uses signatures for identity verification as follows:
-
When you configure Notifications in Agora Console, Agora SD-RTN™ generates a secret you use for verification.
-
When sending a notification, Notifications generates two signature values from the secret using
HMAC/SHA1
andHMAC/SHA256
algorithms. These signatures are added asAgora-Signature
andAgora-Signature-V2
to theHTTPS
request header. -
When your server receives a callback, you can verify
Agora-Signature
orAgora-Signature-V2
:- To verify
Agora-Signature
, use the secret, the raw request body, and thecrypto/sha1
algorithm. - To verify
Agora-Signature-V2
, use the secret, the raw request body, and thecrypto/sha256
algorithm.
- To verify
The following sample code uses crypto/sha1
.
To add signature verification to your server, take the following steps:
-
In the
main.go
file, replace your imports with with the following: -
Add the following code after the list of imports:
-
In the
main.go
file, add the following code afterfmt.Println("Request Body:", string(body))
: -
To test the server, follow the steps given in the Enable notifications section.
-
When you receive an event from the console, and if the signature matches, the event details are displayed in your browser.
Reference
This section contains in depth information about Notifications.
Request Header
The header of notification callbacks contains the following fields:
Field name | Value |
---|---|
Content-Type | application/json |
Agora-Signature | The signature generated by Agora using the Secret and the HMAC/SHA1 algorithm. You need to use the Secret and HMAC/SHA1 algorithm to verify the signature value. For details, see Signature verification. |
Agora-Signature-V2 | The signature generated by Agora using the Secret and the HMAC/SHA256 algorithm. You need to use the Secret and the HMAC/SHA256 algorithm to verify the signature value. For details, see Signature verification. |
Request Body
The request body of notification callbacks contains the following fields:
Field name | Type | Description |
---|---|---|
noticeId | String | The notification ID, identifying the notification callback when the event occurs. |
productId | Number | The product ID:
|
eventType | Number | The type of event being notified. For details, see event types. |
notifyMs | Number | The Unix timestamp (ms) when Notifications sends a callback to your server. This value is updated when Notifications resends the notification callback. |
payload | JSON Object | The content of the event being notified. The payload varies with event type. |
Example
Event types
You can subscribe to the following Media Pull events from Agora Console:
eventType | Event name | Description |
---|---|---|
1 | Player Created | Cloud player successfully created. |
3 | Player Destroyed | Cloud player destroyed. |
4 | Player Status Changed | State of the cloud player changed at runtime. |
Player Created
When you successfully create a cloud player by calling the Create
API, Notifications sends a notification for this event to your server.
The eventType
is 1(Player Created)
. The payload
contains data with the following structure:
player
: JSON Object. Contains the following fields:channelName
: String. The name of the Agora channel.createTs
: Number. The Unix timestamp (in seconds) when creating the cloud player.id
: String. UUID (Universally Unique Identifier) to identify the cloud player created. It is the ID of the cloud player.idleTimeout
: Number. The maximum length of time (in seconds) that the cloud player is idle. The "idle" state means that the media stream is not playing. When the idle state exceedsidleTimeout
, the cloud player is automatically destroyed.name
: String. The name of the cloud player.streamUrl
: String. The RTMP URL of the online media stream.token
: String. The authentication token used by the cloud player in the channel.uid
: Number. The User ID of the cloud player in the channel.account
: String. The User Account of the cloud player in the Agora channel.status
: String. The state of the cloud player at runtime:"connecting"
: Agora's server is connecting to the address of the media stream or detecting the audio and video data.
lts
: Number. The Unix timestamp (ms) when the event occurs in Agora's server for the cloud player function.xRequestId
: String. UUID (Universally Unique Identifier) to identify this request. It is the same as theX-Request-ID
field in the request header.
Player Destroyed
When the cloud player is destroyed, Notifications sends a notification for this event to your server. The reason for destruction is mentioned in the destroyReason
field.
The eventType
is 3(Player Destroyed)
. The payload
contains data with the following structure:
player
: JSON Object. Contains the following fields:channelName
: String. The name of the Agora channel.id
: String. UUID (Universally Unique Identifier) to identify the cloud player created. It is the ID of the cloud player.name
: String. The name of the cloud player.
lts
: Number. The Unix timestamp (ms) when the event occurs in Agora's server for the cloud player function.destroyReason
: String. The reason why the cloud player is destroyed:Delete Request
: You call theDelete
API to successfully destroy the cloud player.Internal Error
: The error occurs when setting the parameters and fields related to the Agora channel, such as thetoken
is invalid or expires.Idle Timeout
: Within the specifiedidleTimeout
, Agora's server for the cloud player function cannot connect the address of the media stream or the media stream cannot be played.Stream Stopped
: Media stream playback ends.
fields
: String. The field mask to represent a set of symbolic field paths. The field mask is encoded as a single string where paths are separated by a comma. It specifies a subset of fields that should be returned. In the sample code,fields
specifies to return thename
,channelName
, andid
fields. For details, see Google protobuf FieldMask.
Player Status Changed
When the state of the cloud player at runtime changes, Notifications sends a notification for this event to your server.
The eventType
is 4(Player Status Changed)
. The payload
contains data with the following structure:
player
: JSON Object. Contains the following fields:channelName
: String. The name of the Agora channel.id
: String. UUID (Universally Unique Identifier) to identify the cloud player created. It is the ID of the cloud player.name
: String. The name of the cloud player.status
: String. The state of the cloud player at runtime:"connecting"
: Agora server for the cloud player function is connecting to the address of the media stream or detecting the audio and video data."success"
: Agora server is successfully connected to the address of the media stream."running"
: Playing."failed"
: Agora's server cannot connect to the address of the media stream, or the media stream cannot be played.stopped
: Media stream playback ends.
lts
: Number. The Unix timestamp (ms) when the event occurs in Agora's server for the cloud player function.fields
:String. The field mask to represent a set of symbolic field paths. The field mask is encoded as a single string where paths are separated by a comma. It specifies a subset of fields that should be returned. In the sample code,fields
specifies to return thename
,channelName
,id
andstatus
fields. For details, see Google protobuf FieldMask.
IP address query API
If your server that receives notification callbacks is behind a firewall, call the IP address query API to retrieve the IP addresses of Notifications and configure your firewall to trust all these IP addresses.
Agora occasionally adjusts the Notifications IP addresses. Best practice is to call this endpoint at least every 24 hours and automatically update the firewall configuration.
Prototype
- Method:
GET
- Endpoint:
https://api.agora.io/v2/ncs/ip
Request header
Authorization: You must generate a Base64-encoded credential with the Customer ID and Customer Secret provided by Agora, and then pass the credential to the Authorization field in the HTTP request header.
Request body
This API has no body parameters.
Response body
When the request succeeds, the response body looks like the following:
Each primary IP field shows an IP address of Notifications server. When you receive a response, you need to note the primary IP fields and add all these IP addresses to your firewall's allowed IP list.
Considerations
-
Notifications does not guarantee that notification callbacks arrive at your server in the same order as events occur. Implement a strategy to handle messages arriving out of order.
-
For improved reliability of Notifications, your server may receive more than one notification callback for a single event. Your server must be able to handle repeated messages.
TipTo implement a strategy to ensure that you log only one callback event and ignore duplicate events, use a combination of the
noticeId
andnotifyMs
fields in the response body.