EEG101 event booking organiser guide

EEG101 event booking organiser guide

Operating model

The existing Events feed is the only public list of EEG101 events. It already draws every event from _data/events.yml. A booking-enabled event displays a Register button directly on its Events card and in its calendar popover. There is no separate event list or Event Hub page to maintain.

GitHub Pages serves the public event information only. The booking action opens the Google Apps Script registration form inside the existing EEG101 page, avoiding a cross-origin request that could not reliably report success or failure. The script writes the registration to the private EEG101 workbook and sends the confirmation email. The private spreadsheet and the Apps Script editor provide the organiser-only administration environment. This keeps attendee information out of the public repository and prevents a publicly accessible website route from exposing the registration ledger.

One-time activation

The registration workbook is named EEG101 Event Hub Registrations. Registrations for each event are kept on that event’s own tab. The Apps Script must be deployed by a Google account that has Editor access to this workbook. If the script is deployed through faisalmushtaq@gmail.com, share the workbook with that address as an Editor before deployment.

Create or open an Apps Script project at script.google.com under the account that will administer registrations. Replace the contents of Code.gs with the repository file scripts/google-apps-script/event-hub.gs, then open Project Settings and add the Script property EEG101_EVENT_BOOKING_SHEET_ID with the private registration workbook’s ID as its value. This keeps the workbook identifier out of the public website repository. Save the project and select Deploy → New deployment → Web app. Choose Execute as: Me and set access to Anyone. The embedded form uses the script’s authenticated server-side function and reports a verified success or failure message back to the EEG101 page. The script blocks a duplicate email registration for the same Event ID, uses a lock to prevent concurrent capacity oversubscription, and stores later registrations on the waiting list when capacity is reached.

Before the first deployment, run installPendingEmailTrigger once to create the hourly trigger that sends queued emails. This asks for authorisation the first time it runs. If columns are later added to the script, run updateLedgerHeaders to add the new headers to every event tab. After authorising the deployment, copy the resulting web-app URL. When the script changes later, paste the new version into the editor and use Deploy → Manage deployments → Edit → New version, which keeps the same web-app URL. In _data/site.yml, set event_booking_endpoint to that URL. This is a public endpoint URL, not a secret. The web-app does not contain credentials in the Jekyll repository. Commit and push the website update on main; GitHub Pages will rebuild the site.

Changes waiting to be deployed

Editing scripts/google-apps-script/event-hub.gs in this repository does not change the live booking form. The form is served by the Apps Script deployment at event_booking_endpoint, which runs its own copy of the file. Until someone pastes the new version in and runs Deploy → Manage deployments → Edit → New version, the old code keeps serving.

Outstanding at the time of writing:

Change Why
The Community Framework prompt now links to https://www.eeg101.eu/framework/ instead of https://sign-cf.eeg101.eu/ The Framework moved onto the main site; the old microsite is being retired. The prompt is shown only for events with communityFrameworkPrompt: true in EVENT_EXTRA_QUESTIONS, currently just diversity-eeg-populations-2026-11.
The inclusive gender options are now the standard set for every event They were added for the diversity seminar only, so every other form offered Male / Female / Prefer not to say. The per-event genderExtended flag is gone and GENDER_OPTIONS is the single list.
The diversity seminar’s programme is written into its calendar file, and .ics lines are now folded by bytes See Putting a programme in an event’s calendar file below. Existing registrants get it when their joining link is next emailed.

To check what the live deployment is actually serving, request the endpoint directly with any event’s ID and search the HTML:

curl -sL "<event_booking_endpoint>?event_id=diversity-eeg-populations-2026-11" | grep -c sign-cf

0 means the deployment is current.

Putting a programme in an event’s calendar file

Every calendar file the site produces — the Add to calendar download, the confirmation email attachment, the waiting-list promotion email and the joining-link email — is built by makeCalendar() in event-hub.gs. To put a running order in the invite’s description, add the event to EVENT_PROGRAMMES in that file: one array entry per line, '' for a blank line, times stated in the event’s own zone. It is keyed by event ID, so a typo in the ID silently does nothing; check by generating the file (see below).

Why it lives in the script rather than events.yml: the booking form receives event details in a URL, which a full programme would overflow.

  • The description reads: joining link (or “will be emailed”), then the programme, then the standard footer.
  • A programme raises the file’s SEQUENCE by one, so a calendar treats the version that has it as newer than one that does not. Link plus programme is 2.
  • Lines are folded at 75 bytes, as RFC 5545 requires. En dashes, curly quotes and accented names are 2–3 bytes each, so folding by character count overruns on exactly this kind of text.
  • People who registered earlier do not get a new file automatically. They receive one when the joining link is next emailed to them (which happens on its own within the hour of a link being added or changed), and anyone registering from now on gets it straight away.

The diversity seminar’s programme is diversity-eeg-populations-2026-11 and comes from EEG101_Diversity_Seminar_Programme_for_261120_final.pdf. If that PDF is revised, edit the array to match.

Add an event with booking

Add the event once to _data/events.yml using the established event fields and include the booking fields below. The id must be unique and should remain stable because it links the Events card, calendar popover, registration, calendar invitation, and Sheet records.

