GoTo Developer

How to use GoToWebinar webhooks

The following steps are required to implement a webhook for GoToWebinar. (See the Webhooks overview for background.) The data examples are complete to show an exact example, however some strings have been modified to protect sensitive data. Modified data is in italic.

Prerequisites

This article assumes you can make API calls successfully which requires:

Webhook steps

To create and use webhooks, you will need to:

  • Create a secret webhook key for your GoToDevelopers account
  • Create a webhook
  • Activate the webhook
  • Review webhook status
  • Authenticate application end-user
  • Subscribe to the webhook
  • Verify the webhook signature

Create Secret Key

The secret webhook key provides your development account with a code that can be used to validate data output. This ensures your program can validate the data received as safe.

cURL example

NOTE: The access token and refresh token displayed in the examples on this page are a fragmentary sample of the value. The tokens are significantly larger.

curl -X POST \
  https://api.getgo.com/G2W/rest/v2/webhooks/secretkey \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer 4CVVlFAKeVaorni30Sj045qe7yOx...' \
  -H 'Content-Type: application/json'

Successful response example

{
    "value": "f1679e36-17fe-48fa-93da-44195fd9e293",
    "validFrom": "2019-03-14T18:03:58.317Z",
    "id": 63
}

Create webhook

You can now create a webhook for a specific event in the associated GoTo product. You will use the webhookKey that is returned to activate or update the webhook. You will also use the webhookKey to subscribe users to the events.

Curl example

curl -X POST \
  https://api.getgo.com/G2W/rest/v2/webhooks \
  -H 'Authorization: Bearer 4CVVlFAKeVaorni30Sj045qe7yOx...' \
  -H 'Content-Type: application/json' \
  -d '[
    {
     "callbackUrl":"https://en1vd6q5jmpqb.x.pipedream.net",
     "eventName":"registrant.added",
     "eventVersion":"1.0.0",
     "product":"g2w"
    }
]'

Successful response example

{
    "_embedded": {
        "webhooks": [
            {
                "eventName": "registrant.added",
                "eventVersion": "1.0.0",
                "callbackUrl": "https://en1vd6q5jmpqb.x.pipedream.net",
                "product": "g2w",
                "webhookKey": "dff781bc-fake-4361-81ff-d5e9861fb0e1",
                "state": "INACTIVE",
                "createTime": "2019-03-14T18:06:30.365Z"
            }
        ]
    }
}

Activate the webhook

The webhooks are created in an inactive state. An explicit call must be sent to activate the webhook. You can switch the webhook between active and inactive at any time.

cURL example

curl -X PUT \
  https://api.getgo.com/G2W/rest/v2/webhooks \
  -H 'Authorization: Bearer 4CVVlFAKeVaorni30Sj045qe7yOx...' \
  -H 'Content-Type: application/json' \
  -d '[
    {
        "state":"ACTIVE",
        "webhookKey":"dff781bc-fake-4361-81ff-d5e9861fb0e1"
    }
]'

Successful response example

204 No Content

Review webhook status

At any time, you can use the GET webhook call to review status and other webhook details.

cURL example

curl -X GET \
  https://api.getgo.com/G2W/rest/v2/webhooks/dff781bc-fake-4361-81ff-d5e9861fb0e1 \
  -H 'Authorization: Bearer 4CVVlFAKeVaorni30Sj045qe7yOx...' \
  -H 'Content-Type: application/json' \

Successful response example

200 OK
{
    "eventName": "registrant.added",
    "eventVersion": "1.0.0",
    "callbackUrl": "https://enih2xxhnu6.x.pipedream.net/",
    "product": "g2w",
    "webhookKey": "dff781bc-fake-4361-81ff-d5e9861fb0e1",
    "state": "ACTIVE",
    "createTime": "2019-03-14T18:06:30.365Z"
}

Subscribe to the webhook

Once you have an active webhook, the user can be subscribed to any events that are defined with webhooks in the system. Note that you need to give an access token representing the user, in the next example that will be nEZGXNdZL96OkFakEIUrTvBYOdLw.... Follow this link if you want to get an access token for your users.

