Yes! You can use the ActivityHero Schedule API to keep your external schedules in sync with the ActivityHero database. You can call this webhook whenever new schedules are added or when there are updates to existing schedules.
How the API moves data from your system to ActivityHero
This webhook is implemented using the SHA256 webhook signature verification method.
Sender’s End
(Generating Signature and sending your schedule data to ActivityHero)
You are the Sender (Provider) and will need to implement the following code for generating the signature.
def generate_hmac(key, data)
Base64.strict_encode64(OpenSSL::HMAC.digest('sha256', key, data))
end
This code is written in Ruby
The custom data for this code is automatically generated for you and can be found in the API section of your ActivityHero dashboard.
Parameters
Key - This is the value in the “secret” box
Data - This string is your unique Provider ID# and the request timestamp (in seconds) joined by an underscore.
Your Provider ID# can be found in the URL when you are logged in to your ActivityHero dashboard, and the request timestamp you can get from the payload in the “time” key (see sample Payload below).
Example: This Provider ID# is “12345" and the request timestamp in seconds is “1671040686”. The combined data string will be “12345_1671040686".
** This function will return a secret signature which will need to be passed in the headers as a value of the secret key.
headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Signature': generate_hmac(‘secret column from schedule_webhook table’, ‘providerId_timestamp )
}Sender
Sample of the header data code
Receiver’s End
(Validating the Signature and Storing the Data)
The Receiver of the data (ActivityHero) will implement the following code for validating the signature. Below is the code implemented in Ruby language-
def verify_webhook(data, api_secret_key, hmac_signature)
calculated_hmac = Base64.strict_encode64(OpenSSL::HMAC.digest('sha256', api_secret_key, data))
ActiveSupport::SecurityUtils.secure_compare(calculated_hmac, hmac_signature)
end
This code is written in Ruby
Parameters
Data - This string is your unique Provider ID# and the request timestamp (in seconds) joined by an underscore.
Your Provider ID# can be found in the URL when you are logged in to your ActivityHero dashboard, and the request timestamp you can get from the payload in the “time” key (see sample Payload below).
Example: This Provider ID# is “12345" and the request timestamp in seconds is “1671040686”. The combined data string will be “12345_1671040686".
‘hmac_signature’ param’s value will be the value of “secret” key from the header’s data (Sample below). “Api_secret_key” is the secret shared and “data” can be generated from payload using provider_id and time field of json.
(“provider_id}_{time}")
headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Signature': 'Signature' // generated at Sender’s end
}
Sample Payload
Once the API is in place, the following data is what will be exchanged between your external system and ActivityHero:
{
"time": 1671040686,
"provider_id": 123,
"data":[
{
"activity_schedule_id": "",
"location_name": "Cubberley Grass Field",
"activity_name": "Coach Ken Soccer Camps",
"session_type": "series",
"session_name": "DR",
"start_date": "12/10/2022",
"end_date": "12/14/2022",
"start_time": "09:00 AM",
"end_time": "01:00 PM",
"days_of_week": "mon,thur,fri",
"min_age_in_months": 48,
"min_age_in_years": 4,
"max_age_in_months": 144,
"max_age_in_years": 12,
"min_grade": 1,
"max_grade": 3,
"price": "",
"price_label": "",
"single_day_price": 51,
"single_day_alt_price": "",
"alt_price": "",
"alt_price_label": "",
"price_type": "per_session",
"status": "Published",
"num_of_openings": 51,
"external_schedule_id": "",
"registration_start_timezone": "Pacific Time (US & Canada)",
"registration_start_date": "",
"registration_start_time": "",
"registration_ends": "when the session ends",
"registration_cutoff_days": "",
"registration_cutoff_date": "10/10/2022 11:59 PM",
"single_day_registration_cutoff_days": "",
"allow_proration": "FALSE",
"num_of_scholarship_spots": "",
"lowest_scholarship_price": "",
"meeting_url": "",
"meeting_details": "",
"payment_plan_names": "",
"extended_care_am_time": "",
"extended_care_pm_time": "",
"extended_care_am_price": "",
"extended_care_pm_price": "",
"extended_care_overall_price": "",
"extended_care_overnight_price": "",
"extended_care_am_per_day_price": "",
"extended_care_pm_per_day_price": "",
"extended_care_per_day_price": "",
"extended_care_per_hour_price": "",
"teacher_name": "",
"room_num": "",
"activity_id": "",
"provider_location_id": "",
"external_activity_id": 10020,
"external_location_id": 2032,
"flexible_schedule": "",
"Additional Hours": "",
"Additional Days (beyond first 2 days)": ""
}]
}
NOTE: If the total number of sessions to be exchanged exceeds 100, the API will fail, and you will receive an error. To import more than 100 sessions, consider a manual CSV import instead.
Refer to this link for webhook signature verification:
https://hookdeck.com/webhooks/guides/how-to-implement-sha256-webhook-signature-verification