Hi,
I am prototyping a private Rocket.Chat App that posts one daily reflection card to selected rooms.
The content set contains 78 fixed cards. This is the reference list I am currently using for the IDs, titles and source links:
[Edited - spam links are not permitted]
Disclosure: I maintain the linked website. I am sharing it only to show the real content set the Rocket.Chat App would consume.
The planned behaviour is:
-
An administrator enables the app for selected rooms
-
Each room can choose its own posting time and timezone
-
The app selects one card per room per day
-
The result is posted using UI Kit blocks
-
Users can also run
/dailycard -
Repeating the command on the same day should return the same card
-
Different rooms should have independent selections
-
The message should include the card title, a short summary and a source button
-
No user data needs to be sent to the external website
I am considering exposing a small JSON endpoint from the content site rather than parsing the HTML page.
A response might look like this:
{
"id": "the-world",
"title": "The World",
"summary": "Completion, integration and the end of a cycle.",
"url": "https://deckaura.com/blogs/guide/world-tarot-meaning"
}
I have several architecture questions.
1. One scheduler or one scheduler per room?
Would it be better to register one recurring scheduler that runs every few minutes and checks which rooms are due?
Or should the app create a separate scheduled job for each configured room?
The first option seems easier to manage, but it may become inefficient if many rooms are configured.
2. Per-room configuration
What is the recommended way to store settings such as:
-
Enabled or disabled
-
Local posting time
-
Timezone
-
Target room
-
Whether slash commands are allowed
-
Whether source links should be displayed
Should this be stored through Apps-Engine persistence, or is there a standard per-room settings pattern?
3. Deterministic daily selection
I want every user in the same room to see the same card for a given calendar date.
Would you generate the selection deterministically from:
roomId + localDate
Or randomly select the card once and persist the result?
The persisted approach would make the result easier to audit, but deterministic selection would reduce stored data.
4. Preventing duplicate messages
How should the app prevent duplicate posts if:
-
The scheduler runs twice
-
The server restarts around the posting time
-
Multiple Rocket.Chat instances process the same scheduled task
-
The first message is posted but the persistence write fails
I am considering a persistence key such as:
daily-card:{roomId}:{yyyy-mm-dd}
The app would create that record before posting, but I am not sure whether Apps-Engine persistence provides an atomic create-if-absent operation suitable for this.
5. Remote request and caching
Would it be reasonable to fetch the card data from an HTTPS JSON endpoint once per day and cache the complete 78-card data set inside the app?
If the endpoint is temporarily unavailable, the app should continue using the most recently cached version.
Is Apps-Engine persistence appropriate for this cache, or should the static data be packaged with the app and updated only when the app itself is released?
6. UI Kit interaction
The posted message would contain:
-
Card title
-
Short description
-
“Read full meaning” URL button
-
Optional “Why this card?” button
-
Optional “Draw another” button
Would button interactions on an existing message be the right pattern, or should /dailycard open a modal and then post the selected result?
I would also like to restrict “Draw another” so that it does not change the official daily card for the entire room.
7. Slash command response visibility
For /dailycard, can the initial response be ephemeral to the requesting user, followed by an optional button to share it with the room?
I do not want repeated slash-command use to flood public channels.
8. External URL allowlisting
Does an Apps-Engine app need to declare or request permission for every external domain it calls?
The app would communicate only with one fixed HTTPS API endpoint. It should not accept arbitrary URLs from users.
9. Timezone and daylight-saving behaviour
Should the room’s next scheduled execution be stored as an absolute timestamp and recalculated after every post?
Or is there a recommended scheduler pattern for a local time such as 09:00 that must remain correct when daylight-saving rules change?
I am mainly looking for the recommended Apps-Engine architecture before implementing the first version.
The initial prototype would support one room, one timezone and the /dailycard slash command. Scheduled multi-room posting would be added after the basic persistence and duplicate-prevention logic is reliable.