Webhooks

Configure Viafoura webhooks to receive near real-time audience engagement events, including follow and unfollow events.

Viafoura supports third-party services to receive audience engagement events in near real-time. Business intelligence and reporting dashboards can be enriched and empower your staff with insights into the real-time activity of your audience as they engage with content and each other.

You will need to:

  1. Configure an endpoint and provide the API path
  2. Provide us with an Authentication header we can pass to your API to let you know it's coming from us

Please contact your client success representative with this information and they will get this set up with you.

Webhooks Details

Security
Note that:
The service will be available over SSL (https) using a valid certificate
Viafoura application will use the certificate for both Authentication and Authorization

Conversation Pattern
The conversation between client and server will be Fire and Forget.
RESTful Service Specification

Request
Scheme: https
URL: will be provided by you to your CS representative
*HTTP Method: POST

Parameters

Request Headers

Header nameDescription
x-request-idRandom request ID provided by viafoura on each HTTP request, the value is the same as “request_uuid” in the request body
authorizationAt least 64 bytes, hexadecimal. Please provide this to your CS representative
content-typeapplication/json; charset=utf-8
acceptapplication/json

Request Body
The request body is a JSON encoded string that follows the schema below:

FieldTypeDescription
request_uuidnumberSame as “X-Request-ID” in header
timenumberThe time in milliseconds
versionnumberThe current value is 1
eventsarrayArray of Event object

Response
HTTP Status
A 200, 201 or 202 response code is expected in the HTTP response code. However third-party service can return other status codes to let our customer success team help with diagnosing possible issues in the integration.

Error CodeDescription
404Not Found
500Any internal error
400Data is not valid
200-201Request accepted
403Authorization failed

Response Body from Third Party Service
The expected response from the third party service will only be parsed if the following schema is used.

FieldTypeDescription
request_uuidstringrequest_id of corresponding request
resultsarrayArray of Result objects

Result object

FieldTypeDescription
event_uuidstringEvent ID
typestringEither “success” or “failure”
error_typestringArbitrary value
error_descriptionstringArbitrary value

JSON Object Definitions

Event
Event objects describe state changes in the Viafoura system. Additional fields may be included based on message_type and action.

Poll-vote events are delivered through the User Action callback (USER_ACTION_SERVER_CALLBACK_ENDPOINT) using the same /content-actions request shape as other content-action events.

Event triggers

Message TypeActionTrigger
livecomment_postcreatednew comment created
livecomment_postvisiblecomment enabled after moderation
livecomment_postdisabledcomment disabled by moderation or if the report (flag) threshold has been reached
livecomment_postupdatedcomment modified
livecomment_postlikedcomment liked by a user
livecomment_postunlikedcomment like reverted by a user
livecomment_postdislikedcomment disliked by a user
livecomment_postundislikedcomment dislike reverted by a user
livecomment_postflaggedcomment has been reported
livecomment_postspammedcomment was marked as spam by moderation
livecomment_postpinnedcomment was pinned to the top
livecomment_postunpinnedcomment was unpinned from the top
livecomment_postpickedcomment was marked as "editor's pick"
livecomment_postunpickedremoved the "editor's pick" mark from the comment
reply_to_livecomment_postcreatednew comment reply created
reply_to_livecomment_postvisiblecomment reply enabled after moderation
chat_messagecreatedchat message is created
chat_messagevisiblechat message is enabled after moderation
chat_messagelikedchat message liked by a user
chat_messageunlikedchat message like reverted by a user
chat_messagedislikedchat message disliked by a user
chat_messageundislikedchat message dislike reverted by a user
reply_to_chat_messagecreatedchat message reply is created
reply_to_chat_messagevisiblechat message reply is enabled after moderation
liveblog_postcreatedliveblog post is created
liveblog_postdisabledliveblog post disabled by admin
liveblog_postupdatedliveblog post modified
liveblog_postlikedliveblog post liked by a user
liveblog_postunlikedliveblog post like reverted by a user
liveblog_postdislikedliveblog post disliked by a user
liveblog_postundislikedliveblog post dislike reverted by a user
liveblog_postpickedliveblog post was marked as "editor's pick"
liveblog_postunpickedremoved the "editor's pick" mark from the liveblog post
liveblog_postpinnedliveblog post was pinned to the top
liveblog_postunpinnedliveblog post was unpinned from the top
livereview_postcreatednew review was created
livereview_postvisiblereview enabled after moderation
livereview_postdisabledreview disabled due to moderation
livereview_postupdatedreview edited/changed
livereview_postlikedreview marked as helpful by a user
livereview_postunlikedreview marked as not helpful by a user
livereview_postdislikedreview unmarked as helpful by a user
livereview_postundislikedreview unmarked as not helpful by a user
livereview_postflaggedreview has been reported
livereview_postspammedreview marked as spam
livereview_postpinnedreview pinned to the top
livereview_postunpinnedreview unpinned from top
livereview_postpickedreview marked as "editors pick"
livereview_postunpickedremoved the "editor's pick" mark from the review
reply_to_livereview_postcreateda reply to a review was created
reply_to_livereview_postvisiblereview reply enabled after moderation
livequestioncreatednew Live Q&A session created
livequestionupdatedLive Q&A session details modified (title, settings)
livequestionstartedLive Q&A session moved from Upcoming to Live
livequestionconcludedLive Q&A session moved from Live to Concluded
livequestionreopenedLive Q&A session moved from Concluded back to Live
livequestion_postcreatednew question created
livequestion_postvisiblequestion enabled after moderation
livequestion_postdisabledquestion disabled by moderation or if the report (flag) threshold has been reached
livequestion_postupdatedquestion modified
livequestion_postdeletedquestion deleted
livequestion_postlikedquestion liked by a user
livequestion_postunlikedquestion like reverted by a user
livequestion_postdislikedquestion disliked by a user
livequestion_postundislikedquestion dislike reverted by a user
livequestion_postflaggedquestion has been reported
livequestion_postspammedquestion was marked as spam by moderation
reply_to_livequestion_postcreatednew question reply created
reply_to_livequestion_postvisiblequestion reply enabled after moderation
follow_authorfolloweda user follows another user (author)
follow_authorunfolloweda user unfollows another user (author)
follow_topicfolloweda user follows a topic
follow_topicunfolloweda user unfollows a topic
poll_votevoteda signed-in user votes in a poll