cURL example

curl -X POST \
  https://api.getgo.com/G2W/rest/v2/userSubscriptions \
  -H 'Authorization: Bearer nEZGXNdZL96OkFakEIUrTvBYOdLw...' \
  -H 'Content-Type: application/json' \
  -d '[
    {
        "webhookKey": "dff781bc-fake-4361-81ff-d5e9861fb0e1",
        "userSubscriptionState": "ACTIVE"
    }
]'

Successful response example

200 OK
{
    "_embedded": {
        "userSubscriptions": [
            {
                "webhookKey": "dff781bc-fake-4361-81ff-d5e9861fb0e1",
                "callbackUrl": "https://enih2xxhnu6.x.pipedream.net/",
                "userSubscriptionState": "ACTIVE",
                "activationState": "ACTIVE",
                "userSubscriptionKey": "8e33dfee-c7b3-4f67-96ac-e3fakeb54f3f",
                "eventName": "registrant.added",
                "product": "g2w",
                "eventVersion": "1.0.0",
                "createTime": "2019-03-14T18:18:45.442Z"
            }
        ]
    }
}

Signature verification steps

Webhook infrastructure signs all the events sent to the callback URL. The signature is included in X-Webhook-Signature header. This allows external developers to validate that the event is sent by LogMeIn webhook infrastructure, not by a third party.

  1. Sample event posted to callback URL. (See the Callback Event Example, below.)
  2. Extract X-Webhook-Signature, X-Webhook-Signature-Timestamp.
  3. Prepare payload for signature generation. This can be done by concatenating:
    1. X-Webhook-Signature-Timestamp header value;
    2. The colon character ":"; and
    3. Event received as string. (See the Event String Example, below.)
  4. Calculate expected signature. Compute an HMAC with the SHA256 hash function. Use the secret key with id X-Webhook-SecreteKey-Id, use the payload from previous step as the message and encode it. One example of command line for it :
echo -n '${EVENT_STRING_EXAMPLE}' | openssl dgst -sha256 -hmac "${YOUR_SECRET_KEY}" -binary | openssl enc -base64 -A
  1. Compare the signature in the header to the expected signature. If a signature matches, compute the difference between the current timestamp and the received timestamp, then decide if the difference is within your tolerance.

Callback Event Example

Headers :

     Accept: application/json, application/*+json
     Content-Type: application/json
     X-Webhook-SecretKey-Id: 1
     X-Webhook-Signature: OfpnJDFpdMKYS8tM8q7RxT/ynw5HDenv4NdU+vEtoGo=
     X-Webhook-Signature-Timestamp: 1554356824634
     X-Webhook-Signature-Version: 0
     Content-Length: 468

Body :
     {
     "eventName":"registrant.joined",
     "eventVersion":"1.0.0",
     "product":"g2w",
     "eventKey":"74d38461-9db8-4e41-8f59-d99f00b82411",
     "sessionKey":15887209,
     "webinarKey":5620084814059709442,
     "firstName":"Abhinav",
     "lastName":"Gandhi",
     "email":"a@g.com",
     "timestamp":"2019-04-04T05:47:04.517Z",
     "webinarCreatorKey":710161738256079372,
     "webinarTitle":"New Webinar!!",
     "experienceType":"CLASSIC",
     "recurrenceType":"single_session",
     "registrantKey":8325357307900339981,
     "joinTime":1554356793898
      }

Event String Example

1554356824634:{"eventName":"registrant.joined","eventVersion":"1.0.0","product":"g2w","eventKey":"74d38461-9db8-4e41-8f59-d99f00b82411","sessionKey":15887209,"webinarKey":5620084814059709000,"firstName":"Abhinav","lastName":"Gandhi","email":"a@g.com","timestamp":"2019-04-04T05:47:04.517Z","webinarCreatorKey":710161738256079400,"webinarTitle":"New Webinar!!","experienceType":"CLASSIC","recurrenceType":"single_session","registrantKey":8325357307900340000,"joinTime":1554356793898}