Notification Webhook
Have notification event information sent to a webhook endpoint
The Notification Webhook enables you to monitor message-related events. Through a POST
API call, the Notification Webhook sends event information to a webhook endpoint, such as those in the following list:
- Someone liked your message
- Your message was approved or rejected
- Someone replied to your message
- An author you follow posted a new article
- A new topic that has a keyword you follow has been posted
- Someone mentioned you in a comment
- Someone started following you
- Someone you follow commented or replied on any other comment
OpenWeb only sends notifications events for notifications that the user is expecting to receive. Users set their notification settings within their OpenWeb notification preferences.
If you use an SSO implementation, you can also create custom notification checkboxes for your users. Once a user has set the notifications to be received, you can make an Update User API call to update the user's OpenWeb notification settings.
The following sections explain how to set up and maintain the Notification Webhook.
Set up the Notification Webhook
-
Create a webhook endpoint.
Be sure that your endpoint accepts both
HTTPS
connections andPOST
requests. -
Identify the notification events that you want to receive.
-
Prepare the required configuration JSON.
-
Contact your OpenWeb representative with your webhook configuration. Your OpenWeb representative will create and configure a unique authenticated endpoint request for you.
Security
OpenWeb supports authenticating your webhook using any of the methods listed in the following sections.
Tokens
Webhook Token
When OpenWeb sends an event notification to a registered webhook, an x-openweb-notification-event-webhook-token
header is included so that you know the request was sent from OpenWeb servers.
OpenWeb strongly recommends that you verify the header when you receive a request at your webhook endpoint.
Please provide your token in a secure way to your OpenWeb representative.
Oauth2
OpenWeb supports authentication via the implementation of the RFC7523 (client_secret_jwt
).
When using this approach, please provide the associated client secret in a secure way to your OpenWeb representative. OpenWeb will then securely store the client secret and sign the authentication requests with that key.
- This flow creates a signed JWT in order to issue the request, The JWT expiration is *600 seconds.
- The JWT Signing method uses HS256 (HMAC with SHA-256).
{
"client_id": "CLIENT_ID",
"client_secret": "CLIENT_SECRET",
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"grant_type": "client_credentials",
"token_uri": "TOKEN_URI",
"audience": "AUDIENCE",
"extra_grants": {
"scope": "PARTNER_SCOPE",
"realm": "PARTNER_REALM"
}
}
Parameter | Description |
---|---|
audience* string | Claim containing a value that identifies the authorization server as an intended audience |
client_id* string | ID of the client who must be authenticated |
token_uri* string | URL used to request an access token |
client_assertion_type string | Format of the assertion as defined by the authorization server Default value: urn:ietf:params:oauth:client-assertion-type:jwt-bearer |
client_secret string | Secret used to sign the JWT request to the authentication server
This is provided as a placeholder. You will need to supply this value in a secure way to your OpenWeb representative. |
extra_grants string | Various optional extra grants needed for the authorization request |
grant_type string | Credential representing the resource owner's authorization for the client to access its protected resources The grant_type is used by the client to obtain an access token.Default value: Client credentials |
The successful authentication returns the following JSON.
{
"access_token": "ACCESS_TOKEN",
"token_type":" Bearer",
"expires_in": 600
}
Parameter | Description |
---|---|
access_token* string | Access token used to issue webhook calls |
expires_in* string | Expiration time of the access token in seconds
OpenWeb will re-issue an authentication one minute before expiration. Be sure to return a value that is greater than 300 seconds. |
token_type string | Token type that is received
This is unused by OpenWeb. |
Response codes and retries
The following table lists the response codes that OpenWeb issues for responses that are received from an authentication request.
If OpenWeb does not receive a 2xx
response within 10 seconds of posting an event to your webhook endpoint, an attempt to resend the event occurs according to your configuration.
Status Code | Description |
---|---|
200 | Success: The access_token will be used for further webhook calls. |
401 | Unauthorized: OpenWeb will try to re-authenticate. If unsuccessful, the event will go through the regular retry cycle. |
403 | Forbidden: OpenWeb will try to re-authenticate. If unsuccessful, the event will go through the regular retry cycle. |
Configuration
{
"enabled" : true,
"endpoint": "ENDPOINT_URL",
"auth_type": "partner_secret_token",
"auth_config": {
"secret_name": "OW secret store entry that contains your token"
},
"retry_base": 2,
"retry_max_count": 5,
"registered_events": {
"email": [
"user-mentioned",
"user-followed",
"liked-message"
],
"in-app": []
}
}
{
"enabled" : true,
"endpoint": "ENDPOINT_URL",
"auth_type": "client_secret_jwt",
"auth_config": {
"client_id": "CLIENT_ID",
"client_secret": "CLIENT_SECRET",
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"audience": "AUDIENCE",
"token_uri": "TOKEN_URI",
"grant_type": "client_credentials",
"extra_grants": {
"scope": "PARTNER_SCOPE",
"realm": "PARTNER_REALM"
}
},
"retry_base": 2,
"retry_max_count": 5,
"registered_events": {
"email": [
"user-mentioned",
"replied-your-message",
"liked-message"
],
"in-app": []
}
}
Notification Event | Description |
---|---|
endpoint* string | Events will be sent to this URL |
spot_id* string | Spot ID that should be used for those notifications |
registered_events object | List of email and in-app events per channel to which the user would like to register
This will always match the user's settings. For cases of a mismatch between both configurations (no registered channels), notification will not be sent for that user. |
retry_base integer | Base value to perform exponential retries
The formula for retries is: retry_base seconds.
Default: 2 Minimum: 1 Maximum: 5 |
retry_max_count integer | Maximum number of retries per event after which the event will be discarded
The formula for retries is: retry_base seconds.
Default: 5 Minimum: 0 Maximum: 10 |
Events
OpenWeb enables you to configure your webhook endpoints to receive only the types of events required by your integration.
When event processing, be mindful of the following points:
- You should account for receiving the same event more than once. We advise you to guard against duplicated events by checking the event id or making your event processing idempotent.
- Event processing should rely upon event timestamps. Events are not guaranteed to be delivered in chronological order.
- Events are sent one by one. They are not batched.
The following table lists all supported event types.
Notification Event | Description |
---|---|
followee-commented | Someone you follow commented or replied |
liked-message | Someone liked your message |
message-auto-approved | Your message was approved by system |
message-approved | Your message was approved by moderator |
message-rejected | Your message was rejected by moderator |
replied-message | Someone replied to your message |
topic-by-author | There is a new article from an author you are following |
topic-by-keyword | There is a new topic by keyword you are following |
user-followed | Someone started following you |
user-mentioned | Someone mentioned you in a comment |
Responses
Each type of event returns a specific event response.
followee-commented
{
"event_id": EVENT_ID, // hash of event
"channels": [
"email",
"in-app"
],
"type": "followee-commented",
"action_link": "ARTICLE_URL",
"conversation_id": "CONVERSATION_ID",
"conversation_title": "ARTICLE_TITLE",
"user": {
"user_id": "USER_ID",
"sso_user_id": "SSO_USER_ID",
"user_name": "USER_NAME",
"display_name": "DISPLAY_NAME",
"registered": true
},
"comment": {
"content": [{
"type": "text|image|animation",
"text": "COMMENT_TEXT"
}],
"comment_id": "COMMENT_ID",
"type": "comment",
"timestamp": 1642598712
},
"followee": {
"user_id": "USER_ID2",
"sso_user_id": "SSO_USER_ID2",
"user_name": "USER_NAME2",
"display_name": "DISPLAY_NAME2",
"registered": true
}
}
liked-message
{
"event_id": EVENT_ID, // event hash
"channels": [
"email",
"in-app"
],
"type": "liked-message",
"action_link": "ARTICLE_URL",
"conversation_id": "CONVERSATION_ID",
"conversation_title": "ARTICLE_TITLE",
"user": { // recipient
"user_id": "USER_ID",
"sso_user_id": "SSO_USER_ID",
"user_name": "USER_NAME",
"display_name": "DISPLAY_NAME",
"registered": true
},
"comment": {
"content": [{
"type": "text|image|animation",
"text": "COMMENT_TEXT",
"url": "IMAGE_URL"
}],
"type": "comment",
"comment_id": "COMMENT_ID",
"timestamp": 1641492345
},
"total_count": 10,
"liker": {
"user_id": "USER_ID2",
"sso_user_id": "SSO_USER_ID2",
"user_name": "USER_NAME2",
"display_name": "DISPLAY_NAME2",
"registered": false
}
}
message-approved | message-rejected
{
"event_id": EVENT_ID, // event hash
"channels": [
"email",
"in-app"
],
"type": "message-approved", // could also be message-rejected
"action_link": "ARTICLE_URL",
"conversation_id": "CONVERSATION_ID",
"conversation_title": "ARTICLE_TITLE",
"user": { // recipient
"user_id": "USER_ID",
"sso_user_id": "SSO_USER_ID",
"user_name": "USER_NAME",
"display_name": "DISPLAY_NAME",
"registered": true
},
"comment": {
"content": [{
"type": "text|image|animation",
"text": "COMMENT_TEXT",
"url": "IMAGE_URL"
}],
"comment_id": "COMMENT_ID",
"state": "approved | rejected",
"type": "comment",
"timestamp": 1642598712
}
}
replied-message
{
"event_id": EVENT_ID, // event hash
"channels": [
"email",
"in-app"
],
"type": "replied-message",
"action_link": "ARTICLE_URL",
"conversation_id": "CONVERSATION_ID",
"conversation_title": "ARTICLE_TITLE",
"user": { // recipient
"user_id": "USER_ID",
"sso_user_id": "SSO_USER_ID",
"user_name": "USER_NAME",
"display_name": "DISPLAY_NAME",
"registered": true
},
"comment": {
"content": [{
"type": "text|image|animation",
"text": "COMMENT_TEXT",
"url": "IMAGE_URL"
}],
"comment_id": "COMMENT_ID",
"type": "comment",
"timestamp": 1643201248
},
"replier": {
"user_id": "USER_ID2",
"sso_user_id": "SSO_USER_ID2",
"user_name": "USER_NAME2",
"display_name": "DISPLAY_NAME2",
"registered": false
},
"reply": {
"content": [{
"type": "text|image|animation",
"text": "COMMENT_TEXT",
"url": "IMAGE_URL"
}],
"comment_id": "COMMENT_ID",
"type": "reply",
"timestamp": 1643201248
}
}
topic-by-author | topic-by-keyword
{
"event_id": EVENT_ID, // event hash
"channels": [
"email",
"in-app"
],
"type": "topic-by-author | topic-by-keyword", // to complete
"action_link": "ARTICLE_URL",
"conversation_id": "CONVERSATION_ID",
"conversation_title": "ARTICLE_TITLE",
"description": "DESCRIPTION",
"timestamp": 1642598712,
"user": { // recipient
"user_id": "USER_ID",
"sso_user_id": "SSO_USER_ID",
"user_name": "USER_NAME",
"display_name": "DISPLAY_NAME",
"registered": true
},
"keywords": [
"Chris Columbus"
],
"authors": [
"John Doe"
]
}
user-followed
{
"event_id": EVENT_ID, // hash of event
"channels": ["email", "in-app"],
"type": "user-followed",
"action_link": "URL",
"user": {
"user_id": "USER_ID",
"sso_user_id": "SSO_USER_ID",
"user_name": "USER_NAME",
"display_name": "DISPLAY_NAME",
"registered": true
},
"follower": {
"user_id": "USER_ID2",
"sso_user_id": "SSO_USER_ID2",
"user_name": "USER_NAME2",
"display_name": "DISPLAY_NAME2",
"registered": true
}
}
user-mentioned
{
"event_id": EVENT_ID, // event hash
"channels": [
"email",
"in-app"
],
"type": "user-mentioned",
"action_link": "ARTICLE_URL",
"conversation_id": "CONVERSATION_ID",
"conversation_title": "ARTICLE_TITLE",
"user": { // recipient
"user_id": "USER_ID",
"sso_user_id": "SSO_USER_ID",
"user_name": "USER_NAME",
"display_name": "DISPLAY_NAME",
"registered": false
},
"comment": {
"content": [{
"type": "text|image|animation",
"text": "COMMENT_TEXT",
"url": "IMAGE_URL"
}],
"comment_id": "COMMENT_ID",
"type": "comment",
"timestamp": 1641384172
},
"mentioner": {
"user_id": "USER_ID2",
"sso_user_id": "SSO_USER_ID2",
"user_name": "USER_NAME2",
"display_name": "DISPLAY_NAME2",
"registered": false
}
}
Parameter | Description |
---|---|
action_link string | URL of the comment or reply
The URL can contain a combination of the following query strings:
Relevant events:
URL of the article Relevant events:
URL of the user's profile on the article the following action happened Relevant event:
|
authors array[string] | List of article creators being followed
Relevant event:
|
channels array[string] | List of notification channels about which the user wants to be notified
If a user subscribed to a channel to which the webhook configuration is not subscribed, the channel will be removed from this list. If there is no match between the user channel configuration and webhook channel configuration (empty channel array), the event will not be sent to the webhook. Possible values:
|
comment object | Contents and metadata of the comment
See: comment object Relevant events:
|
conversation_id string | Unique identifier that is a combination of the Spot ID and post ID
Relevant events: All |
conversation_title string | Title of the article
Relevant events: All |
event_id string | Unique identifier for the notification event
Relevant events: All |
followee object | Information about the user who commented or replied on any article, and the user follows that followee
See: user object Relevant event:
|
follower object | Information about the user who started following the recipient
See: user object Relevant event:
|
keywords array[string] | List of one or several keywords being followed
Relevant event:
|
liker object | Information about the user who liked a message written by the notification recipient
See: user object Relevant event:
|
mentioner object | Information about the user who mentioned the notification recipient within a comment
See: user object Relevant event:
|
replier object | Information about the user who replied to a comment written by the notification recipient
See: user object Relevant event:
|
reply object | Contents and metadata of the reply
See: comment object Relevant event:
|
total_count integer | Number of likes for that comment or reply
Relevant event:
|
type string | Type of webhook notification Possible values:
Relevant events: All |
user object | Information about the user (the recipient) receiving the notification
See: user object Relevant events: All |
comment object
Parameter | Description |
---|---|
comment_id string | Unique identifier of the comment or reply
Relevant events:
|
content array[string] | List of content the comment or reply contains
See: comment.content object Relevant events:
|
state string | Approval status of a comment
Possible values:
Relevant events:
|
timestamp integer | List of content the comment or reply contains
Time of the comment or reply in Unix Epoch time Relevant events:
|
type string | Type of comment
Possible values:
Relevant events:
|
comment.content object
Comment content object represents an array of contents the comment has, There are several combination that are possible:
- text
- animation
- image
- text + animation
- text + image
Parameter | Description |
---|---|
text string | Written, non-image, HTML-encoded content of the comment
This is relevant only for the text type portion of the comment.
Relevant events:
|
type string | Type of content of the comment
Possible values:
Relevant events:
|
url string | URL of the image in the comment
This is relevant only for animation and image type portion of the comment.
Relevant events:
|
user object
The following object is relevant for all following events:
followee
object forfollowee-commented
follower
object foruser-followed
liker
object forliked-message
mentioner
object foruser-mentioned
replier
object forreplied-message
user
object for all events
Parameter | Description |
---|---|
display_name string |
Non-unique personal identifier used prominently throughout the platform
Relevant events: All |
registered boolean | Identifies if the user is a registered user
Possible values:
For the user-followed follower object and followee-commented followee object, the value is always true . A guest cannot follow or be followed
Relevant events: All |
sso_user_id string | Partner user identifier
This parameter is not returned for non-SSO implementations. Relevant events: All |
user_id string | OpenWeb user identifier
Relevant events: All |
user_name string | Unique personal identifier used to differentiate between different users
Relevant events: All |
Updated 3 months ago