Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NIP-52: Calendar Events, Calendars, Calendar Event RSVPs #597

Merged
merged 1 commit into from
Aug 1, 2023

Conversation

tyiu
Copy link
Contributor

@tyiu tyiu commented Jun 11, 2023

There are many useful types of applications that can be built on top of this NIP. For example:

  • calendar app
  • meetup app
  • conference app

@tyiu tyiu force-pushed the nip52-calendar-events branch from 9655d09 to 903ee33 Compare June 11, 2023 01:37
@tyiu
Copy link
Contributor Author

tyiu commented Jun 11, 2023

Amended my commit to mention that recurring calendar events are an unsolved limitation. Somebody reminded me that I didn't tackle it. I'll think about how to add it to the NIP.

52.md Outdated Show resolved Hide resolved
@vitorpamplona
Copy link
Collaborator

vitorpamplona commented Jun 11, 2023

How do we do private events?

Secret-based encryption? Build a secret, share with invitees individually and they use it to decrypt.

52.md Outdated Show resolved Hide resolved
@tyiu
Copy link
Contributor Author

tyiu commented Jun 11, 2023

How do we do private events?

Secret-based encryption? Build a secret, share with invitees individually and they use it to decrypt.

I feel like there's case to be made for a separate NIP that specifies how to do this with any kind, not just for calendar events. I'm not sure how you would share the secret with invitees.

52.md Outdated Show resolved Hide resolved
52.md Outdated Show resolved Hide resolved
52.md Outdated Show resolved Hide resolved
52.md Outdated Show resolved Hide resolved
@nolim1t
Copy link

nolim1t commented Jun 11, 2023

looks cool.

Maybe find a way to include payment for an event too, as nostr events can be zapped too.

And you can verify proof of payment according to NIP57

(replied on nostr as well)

@nostronaut
Copy link

how would you signal if a calendar event got cancelled?

@MiningSC
Copy link

How do we do private events?

Secret-based encryption? Build a secret, share with invitees individually and they use it to decrypt.

Could this be done with NIP-04? When a private calendar event is created, send a kind 4 event to anyone who is an invitee, the 31923 json data could be included in the content of the kind 4 message. When invitees RSVP, they could respond via a calendar app to the creator, or all invitees with kind 4 messages with the 31924 data being included in the message. A calendar app could require the user to login to see their private events. If a user logs in, the app would parse their kind 4 messages for calendar events to be shown, in addition to any other public calendars they are subscribed to.

@pablof7z
Copy link
Member

how would you signal if a calendar event got cancelled?

Delete kind

@nostronaut
Copy link

how would you signal if a calendar event got cancelled?

Delete kind

that is a bit too implicit

the user of a stateless client searches for a calendar event they planned on going and the event is not there anymore -- confused user

a stateful client upon seeing the event being deleted before its due date displays to the user calendar event cancelled

@pablof7z
Copy link
Member

looks cool.

Maybe find a way to include payment for an event too, as nostr events can be zapped too.

You don't need to do anything special for zaps; any nostr event can be zapped so there's no need to explicitly call that out on each nip

@pablof7z
Copy link
Member

how would you signal if a calendar event got cancelled?

Delete kind

that is a bit too implicit

the user of a stateless client searches for a calendar event they planned on going and the event is not there anymore -- confused user

a stateful client upon seeing the event being deleted before its due date displays to the user calendar event cancelled

All clients should be stateless (other than a cache)

There're no guarantees in nostr and all clients should take this into account; even if you replaced the event itself to signal it was cancelled a client might not see the replaced event.

@tyiu
Copy link
Contributor Author

tyiu commented Jun 11, 2023

how would you signal if a calendar event got cancelled?

Delete kind

that is a bit too implicit

the user of a stateless client searches for a calendar event they planned on going and the event is not there anymore -- confused user

a stateful client upon seeing the event being deleted before its due date displays to the user calendar event cancelled

All clients should be stateless (other than a cache)

There're no guarantees in nostr and all clients should take this into account; even if you replaced the event itself to signal it was cancelled a client might not see the replaced event.

How deletions work currently only accept e tags which doesn't seem to work well with kind 3xxxx. I think we need to expand the deletion NIP to support a tags.

@AtlantisPleb
Copy link
Contributor

Looks cool, will use it!

How do we do private events?

Secret-based encryption? Build a secret, share with invitees individually and they use it to decrypt.

