updated README with support for new services

This commit is contained in:
dylan 2025-12-28 22:18:27 +00:00
parent 3faa24b283
commit 2165ce5bd3

195
README.md
View file

@ -2,13 +2,13 @@
Automatically updates your omg.lol Now page with your latest activity. Automatically updates your omg.lol Now page with your latest activity.
> Fork of [melanie/now-updater](https://source.tube/melanie/now-updater) with added support for HTML output links, Mastodon, Last.fm, and dynamic URLs. > Fork of [melanie/now-updater](https://source.tube/melanie/now-updater) with added support for HTML links, images/videos, Steam, Hardcover, some.pics, and simplified service configuration.
Demo: [dylan.omg.lol/now](https://dylan.omg.lol/now) Demo: [dylan.omg.lol/now](https://dylan.omg.lol/now)
## How It Works ## How It Works
Fetches content from RSS feeds, JSON feeds, and different services (Letterboxd, Trakt, Mastodon, Last.fm) and updates HTML or markdown links on your Now page. Runs every 3 hours via Forgejo Actions, only updating your page when changes are detected. 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.
### Example ### Example
Your Now page links will be automatically updated from this: Your Now page links will be automatically updated from this:
@ -37,15 +37,14 @@ to this:
[Pushed to repository](https://gitlab.com/username/project) [Pushed to repository](https://gitlab.com/username/project)
``` ```
**New in this fork**: Use service names as link text instead of URLs! Just write `<a href="service-link">servicename</a>` and the script fills in both the text and URL.
## Setup ## Setup
1. Fork this repo 1. Fork this repo
2. Enable Actions in repo settings 2. Enable Actions in repo settings
3. Add Actions variables: `OMGLOL_USERNAME` (your omg.lol username) 3. Add Actions variables: `OMGLOL_USERNAME` (your omg.lol username)
4. Add Actions secrets: `OMGLOL_KEY` (your API key), `TRAKT_SLURM` (optional, see [Trakt](#trakt) for details) 4. Add Actions secrets: `OMGLOL_KEY` (your API key)
5. Add your sources in `config.js` 5. Add optional secrets for services you want to use: `TRAKT_SLURM`, `STEAM_WEBAPI_KEY`, `HARDCOVER_API_KEY`
6. Activate your services in `services.js` by setting `isActive: true`
For local development, copy `.env.example` to `.env` with your credentials. For local development, copy `.env.example` to `.env` with your credentials.
@ -53,29 +52,34 @@ For local development, copy `.env.example` to `.env` with your credentials.
**Now page template:** **Now page template:**
```html ```html
I wrote this: [tktk](https://your-blog.com) I wrote this: <a href="https://your-blog.com">blog</a>
I watched this: [tktk](trakt.tv/users/username) I watched this: <a href="https://letterboxd.com/username">letterboxd</a>
I listened to: <a href="https://www.last.fm/user/username">lastfm</a>
``` ```
**config.js:** **services.js:**
```js ```js
export const linkFormat = 'markdown' export const services = [
export const items = [
{ {
id: 'blog', id: 'blog',
regex: htmlLinkRegex('your-blog.com'), isActive: true,
getLatest: async () => getJsonFeedItemTitle('https://your-blog.com/feed.json'), feedUrl: 'https://your-blog.com/feed.json',
feedType: 'json',
}, },
{ {
id: 'letterboxd', id: 'letterboxd',
regex: htmlLinkRegex('letterboxd.com/username'), isActive: true,
getLatest: async () => getLetterboxdActivity('username', true), // with image userId: 'your-username',
feedUrlTemplate: 'https://letterboxd.com/{userId}/rss/',
feedType: 'letterboxd',
showImage: true, // optional: include movie posters
}, },
{ {
id: 'trakt-movie', id: 'lastfm',
regex: htmlLinkRegex('trakt.tv/users/username'), isActive: true,
getLatest: async () => getTraktMovie('username', 'your-trakt-id', false), // text only userId: 'your-username',
feedUrlTemplate: 'https://lfm.xiffy.nl/{userId}',
feedType: 'rss',
}, },
] ]
``` ```
@ -95,81 +99,124 @@ export const items = [
{ {
id: 'gitlab', id: 'gitlab',
isActive: true, // just change this! isActive: true, // just change this!
regex: htmlServiceLinkRegex('gitlab'), userId: 'your-username',
feedUrl: 'https://gitlab.com/users/your-username/activity.atom', feedUrlTemplate: 'https://gitlab.com/users/{userId}/activity.atom',
feedType: 'atom', feedType: 'atom',
} }
``` ```
That's it! No importing, no commenting/uncommenting. 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 `id`s and matching link texts. Like so:
```js
{
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 ### Files
- **config.js** - Link format setting and filter logic (rarely needs editing) - **config.js** - Link format setting (`html` or `markdown`) and filter logic
- **services.js** - All available services with `isActive` flags (edit this to enable/disable services) - **services.js** - All available services with `isActive` flags (edit this to enable/disable services)
- **utils.js** - Generic feed handlers and special service logic - **utils.js** - Generic feed handlers and service-specific logic
### Service Structure ### Service Structure
Each service has: Each service has:
- `id`: identifier for logs - `id`: Identifier that matches the link text in your Now page (e.g., `id: 'blog-1'` matches `<a>blog-1</a>`)
- `isActive`: `true` to enable, `false` to disable - `isActive`: `true` to enable, `false` to disable
- `regex`: matches service name in your Now page - `feedType`: Handler to use (`rss`, `atom`, `json`, or special handler name like `letterboxd`, `steam`, `hardcover`)
- `feedType`: Handler to use (`rss`, `atom`, `json`, or special handler name like `mastodon`)
- `feedUrl`: Direct feed URL (use this for custom feeds without usernames) - `feedUrl`: Direct feed URL (use this for custom feeds without usernames)
- `feedUrlTemplate`: URL template with `{userId}` placeholder (use this for standard services) - `feedUrlTemplate`: URL template with `{userId}` or `{instance}` placeholders
- `userId`: Your username/ID (only needed with feedUrlTemplate) - `userId`: Your username/ID (only needed with feedUrlTemplate)
- Extra params as needed (e.g., `instance`, `steamId`, `traktId`, `showImage`) - `showImage`: Optional. Controls whether image/videos are included (defaults based on service)
- Extra params as needed (e.g., `instance` for federated services, `traktId` for Trakt widgets)
**Note**: Use either `feedUrl` (direct) OR `feedUrlTemplate` + `userId` (template). Both work! Set `linkFormat` in config.js to `'html'` or `'markdown'` depending on your Now page format.
Set `linkFormat` in config.js to `'html'` or `'markdown'`. ### Image and Video Support
## Available Functions Many services support optional images and videos:
- **Letterboxd**: Movie posters from CDATA descriptions
- **Trakt**: Episode/movie poster widgets (portrait orientation, change the URL from `poster` to `thumb` for landscape)
- **Hardcover**: Book cover images
- **Steam**: Game library posters
- **Mastodon**: Attached images and videos from `media:content` tags (iffy, may not always work)
- **some.pics**: Photo images from RSS CDATA
### Code Activity 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.
- `getSourceTubeActivity(username)` - Forgejo activity on source.tube
- `getGitLabActivity(username)` - GitLab activity feed
- `getCodebergActivity(username)` - Codeberg activity feed
### Content Creation ## Available Services
- `getYouTubeLatestVideo(channelId)` - Latest YouTube video (requires channel ID starting with "UC")
- `getVimeoLatestVideo(username)` - Latest Vimeo video
- `getTwitchLatestStream(channel)` - Latest Twitch stream/VOD (via TwitchRSS, no API key needed)
### Gaming All handlers now use a config object with consistent parameters. The `feedType` in services.js maps to these handlers.
- `getBackloggdActivity(username, showImage)` - Backloggd game activity with optional cover images
- `getExophaseActivity(username, showImage)` - Multi-platform gaming achievements
- `getSteamRecentlyPlayed(steamId)` - Recently played Steam game (requires STEAM_WEBAPI_KEY)
### Books ### Generic Feed Handlers
- `getGoodreadsActivity(userId, showImage)` - Goodreads activity (requires numeric user ID, not username) - `getRSSItemTitle(feedUrl)` - Standard RSS feeds
- `getHardcoverActivity(username)` - Currently reading books via GraphQL API - `getAtomFeed(url)` - Standard Atom feeds
- `getJsonFeedItemTitle(feedUrl, showImage)` - JSON feeds with optional images
### omg.lol Services
- `getSomePicsPost(feedUrl)` - some.pics photo posts with images extracted from CDATA
### Music ### Music
- `getListenBrainzScrobble(username)` - Latest music scrobble (open source Last.fm alternative) - `getListenBrainzScrobble(config)` - ListenBrainz scrobbles (not tested, let me know!)
- Config: `{ feedUrl, userId }`
- For Last.fm, use generic RSS handler with `https://lfm.xiffy.nl/{userId}`
### Social Media ### Social Media
- `getPixelfedPost(instance, username)` - Latest Pixelfed post from federated instance - `getMastodonPost(config)` - Latest non-reply Mastodon post with optional images/videos
- `getBlueskyPost(handle)` - Latest Bluesky post (note: links not clickable in RSS) - Config: `{ feedUrl, showImage }`
- Extracts media from `media:content` tags and filters out replies
### General/Legacy ### Movies & TV
- `getRSSItemTitle(feedUrl)` - Standard RSS feeds - `getLetterboxdActivity(config)` - Letterboxd activity with optional poster images
- `getJsonFeedItemTitle(feedUrl, showImage)` - JSON feeds - Config: `{ feedUrl, showImage }`
- `getLetterboxdActivity(username, showImage)` - Letterboxd activity - Extracts images from CDATA descriptions
- `getTraktEpisode(username, id, showImage)` - Latest TV episode - `getTraktEpisode(config)` - Latest TV episode with optional poster
- `getTraktMovie(username, id, showImage)` - Latest movie - Config: `{ userId, traktId, showImage }`
- `getTraktEpisodeAndMovie(username, id, showImage)` - Latest episode and movie combined - Requires `TRAKT_SLURM` environment variable
- `getMastodonPost(feedUrl)` - Latest non-reply Mastodon post - Uses portrait poster widgets
- `getMalojaScrobble(url)` - Latest music scrobble from [maloja](https://github.com/krateng/maloja) - `getTraktMovie(config)` - Latest movie with optional poster
- Config: `{ userId, traktId, showImage }`
- Requires `TRAKT_SLURM` environment variable
- Uses portrait poster widgets
### Books
- `getHardcoverActivity(config)` - Currently reading books with cover images
- Config: `{ userId, feedUrl }`
- Uses GraphQL API, requires `HARDCOVER_API_KEY`
- `userId` must be numeric user ID (not username)
### Gaming
- `getSteamRecentlyPlayed(config)` - Recently played Steam game with library poster
- Config: `{ userId }`
- Requires `STEAM_WEBAPI_KEY` environment variable
- `userId` must be Steam ID 64 (convert at https://steamid.io/)
### 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")
**Important Notes:** **Important Notes:**
- `showImage` (defaults to `true`) controls whether images/posters are included in the output. Set it to `false` to show text only. - `showImage` controls whether images/videos are included in the response
- For Last.fm, use `getRSSItemTitle('https://lfm.xiffy.nl/your-username')` (via [lfm.xiffy.nl](https://lfm.xiffy.nl)) - Images and videos are returned separately from text (as `{ text, url, image, video }`)
- **YouTube** requires channel ID (not username), find it in your channel's page source or URL - Generic RSS/Atom/JSON handlers work with most standard feeds
- **Goodreads** requires numeric user ID (found in profile URL after `/user/show/`)
- **Steam** requires Steam ID 64 (convert at https://steamid.io/)
- **Pixelfed** requires instance domain and username (e.g., `pixelfed.social`, `username`)
## API Keys Setup ## API Keys Setup
@ -179,19 +226,31 @@ To get your Trakt slurm key, follow these steps:
1. Go to your History page on Trakt: `https://trakt.tv/users/your-username/history` 1. Go to your History page on Trakt: `https://trakt.tv/users/your-username/history`
2. There should be an RSS feed icon on the top right of the page. Click it. 2. There should be an RSS feed icon on the top right of the page. Click it.
3. The URL it shows will look something like this: `https://trakt.tv/users/crankle/history.atom?slurm=your-slurm-key` 3. The URL it shows will look something like this: `https://trakt.tv/users/username/history.atom?slurm=your-slurm-key`
4. Copy the `slurm` value from the URL and add it as a secret in your Actions settings named `TRAKT_SLURM`. 4. Copy the `slurm` value from the URL and add it as a secret in your Actions settings named `TRAKT_SLURM`.
5. Add it to your `.env` file for local testing.
### Steam ### Steam
To get your Steam Web API key: To get your Steam Web API key:
1. Visit https://steamcommunity.com/dev/apikey 1. Visit https://steamcommunity.com/dev/apikey
2. Enter a domain name (can be localhost for personal use) 2. Enter a domain name (I used omg.lol, I don't know if that will cause me issues later)
3. Agree to the terms and get your API key 3. Agree to the terms and get your API key
4. Add it to your `.env` file as `STEAM_WEBAPI_KEY` or to Actions secrets 4. Add it to your `.env` as `STEAM_WEBAPI_KEY` and to Actions secrets
5. Find your Steam ID 64 at https://steamid.io/ (enter your profile URL) 5. 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:
1. Visit https://hardcover.app/account/api (Make sure you're logged in)
2. Find the authorisation header token section
3. **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)
4. Add the token to your `.env` file as `HARDCOVER_API_KEY` and to Actions secrets
## Credits ## Credits
Original project by [melanie kat](https://source.tube/melanie/now-updater). Without her work, this fork would not exist. Original project by [melanie kat](https://source.tube/melanie/now-updater). Without her work, this fork would not exist.