Kicking off a dedicated space for discussion for Calendar, Events, RSVP

It turns out that community adoption of the lexicon has worked!.

One of the things that is stale about the lexicon versus usage in the wild are dedicated media fields.

https://github.com/lexicon-community/lexicon/tree/main/community/lexicon/calendar

Should bring together everyone working on events and form a working group to see what evolving it looks like.

We’re all going to be pretty busy with the conference, but wanted to put this out there as a space we can discuss.

4 Likes

Hello! I am the maintainer of OpenEvnt; I am very pleased to be working with you all.

Before Evnt, I used to work on a website to find local cosplay events around the cities where I lived, and iterating on its design gave me a lot of useful insights on what event information needs to have. Translations (language keyed string objects) quickly became apparent as a need as I kept seeing titles and descriptions in 2+ languages. Along with multiple locations, time spans and extendable metadata.

For media; Evnt currently defines a Component called SplashMediaComponent that can appear many times for cover/banner/etc media. Evnt is kind of defined to be protocol/transport agnostic so the component itself doesn’t make that much sense when in an atproto context…

1 Like

Hello and welcome!

I strongly encourage you to rethink creating a new, custom event lexicon and instead of looking at patterns to extend the community one.

  • You don’t need to use fields that don’t make sense to you or feel appropriate for your use case. For example, I think that I remember some of the schema.org fields not really aligning with what you want. That’s OK! The only required fields are “createdAt” and “name”.

    See community.lexicon.calendar.event Documentation (EN) - Lexicon Garden

  • The “sidecar record” pattern exists to make it easier to have a base record and then custom content associated with it. In Smoke Signal I use it for smokesignal-events-specific configuration like external ticket links. When the primary event is created, the sidecar record is created with the same record key making record lookup easy and reducing the indexing burden.

    See events.smokesignal.calendar.eventConfiguration Documentation (EN) - Lexicon Garden

  • Adding additional fields to the record is OK, but proceed with caution. Smoke Signal, Atmos RSVP, and Open Meet all have their own forms of custom data that isn’t part of the spec (yet). Some very basic coordination and careful planning allowed us to experiment with how media (headers, thumbnails, etc.) for events can be included.

    It looks like your splash media component is already pretty close to what the rest of us is doing by having a list of media (blobs), with alt text, and a designated role (header, thumbnail, etc.).

    Another example are the atmosphereconf.org events. Those events created from the atmosphereconf.org site have an additional “additionalData” field that includes conference-specific internal information.

4 Likes

I’d love to attempt at doing what you said, but unfortunately Evnt started off as being just the data format so it was designed to be protocol-agnostic; sidecar records for specific data unfortunately goes against that philosophy.

I do plan to add “syncing” to the reference client to make community.lexicon.calendar.event records with the same record key as directory.evnt.event as a band-aid fix for this. There will be information loss.

The structure between the Evnt format and community event lexicon is just too different to “extend” easily. I’d rather not break existing implementations and attempt to implement my radical ideas on a new slate. Thank you though

i think we really should extend the spec with the stuff that we’re actively using but isn’t part of the spec (+ add a few more optional fields):

  • media (i’d personally prefer something like adding an icon field with a known aspect ratio / expected dimension and slowly depreciating the media thing)
  • clarify description: openmeet afaik uses markdown (commonmark?), smokesignal uses facets (both are not part of the spec afaik), atmo.rsvp and blento currently show both but for creation only use facets (i’d personally prefer markdown, but with some extra stuff e.g. for embeds :stuck_out_tongue: ive been playing around a bit with that for blento blogs)
  • startsAt and endsAt (clarify the expected timestamp format here? or is format: datetime already clear regarding timezones etc?)
  • createdBy (useful for which client created that, atmo.rsvp is already adding that)

other extra fields we should consider imo:

  • bskyPostRef (e.g. for comments)
  • parentEvent (for events like the atmosphereconf talks that are part of another event)
  • tags (thats probably a difficult one)
  • additionalHosts (array of dids, somehow the other person has to “accept” that probably, also complicated so maybe add later)

i’ve also been thinking a bit about groups for events and really like the luma approach with calendars (you can add people to a calendar and those people can then add events to that calendar), could also be used for individual people that have different types of events (e.g. nate makes a calendar just for the weekly dev meetups), and allows people to subscribe to a calendar → see all events from that calendar.

in practice that would mean one extra lexicon:

community.lexicon.calendar.calendar (??)

  • name (only one thats required)
  • description
  • icon
  • participants (array of dids that can add events)

and an extra field on events:

  • calendar (ref, gets ignored if creator of event is not part of participants)

subscribing to calendars would then be yet another lexicon probably

3 Likes

Yeah, I think the lexicon is overdue for some updates. The main thing is that it’s currently missing the media block.

I think we should really consider something like a manifest for resources used by events. The structure is pretty straight forward:

{
    "name": "My Awesome Event",
    "createdAt": "2026-03-20T14:00:00.000Z",
    "images": [
        {
            "alt": "An awesome event banner image.",
            "purpose": "banner",
            "src": "/banner.png"
        }
    ],
    "resources": {
        "/banner.png": {
            "$link": "bafk…",
            "contentType": "image/png",
            "dimensions": {
                "height": 100,
                "width": 300
            },
            "size": 100
        }
    }
}

The reason I went with text is because it avoids the markup problem and sets a very very basic expectation that whatever content is in there should be able to be read by humans just the way it is. If open meet wants to render it as markdown, that’s fine. If a client doesn’t support additional facets, that’s OK too.

The startsAt and endsAt are strings with the “datetime” format. That’s set by the lexicon spec. There isn’t much room for interpretation there: https://atproto.com/specs/lexicon#datetime

As for everything else, we should split those into discussions. Practically speaking, I really want to avoid loading the event lexicon with additional stuff. If we can create additional supplementary records for things like localization, reference material (parent app.bsky.feed.post and refs), redirects / new-owner-transfer, multi-organizer, etc. then we should.

2 Likes

Also, I’d like to point out something I do at Evnt; a components array for any metadata that isn’t tied to locations or time spans. It’s basically kinda-but-not-really-like facets. I think having the bskyPostRef, parentEvent and tags fields would be better as “features” that get added to the event.

Another thing I’d like to point out is that I think having event descriptions be more like long form rich-text documents could be really nice. You could go ahead and either imitate what standard.site.document does (by referencing another record that contains renderable long form content, I think this has more technical complexity though) or just bake in a similar but extendable way to have rich text content into the description field. This would allow everyone to benefit from markdown and also enable us to have inline embeds of the like.

I’ve been eyeing this post by pfrazee and thinking about using it as a base for RichText in Evnt.

1 Like