Perhaps NIP-112: Encrypted Group Events

@pablof7z
Copy link
Member

how would you signal if a calendar event got cancelled?

Delete kind

that is a bit too implicit

the user of a stateless client searches for a calendar event they planned on going and the event is not there anymore -- confused user

a stateful client upon seeing the event being deleted before its due date displays to the user calendar event cancelled

All clients should be stateless (other than a cache)

There're no guarantees in nostr and all clients should take this into account; even if you replaced the event itself to signal it was cancelled a client might not see the replaced event.

How deletions work currently only accept e tags which doesn't seem to work well with kind 3xxxx. I think we need to expand the deletion NIP to support a tags.

There's nothing special about the e vs a kind on the delete event. Highlighter does a tags on delete kinds. Probably habla does a tag deletes on NIP-23s.

@tyiu
Copy link
Contributor Author

tyiu commented Jun 11, 2023

how would you signal if a calendar event got cancelled?

Delete kind

that is a bit too implicit
the user of a stateless client searches for a calendar event they planned on going and the event is not there anymore -- confused user
a stateful client upon seeing the event being deleted before its due date displays to the user calendar event cancelled

All clients should be stateless (other than a cache)
There're no guarantees in nostr and all clients should take this into account; even if you replaced the event itself to signal it was cancelled a client might not see the replaced event.

How deletions work currently only accept e tags which doesn't seem to work well with kind 3xxxx. I think we need to expand the deletion NIP to support a tags.

There's nothing special about the e vs a kind on the delete event. Highlighter does a tags on delete kinds. Probably habla does a tag deletes on NIP-23s.

I agree, but https://github.com/nostr-protocol/nips/blob/master/09.md as written today requires e tags.

A special event with kind 5, meaning "deletion" is defined as having a list of one or more e tags, each referencing an event the author is requesting to be deleted.
Each tag entry must contain an "e" event id intended for deletion.

@pablof7z
Copy link
Member

how would you signal if a calendar event got cancelled?

Delete kind

that is a bit too implicit

the user of a stateless client searches for a calendar event they planned on going and the event is not there anymore -- confused user

a stateful client upon seeing the event being deleted before its due date displays to the user calendar event cancelled

All clients should be stateless (other than a cache)

There're no guarantees in nostr and all clients should take this into account; even if you replaced the event itself to signal it was cancelled a client might not see the replaced event.

How deletions work currently only accept e tags which doesn't seem to work well with kind 3xxxx. I think we need to expand the deletion NIP to support a tags.

There's nothing special about the e vs a kind on the delete event. Highlighter does a tags on delete kinds. Probably habla does a tag deletes on NIP-23s.

I agree, but https://github.com/nostr-protocol/nips/blob/master/09.md as written today requires e tags.

A special event with kind 5, meaning "deletion" is defined as having a list of one or more e tags, each referencing an event the author is requesting to be deleted.

Each tag entry must contain an "e" event id intended for deletion.

I'll update that NIP to also mention a tags, don't let the fact that it's not named deter you from using 🤙

@tyiu
Copy link
Contributor Author

tyiu commented Jun 11, 2023

One situation that I've left undefined is how to handle situations where a calendar event substantially changes after an RSVP has been submitted. I'm leaning towards letting this behaviour be undefined, and letting the client determine what to do with that. Clients can observe the sequence of changes based off of the created_at timestamp.

I'll add an amendment to make that explicit.

@tyiu
Copy link
Contributor Author

tyiu commented Jun 11, 2023

One situation that I've left undefined is how to handle situations where a calendar event substantially changes after an RSVP has been submitted. I'm leaning towards letting this behaviour be undefined, and letting the client determine what to do with that. Clients can observe the sequence of changes based off of the created_at timestamp.

I'll add an amendment to make that explicit.

Actually, should RSVPs use the calendar event e tag, in addition to the a tag? So that we can tell what version of the calendar event it was in response to.

@tyiu
Copy link
Contributor Author

tyiu commented Jun 11, 2023

One situation that I've left undefined is how to handle situations where a calendar event substantially changes after an RSVP has been submitted. I'm leaning towards letting this behaviour be undefined, and letting the client determine what to do with that. Clients can observe the sequence of changes based off of the created_at timestamp.
I'll add an amendment to make that explicit.

