- Python 100%
| bot.py | ||
| cards.py | ||
| config.json | ||
| config.py | ||
| image.png | ||
| lastfm.py | ||
| LICENSE | ||
| mappings.py | ||
| matrix.py | ||
| README.md | ||
| requirements.txt | ||
MatrixFM
A Matrix bot for displaying user activity on Last.fm
Features
- Show the currently playing (or last played) track for any Last.fm user as a rendered card image
- Show a top artists or top tracks stats card for any Last.fm user across various time periods
- Automatically fetch and embed album/artist art into the card
- Map your Matrix account to a Last.fm username so you never have to type it again
- Customizable card background color per user, with presets and hex support
- Respond in multiple rooms, each with its own optional homeserver whitelist
Example activity card
Requirements
- Python 3.9+
- A Matrix account and access token for the bot
- A Last.fm API key
- Playwright with Chromium (used to render cards)
Installation
python3 -m pip install -r requirements.txt
playwright install chromium
playwright install-deps chromium
Configuration
On first run, a config.json template is created automatically. Fill in the required fields:
{
"MATRIX_HOMESERVER": "https://matrix.org",
"MATRIX_ACCESS_TOKEN": "your_token_here",
"MATRIX_USER_ID": "@matrixfm:matrix.org",
"ROOMS": [
{
"id": "!roomid:matrix.org",
"allowed_homeservers": ["matrix.org"]
}
],
"ALLOWED_HOMESERVERS": [],
"LASTFM_API_KEY": "your_lastfm_api_key"
}
| Field | Description |
|---|---|
MATRIX_HOMESERVER |
URL of your Matrix homeserver |
MATRIX_ACCESS_TOKEN |
Access token for the bot's Matrix account |
MATRIX_USER_ID |
Full Matrix user ID of the bot (e.g. @matrixfm:example.org) |
ROOMS |
List of rooms to respond in (see below). Set to [] to respond in all rooms |
ALLOWED_HOMESERVERS |
Global homeserver whitelist fallback (see below). Set to [] to allow all |
LASTFM_API_KEY |
Your Last.fm API key |
All fields can also be set as environment variables using the same names. Environment variables take precedence over config.json.
User-to-username mappings are stored separately in mappings.json, which is created automatically.
Multi-room support
The ROOMS field accepts a list of rooms. Each entry can be either a plain room ID string or an object with a per-room homeserver whitelist:
"ROOMS": [
{
"id": "!abc123:matrix.org",
"allowed_homeservers": ["matrix.org"]
},
{
"id": "!xyz456:example.org",
"allowed_homeservers": ["example.org", "matrix.org"]
},
"!public:matrix.org"
]
Set ROOMS to [] (or omit it) to respond in every room the bot is a member of.
Homeserver whitelists
Access can be restricted by the sender's homeserver at two levels:
| Level | Field | Behaviour |
|---|---|---|
| Per-room | allowed_homeservers inside a room object |
Only applies to that room |
| Global fallback | Top-level ALLOWED_HOMESERVERS |
Applies to rooms without their own whitelist |
The resolution order for any incoming message is:
- If the room has its own
allowed_homeserverslist → use that - Otherwise → use the top-level
ALLOWED_HOMESERVERSlist - If the effective list is empty → all homeservers are allowed
Messages from senders whose homeserver is not on the effective whitelist are silently ignored.
Example:
{
"ROOMS": [
{
"id": "!staff:company.org",
"allowed_homeservers": ["company.org"]
},
"!public:matrix.org"
],
"ALLOWED_HOMESERVERS": ["matrix.org", "example.org"]
}
!staff:company.orgonly accepts users fromcompany.org!public:matrix.orgfalls back to the global list (matrix.organdexample.org)
Legacy ROOM_ID / ROOM_IDS
The old ROOM_ID scalar and ROOM_IDS list fields are still supported and are automatically migrated to the ROOMS format on first run. It is recommended to update your config to the new format.
Environment variables
| Variable | Description |
|---|---|
ROOM_IDS |
Comma-separated room IDs (no per-room HS override; use config.json for that) |
ALLOWED_HOMESERVERS |
Comma-separated global homeserver whitelist |
Running
python3 bot.py
Press Ctrl-C to stop.
Commands
| Command | Description |
|---|---|
!np [username] |
Show what a Last.fm user is playing right now (or last played) |
!fm [username] |
Alias for !np |
!fmstats [username] [period] [artists|tracks] |
Show a top artists or top tracks stats card |
!setfm <username> |
Link your Matrix account to a Last.fm username |
!unsetfm |
Remove your Last.fm mapping |
!showfm |
Show your currently mapped Last.fm username and card colour |
!setcolor <preset|#hex> |
Set your card background colour |
!colors |
List all available colour presets |
Once you've used !setfm, you can run !np and !fmstats with no arguments and the bot will use your mapped account automatically.
Examples:
!np # uses your saved mapping
!np lastfm_username # look up any username directly
!fmstats # top artists, last 7 days, your mapping
!fmstats bob # top artists for user bob, last 7 days
!fmstats bob month # top artists for user bob, last month
!fmstats bob month tracks # top tracks for user bob, last month
!fmstats year tracks # top tracks for your mapping, last year
!fmstats year # top artists for your mapping, last year
!setfm lastfm_username # save your mapping
!unsetfm # remove your mapping
!showfm # check your mapping and card colour
!setcolor navy # set card background to a preset colour
!setcolor #1a1a2e # set card background to a hex colour
!setcolor reset # reset card background to default
!colors # list all colour presets
!fmstats periods
| Argument | Period |
|---|---|
week / 7day |
Last 7 days |
month / 1month |
Last month |
3month |
Last 3 months |
6month |
Last 6 months |
year / 12month |
Last year |
all / overall |
All time |
If no period is given, the last 7 days are used.
!fmstats modes
| Argument | Mode |
|---|---|
artists (default) |
Top 5 artists by scrobble count |
tracks |
Top 5 tracks by scrobble count, with artist name shown below each track |
If no mode is given, artists is used.
License
Distributed under the MIT License. See LICENSE for more information.