- id: wg2-training-october-2026
  short_name: "WG2 training"
  audience: "open"
  title: "EEG101 WG2 Training Session"
  start_date: 2026-10-15
  end_date: 2026-10-15
  time: "14:00"
  end_time: "16:00"
  timezone: "Europe/London"
  location: "Online"
  format: "online"
  category: "Events"
  summary: "A practical EEG101 training session for Working Group 2 members."
  booking_enabled: true
  booking_status: "open"
  capacity: 60
  tags:
    - WG2
    - training
    - online

Set booking_status to closed when registrations should stop. Omit the booking fields for an event that does not require registration. The site validation step rejects any incomplete or contradictory booking configuration before the website can publish, including a bookable event that lacks the private Apps Script endpoint. Later registrants are added to the waiting list once the private Sheet contains the configured number of confirmed places.

Registration administration

Each event has its own tab in the registration workbook, named from its short_name and date, for example WG2 training (2026-10-15). The tab is created automatically when the first person registers. If short_name is omitted, the title is used instead. Tabs can be renamed or reordered freely because the script tracks them by their internal ID.

The registration form asks for first name, last name, institution, country, email address, whether the attendee is under 40 (Young Researcher and Innovator status) and gender (Male; Female; Beyond the binary; Prefer to self-describe, with a free-text box; Prefer not to say), and whether they are a member of the EEG101 COST Action. A self-described gender is recorded in the Notes column. Membership never prevents booking; for events with audience: "open" (the default) the form states that membership is not required. Attendees must tick a recording consent (being recorded and the recording being published online) and the privacy consent before they can book. Each registration is written to the ledger before any email is attempted, and the attendee immediately sees an on-screen confirmation with an Add to calendar (.ics) download. Waiting-list registrants see a waiting-list confirmation without a calendar file.

Google limits a personal Gmail account to 100 email recipients a day. When that limit is reached, bookings continue normally and the Email status column records Email pending. The hourly trigger sends queued emails in registration order once quota is available again, and the menu item Send pending emails now does the same on demand. Attendees are never shown the queued state.

The script adds an EEG101 Event Booking menu to the private Sheet. Use Promote the next waiting-list attendee after a confirmed attendee cancels. The script changes the earliest waiting-list entry for that event to confirmed and sends a promotion email.

The same menu provides Delete records older than 12 months. This action includes a confirmation step and permanently removes qualifying records. Before using it, check whether University of Leeds or COST Action procedures require any longer retention period for a particular event.

Public and members-only events

Set audience on each event. audience: "open" (the default) is a public event booked through the website form described above.

audience: "members" is for EEG101 COST members only. These events are not booked on the website: invitations are sent formally through the e-COST platform, and members accept them there. Leave booking_enabled, booking_status, capacity and joining_link out; the site validation rejects them on members-only events so that no joining link is ever published. The event card and calendar popover show a COST members only badge and a How to attend button. This asks visitors whether they are members of the EEG101 COST Action. Members are told to look out for their e-COST invitation and accept it there. Non-members are told that event details are shared with approved members and are directed to the Join page. No personal information is collected.

- id: mc2-2026
  title: "EEG101 Management Committee Meeting"
  start_date: 2026-12-01
  end_date: 2026-12-01
  time: "10:00"
  end_time: "12:00"
  timezone: "Europe/Brussels"
  timezone_label: "CET"
  location: "Online"
  format: "online"
  category: "Events"
  audience: "members"
  summary: "Management Committee meeting for EEG101 members."

A joining link can be added in either of two places.

On the website (simplest). Add joining_link: "https://..." to the event in _data/events.yml and push to main. Within the hour, the booking system reads the link from the published site, emails it with an updated calendar invitation to every confirmed attendee who has not yet received it, and includes it in every later confirmation. If the link is changed later, the new link is sent to all confirmed attendees. The event data is public, so anyone viewing the page source or the repository can see a link added this way.

Privately in the registration workbook. For a link that must not be public, leave joining_link empty and paste the link into the Joining link (private) column of the Joining links tab. Then open the event’s tab and choose EEG101 Event Booking → Email the joining link to everyone booked. A private link takes precedence over a website link.

When no link has been added yet, attendees of online and hybrid events are told that the joining link will be emailed nearer the time. The Joining link emailed column on each event tab records who has been sent the link, and the hourly trigger continues any mailing that the daily email quota interrupted.

Pre-publication checks

Before announcing a bookable event, confirm that the GitHub Pages build has completed, the Register button appears on the relevant Events card and calendar popover, the capacity and time zone are correct, and the privacy link resolves. Submit a genuine test registration from a non-organiser email address. Confirm that the private Sheet receives the row, that the confirmation message arrives, and that the .ics attachment opens in a calendar application. Delete the test row after completing the check.

Privacy and access controls

The public website contains no attendee list or organiser interface. Attendee fields are collected only after an explicit consent checkbox and are described in /privacy/. Limit spreadsheet sharing to authorised organisers and review access when responsibilities change. Do not place the App Script deployment URL, registration workbook ID, or attendee data in public news posts or web-page content.