Event fields

FieldTypeDescription
event_uuidstringEvent ID
timenumberThe time in milliseconds
user_agentstringHTTP User-Agent header captured when the event was generated; may be absent for internally-generated events (e.g. moderation actions).
message_typestringlivecomment_post
reply_to_livecomment_post
liveblog_post
chat_message
reply_to_chat_message
follow_author
follow_topic
poll_vote
actionstringcreated
visible
disabled
updated
liked
unliked
disliked
undisliked
flagged
spammed
pinned
unpinned
picked
unpicked
followed
unfollowed
voted
detailobjectPoll-vote details for poll_vote events. Absent for all other event types.
content_uuidstringID of the content item that was interacted with. For poll_vote, this is the poll UUID and equals detail.poll_uuid.
actor_uuidstringid of the user or actor who caused the interaction (this could be internal ids in the case of moderation events)
author_uuidstringid of the user who created the content (e.g. the author of the comment)
topic_idstringTopic identifier for follow_topic events. Absent for other event types.
topic_namestringOptional human-readable topic name for follow_topic events. Absent for other event types.
content_container_uuidstringid of the content container that was interacted on
section_uuidstringid of the viafoura section where the action occurred
page_urlstringFull URL where the action occurred. Absent for poll_vote events.

For follow events, content_uuid, content_container_uuid, and page_url are absent. actor_uuid is the user performing the follow. For follow_author, author_uuid is the user being followed.

Poll vote event fields

detail is present only when message_type is poll_vote. It contains a snapshot of the poll when the vote was cast; later changes to the question or options do not change an event that has already been delivered.

FieldTypeDescription
detail.poll_uuidstringPoll UUID. This intentionally duplicates content_uuid so the detail object is self-contained.
detail.poll_questionstringPoll question at the time of the vote. Absent if the upstream record does not contain a question.
detail.optionsarray of PollVoteOptionEvery poll option in presentation order, including options the voter did not select. The array can be empty when the upstream record contains no options.
detail.options[].option_uuidstringOption UUID.
detail.options[].option_descriptionstringOption description at the time of the vote.
detail.options[].is_selectedbooleanWhether the voter selected this option. At most one option is true; all options are false when the selection cannot be resolved upstream.

For poll_vote events, actor_uuid identifies the voter. author_uuid, topic_id, topic_name, and page_url are absent. Fields with null values are omitted from the request body.

When poll votes are not delivered

Viafoura does not send a poll_vote event when:

  • A signed-out visitor casts the vote. Poll-vote events require actor_uuid.
  • The upstream record has no payload or poll UUID.
  • The source topic message is not a vote.

Example

Request

{ 
 request_uuid: 'abcc2254-b0a4-492c-a8f2-ae7820f4968a',
 time: 1593205167183,
 version: 1,
 events:
  [ 
    { event_uuid: '99d2a532-e1a1-4455-834a-775148570e9d',
      time: 1593205166938,
      section_uuid: '00000000-0000-4000-8000-337a437adec1',
      content_container_uuid: '0dc371b9-cecd-4dc3-954b-e5255794e2e7',
      content_uuid: 'bf890170-4828-4d1d-a1b0-a0072a6117d3',
      actor_uuid: '00000000-0000-4000-8000-017ea245f200',
      author_uuid: '00000000-0000-4000-8000-485fe358a524',
      message_type: 'livecomment_post',
      page_url: 'https://action.click/livecomments/actioncomments.html',
      action: 'liked' 
    } 
  ] 
}

Poll vote request

{
  "request_uuid": "3f578154-5e7b-470e-8f40-038f5c40d08c",
  "time": 1788381240669,
  "version": 1,
  "events": [
    {
      "event_uuid": "01a063d4-1d55-714c-8bdf-36f732b99465",
      "section_uuid": "00000000-0000-4000-8000-000000000bda",
      "content_container_uuid": "01a063d0-37d6-7b71-bf52-af42d0c01016",
      "content_uuid": "9f1c2f7e-0000-4000-8000-000000000001",
      "actor_uuid": "00000000-0000-4000-8000-0000000013b1",
      "message_type": "poll_vote",
      "action": "voted",
      "detail": {
        "poll_uuid": "9f1c2f7e-0000-4000-8000-000000000001",
        "poll_question": "Which option do you prefer?",
        "options": [
          {
            "option_uuid": "aaaa0000-0000-4000-8000-000000000001",
            "option_description": "Option A",
            "is_selected": true
          },
          {
            "option_uuid": "bbbb0000-0000-4000-8000-000000000002",
            "option_description": "Option B",
            "is_selected": false
          }
        ]
      }
    }
  ]
}

Follow author request

{
  request_uuid: 'abcc2254-b0a4-492c-a8f2-ae7820f4968a',
  time: 1593205167183,
  version: 1,
  events: [
    {
      event_uuid,
      time,
      section_uuid,
      actor_uuid,
      author_uuid,
      message_type: 'follow_author',
      action: 'followed'
    }
  ]
}

Follow topic request

{
  request_uuid: 'abcc2254-b0a4-492c-a8f2-ae7820f4968a',
  time: 1593205167183,
  version: 1,
  events: [
    {
      event_uuid,
      time,
      section_uuid,
      actor_uuid,
      message_type: 'follow_topic',
      action: 'followed',
      topic_id: 'sports/nba',
      topic_name: 'NBA'
    }
  ]
}

The unfollowed variants are identical except action: 'unfollowed'.

Response

{
    "request_uuid": "c71b5cb1-ce44-4239-8b6e-87b99cf2b1f0",
    "results": [
        {
            "event_uuid":"c71b5cb1-ce44-4239-8b6e-87b99cf2b1a0",
            "type": "failure",
            "error_type": "unknown",
            "error_description": "unable to store"
        },
        {
            "event_uuid":"dd519c8a-3619-4cb0-b31b-0ffd14d24aab",
            "type": "success"
        },
        {
            "event_uuid":"d8a6a231-0cef-4385-83d8-66b6160811a5",
            "type": "success"
        },
        {
            "event_uuid":"5c0c5ab3-f3be-4194-bfc5-2000f94665ad",
            "type": "success"
        }
    ]
}

Integration Testing

  1. Sign up for RequestBin which is a free Webhook testing platform.
  2. Pipedream will provide a public callback URL which you need to configure in Viafoura Admin → General → Notifications for the site you want to test as shown below.
  3. You will also need to get your API key from your pipe dream account by going to your Pipedream Account Settings page.
  4. In Viafoura Admin → General → Notifications under the server-to-server callback authorization header parameter, configure the Pipedream API Key as ‘Bearer PI Key]’ ’ as shown below.
  5. Contact your Viafoura Customer Success Manager to enable Server-to-Server callbacks for your domain.

Done! Now when you perform actions that trigger webhook messages on the site you configured you will see the Webhook messages in Pipdream under the page for the Requestbin you created.


Did this page help you?