Actually, should RSVPs use the calendar event e tag, in addition to the a tag? So that we can tell what version of the calendar event it was in response to.

Thinking about it more. It can easily get out of hand because the invitee list is encoded in the calendar event. If someone wants to invite someone additional without changing the calendar event, we don't want clients to unnecessarily invalidate the RSVP.

Never mind! Leaving the e tag off.

@alexgleason
Copy link
Member

This NIP would allow bridging ActivityPub calendar events to Nostr. See: https://docs.joinmobilizon.org/contribute/activity_pub/#event_1

At a glance it looks compatible enough.

@tyiu
Copy link
Contributor Author

tyiu commented Jun 11, 2023

Addressed all the feedback so far. Please take another look.

@tyiu tyiu requested review from pablof7z and fiatjaf June 11, 2023 19:24
52.md Outdated Show resolved Hide resolved
52.md Show resolved Hide resolved
@nolim1t
Copy link

nolim1t commented Jun 12, 2023

Amended my commit to mention that recurring calendar events are an unsolved limitation. Somebody reminded me that I didn't tackle it. I'll think about how to add it to the NIP.

Probably better not to overcomplicate something at base level protocol.

Also as an immutable platform theres a lot of things to consider

If someone really wants a recurring event, they can write a script with cron to create it.

52.md Outdated

This NIP intentionally omits support for recurring calendar events and pushes that complexity up to clients to manually implement if they desire. i.e., individual calendar events with duplicated metadata represent recurring calendar events.

### Time Zones
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a mistake. Timezones matter, and we can't simply ignore their existence. What's more, timezones as unfun as they can be, are a solved problem.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Timestamps should be a nice universal way to solve that without doing too much at the base protocol.

The client can convert that timestamp into whatever the local time is set to

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a mistake. Timezones matter, and we can't simply ignore their existence. What's more, timezones as unfun as they can be, are a solved problem.

Not implying that we ignore time zones. Rather, what's being suggested is that this is something that gets pushed up to clients and users to figure out.

