Open lukehesluke opened 4 years ago
@lukehesluke looks great! Just a couple of additions...
There is a new virtual events requirement for organizer
@id
(https://developer.openactive.io/publishing-data/virtual-events#conformance-criteria), based on what Sport England require for #StayInWorkOut - hopefully simple to add.
So the above would look something like this (using the preferred @type
and @id
for better compatibility with JSON-LD, though type
and id
are still valid):
"organizer": {
"@type": "Organization",
"@id": "https://id.bookwhen.com/organizer/1fihlz2a8ot5",
"identifier": "organization-1fihlz2a8ot5",
"name": "Studio 44",
"email": "hello@studio-44.co.uk",
"telephone": "01246641000",
"url": "https://www.studio-44.co.uk"
},
Additionally, to pass validation properties with values that are empty arrays and empty strings must be omitted.
Hi @jopotts,
We thought it might be helpful to split @lukehesluke's suggestions into 3 categories ("Simple re-names / moving fields around", "Logic changes" and "Nice-to-haves") to make it easier for you. Hopefully this will save you time and allow you to focus on those quick-win changes ("simple re-names / moving fields around" - maybe <30 mins total time?) that will bring your feed more inline with the Spec. and allow your virtual classes to be advertised across user-facing platforms.
(we estimate <30 mins total time for all of these)
event_type
in general:kind
: SessionSeries
data.type
: SessionSeries
data['@context']
to equal:
["https://openactive.io/", "https://openactive.io/ns-beta"]
data.offer
-> data.offers
"type": "GeoCoordinates"
to data.location.geo
event_type
with a recurrence rule:.eventSchedule
out of subEvent and into the top level of the SessionSeries. (this might be easier to see if you look at the example at the bottom of this description)duration
out of subEvent and into the Schedule
item.Schedule
item:
--"scheduledEventType": "ScheduledSession"
--"scheduleTimezone": "Europe/London"beta:urlTemplate
into the Schedule
item. Validator will not recognise this field but, for now, we'll accept it. There is a urlTemplate
field for Schedules (https://www.openactive.io/modelling-opportunity-data/#publishing-event-schedules), but it has a different format so I imagine this would be a big changesubEvent
, subEvent
can just be deleted. It is not needed for a SessionSeries with a Scheduleevent_type
with just one occurrence:"type": "Event"
to "type": "ScheduledSession"
["https://openactive.io/", "https://openactive.io/ns-beta"]
"type": "Event"
to "type": "ScheduledSession"
superEvent
, so that it is the URL ID of the SessionSeries that is this ScheduledSession's parent. Use the method described above for a SessionSeries' .data.id
to construct this ID, e.g. where, before, the superEvent was:
"superEvent": {
"identifier": "eventType-nx610pp9r6p7"
}
... change it to:
"superEvent": "https://bookwhen.com/api/openactive/session-series/nx610pp9r6p7"
(we estimate 30-35 mins total time for both of these - the first one could take less than 5 minutes!)
data.id
using data.identifier
and the feed's URL -> very quick (maybe 5 mins?).
For example, if the SessionSeries feed is hosted at https://bookwhen.com/api/openactive/session-series and a SessionSeries' identifier is pysafz84ka8v
, the id
should be:
https://bookwhen.com/api/openactive/session-series/pysafz84ka8vp
repeatFrequency
instead of frequency
and interval
-> perhaps <30 mins.
For example, frequency: weekly & interval: 1 => "repeatFrequency": "P1W"
@gregjoy1 as discussed issues below:
So there should be three feeds here: a SessionSeries
and ScheduledSession
feed pair for recurring events (documentation), and an Event
feed for one-off events (documentation).
/sessionseries
- only entries that have a recurrence rule and include a eventSchedule
. @type
and kind
in this feed are both SessionSeries
./scheduledsessions
- is event occurrences which have a booking on them (the current contents of the /events
feed). @type
and kind
in this feed are both ScheduledSession
./events
- entries that have a single occurrence (currently these are included in /sessionseries
with a just a subEvent
). @type
and kind
in this feed are both Event
. The properties of the single subEvent
can be moved into the parent Event
itself, and no subEvent
is required.activity
is missinghttps://bookwhen.com/api/openactive/session_series?afterId=5wkobfev8rwr&afterTimestamp=1573822146
Has activity
been accidentally missed here?
Example below:
"activity": [
{
"@type": "Concept",
"@id": "https://openactive.io/activity-list#5e78bcbe-36db-425a-9064-bf96d09cc351",
"prefLabel": "Bodypump™",
"inScheme": "https://openactive.io/activity-list"
}
]
price
must be a decimalhttps://bookwhen.com/api/openactive/session_series?afterId=5wkobfev8rwr&afterTimestamp=1573822146
"price": "5.00"
should be
"price": 5.00
beta:virtualLocation
for online eventshttps://bookwhen.com/api/openactive/session_series?afterId=5wkobfev8rwr&afterTimestamp=1573822146
location
is not permitted for online-only events
"location": {
"type": "Place",
"identifier": "izdxleom4a4b",
"description": "Example description",
"name": "Online"
},
should be replaced by
"beta:virtualLocation": {
"@type": "VirtualLocation",
"identifier": "izdxleom4a4b",
"description": "Example description",
"name": "Online"
}
SessionSeries
eventAttendanceMode
is not required in ScheduledSession
, unless it has a different value from the related parent SessionSeries
.
@type
and @id
consistentlytype
should be renamed to @type
id
within the data
property should be renamed to @id
(note the id
that sits at the same level as kind
must stay as id
)Properties should not be included where their value is an empty string and or empty array, or an empty object that contains only an @type
(e.g. below):
"ageRange": {
"@type": "QuantitativeValue"
},
The OpenActive Ruby library will do this for you.
@gregjoy1 just reviewed the latest feeds, great work so far! Fresh feedback below:
Schedule
without beta propertiesInclude the idTemplate
and urlTemplate
as specified in https://developer.openactive.io/publishing-data/schedules. Note for your usecase we recommend creating a simple 301 redirect that takes users from e.g. https://bookwhen.com/openactive/events/s51e/2018-04-25T18-00-00Z (or whatever urlTemplate
you use) to e.g. https://bookwhen.com/hulafit/e/ev-s51e-20180425180000
This means you can stop using the long-since deprecated beta:urlTemplate
.
remainingAttendeeCapacity
and beta:attendanceCount
appear to be missing from https://bookwhen.com/api/openactive/events
price
must be a decimalhttps://bookwhen.com/api/openactive/session_series?afterId=5wkobfev8rwr&afterTimestamp=1573822146
"price": "5.00"
should be
"price": 5.00
url
should be used instead of beta:website
"organizer": {
"@type": "Organization",
"@id": "https://bookwhen.com/api/openactive/organizers/uwdefqoiez8h",
"beta:website": "http:/www.kasostudios.co.uk",
...
},
Should be
"organizer": {
"@type": "Organization",
"@id": "https://bookwhen.com/api/openactive/organizers/uwdefqoiez8h",
"url": "http:/www.kasostudios.co.uk",
...
},
eventAttendanceMode
only required in SessionSeries
eventAttendanceMode
is not required in ScheduledSession
, unless it has a different value from the related parent SessionSeries
.
I've just noticed the property "beta:course": true
, and realised that Bookwhen also supports courses! Courses should in fact be a separate feed at /course-instances
using the CourseInstance
type, as they are different to regularly scheduled sessions.
See here for an example: https://validator.openactive.io/?url=https%3A%2F%2Fopenactive.io%2Fdata-models%2Fversions%2F2.x%2Fexamples%2Fcourseinstance_event_example_1.json&version=2.x
Note that you don't need to include beta:course
property referenced in the example, just put everything that was in the SessionSeries
into the CourseInstance
.
Also you'll need to add the course-related subEvents
to that feed instead of putting them in the ScheduledSession
feed (as per example)
byDay
is an array"byDay": "1SU",
should be "byDay": [ "1SU" ],
Hi @nickevansuk, @domfennell and @lukehesluke, thank you all for helpfully and clearly setting out these requirements, sorry for the delay in responding to them. We have recently released the requested updates :)
The only thing not included is 3, this is because the JSON serialiser we use at Bookwhen always casts decimals as strings - https://apidock.com/rails/BigDecimal/as_json
It appears the OA Gem also has the same constraint as it also returns strings for decimals - https://github.com/openactive/models-ruby
Is it possible to quietly still consume it considering its known to be a decimal? :)
Also are these changes enough for us to be consumed in your universal feed reader yet? :)
Thanks @gregjoy1! Will take a proper look after the dataset site is updated too.
However one quick thing, free activities (where "isAccessibleForFree": true
) for events, courses, and sessions should also include a zero priced Offer
(priceCurrency
is not required), e.g.:
"offers": [
{
"@type": "Offer",
"price": 0
}
],
Hi @nickevansuk, @domfennell and @lukehesluke, the updated the dataset site can be found here - https://data.bookwhen.com/ :)
Great work @gregjoy1 - one small note: you seem to be using a background image hot-linked to another dataset site (https://data.better.org.uk/images/bg.jpg).
Perhaps replace it with something hosted on your own CDN? There's a great selection or relevant free images here: https://unsplash.com/photos/gJtDg6WfMlQ
Also please feel free to delete this old repo: https://github.com/bookwhen/openactive-datasite, so that it's easy to see from the forks that you've migrated successfully.
Hey @gregjoy1, so this round of feedback is by way of extracts in the validator.
Please address the errors shown in the validator for each of the following:
Courses Feed 1 - Noting additionally https://github.com/bookwhen/opendata/issues/11#issuecomment-663612568 is still an issue
ScheduledSession Feed 1 - beta:attendanceCount
should be beta:attendeeCount
(this issue also exists in the Events
feed).
There are also still a number of empty strings. Consider code like this to ensure that properties that are null or empty are not included: https://github.com/openactive/models-ruby/blob/06790cbdd1616713d8d1b58346c6912cb3649d9e/lib/openactive/helpers/json_ld.rb#L64
Note: It's fine to keep those items in that are missing activity
, though perhaps stronger signposting to let users know they need to fill in this field could be useful?
Will have a think about about the issue with price
... TeamUp have also had the same issue. See proposal here
Thanks @nickevansuk, il get this into an upcoming sprint :)
I recommend closing this issue, as all issues listed above have been checked and are resolved (except for price
, which needs to be addressed in the standard and the validator).
Hi @jopotts ,
Thanks for our call earlier. Further to that, here's some notes about how you might update your feed to be sufficiently conformant so that the feeds can be ingested by our "universal" adapter which should hopefully be quick wins.
I've included an example for a SessionSeries with a Schedule at the end, which might be easier to digest than a big list of changes
Changes
For
event_type
in general:kind
:SessionSeries
data.type
:SessionSeries
data['@context']
to equal:data.offer
->data.offers
"type": "GeoCoordinates"
todata.location.geo
data.id
usingdata.identifier
and the feed's URL. e.g. if the SessionSeries feed is hosted at https://bookwhen.com/api/openactive/session-series, and a SessionSeries' identifier ispysafz84ka8v
, theid
should be:For an
event_type
with a recurrence rule.eventSchedule
out of subEvent and into the top level of the SessionSeries. (this might be easier to see if you look at the example at the bottom of this description)duration
out of subEvent and into theSchedule
item.Schedule
item:repeatFrequency
instead offrequency
andinterval
. e.g. frequency: weekly & interval: 1 =>"repeatFrequency": "P1W"
beta:urlTemplate
into theSchedule
item. Validator will not recognise this field but, for now, we'll accept it. There is aurlTemplate
field for Schedules (https://www.openactive.io/modelling-opportunity-data/#publishing-event-schedules) but it has a different format so I imagine this would be a big changesubEvent
,subEvent
can just be deleted. It is not needed for a SessionSeries with a ScheduleFor an
event_type
with just one occurrence:"type": "Event"
to"type": "ScheduledSession"
For an event:
"type": "Event"
to"type": "ScheduledSession"
superEvent
, so that it is the URL ID of the SessionSeries that is this ScheduledSession's parent. Use the method described above for a SessionSeries'.data.id
to construct this ID. e.g. where, before, the superEvent was:Change it to:
Example
This is a SessionSeries with a Schedule. This is how it looks presently:
This is how it would look with the changes detailed above: