Creating calendar event through API for multiple users

Hello,

I have an app totally independant from Nextcloud. This app written in nodejs has its own users and learning sessions management.

When a user subscribe to a session, I would like to insert this session date into the standard user’s calendar app (outlook, thunderbird, etc).

I could mount a full Sabre/Dav server (or other CalDAV servers), but I felt it should be cool to sync with a Nextcloud instance and its calendar app.

I created a “superuser” in the nextcloud instance, and I use its user/password to make my calls:

  • sync users (with API /ocs/v2.php)
  • sync users passwords (with API (ocs/v1.php)
  • add calendar event with webdav inside the superuser personal calendar

All this is working, but…

What I’m searching for is to add a new event calendar for any users inside this Nextcloud instance. And I really don’t want to store “in clear” my users passwords.

Is there a way, either to add a calendar event “in the behalf of” a user? Or eventually to share an event calendar with other users? (I would prefer the first one :slight_smile: )

Thanks for your help

I tried to play with attendies in ICS definition. Attendies are visible in the event, but the event itself is not visible in their calendars.

BEGIN:VCALENDAR
BEGIN:VEVENT
UID:xxx
STATUS:CONFIRMED
SUMMARY:test
DTSTART:20250317T120000
DTEND:20250317T180000
ATTENDEE;CN=Other User;ROLE=REQ-PARTICIPANT;PARTSTAT=COMPLETED:mailto:other-user@mydomain.com
END:VEVENT
END:VCALENDAR

Still need some help on this topic, thanks.

Well, it is a bit unclear to me what you want to achieve. You have an external app with some users. Is there a 1-to-1 mapping of the users with NC or are they completely unrelated?

Normally, I would expect something like this: The users are working on their frontend sending some data to the backend (this is your job, not NC related). Once there is a new appointment to be created, the backend has a token mebedded that allows the backend (that you can trust) to create an appointment in the NC calendar on behalf of a certain user you want to do it.

The simplest way to do this is most probably to use WebDAV protocol and access the NC server as a WebDAV/CalDAV server. You can then create a new event (aka WebDAV node) in the corresponding calendar of the destination user. The calendar sharing can be handled in NC completely, at least when I understand your use case correctly. A WebDAV library should be present for node.js as well. I did something similar with Python (no web app but a CLI to update a bunch of appointments in bulk).

So, maybe you need to seperate concerns a bit:

  1. Where should be stored what? Who should communicate with whom? (That is generate an overall architecture of your programs)
  2. Check what settings you need in NC to create a development environment that you reset in case of damage
  3. Get a CalDAV library and get yourself familiar with it.
  4. Implement your logic in node.js (this should be straight forward)

Chris

Thanks for your reply.

Yes, my user database is in sync with NC.

When I need to set a new event with attendies in it, I can do it because I have a NC user with username/password which is set in my app.

But my problem is when you say: create a new event in the corresponding calendar of the destination user

Right now, I can’t create an event in calendar which is not owned by my “superuser”.

From what I see, to add an event in a specific user calendar, I need to connect to NC (webdav) with username/password of the corresponding user. Which is not what I want to do (passwords are of course crypted in my database, so I can’t use them to connect to NC).

Either playing with iCalendar Attendies, or with NC calendar sharing, are the solutions. But right now, I’m a bit lost.

OK, I thin we are getting closer. Still one question: Who should create the events in which calendars? I just want to get this 100% crisp clear as there are a zillion options here.

Let’s say user Alice wants to subscribe to a session. She goes to your app and does her stuff there. Now, there should be an event in a calendar inserted.

  • Which calendar? The calendar of Alice?
  • Should there be another calendar entry involved in the calendar of Bob? Who is Bob? The teacher?
  • Should the other persons/scholars (like Charlie) be able to see the session booked?
  • Are the users (aka Alice/Charlie and Bob) aware that there is a NC instance in the background?

Right now, you have a super user Omega that holds all rights as far as I understand. Omega can write to the calendars of Alice and Charlie as these calendars are shared with Omega.

Is this correct so far?


The point is that you should first make clear what you want to achieve before you dig into the details of the implementation. You might have some ideas in front of your mental eye but at least to me the image is not clear enough. I tried to extrapolate and guess from your posts a story (Alice/Bob/…) that you can easily write and understand as a human being. Starting from there, we can piece by piece try to find a solution. I have some possible solutions in mind but as I am not sure, they fit the requirements, it’s tedious to write them all down. So, first get the requirements clear and then we can discuss, ok?

Chris

Ok, so let’s run through the scenario :

App = the specific app outside of NC
NC = Nextcloud instance

First, the goal :

  • Omega creates two sessions X and Y in App
  • teacher Tracy is linked to sessions X and Y in App
  • student Alice subscribe to session X in App
  • student John subscribe to session Y in App
  • Alice, John and Tracy can copy a personal link, from their App account, that they can paste inside their Outlook/Thunderbird/Google calendar app
  • Tracy sees both sessions X and Y in her calendar app
  • Alice sees only session X in her calendar app
  • John sees only session Y in his calendar app
  • if Omega changes information about the sessions (date/time, title, etc.), these are reflected in Alice, John and Tracy calendar app

At this stage, nobody knows about NC. Now, what I’m doing right now is the following:

  • Omega creates a session in App
  • Alice subscribe to this session in App
  • an event is emitted in the App infrastructure, which is listened by the App-NC-sync service
  • this service, in App, knows the login/password of Omega on NC
  • an ICS event string is generated, based on the session information
  • the ICS event string is pushed from App to NC, where the connection information relates to Omega NC account
  • the ICS event appears on personal calendar of Omega NC account
  • this is where I am \o/

I know I can push the event in Alice calendar if I use her NC credentials, but that’s not an option.

And if I use one big calendar in Omega NC account, which is shared, I still need to show only relevant sessions to Alice, John and Tracy (not all the sessions for everybody).

Edit: I was thinking about creating a calendar per user (one for Alice, on for John and one for Tracy) in Omega NC account, and pushing the event in every concerned calendars. Each calendar is shared only with the concerned user.

Thanks for forcing me to be clearer :wink:

1 Like

OK, this is getting cleaner to me now. Thanks for writing it verbosely!

On the NC side, you need rather thorough permissions and rights: You want the users Alice/John/Tracy not to be aware of NC. So, they will not be able to share their calendar (writable) to Omega. Also it is not possible to let the users create tokens using the login flow per user.

Shared calendars from Omega

One solution you mentioned already is to let the App create one calendar for Omega per User and share them (read-only ?) with the users. This has the benefit that all can be handled rather straight forward, form Omega’s perspective, it is just a simple (“own”) event and the other users (Alice&Tracy) will see the event also as their own events.

The complexity will be in creating the calendars for Omega programmatically and keeping the sharing in sync. It feels to me like a bunch of hassle, to be honest.

Create an NC app accessing the calendars

You could create a custom app (NC internal) as a companion to your App. It would have a REST (or OCS) api, that would allow you to access all the various calendars using PHP. You weould have to setup some authentication so that only your App can access the endpoints.
From there, you could directly modify all the calendars of the users (Alice/Tracy) and make the events appear “out of nowhere”.

Note however, that the calendars are owned by these users. Thus, they could alter/delete the events anytime. You would either have to notify the other (e.g. if Alice falls ill, she might simply remove the event, Tracy must be notified of this eventually?) or plainly ignore it (its your data, you should know what you are doing).

Reference docs

Create event invitations by mail

You could use Omega and the ICS way to add attendees to the event. Then, it becomes obvious that the event is owned by Omega and the users are getting only notifications. However, the users might decide to reject the events or suggest other times. These returned information will be directed at Omega thus you might to have to cope with this.

On the pro side, you might not even need the NC integration for all users as you could simply use their own mails and their own calendars (be it google, MS, …).

Structure of an ICS with invitations I tested the ICS on my dev environment to invite an internal user and an external user by mail. It just sent a PUT request to the WebDAV server to create the event. The rest was handled by NC server as far as I can tell. The ICS was
BEGIN:VCALENDAR
PRODID:-//IDN nextcloud.com//Calendar app 5.2.0-rc.1//EN
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VEVENT
CREATED:20250318T114324Z
DTSTAMP:20250318T114626Z
LAST-MODIFIED:20250318T114626Z
SEQUENCE:2
UID:ba5c860c-9ea9-4eb1-badb-b25715af0d64
DTSTART;TZID=Europe/Berlin:20250318T130024
DTEND;TZID=Europe/Berlin:20250318T140024
STATUS:CONFIRMED
SUMMARY:Test
ATTENDEE;CN=admin;CUTYPE=INDIVIDUAL;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIP
 ANT;RSVP=TRUE;LANGUAGE=en:mailto:admin@example.net
ATTENDEE;CN=christian@example.com;CUTYPE=INDIVIDUAL;PARTSTAT=NEEDS-ACTION;R
 OLE=REQ-PARTICIPANT;RSVP=TRUE:mailto:christian@example.com
ORGANIZER;CN=alice:mailto:foo@example.com
END:VEVENT
BEGIN:VTIMEZONE
TZID:Europe/Berlin
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:CEST
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:CET
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
END:STANDARD
END:VTIMEZONE
END:VCALENDAR

Create your own calendars in NC

You can also create/define your own set of calendars when you create an app. Similarly to the default calendar app, you can define your own calendar with your own events and stuff. The communication would again be probably a token based authentication to prevent malicious access.

This is an advanced solution (somewhat) but allows you to get notified once a user tried to modify the events or removed them. You are in control of the events (as part of your own DB) and can thus install custom gatekeepers.

Reference docs (especially note the legacy part)


OK, these are the options, I came quickly up with. Maybe there are more.

Chris

Great reply!

There are 2 more things which can narrow the choice.

First, these calendars should be readonly. People here cannot say “i’m not here” or “please change the date”. Date and time is not the choice of the users. And the fact that people were present or not is an other workflow defined in the App.

Second, there’re sometimes where privacy takes precedence over everything else. I feel that invitations and attendies are not suitable, since they are written inside ICS and thus are public.

I would put aside the creation of event invitation by email, and the creation of my own calendars in NC (too complex for what I need).

The NC app could be an option, just as shared calendars. I will think about it.

Thanks a lot!

1 Like