|
|
||
|---|---|---|
| .forgejo/workflows | ||
| .env.example | ||
| .gitignore | ||
| config.js | ||
| index.js | ||
| now-page-template.md | ||
| package-lock.json | ||
| package.json | ||
| profile-page-template.md | ||
| README.md | ||
| services.js | ||
| utils.js | ||
now-updater
Automatically updates your omg.lol Now page with your latest activity.
Fork of melanie/now-updater with added support for HTML links, images/videos, Steam, Hardcover, some.pics, and simplified service configuration.
Demo: dylan.omg.lol/now
How It Works
Fetches content from RSS feeds, JSON feeds, and different services (Letterboxd, Trakt, Last.fm, Steam, Hardcover, etc.) and updates HTML or markdown links on your Now page. Supports optional images and videos for services that provide them (These are... iffy so if something breaks it's probably this). Runs every 3 hours via Forgejo Actions, only updating your page when changes are detected.
Images are matched using a data-service attribute on the img tag, which allows them to be updated repeatedly even after the initial replacement.
Example
Your Now page links will be automatically updated from this:
HTML links (before):
<a href="service-link">blog</a>
<a href="service-link">gitlab</a>
Markdown links (before):
[blog](service-link)
[gitlab](service-link)
to this:
HTML links (after):
<a href="https://your-blog.com/2025/12/my-latest-post">My Latest Post</a>
<a href="https://gitlab.com/username/project">Pushed to repository</a>
Markdown links (after):
[My Latest Post](https://your-blog.com/2025/12/my-latest-post)
[Pushed to repository](https://gitlab.com/username/project)
Setup
- Fork this repo
- Enable Actions in repo settings
- Add Actions variables:
OMGLOL_USERNAME(your omg.lol username) - Add Actions secrets:
OMGLOL_KEY(your API key) - Add optional secrets for services you want to use:
TRAKT_SLURM,STEAM_WEBAPI_KEY,HARDCOVER_API_KEY - Activate your services in
services.jsby settingisActive: true
For local development, copy .env.example to .env with your credentials.
Basic Example
Now page template:
I wrote this: <a href="https://your-blog.com">blog</a>
I watched this: <a href="https://letterboxd.com/username">letterboxd</a>
<img data-service="letterboxd" src="letterboxd-image" style="max-width: 120px;">
I listened to: <a href="https://www.last.fm/user/username">lastfm</a>
services.js:
export const services = [
{
id: 'blog',
isActive: true,
feedUrl: 'https://your-blog.com/feed.json',
feedType: 'json',
},
{
id: 'letterboxd',
isActive: true,
userId: 'your-username',
feedUrlTemplate: 'https://letterboxd.com/{userId}/rss/',
feedType: 'letterboxd',
showImage: true, // optional: include movie posters
},
{
id: 'lastfm',
isActive: true,
userId: 'your-username',
feedUrlTemplate: 'https://lfm.xiffy.nl/{userId}',
feedType: 'rss',
},
]
Configuration
Quick Start
- In your Now page, use service names as link text:
<a href="service-link">blog</a>
<a href="service-link">gitlab</a>
- In services.js, find the service and flip
isActivetotrue:
{
id: 'gitlab',
isActive: true, // just change this!
userId: 'your-username',
feedUrlTemplate: 'https://gitlab.com/users/{userId}/activity.atom',
feedType: 'atom',
}
The service id is used to match the link text in your Now page (e.g., <a href="...">blog</a> matches id: 'blog'). If you need multiple instances of the same service just create separate entries in services.js with unique ids and matching link texts. Like so:
{
id: 'mastodon-personal',
isActive: false,
userId: 'dylan',
instance: 'social.lol', // your mastodon instance
feedUrlTemplate: 'https://{instance}/@{userId}.rss',
feedType: 'mastodon',
showImage: true,
},
{
id: 'mastodon-work',
isActive: false,
userId: 'mrdylan',
instance: 'mastodon.instance', // your mastodon instance
feedUrlTemplate: 'https://{instance}/@{userId}.rss',
feedType: 'mastodon',
showImage: true,
},
Then you can have multiple Mastodon accounts on your Now page with different link texts: [mastodon-personal](service-link) and [mastodon-work](service-link).
Files
- config.js - Link format setting (
htmlormarkdown) and filter logic - services.js - All available services with
isActiveflags (edit this to enable/disable services) - utils.js - Generic feed handlers and service-specific logic
Service Structure
Each service has:
id: Identifier that matches the link text in your Now page (e.g.,id: 'blog-1'matches<a>blog-1</a>)isActive:trueto enable,falseto disablefeedType: Handler to use (rss,atom,json, or special handler name likeletterboxd,steam,hardcover)feedUrl: Direct feed URL (use this for custom feeds without usernames)feedUrlTemplate: URL template with{userId}or{instance}placeholdersuserId: Your username/ID (only needed with feedUrlTemplate)showImage: Optional. Controls whether image/videos are included (defaults based on service)- Extra params as needed (e.g.,
instancefor federated services,traktIdfor Trakt widgets)
Set linkFormat in config.js to 'html' or 'markdown' depending on your Now page format.
Image and Video Support
Many services support optional images and videos:
- Letterboxd: Movie posters from CDATA descriptions
- Trakt: Episode/movie poster widgets (portrait orientation, change the URL from
postertothumbfor landscape) - Hardcover: Book cover images
- Steam: Game library posters
- Mastodon: Attached images and videos from
media:contenttags (iffy, may not always work) - some.pics: Photo images from RSS CDATA
Control image inclusion with the showImage flag in your service config. Images are returned separately from text so you can control placement on your Now page.
To use images, your img tags must include a data-service attribute matching the service id from services.js. For example:
<img data-service="letterboxd" src="letterboxd-image" style="max-width: 120px;">
<img data-service="steam" src="steam-image" style="max-width: 120px;">
The src attribute can start with a placeholder (like letterboxd-image) or an existing URL - the updater will replace it either way as long as the data-service attribute is present.
Available Services
All handlers now use a config object with consistent parameters. The feedType in services.js maps to these handlers.
Generic Feed Handlers
getRSSItemTitle(feedUrl)- Standard RSS feedsgetAtomFeed(url)- Standard Atom feedsgetJsonFeedItemTitle(feedUrl, showImage)- JSON feeds with optional images
omg.lol Services
getSomePicsPost(feedUrl)- some.pics photo posts with images extracted from CDATA
Music
getListenBrainzScrobble(config)- ListenBrainz scrobbles (not tested, let me know!)- Config:
{ feedUrl, userId }
- Config:
- For Last.fm, use generic RSS handler with
https://lfm.xiffy.nl/{userId}
Social Media
getMastodonPost(config)- Latest non-reply Mastodon post with optional images/videos- Config:
{ feedUrl, showImage } - Extracts media from
media:contenttags and filters out replies
- Config:
Movies & TV
getLetterboxdActivity(config)- Letterboxd activity with optional poster images- Config:
{ feedUrl, showImage } - Extracts images from CDATA descriptions
- Config:
getTraktEpisode(config)- Latest TV episode with optional poster- Config:
{ userId, traktId, showImage } - Requires
TRAKT_SLURMenvironment variable - Uses portrait poster widgets
- Config:
getTraktMovie(config)- Latest movie with optional poster- Config:
{ userId, traktId, showImage } - Requires
TRAKT_SLURMenvironment variable - Uses portrait poster widgets
- Config:
Books
getHardcoverActivity(config)- Currently reading books with cover images- Config:
{ userId, feedUrl } - Uses GraphQL API, requires
HARDCOVER_API_KEY userIdmust be numeric user ID (not username)
- Config:
Gaming
getSteamRecentlyPlayed(config)- Recently played Steam game with library poster- Config:
{ userId } - Requires
STEAM_WEBAPI_KEYenvironment variable userIdmust be Steam ID 64 (convert at https://steamid.io/)
- Config:
Code & Development
getSourceTubeActivity(config)- Forgejo activity on source.tube- Config:
{ feedUrl, userId } - Strips username prefix from activity descriptions (e.g., "dylan pushed to repository" becomes "pushed to repository")
- Config:
Important Notes:
showImagecontrols whether images/videos are included in the response- Images and videos are returned separately from text (as
{ text, url, image, video }) - Generic RSS/Atom/JSON handlers work with most standard feeds
API Keys Setup
Trakt
To get your Trakt slurm key, follow these steps:
- Go to your History page on Trakt:
https://trakt.tv/users/your-username/history - There should be an RSS feed icon on the top right of the page. Click it.
- The URL it shows will look something like this:
https://trakt.tv/users/username/history.atom?slurm=your-slurm-key - Copy the
slurmvalue from the URL and add it as a secret in your Actions settings namedTRAKT_SLURM. - Add it to your
.envfile for local testing.
Steam
To get your Steam Web API key:
- Visit https://steamcommunity.com/dev/apikey
- Enter a domain name (I used omg.lol, I don't know if that will cause me issues later)
- Agree to the terms and get your API key
- Add it to your
.envasSTEAM_WEBAPI_KEYand to Actions secrets - Find your Steam ID 64 at https://steamid.io/ (enter your profile URL)
Note: The Steam handler uses the GetOwnedGames API endpoint sorted by rtime_last_played, which has no time limit. GetRecentlyPlayedGames can be used too, but it only shows anything played in the last 14 days which may be limiting.
Hardcover
To get your Hardcover API key:
- Visit https://hardcover.app/account/api (Make sure you're logged in)
- Find the authorisation header token section
- Important: The token shown will include "Bearer " at the beginning - do not include this prefix when adding it (Note the space after "Bearer", that needs to be removed too)
- Add the token to your
.envfile asHARDCOVER_API_KEYand to Actions secrets
Credits
Original project by melanie kat. Without her work, this fork would not exist.
Thank you also to xiffy for the Last.fm scrobble fetching service this uses.
Support
Did you find this useful like I did? Melanie asks that you donate to Trans Lifeline or The Trevor Project if you can. I will also add Belong To to that list.