If time zones were encoded into the spec, you can certainly communicate some intent of which time zone a calendar event was meant to be scheduled in. But it doesn't do much if the other participants are in different time zones. They would still need some consensus mechanism to settle on a time that works best for each of them.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get it? Isn't it easy to display time in any timezone once you have a unix timestamp? That feels like an easy job that fits in the client rendering layer unless I'm missing something. We do the same for event created_at and seems to be working so far.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose if I'm travelling to an event (eg I'm in Texas, but looking at Nostrasia), I might want to see the time of the event in its actual location rather than in my current timezone. But if we have the location of the event, clients should be able to determine its local timezone based on the location.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need for anything extra.

The UNIX timestamp we use is on GMT. If you want to schedule an appointment, apps need to convert from the UI (say, EST) to GMT and send it. When receiving, the UI parses the event and converts back to the timezone of the receiver. If you are traveling, the UI should have a timezone selector so you can mark the event at 5pm JPN time, for instance. The UI converts from JPN to GMT and sends the event.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ended up adding an optional start and end time zone identifier in 2ce758a

Use case: I'm in North America and would like to know the schedule of Nostrasia in Tokyo before I get there in Asia/Tokyo time, but I don't want to need to compute it from the geohash as it's non-trivial and implicit.

@tyiu
Copy link
Contributor Author

tyiu commented Jul 17, 2023

Forgot to update the README to include distinction between the two calendar event kinds: 31922 (date-based calendar event) and 31923 (time-based calendar event). Amended the commit to include that.

@fiatjaf
Copy link
Member

fiatjaf commented Jul 18, 2023

What is the difference between the two types of calendars? I think it is terrible, awful, very bad idea to have two kinds of events that are the same thing, but with different ways of representing dates.

Why not just use Unix timestamps? If the event is not meant to happen at an exact timestamp we just need another tag there saying "full-day event" or "approximated". I don't know, that may feel ugly, but I believe for implementors it makes things much simpler.

@vitorpamplona
Copy link
Collaborator

vitorpamplona commented Jul 18, 2023

@fiatjaf, Two kinds are actually necessary. Unix timestamps can't represent full-day events that are independent of the timezone. A New Year's holiday, for instance, cannot be coded with start-end time unless you create a different event for each timezone on the planet and then only invite people in that timezone for each event. Merging into one event brings unnecessary complexity.

52.md Outdated
["start", "<YYYY-MM-DD>"],
["end", "<YYYY-MM-DD>"],

["start_tzid", "<IANA Time Zone Database identifier>"],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

start_tzid and end_tzid got copy-pasta'd from time-based calendar events into date-based calendar events. I'm going to remove them because time zones do not make sense for date-based calendar events.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed in 4042ab1

@tyiu tyiu force-pushed the nip52-calendar-events branch from 4042ab1 to cc05010 Compare July 19, 2023 03:11
@tyiu
Copy link
Contributor Author

tyiu commented Jul 19, 2023

@fiatjaf It's actually necessary for calendars. Unix timestamps can't represent full-day events that are independent of the timezone. A New Year's holiday, for instance, cannot be coded with start-end time unless you create a different event for each timezone on the planet and then only invite people in that timezone for each event. Unnecessary complexity.

Agreed. There are real-world use cases where a time zone agnostic date-based calendar event is necessary. Majority of people around the world operate on these mental models. This was written in the NIP but I'll reiterate it here:

This kind of calendar event starts on a date and ends before a different date in the future. Its use is appropriate for all-day or multi-day events where time and time zone hold no significance. e.g., anniversary, public holidays, vacation days.

@fiatjaf
Copy link
Member

fiatjaf commented Jul 19, 2023

OK, I see the point. Thank you.

But is the difference between the two kinds just that? I think in that case they should be the same kind then. We gain nothing by using two different kinds.

@shawndearmond
Copy link

It would be really hard to query the relay for calendar events with a date greater than or equal to today if the field might contain Unix timestamp or ISO.

@fiatjaf
Copy link
Member

fiatjaf commented Jul 19, 2023

You can't do that anyway already.

@staab
Copy link
Member

staab commented Jul 20, 2023

Just implemented a subset of this nip here. I don't know if it counts as a client implementation, but I wanted to mention it here since you all are interested in this topic. If you want to fork or contribute, be my guest, I won't be able to spend much time maintaining it.

@tyiu
Copy link
Contributor Author

tyiu commented Jul 20, 2023

OK, I see the point. Thank you.

But is the difference between the two kinds just that? I think in that case they should be the same kind then. We gain nothing by using two different kinds.

The data model could get messy. Basically each implementer would need to check a field to see if it’s a date-based calendar event or a time-based calendar event. Conditional on that field, they would have to deserialize or parse the calendar event in a different way. We would probably have to make sure to name the start and end fields differently between the two kinds of calendar events. It could get even messier if there’s a different type of calendar event that we didn’t anticipate (e.g., I know we said we weren’t going to do recurring events, but if that happens to be a horrendous mistake and change our minds, that would be something to consider)

On the other hand, there’s a large overlap of the same tags, so one could make the argument that it’s worthwhile.

But I feel like the former argument in my first paragraph is a compelling enough reason to keep them separate, though I could be convinced otherwise. Curious to hear other opinions.

@shawndearmond
Copy link

You can't do that anyway already.

Why do you say that?

@GBKS
Copy link

GBKS commented Jul 20, 2023

As an implementor, I would prefer a single event kind. It's a (IMHO) subtle difference in a couple of tags. Clients already have to do a lot of parsing to piece events together into a coherent presentation (live activities, for example, which you want to treat very differently when they are currently happening). Feel free to ignore my opinion though, not a pro on these things.

@fiatjaf
Copy link
Member

fiatjaf commented Jul 23, 2023

You can't do that anyway already.

Why do you say that?

Because you can only query for exact tags.

@fiatjaf
Copy link
Member

fiatjaf commented Jul 23, 2023

Unix timestamps can't represent full-day events that are independent of the timezone. A New Year's holiday, for instance, cannot be coded with start-end time unless you create a different event for each timezone on the planet and then only invite people in that timezone for each event. Unnecessary complexity.

Revisiting this, I retract what I said. I think these date-based events are the real unnecessary complexity. What is the use case for creating a single "new year" event that happens in the entire world? This doesn't seem to be a real use case to me.

For that reason I think it is fine to keep it as a separate event kind, and hope no one implements that.

@tyiu
Copy link
Contributor Author

tyiu commented Jul 23, 2023

Unix timestamps can't represent full-day events that are independent of the timezone. A New Year's holiday, for instance, cannot be coded with start-end time unless you create a different event for each timezone on the planet and then only invite people in that timezone for each event. Unnecessary complexity.

Revisiting this, I retract what I said. I think these date-based events are the real unnecessary complexity. What is the use case for creating a single "new year" event that happens in the entire world? This doesn't seem to be a real use case to me.

For that reason I think it is fine to keep it as a separate event kind, and hope no one implements that.

Think about it in the context of a shared company calendar. It’s a company holiday and its employees are in different time zones. It’s not possible to represent accurately as a time-based calendar event unless you create a 24-hour long time-based calendar event per time zone, which is way more infeasible than a single date-based calendar event.

Another example, my birthday is on a specific day but I was born on the other side of the world. I’ve since moved. So now my birthday is represented as a day earlier because time zones. That makes no sense.

There are a ton of use cases.

@shawndearmond
Copy link

You can't do that anyway already.

Why do you say that?

Because you can only query for exact tags.

Seems pretty necessary that relays be queried for future calendar events only. Should we add a bit in this nip for how that subscription would be formatted, and how relays should behave?

@PeerRich
Copy link

PeerRich commented Jul 26, 2023

i run cal.com (https://github.com/calcom/cal.com) and for the love of god please dont invent a new calendar standard

the existing ones cover everything we need here

also timezones are a b*tch, don't underestimate them

iCal is good

also remember a CalDav interface would make instant compatibility with pretty much most calendars nowadays

how are we planning to subscribe to calendars? or invite people? what is Nostr-Cal solving right now?

i think saving a calendar event as a note is just the tip of the iceberg. not sure if this even needs a new nip vs just a normal note 🤔

figuring out how inviting, editing, moving dates around is where the value is and i dont think this nip gets close to it

@tyiu
Copy link
Contributor Author

tyiu commented Jul 26, 2023

i run cal.com (https://github.com/calcom/cal.com) and for the love of god please dont invent a new calendar standard

the existing ones cover everything we need here

also timezones are a b*tch, don't underestimate them

iCal is good

also remember a CalDav interface would make instant compatibility with pretty much most calendars nowadays

how are we planning to subscribe to calendars? or invite people? what is Nostr-Cal solving right now?

i think saving a calendar event as a note is just the tip of the iceberg. not sure if this even needs a new nip vs just a normal note 🤔

figuring out how inviting, editing, moving dates around is where the value is and i dont think this nip gets close to it

Can you elaborate? The proposed NIP answers all your questions so I’m not sure what the concern is. Have you read it?

Also, what does it even mean when you say it can just be a normal note? That doesn’t make sense to me.

I understand the appeal of not inventing a new standard. But we are also rebuilding the web with Nostr, so some things that feel natural in one standard might not necessarily fit with how Nostr works.

Copy link
Member

@alexgleason alexgleason left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lol can we merge this already? It's excruciating seeing all the panicked comments about destroying the universe by reinventing calendars. It's important to do it right, but at this point if it's still wrong just do a follow-up pull request. Even NIP-01 is still getting changes.

@tyiu tyiu force-pushed the nip52-calendar-events branch from cc05010 to acd84b3 Compare July 26, 2023 15:16
@tyiu
Copy link
Contributor Author

tyiu commented Aug 1, 2023

You can't do that anyway already.

Why do you say that?

Because you can only query for exact tags.

Seems pretty necessary that relays be queried for future calendar events only. Should we add a bit in this nip for how that subscription would be formatted, and how relays should behave?

@shawndearmond Like fiatjaf said, Nostr allows searching for only exact tag matches at the moment. I'm open to exploring other types of subscriptions, but I think we can explore that later on as a general problem space independent of this NIP. For now, a poor man's subscription could be made by filtering on only calendar events that were created or updated after a given timestamp. Further filtering can be done on the client for now if they truly want to show only future calendar events.

@tyiu
Copy link
Contributor Author

tyiu commented Aug 1, 2023

@fiatjaf Is this PR mergeable or do you need more concrete examples of client implementations?

@richgarner-nsw-gov
Copy link

Wanna get this in my (somewhat basic and early-days) client:

https://github.com/grubstarstar/nostr-client

Events and DMs are the only thing keeping me tied to Facebook 🤌.

Do you know any relays using this?

@fiatjaf fiatjaf merged commit b4cdc1a into nostr-protocol:master Aug 1, 2023
@alexgleason
Copy link
Member

ablobcatrainbow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.