Closed FoxxMD closed 2 months ago
Offline played track events from Symfonium (#87) manifest in JF as:
ActivityLogEntry
from the ActivityLog endpoint, but these only include timestamp the activity was received and the library item does not not get updated UserData so no LastPlayedDate is available
UserItemDataDto
) including LastPlayedDate which is what we needUnfortunately, the openapi spec/sdk does not have a good way to get all change events for all sessions in a way that is helpful because the offline events are registered in an "instantaneous" session by the client (android symfonium) IE the client connects to send change data and then disconnects -- if we are only using API polling its possible (probable) we will entirely miss the session being active unless polling interval is extremely short.
There is another solution: the websockets system bubbles all session data a user has access to which includes these short lived sessions. The data recieved is what I need:
{
"MessageId": "8e5e58bb1a104683b2bf1232d6955dbf",
"Data": {
"UserId": "1ae8a43ed293456da28274f1a89cd2a5",
"UserDataList": [
{
"PlaybackPositionTicks": 0,
"PlayCount": 1,
"IsFavorite": false,
"LastPlayedDate": "2024-08-29T17:00:19.9369451Z",
"Played": true,
"Key": "Ana Tijoux-1977-0001-0005Obst\u00E1culo",
"ItemId": "097bd1f3c949da7e0b7d4a0f52bae481"
},
{
"PlaybackPositionTicks": 0,
"PlayCount": 0,
"IsFavorite": false,
"Played": false,
"Key": "39f26414-6687-7c9b-adac-f506b347cb15",
"ItemId": "39f2641466877c9badacf506b347cb15"
}
]
},
"MessageType": "UserDataChanged"
}
More unfortunately, the JS sdk does not have a websocket api yet and the JF devs confirmed for me on matrix that the WS protocol is undocumented. I'll need to dig through the JF web client to figure out exactly what is going on.
Sidebar: The two UserDataList
entries in the ws message may explain why the jf webhook plugin was sending multiple events for one playback stopped action...
EDIT: Nope doesn't work. Even though the data from offline client (symfonium) is pushed by WS the LastPlayedDate
is still the LAST played date from being the offline play and not the actual timestamp when it was played offline. Checking the item after this data is pushed still shows the stale last played (not offline) so that's not useful either.
Additionally, and inconveniently, the WS data for sessions is only available if the authentication is done using a username/password so its not available to API authentication.
At this point I'm giving up on offline scrobbling because JF just doesn't surface the right info through its API and its impossible to coax it out. It may be stored/sent correctly (see all discussion in #87) but its not retrievable and might as well not exist.
Use docker image foxxmd/multi-scrobbler:pr-172
Must be using Jellyfin 10.7 or greater
http://YOUR_JELLYIN_URL/web/index.html#!/apikeys.html
)+
button and create a new key with App name multi-scrobbler
It is recommended to use API Key + username but if you are not an admin for your Jellyfin instance you can also authenticate with your Jellyfin username and password.
[
{
"name": "MyJellyfin",
"enable": true,
"clients": [],
"data": {
"url": "http://localhost:8096",
"user": "FoxxMD",
//either this
"password": "mypass"
// or this
"apiKey": "c9fa0875pfbf411ebb9c55b56bd6540c",
// optional
"usersAllowed": ["FoxxMD","SomeOtherUser"],
"usersBlocked": ["AnotherUser"],
"devicesAllowed": ["firefox"],
"devicesBlocked": ["google-home"]
},
"options": {
"logFilterFailure": "debug"
}
}
]
Environmental Variable | Required? | Default | Description |
---|---|---|---|
JELLYFIN_URL |
Yes | The URL of the Jellyfin server IE http://localhost:8096 |
|
JELLYFIN_USER |
Yes | The user to authenticate with the API | |
JELLYFIN_APIKEY |
No | The API Key to use for authentication (Must provide either apikey or password) | |
JELLYFIN_PASSWORD |
No | The password of the user to authenticate for. (Must provide either apikey or password) | |
JELLYFIN_USERS_ALLOWED |
No | Comma-separated list of usernames (from Jellyfin) to scrobble for | |
JELLYFIN_DEVICES_ALLOWED |
No | Comma-separated list of devices to scrobble from |
To play around with this PR, pull an image:
foxxmd/multi-scrobbler:pr-172
foxxmd/multi-scrobbler:pr-172-alpine
.Images are available for x86_64 and ARM64.
Latest commit: be30cdd54079d4233644ff4dfc16878039366db0
Edit: Nevermind my error in the original message. I had a typo in my jellyfin url. Now it works like a charm. Thanks for the work and fixing the old issue. Really appreciate it!
I will leave the original message in, in case someone else has a typo in their url :D.
Best, Karsten
Hi @FoxxMD
I am trying to test this new api connection. I get the following error:
multiscrobbler | [2024-08-30 08:18:54.543 +0200] DEBUG : [App] [Sources] (jellyfin_karsten) Constructing jellyfin source
multiscrobbler | [2024-08-30 08:18:54.553 +0200] DEBUG : [App] [Sources] [Jellyfin - jellyfin_karsten] Attempting to initialize...
multiscrobbler | [2024-08-30 08:18:54.556 +0200] VERBOSE: [App] [Sources] [Jellyfin - jellyfin_karsten] Building required data init succeeded
multiscrobbler | [2024-08-30 08:18:59.641 +0200] ERROR : [App] [Sources] [Jellyfin - jellyfin_karsten] Initialization failed
multiscrobbler | Error: Initialization failed
multiscrobbler | at JellyfinApiSource.initialize (CWD/src/backend/common/AbstractComponent.ts:50:31)
multiscrobbler | at runNextTicks (node:internal/process/task_queues:60:5)
multiscrobbler | at listOnTimeout (node:internal/timers:540:9)
multiscrobbler | at process.processTimers (node:internal/timers:514:7)
multiscrobbler | at ScrobbleSources.addSource (CWD/src/backend/sources/ScrobbleSources.ts:596:18)
multiscrobbler | at ScrobbleSources.buildSourcesFromConfig (CWD/src/backend/sources/ScrobbleSources.ts:497:25)
multiscrobbler | at <anonymous> (CWD/src/backend/index.ts:115:9)
multiscrobbler | caused by: Error: Communicating with upstream service failed
multiscrobbler | at JellyfinApiSource.checkConnection (CWD/src/backend/common/AbstractComponent.ts:176:19)
multiscrobbler | at runNextTicks (node:internal/process/task_queues:60:5)
multiscrobbler | at listOnTimeout (node:internal/timers:540:9)
multiscrobbler | at process.processTimers (node:internal/timers:514:7)
multiscrobbler | at JellyfinApiSource.initialize (CWD/src/backend/common/AbstractComponent.ts:40:13)
multiscrobbler | at ScrobbleSources.addSource (CWD/src/backend/sources/ScrobbleSources.ts:596:18)
multiscrobbler | at ScrobbleSources.buildSourcesFromConfig (CWD/src/backend/sources/ScrobbleSources.ts:497:25)
multiscrobbler | at <anonymous> (CWD/src/backend/index.ts:115:9)
multiscrobbler | caused by: TypeError: Cannot read properties of undefined (reading 'address')
multiscrobbler | at JellyfinApiSource.doCheckConnection (CWD/src/backend/sources/JellyfinApiSource.ts:163:51)
multiscrobbler | at runNextTicks (node:internal/process/task_queues:60:5)
multiscrobbler | at listOnTimeout (node:internal/timers:540:9)
multiscrobbler | at process.processTimers (node:internal/timers:514:7)
multiscrobbler | at JellyfinApiSource.checkConnection (CWD/src/backend/common/AbstractComponent.ts:163:25)
multiscrobbler | at JellyfinApiSource.initialize (CWD/src/backend/common/AbstractComponent.ts:40:13)
multiscrobbler | at ScrobbleSources.addSource (CWD/src/backend/sources/ScrobbleSources.ts:596:18)
multiscrobbler | at ScrobbleSources.buildSourcesFromConfig (CWD/src/backend/sources/ScrobbleSources.ts:497:25)
multiscrobbler | at <anonymous> (CWD/src/backend/index.ts:115:9)
My url is not with http but https (running it through a tailscale funnel). Could that be the problem?
Checklist before requesting a review
develop
branch and NOTmaster
.Type of change
Describe your changes
171