jmt-gh / audiobookshelf-sonos

Play your audiobooks from Audiobookshelf on your Sonos speakers
32 stars 5 forks source link

More detailed instruction #2

Open mxdalchau opened 1 year ago

mxdalchau commented 1 year ago

Hey,

could you write a more detailed instruction please?

thanks :)

jmt-gh commented 1 year ago

Could you be a bit more specific in what you're looking for? The "how to use" section is step by step on how to get things running. I'm more than happy to add additional information, but I'm not sure what exactly you're looking for

prolife86 commented 1 year ago

He might mean weather you are going to publish it on DockerHub? This might make it easier for people to implement. Just guessing here, and following this project with great interest!

mxdalchau commented 1 year ago

Hey, sorry my english is no t so good...

If i use docker-compose with docker file.. which file i should edit?

mxdalchau commented 1 year ago

so the docker-compose is running http://xxx.xxx.xxx.xxx:3333/wsdl

there is only a white site

could i see a log ... to analyze whats the problem

mreitschuster commented 1 year ago

I think a more detailed how-to might help. I am struggling with quite a few point:

  1. where can the file "soap-server.js" be found? it is described and when running without docker it seems to be the mian file ("run node soap-server.js") but I cannot find that file not found in this repo

Since I couldnt find it I tried via docker-compose

  1. docker-compose refers to node-docker but that cannot be found or installed.

    audiobookshelf-sonos Error  
    Error response from daemon: pull access denied for node-docker, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
  2. The "ABS_TOKEN=" likely stands for the audiobookshelf user token, that can be found when logging in as root and clicking on settings -> users -> specific username

  3. ABS_LIBRARY_ID= is not clear. Does it expect a ID (likely numeric) or the name of the library?

  4. are the modifications of config.js and sonos.wsdl also necessary when running via docker compose? if yes how does docker compose know which files to take - the only volumne defined there is sonos.wsdl?

jt196 commented 1 year ago

I've spent a bit of time looking at this and have a few answers to the above.

  1. The file is server.js, I think it's been renamed but the docs haven't been updated.
  2. The docker image isn't hosted anywhere, so you need to build it. If you cd into the cloned directory, and run the command docker build -t node-docker:latest, the command will run and it should work.
  3. Pretty sure this is correct.
  4. This is a bit confusing, if you've got just one library, I belive the id is just "main". If you have a second library, you can see the id in the URL, "lib_xxxx".
  5. I think you need to add the environment variables in the Docker compose, and modify the sonos.wsdl file as well. From what I can see, you need to avoid inverted commas in the docker-compose ENV variables.

Anyway, I've tried all these, and still not working.

jt196 commented 1 year ago

@jmt-gh, what sort of response should we be getting from the URLs: https://soap.server.com/wsdl or https://soap.server.com/manifest?

I get a 200 response but 0 bytes return from the /wsdl, and this response from the /manifest:

{
  "schemaVersion": "1.0",
  "endpoints": [
    {
      "type": "reporting",
      "uri": "https://soap.server.com/wsdl/playback/v2.1/report"
    }
  ]
}

Seems like there should be a bit more in the wsdl response at least.

By the way, if I use this for the env variable in the docker-compose:

- SOAP_URI="https://soap.server.com/wsdl"

The return from the manifest shows this:

      "uri": '"https://soap.server.com/wsdl"/playback/v2.1/report'

When I remove the "", it displays correctly.

mxdalchau commented 1 year ago

should the abs uri only a http or could be https?

mxdalchau commented 1 year ago

i get {"schemaVersion":"1.0","endpoints":[{"type":"reporting","uri":"https://soabs.xxxx.de/wsdl/playback/v2.1/report"}]} what is right, but i can´t access in sonos

jt196 commented 1 year ago

should the abs uri only a http or could be https?

I'd have thought whatever you have set up. Mine is https, so that's what I've put in.

mxdalchau commented 1 year ago

ok me too.. but the sonos app can´t read the libary

jt196 commented 1 year ago

Mine can't either, I get a connection error. There's no feedback on the log of the container, so it's quite hard to debug it.

mxdalchau commented 1 year ago

schade eigentlich wirkte das Projekt vielversprechend

robwalster commented 1 year ago

@jt196 did you ever get this working?

jt196 commented 1 year ago

@jt196 did you ever get this working?

Hacked away at it for half a day but never got it to work. I could add the service to Sonos by unchecking "Support Manifest File", that's about as far as I got. There were no logs on the Docker container when I tried to access it in Sonos, and Sonos itself have disabled a lot of the log checking functions in their speakers. I went a little through their docs, but had little success I'm afraid.

eendenhart commented 1 year ago

Hi! I set this up in a docker container on Unraid, Trial and error but it's running except cant find a way to access the library in the sonosapp. The docker log gives me this error: [getLibraryItems] Error caught. Error: Request failed with status code 404

jt196 commented 1 year ago

@eendenhart no idea, but maybe post how you got so far here so maybe we can get a solution together?

404 is just a not found error, so likely you've entered the audiobookshelf URL incorrectly.

eendenhart commented 1 year ago

I think the url is correct; I checked many times. I got a connection in audiobookshelf: when i typ the wrong token he gives in the logs of audiobookshelf an error.

What i did:

  1. create a directory: /mnt/user/appdata/audiobookshelf-sonos
  2. cloned the repository to this folder
  3. Update the sonos.wsdl file with my SOAP_URI
  4. create the docker image: execute in the unraid terminal docker build /mnt/user/appdata/audiobookshelf-sonos
  5. renamed this docker image: node-docker docker tag 'containerid' node-docker
  6. created the container from my dockerhub: https://hub.docker.com/r/eendenhart/audiobookshelf-sonos/
  7. changed the repository in node-docker:latest
  8. port: 80:3333
  9. added ENV-variables: SOAP_URI, ABS_URI, ABS_LIBRARY_ID, ABS_TOKEN, SONOS_WSDL_FILE, SOAP_ENDPOINT
  10. add volume: /mnt/user/appdata/audiobookshelf-sonos:/app/sonos.wsdl

I got the error [getLibraryItems] Error caught. Error: Request failed with status code 404 when i hit the services in sonos

robwalster commented 1 year ago

@jt196 did you ever get this working?

Hacked away at it for half a day but never got it to work. I could add the service to Sonos by unchecking "Support Manifest File", that's about as far as I got. There were no logs on the Docker container when I tried to access it in Sonos, and Sonos itself have disabled a lot of the log checking functions in their speakers. I went a little through their docs, but had little success I'm afraid.

I've put a bit of time into this today and got a little further but still not working.

First of all I turned on debugging in the servert.js file by uncommenting line 37. Now we can see incoming requests and how the SOAP server responds.

Now for what I had been doing wrong:

  1. I forgot to update the supplied sonos.wsdl with my SOAP_URI on line 2062
  2. when adding the service to sonos for the secure endpoint don't use https, just use http (unless of course, you have the endpoint running on https)
  3. The library ID isn't "main", nor did mine start with "lib_", in audiobookshelf open your library and it's in the url: "http://127.0.0.1:13378/library/[YOUR LIBRARY ID]", alternatively get it with curl following the instructions here: https://api.audiobookshelf.org/#libraries

The first few requests go through and seem to make it to audiobookshelf, however I'm hitting a wall with the error:

TypeError: Cannot read properties of undefined (reading 'id')

Edit: A bit more digging and I got there. Comment out lines: 104, 105, 106, 107, 108, 139, 140, 141, 142, 144, 145 in utils.js. It seems if you have any book metadata missing (author, narrator, album art etc) it causes the wrong data to be returned. after commenting out these lines Sonos finally connects to audio book shelf and shows my library.

However, it still does not play any of the books, saying Sonos is unable to connect. I suspect the function getMediaMetadata on line 16 of sonos-service.js needs completing.

jt196 commented 1 year ago

@robwalster I've played around a little bit and made no progress at all. Some pointers that might be useful.

  1. If you're running Dockerised (and it might be worth trying to run this outside a docker environment, as it can definitely cause issues!), then try adding nodemon to the Dockerfile. If you're sharing the local files, you won't have to restart the dev container.
FROM node:16-alpine
ENV NODE_ENV=production

WORKDIR /app

COPY ["package.json", "package-lock.json", "./"]

RUN npm install --production && npm install -g nodemon

COPY . .

CMD ["nodemon", "server.js"]
  1. Navigate to the page http:///wsdl and see if the wsdl file is served there. I can't see one, maybe I got some stuff wrong. I can't see anything on my Sonos app. If you can, I'd be interested in knowing a bit more about your env variables.
  2. Instead of commenting out the utils, try this code. It'll just enter null if they're empty. You may want to replace the null with '' if that breaks anything.

async function buildLibraryMetadataResult(res) { if (!res || !res.results) { return null; } let libraryItems = res.results; let count = res.total; let total = count; let mediaMetadata = []; for (const libraryItem of libraryItems) { if (!libraryItem || !libraryItem.media || !libraryItem.media.audioFiles || !libraryItem.media.audioFiles[0]) { continue; } let authorId = libraryItem.media.metadata && libraryItem.media.metadata.authors && libraryItem.media.metadata.authors[0] ? libraryItem.media.metadata.authors[0].id : null; let authorName = authorId ? libraryItem.media.metadata.authors[0].name : null; let narratorId = libraryItem.media.metadata && libraryItem.media.metadata.narrators && libraryItem.media.metadata.narrators[0] ? libraryItem.media.metadata.narrators[0].id : null; let narratorName = narratorId ? libraryItem.media.metadata.narrators[0].name : null; var mediaMetadataEntry = { itemType: "audiobook", id: libraryItem.id, mimeType: libraryItem.media.audioFiles[0].mimeType, canPlay: true, canResume: true, title: libraryItem.media.metadata ? libraryItem.media.metadata.title : null, summary: libraryItem.media.metadata ? libraryItem.media.metadata.description : null, authorId: authorId, author: authorName, narratorId: narratorId, narrator: narratorName, albumArtURI: `${ABS_URI}${libraryItem.media.coverPath}?token=${ABS_TOKEN}`, }; mediaMetadata.push(mediaMetadataEntry); } return { getMetadataResult: { count: count, total: total, index: 0, mediaCollection: mediaMetadata, }, }; } async function buildAudiobookTrackList(libraryItem, progressData) { if (!libraryItem || !libraryItem.media || !libraryItem.media.audioFiles) { return null; } let tracks = libraryItem.media.audioFiles; let icount = tracks.length; let itotal = tracks.length; let imediaMetadata = []; for (const track of tracks) { let authorId = libraryItem.media.metadata && libraryItem.media.metadata.authors && libraryItem.media.metadata.authors[0] ? libraryItem.media.metadata.authors[0].id : null; let authorName = authorId ? libraryItem.media.metadata.authors[0].name : null; let narratorId = libraryItem.media.metadata && libraryItem.media.metadata.narrators && libraryItem.media.metadata.narrators[0] ? libraryItem.media.metadata.narrators[0].id : null; let narratorName = narratorId ? libraryItem.media.metadata.narrators[0].name : null; var mediaMetadataEntry = { id: `${libraryItem.id}/${track.metadata.filename}`, itemType: "track", title: track.metadata.filename, mimeType: track.mimeType, trackMetadata: { authorId: authorId, author: authorName, narratorId: narratorId, narrator: narratorName, duration: track.duration, book: libraryItem.media.metadata ? libraryItem.media.metadata.title : null, albumArtURI: `${ABS_URI}${libraryItem.media.coverPath}?token=${ABS_TOKEN}`, canPlay: true, canAddToFavorites: false, }, }; imediaMetadata.push(mediaMetadataEntry); } let positionInformation = {}; if (progressData) { positionInformation = { id: `${libraryItem.id}/${progressData.partName}`, index: 0, offsetMillis: Math.round(progressData.relativeTimeForPart * 1000), }; } return { getMetadataResult: { count: icount, total: itotal, index: 0, positionInformation: positionInformation, mediaMetadata: imediaMetadata, }, }; }

Edit, 'scuse the crappy formating, didn't want to paste the whole lot here but the details tags don't play well with code.

jt196 commented 1 year ago

OK it appears to be an issue with the buildLibraryMetadata function.

This is an object being fed into the loop:

{
  id: '70edd71c-0088-49b8-8ea5-210c8049ce09',
  ino: '370123',
  oldLibraryItemId: 'ab_vm3xuee9z2z7krgw7q',
  libraryId: '96cfd553-cc4e-4a9b-9f67-866838eb62d7',
  folderId: '92fb9312-b5e2-4aae-b1d4-96fd7e521299',
  path: '/audiobooks/C.S. Forester/The Good Shepherd',
  relPath: 'C.S. Forester/The Good Shepherd',
  isFile: false,
  mtimeMs: 1594763569000,
  ctimeMs: 1641490864998,
  birthtimeMs: 1641490864998,
  addedAt: 1646732242162,
  updatedAt: 1646820362213,
  isMissing: false,
  isInvalid: false,
  mediaType: 'book',
  media: {
    id: '43c51480-1e3c-4b50-88b7-b7f045065474',
    metadata: {
      title: 'The Good Shepherd',
      titleIgnorePrefix: 'Good Shepherd, The',
      subtitle: null,
      authorName: 'C.S. Forester',
      authorNameLF: 'Forester, C.S.',
      narratorName: 'Edoardo Ballerini',
      seriesName: '',
      genres: [Array],
      publishedYear: '2020',
      publishedDate: null,
      publisher: 'Podium Audio',
      description: 'The Good Shepherd is now a major motion picture, Greyhound , scripted by and starring Tom Hanks, directed by Aaron Schneider, and produced by Gary Goetzman. A convoy of 37 merchant ships is ploughing through icy, submarine-infested North Atlantic seas during the most critical days of World War II, when the German submarines had the upper hand and Allied shipping was suffering heavy losses. In charge is Commander George Krause, an untested veteran of the US Navy. Hounded by a wolf pack of German U-boats, he faces 48 hours of desperate peril trapped the bridge of the ship. Exhausted beyond measure, he must make countless and terrible decisions as he leads his small fighting force against the relentless U-boats.',
      isbn: null,
      asin: '1774244152',
      language: 'English',
      explicit: false,
      abridged: false
    },
    coverPath: '/audiobooks/C.S. Forester/The Good Shepherd/The Good Shepherd - 001.mp3',
    tags: [],
    numTracks: 17,
    numAudioFiles: 17,
    numChapters: 33,
    numMissingParts: 0,
    numInvalidAudioFiles: 0,
    duration: 28401.437333,
    size: 454976356,
    ebookFormat: null
  },
  numFiles: 17,
  size: 454976356
}

The function expects:

None of these exist in the object, so no wonder it's not returning any results.

According to the API docs, these should be returned in library > library item > book

But for some reason, it's not doing that.

The reason I can see, looks like expected behaviour, getting library items will not retrieve the expected data. The audioFiles and the metadata.authors, metadata.narrators simply aren't there.

jt196 commented 1 year ago

With the data logging, this amended function will return a soap style object in the console:

async function buildLibraryMetadataResult(res) {
  if (!res || !res.results) {
    return null;
  }

  let libraryItems = res.results;
  let total = count;
  let mediaMetadata = [];

  for (const libraryItem of libraryItems) {

    var mediaMetadataEntry = {
      itemType: "audiobook",
      id: libraryItem.id,
      canPlay: true,
      canResume: true,
      title: libraryItem.media.metadata
        ? libraryItem.media.metadata.title
        : null,
      summary: libraryItem.media.metadata
        ? libraryItem.media.metadata.description
        : null,
      author: libraryItem.media.metadata.authorName,
      narrator: libraryItem.media.metadata.narratorName,
      albumArtURI: `${ABS_URI}${libraryItem.media.coverPath}?token=${ABS_TOKEN}`,
    };

    mediaMetadata.push(mediaMetadataEntry);
  }

  return {
    getMetadataResult: {
      count: count,
      total: total,
      index: 0,
      mediaCollection: mediaMetadata,
    },
  };
}

But I still can't get it to show the items...

jt196 commented 1 year ago

I've tried a bunch of stuff and still can't get it to work.

The soap server is working correctly, and returning a correct response, with a properly structured soap xml. I've tested this on SoapUI - even to the point where I'm using the stock responses in the docs here and they still don't work.

I'm wondering at this point whether the customsd form is being filled incorrectly. It's polling the server and SoapUI, but not happy with the result.

Maybe unchecking the "Support Manifest File" is causing the issue? I can't add the service if I don't do this.

jt196 commented 1 year ago

I've put the updated/worked on files in a new repo. They should maybe get some folks a bit further along the line.

I've also added notes about testing, debugging etc. Still can't get it working though!

jmt-gh commented 1 year ago

:wave: Hello all. Sorry for not being particularly active on this project. I can't commit to helping resolve everything here, but I'll try and get things up and running locally again and see if there are any glaring issues I find.

A few things to note:

jmt-gh commented 1 year ago

tl;dr: I was able to get things up easily still, but not necessairly fully funcitonal and running. The latter due to API changes in ABS.

OK, made some progress debugging. A few things:

Some initial things I had to change to make some progress:

  1. I had to go get a new library ID. Looks like ABS updated their formatting for that. It is now something more akin to a UUID
  2. It was crashing all over buildLibraryMetadataResults

    • This is the method that actually takes the library results (which come back successfully) from ABS and formats them in a way to hand off to the SOAP server for SONOS to read. Things here got busted at some point due to ABS API updates.
    • At first it was just hard crashing to a white screen in the sonos app.
    • After updating some of the building of mediaMetadataEntry to comment out things that weren't being responded, I was able to get the SONOS app to start displaying my library
    • The "new" version of mediaMetadataEntry:

      for (const libraryItem of libraryItems) {
      // https://developer.sonos.com/build/content-service-add-features/save-resume-playback/
      var mediaMetadataEntry = { 
      itemType: "audiobook",
      id: libraryItem.id,
      //mimeType: libraryItem.media.audioFiles[0].mimeType,
      canPlay: true,
      canResume: true,
      title: libraryItem.media.metadata.title,
      summary: libraryItem.media.metadata.description,
      //authorId: libraryItem.media.metadata.authors[0].id,
      //author: libraryItem.media.metadata.authors[0].name,
      //narratorId: libraryItem.media.metadata.narrators[0].id,
      //narrator: libraryItem.media.metadata.narrators[0].name,
      //albumArtURI: `${ABS_URI}${libraryItem.media.coverPath}?token=${ABS_TOKEN}`,
      };  
      
      mediaMetadata.push(mediaMetadataEntry);
      }   

I'll keep poking around, as well as update this repo with the new "debugging support" I've added to a few of thes methods to help. My gut is telling me there's a decent chunk of work that needs to be done here to get it working though, or at least working to the level it was prior. That said, the initial issues that were had in this issue definitely weren't related to this, and were most likely just environmental set up issues.

jmt-gh commented 1 year ago

Some more progress:

Had to comment out some more due-to-API-changes fields:

async function buildAudiobookTrackList(libraryItem, progressData) {
  let tracks = libraryItem.media.audioFiles;
  let icount = tracks.length;
  let itotal = tracks.length;
  let imediaMetadata = []; 

  for (const track of tracks) {
    var mediaMetadataEntry = { 
      id: `${libraryItem.id}/${track.metadata.filename}`,
      itemType: "track",
      title: track.metadata.filename,
      mimeType: track.mimeType,
      trackMetadata: {
        authorId: libraryItem.media.metadata.authors[0].id,
        author: libraryItem.media.metadata.authors[0].name,
        //narratorId: libraryItem.media.metadata.narrators[0].id,
        //narrator: libraryItem.media.metadata.narrators[0].name,
        duration: track.duration,
        book: libraryItem.media.metadata.title,
        albumArtURI: `${ABS_URI}${libraryItem.media.coverPath}?token=${ABS_TOKEN}`,
        canPlay: true,
        canAddToFavorites: false,
      },  
    };  

    imediaMetadata.push(mediaMetadataEntry);
  }

This brings SONOS to actually trying to play the file, but throws an error modal in the app that says "Part01.mp3 is no longer available on audiobookshelf" which is interesting. Though the soap part of the server is actively running and participating at this point, as indicated by these messages in the docker output:

audiobookshelf-sonos    | getMediaURI called
audiobookshelf-sonos    | [soapServer] /playback/v2.1/report/timePlayed called
audiobookshelf-sonos    | [soapServer] /playback/v2.1/report/timePlayed called
audiobookshelf-sonos    | oh it got called?

which is great

jmt-gh commented 1 year ago

ABS API reference: https://api.audiobookshelf.org

jmt-gh commented 1 year ago

OK. More progress.

I have audio streaming to the speakers again.

This is the function that actually generates the URL telling the speaker where to fetch the audio from. As with the other breakages, this is no longer valid, in a variety of ways.

async function buildMediaURI(id) {
  let path = `${ABS_URI}/s/item/${id}?token=${ABS_TOKEN}`;

  return {
    getMediaURIResult: path,
  };
}

The path needed now resembles something like: <ABS_URI>/api/items/<library_id>/file/<file_id>?token=<auth_token>. Hardcoding path to be the appropriate URL using an auth token from a web session, and the audio starts playing.

This brings up a couple things:

  1. The library item id we've been getting has been updated to a UUID similarly to the library id.
  2. The library item id we had previously been using doesn' seem particularly relevant here
  3. A new API needs to be implemented to get the file_id (which points to the MP3 to play)
jmt-gh commented 1 year ago

Number 3 doesn't need to happen. It's available in the libraryItem as the ino field already

jmt-gh commented 1 year ago

I've got everything working right now aside from getting progress and setting new progress (you can browse the library, select an audiobook, it will play, you can seek in the file, and seek to other files, etc. it just always starts from the first file in the book) It's definitely possible, just requires some mucking around. I'll look to get to it later this weekend

jmt-gh commented 1 year ago

just reread through most of the comments.

@eendenhart , your 404 is indicative of the ABS API changes. It should be resolved once I push the next update.

@jt196 , there shouldn't be any issues with this running in docker. My debugging session tonight was on a different machine than I initially developed this on leveraging the container. If you've found specific issues with it, let me know, but ideally all troubleshooting is done within the container so we can eliminate variables. As well, the compose file will automatically build the latest local audiobookshelf-sonos/ folder (and can rebuild with docker-compose up --build), which should make it easier for both development and running "production"

jt196 commented 1 year ago

@jmt-gh thanks for dropping in. Appreciate folks don't always have the time to devote to these projects!

Do you want to update the repo with your working code, that would be helpful.

Couple of points.

  1. I couldn't get my set up to work with a URL, it just doesn't poll the backend, well it does but only getLastUpdate function - which it requests and receives a correct response. My settings are:

    • Service Name: audiobookshelf
    • Endpoint URL: http://soap.my_url.com/wsdl
    • Secure Endpoint URL: https://soap.my_url.com/wsdl
    • Polling interval: 10
    • Authentication SOAP header policy: Anonymous
    • Manifest
      • Version: 1.0
      • URI: https://soap.my_url.com/manifest
    • Support manifest file: unchecked - I can't add the service if I check this.

If I use the IP address for the service:

The response with the library data logs to the console.

It looks like this:

[replied] <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://www.sonos.com/Services/1.1"><soap:Body><getMetadataResponse xmlns="http://www.sonos.com/Services/1.1"><getMetadataResult><count>85</count><total>85</total><index>0</index><mediaCollection><itemType>audiobook</itemType><id>74162736-8a64-4b10-a0fc-4c431b398e47</id><canPlay>true</canPlay><canResume>true</canResume><title>Live At the Purple Onion</title><summary xsi:nil="true"></summary></mediaCollection><mediaCollection><itemType>audiobook</itemType><id>59a84934-7a93-48c1-a4f9-837c23e78d24</id><canPlay>true</canPlay><canResume>true</canResume><title>Derek and Clive - Ad Nauseam</title><summary xsi:nil="true"></summary></mediaCollection><mediaCollection><itemType>audiobook</itemType><id>6741e0a4-2468-45be-ac7c-6bce300621b5</id><canPlay>true</canPlay><canResume>true</canResume><title>No Reason To Complain</title><summary xsi:nil="true"></summary></mediaCollection>

Concatenated here, but it looks correctly formed.

  1. Port number: I wonder whether the port number should be different. In my config I have HTTP_PORT: 80 - which is the internal port for the docker container, external being 3333.

  2. mediaCollection vs mediaMetadata. In the buildLibraryMetadataResult function, you're returning this object:

  return {
    getMetadataResult: {
      count: count,
      total: total,
      index: 0,
      mediaCollection: mediaMetadata,
    },
  };

From reading the Sonos docs, it looks more appropriate to just use mediaMetadata: mediaMetadata, as this fits in with a list of all the tracks/audiobooks, rather than a collection of media (genres, artists etc).

  1. Would you be able to provide a little more detail on the customsd settings you have working? The sonos app version/platform would also be useful. I'm using v1, so maybe that's the issue.

I can get the response working, but still no library display. All in all, quite frustrating!

kontiko commented 10 months ago

For me to get the Playback working i had to change the beginning of buildAudiobookTracklist to:

async function buildAudiobookTrackList(libraryItem, progressData) {
  console.log("MEDIA");
  console.log(libraryItem)
  let tracks = libraryItem.media.audioFiles;
  let icount = tracks.length;
  let itotal = tracks.length;
  let imediaMetadata = []; 

  for (const track of tracks) {
    var mediaMetadataEntry = { 
      id: `${libraryItem.media.libraryItemId}/file/${track.ino}`,

and buildMEdiaURI to:

async function buildMediaURI(id) {
  let path = `${ABS_URI}/api/items/${id}?token=${ABS_TOKEN}`;

  return {
    getMediaURIResult: path,
  };
}
jmt-gh commented 9 months ago

Hellooooo. I recognize I never pushed up the update I had mentioned. Sorry about that.

I'm actively working on getting things back to a fully working state. Currently the only thing not working is having progress updated on ABS when listening on Sonos. From my last update, getting progress down from ABS was broken as well. That's been updated with a patch that looks something like this diff:

@@ -151,13 +157,19 @@ async function buildAudiobookTrackList(libraryItem, progressData) {

   let positionInformation = {};
   if (progressData) {
+ try {
+    console.log(`[buildAudiobookTrackList] There was progressData!`)
     positionInformation = {
-      id: `${libraryItem.id}/${progressData.partName}`, // li_{string}/Part##.mp3
+      id: `${libraryItem.id}/file/${progressData.partName}`, // UUID-ITEM-ID/12345
       index: 0,
       // 1) Sonos gets upset if there are too many decimals
       // 2) ABS returns everything in seconds, so multiple by 1000 for milliseconds for sonos
       offsetMillis: Math.round(progressData.relativeTimeForPart * 1000),
     };

Current issue with getting updates back up to ABS is that the sonos side of things just doesn't seem to be trying to reach out to the update endpoint in server.js. I see it reaching out to /manifest, but nothing beyond that.

jmt-gh commented 9 months ago

progress!

I added some logging to server.js, to track every endpoint trying to be hit, be it existing or not:

diff --git a/server.js b/server.js
index 89b49ed..f97e9f3 100644
--- a/server.js
+++ b/server.js
@@ -14,6 +14,10 @@ const SONOS_WSDL_FILE = config.SONOS_WSDL_FILE;
 /**********/

 EXPRESS_APP.use(express.json()); // express.json allows for native body parsing
+EXPRESS_APP.use((req, res, next) => {
+        console.log(`Received request: ${req.method} ${req.url}`);
+       next();
+});

and noticed this requests for progress updates:

audiobookshelf-sonos  | Received request: POST /wsdl
audiobookshelf-sonos  | Received request: POST /wsdl/playback/v2.1/report/timePlayed
audiobookshelf-sonos  | Received request: POST /wsdl
audiobookshelf-sonos  | Received request: POST /wsdl/playback/v2.1/report/timePlayed

specifically the /wsdl/ part at the beginning of POST /wsdl/playback/v2.1/report/timePlayed stood out, as I didn't have that on the routes defined in server.js.

Adding this diff, and I'm not starting ot see progress requests hitting properly, and further code getting processed now:

+  EXPRESS_APP.post(`${SOAP_ENDPOINT}/playback/v2.1/report`, (req, res) => {
     console.log("[soapServer] /playback/v2.1/report called");
   });
+       

-  EXPRESS_APP.post("/playback/v2.1/report/timePlayed", (req, res) => {
+  EXPRESS_APP.post(`${SOAP_ENDPOINT}/playback/v2.1/report/timePlayed`, (req, res) => {
     console.log("[soapServer] /playback/v2.1/report/timePlayed called");

Still looking in to making sure ABS updates the progress properly.

jmt-gh commented 9 months ago

Andddd I think this is the last of it. Similar to a lot of the other changes, it just needed to be moved from the old file name syntax to the new UUID/file-ino syntax.

async function buildProgress(libraryItem, updateObject) {
-  let partId = updateObject.libraryItemIdAndFileName.split("/")[1]; // li_{string}/Part##.mp3
+  //let partId = updateObject.libraryItemIdAndFileName.split("/")[1]; // li_{string}/Part##.mp3
+  let partId = updateObject.libraryItemIdAndFileName.split("/")[2]; // ITEM-UUID/file/12345 -> 12345
+  console.log(`[buildProgress] partId: ${partId}`)
   let audioFiles = libraryItem.media.audioFiles;
+  console.log(`[buildProgress] audioFiles: ${JSON.stringify(audioFiles, null, 2)}`)
+
   let res = {
     progress: updateObject.positionMillis / 1000, // abs tracks progress in seconds
     bookDuration: audioFiles
       .map((audioFile) => audioFile.duration)
       .reduce((result, item) => result + item),
   };
+  console.log(`[buildProgress] res: ${JSON.stringify(res, null, 2)}`)

   for (const audioFile of audioFiles) {
-    let filename = audioFile.metadata.filename;
+    let filename = audioFile.ino;

     if (filename == partId) {
       // only grab as much duration as up to the part we are currently at
jmt-gh commented 9 months ago

I've merged all of the fixes I have right now in to the main branch. I still need to update the README, and add more appropriate logging / logging levels.

jmt-gh commented 9 months ago

README has been updated. It focuses now on configuring the docker-compose.yml file, rather than the conflicting compose file + config file which was confusing before.

jmt-gh commented 9 months ago

Anddd improved logging has been put in place. At least in the sense that there should now be some level of logging for most things -- if they are useful or not.. that's a different story haha.

Please feel free to give all of this with the new readme a shot, and let me know how things go.

mxdalchau commented 9 months ago

hey nice.. step by step... if i want to open audiobookservice in sonos ... i get the message:

Durchsuchen der Musikdateien nicht möglich

but the logs... generate a information from my audiobookshelf

jmt-gh commented 9 months ago

This occurs when the Custom Service Descriptor is set up properly, but the app doesn't received anything when you browse to it.

Most likely either the configuration in the docker-compose file is incorrect, or your speakers are unable to communicate with the server / application.

If you post the log output here it could potentially help diagnose the issue. You'll want the full log output of you opening the app, clicking the ABS entry in the sonos app, etc.

I would also double check the environment configurations are correct in the docker-compose.yml file. The values should not be wrapped in quotes, and you need to ensure the ABS library ID and API key are accurate

jt196 commented 9 months ago

OK dude, just retrying this.

FYI The git clone command currently in the Readme is erroring out, I changed the url to https://github.com/jmt-gh/audiobookshelf-sonos.git and it clones fine. Assume the given URL (git@github.com:jmt-gh/audiobookshelf-sonos.git) might be for the owner of the repo/require credentials?

As per @mxdalchau and my previous experience, I'm getting an "Unable to browse music" message. I've tested this now on a smaller library as well as a test one with just 4 items. Neither works.

The logs produce a list of library items. Here's my logs:

[2024-01-22T11:14:23.852Z] [DEBUG] [Unknown - Unknown:Unknown] Received request: GET /manifest 

[2024-01-22T11:14:23.853Z] [INFO] [Unknown - Unknown:Unknown] /manifest endpoint hit 

[2024-01-22T11:14:28.222Z] [DEBUG] [Unknown - Unknown:Unknown] Received request: POST /wsdl 

[2024-01-22T11:14:28.233Z] [DEBUG] [Unknown - Unknown:Unknown] Received request: POST /wsdl 

[2024-01-22T11:14:28.237Z] [DEBUG] [getMetadata - /app/sonos-service.js:8] getMetadata sonos-service called with args {"id":"root","index":0,"count":100}

[2024-01-22T11:14:28.238Z] [INFO] [getLibraryItems - /app/utils.js:17] Fetching library item at: "https://audiobooks.domain.com/api/libraries/<library_id>/items"

[2024-01-22T11:14:28.305Z] [DEBUG] [buildLibraryMetadataResult - /app/utils.js:116] libraryItem for mediaMetadataEntry: {"id":"022f5ead-e66e-4592-a6bc-bea084ae4f01","ino":"369861","oldLibraryItemId":null,"libraryId":"571b1e8a-e2ac-47fb-b0a1-f0f8d7ec15e3","folderId":"1c6a556e-623a-4e53-bb86-29a32c849558","path":"/audiobooks/Alan Partridge/From the Oasthouse The Alan Partridge Podcast","relPath":"From the Oasthouse The Alan Partridge Podcast","isFile":false,"mtimeMs":1601981799000,"ctimeMs":1694594837580,"birthtimeMs":1694594837580,"addedAt":1705921897649,"updatedAt":1705921897649,"isMissing":false,"isInvalid":false,"mediaType":"book","media":{"id":"a1fedd4d-3533-45cb-9151-9dfd257bc4a2","metadata":{"title":"From the Oasthouse: The Alan Partridge Podcast: An Audible Original","titleIgnorePrefix":"From the Oasthouse: The Alan Partridge Podcast: An Audible Original","subtitle":null,"authorName":"Alan Partridge","authorNameLF":"Partridge, Alan","narratorName":"Alan Partridge","seriesName":"","genres":["Comedy, Podcast"],"publishedYear":"2020","publishedDate":null,"publisher":null,"description":"Broadcaster, writer, philanthroper and one of the first public figures to suggest high-visibility clothing for people manning temporary car parks, the public Alan Partridge is a cherished institution. But what of the unseen Alan? For the first time, this","isbn":null,"asin":null,"language":null,"explicit":false,"abridged":false},"coverPath":"/audiobooks/Alan Partridge/From the Oasthouse The Alan Partridge Podcast/From the Oasthouse The Alan Partridge Podcast An Audible Original.jpg","tags":[],"numTracks":1,"numAudioFiles":1,"numChapters":17,"numMissingParts":0,"numInvalidAudioFiles":0,"duration":24274.279909,"size":385577371},"numFiles":3,"size":385894072}
... the rest of the library below

I can also confirm that if I make a Postman GET request to the ABS url with the login credentials, it returns a list of library items.

So the request for information is producing a list of metadata, but that for whatever reason isn't displaying in the Sonos app.

Incidentally, I finally ran the Sonos v2 upgrade, thinking this might be the culprit. It seems to have helped adding the service with the "support manifest file" checked, but still producing this error.

I've also played around with changing the SOAP_URI variable, but adding /wsdl to the end doesn't seem to solve it. Incidentally, the list of library items is produced regardless of whether the SOAP_URI is entered correctly, but the getMetadata and getLibraryItems aren't logged if it's incorrect.

Here's my docker compose settings if you notice any glaring errors. No quotes have been used here:

version: "3.8"

services:
  audiobookshelf-sonos:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: audiobookshelf-sonos
    environment:
      - SOAP_URI=https://soap.domain.com # also tried with /wsdl
      - ABS_URI=https://audiobooks.domain.com
      - ABS_LIBRARY_ID=<my_library_id>
      - ABS_TOKEN=<redacted>
      - LOG_LEVEL=debug # set to debug, info, warn, error
    ports:
      - 3333:80
    volumes:
      - ./sonos.wsdl:/app/sonos.wsdl

sonos.wsdl:

    <wsdl:service name="Sonos">
        <wsdl:port name="SonosSoap" binding="tns:SonosSoap">
        <soap:address location="https://soap.domain.com"/> <!-- UPDATE WITH SOAP_URI -->
        </wsdl:port>
    </wsdl:service>

Note, also changing this to https://soap.domain.com/wsdl doesn't fix anything.

/customsd.htm

Secure endpoint URL: https://soap.domain.com/wsdl
Polling interval: 10
Authentication SOAP header policy: Anonymous
Manifest: 
    version: 1
    URI: https://soap.domain.com/manifest
Support manifest file: checked
Playback event logging during track play: checked
Playback duration logging at track end: checked 

This adds to the Sonos services without erroring out.

As it's working on your set up, I have a feeling it's likely something like a config error.

I don't know whether this helps but here's some results to GET requests to the soap URIs.

/manifest:

{
  "schemaVersion": "1.0",
  "endpoints": [
    {
      "type": "reporting",
      "uri": "https://soap.jamestorr.com/playback/v2.1/report"
    }
  ]
}

/wsdl: 200 response, empty. /playback/v2.1/report: 404 response (just doing that as the endpoint above points to this)

If I make a POST request with the body:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:son="http://www.sonos.com/Services/1.1">
    <soapenv:Header/>
    <soapenv:Body>
        <son:getMetadata>
            <son:id>root</son:id>
            <son:index>0</son:index>
            <son:count>100</son:count>
        </son:getMetadata>
    </soapenv:Body>
</soapenv:Envelope>

To the URL: https://soap.domain.com/wsdl, with content type XML, I successfully receive a response with the correct metadata. Here's what the response looks like:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://www.sonos.com/Services/1.1">
    <soap:Body>
        <getMetadataResponse xmlns="http://www.sonos.com/Services/1.1">
            <getMetadataResult>
                <count>85</count>
                <total>85</total>
                <index>0</index>
                <mediaCollection>
                    <itemType>audiobook</itemType>
                    <id>74162736-8a64-4b10-a0fc-4c431b398e47</id>
                    <canPlay>true</canPlay>
                    <canResume>true</canResume>
                    <title>Live At the Purple Onion</title>
                    <summary xsi:nil="true"></summary>
                </mediaCollection>
--- continues for the rest of the library ---
            </getMetadataResult>
        </getMetadataResponse>
    </soap:Body>
</soap:Envelope>

Lots of info here, hope it helps. What might be useful would be:

  1. A redacted version of your working config/docker-compose file settings as above.
  2. For you to check POST/GET on your soap server, so we can check our set up.
fayeinmay commented 9 months ago

OK dude, just retrying this.

FYI The git clone command currently in the Readme is erroring out, I changed the url to https://github.com/jmt-gh/audiobookshelf-sonos.git and it clones fine. Assume the given URL (git@github.com:jmt-gh/audiobookshelf-sonos.git) might be for the owner of the repo/require credentials?

As per @mxdalchau and my previous experience, I'm getting an "Unable to browse music" message. I've tested this now on a smaller library as well as a test one with just 4 items. Neither works.

The logs produce a list of library items. Here's my logs:

[2024-01-22T11:14:23.852Z] [DEBUG] [Unknown - Unknown:Unknown] Received request: GET /manifest 

[2024-01-22T11:14:23.853Z] [INFO] [Unknown - Unknown:Unknown] /manifest endpoint hit 

[2024-01-22T11:14:28.222Z] [DEBUG] [Unknown - Unknown:Unknown] Received request: POST /wsdl 

[2024-01-22T11:14:28.233Z] [DEBUG] [Unknown - Unknown:Unknown] Received request: POST /wsdl 

[2024-01-22T11:14:28.237Z] [DEBUG] [getMetadata - /app/sonos-service.js:8] getMetadata sonos-service called with args {"id":"root","index":0,"count":100}

[2024-01-22T11:14:28.238Z] [INFO] [getLibraryItems - /app/utils.js:17] Fetching library item at: "https://audiobooks.domain.com/api/libraries/<library_id>/items"

[2024-01-22T11:14:28.305Z] [DEBUG] [buildLibraryMetadataResult - /app/utils.js:116] libraryItem for mediaMetadataEntry: {"id":"022f5ead-e66e-4592-a6bc-bea084ae4f01","ino":"369861","oldLibraryItemId":null,"libraryId":"571b1e8a-e2ac-47fb-b0a1-f0f8d7ec15e3","folderId":"1c6a556e-623a-4e53-bb86-29a32c849558","path":"/audiobooks/Alan Partridge/From the Oasthouse The Alan Partridge Podcast","relPath":"From the Oasthouse The Alan Partridge Podcast","isFile":false,"mtimeMs":1601981799000,"ctimeMs":1694594837580,"birthtimeMs":1694594837580,"addedAt":1705921897649,"updatedAt":1705921897649,"isMissing":false,"isInvalid":false,"mediaType":"book","media":{"id":"a1fedd4d-3533-45cb-9151-9dfd257bc4a2","metadata":{"title":"From the Oasthouse: The Alan Partridge Podcast: An Audible Original","titleIgnorePrefix":"From the Oasthouse: The Alan Partridge Podcast: An Audible Original","subtitle":null,"authorName":"Alan Partridge","authorNameLF":"Partridge, Alan","narratorName":"Alan Partridge","seriesName":"","genres":["Comedy, Podcast"],"publishedYear":"2020","publishedDate":null,"publisher":null,"description":"Broadcaster, writer, philanthroper and one of the first public figures to suggest high-visibility clothing for people manning temporary car parks, the public Alan Partridge is a cherished institution. But what of the unseen Alan? For the first time, this","isbn":null,"asin":null,"language":null,"explicit":false,"abridged":false},"coverPath":"/audiobooks/Alan Partridge/From the Oasthouse The Alan Partridge Podcast/From the Oasthouse The Alan Partridge Podcast An Audible Original.jpg","tags":[],"numTracks":1,"numAudioFiles":1,"numChapters":17,"numMissingParts":0,"numInvalidAudioFiles":0,"duration":24274.279909,"size":385577371},"numFiles":3,"size":385894072}
... the rest of the library below

I can also confirm that if I make a Postman GET request to the ABS url with the login credentials, it returns a list of library items.

So the request for information is producing a list of metadata, but that for whatever reason isn't displaying in the Sonos app.

Incidentally, I finally ran the Sonos v2 upgrade, thinking this might be the culprit. It seems to have helped adding the service with the "support manifest file" checked, but still producing this error.

I've also played around with changing the SOAP_URI variable, but adding /wsdl to the end doesn't seem to solve it. Incidentally, the list of library items is produced regardless of whether the SOAP_URI is entered correctly, but the getMetadata and getLibraryItems aren't logged if it's incorrect.

Here's my docker compose settings if you notice any glaring errors. No quotes have been used here:

version: "3.8"

services:
  audiobookshelf-sonos:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: audiobookshelf-sonos
    environment:
      - SOAP_URI=https://soap.domain.com # also tried with /wsdl
      - ABS_URI=https://audiobooks.domain.com
      - ABS_LIBRARY_ID=<my_library_id>
      - ABS_TOKEN=<redacted>
      - LOG_LEVEL=debug # set to debug, info, warn, error
    ports:
      - 3333:80
    volumes:
      - ./sonos.wsdl:/app/sonos.wsdl

sonos.wsdl:

    <wsdl:service name="Sonos">
        <wsdl:port name="SonosSoap" binding="tns:SonosSoap">
      <soap:address location="https://soap.domain.com"/> <!-- UPDATE WITH SOAP_URI -->
        </wsdl:port>
    </wsdl:service>

Note, also changing this to https://soap.domain.com/wsdl doesn't fix anything.

/customsd.htm

Secure endpoint URL: https://soap.domain.com/wsdl
Polling interval: 10
Authentication SOAP header policy: Anonymous
Manifest: 
    version: 1
    URI: https://soap.domain.com/manifest
Support manifest file: checked
Playback event logging during track play: checked
Playback duration logging at track end: checked 

This adds to the Sonos services without erroring out.

As it's working on your set up, I have a feeling it's likely something like a config error.

I don't know whether this helps but here's some results to GET requests to the soap URIs.

/manifest:

{
  "schemaVersion": "1.0",
  "endpoints": [
    {
      "type": "reporting",
      "uri": "https://soap.jamestorr.com/playback/v2.1/report"
    }
  ]
}

/wsdl: 200 response, empty. /playback/v2.1/report: 404 response (just doing that as the endpoint above points to this)

If I make a POST request with the body:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:son="http://www.sonos.com/Services/1.1">
    <soapenv:Header/>
    <soapenv:Body>
        <son:getMetadata>
            <son:id>root</son:id>
            <son:index>0</son:index>
            <son:count>100</son:count>
        </son:getMetadata>
    </soapenv:Body>
</soapenv:Envelope>

To the URL: https://soap.domain.com/wsdl, with content type XML, I successfully receive a response with the correct metadata. Here's what the response looks like:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://www.sonos.com/Services/1.1">
    <soap:Body>
        <getMetadataResponse xmlns="http://www.sonos.com/Services/1.1">
            <getMetadataResult>
                <count>85</count>
                <total>85</total>
                <index>0</index>
                <mediaCollection>
                    <itemType>audiobook</itemType>
                    <id>74162736-8a64-4b10-a0fc-4c431b398e47</id>
                    <canPlay>true</canPlay>
                    <canResume>true</canResume>
                    <title>Live At the Purple Onion</title>
                    <summary xsi:nil="true"></summary>
                </mediaCollection>
--- continues for the rest of the library ---
            </getMetadataResult>
        </getMetadataResponse>
    </soap:Body>
</soap:Envelope>

Lots of info here, hope it helps. What might be useful would be:

1. A redacted version of your working config/docker-compose file settings as above.

2. For you to check POST/GET on your soap server, so we can check our set up.

Thought I'm gonna tell you how exactly I got this running pretty quickly, maybe it helps.

  1. Create domain absproxy.mydomain.com
  2. Create SSL certificate for that domain
  3. absproxy.mydomain.com now resolves to my machine on port 8082. Currently this results in a 502 / 404 error as nothing is set up yet.
  4. Follow README "Configuring a Custom Service Descriptor (CSD)", ignore step 4 and 5!
  5. wget https://codeload.github.com/jmt-gh/audiobookshelf-sonos/zip/refs/heads/main
  6. unzip downloaded files
  7. Modify sonos.wsdl line 2062 with location="https://absproxy.mydomain.com"
  8. Run docker build -t sonosabs . (Skip this if using docker-compose)
  9. I converted the docker-compose to a docker run command as I'm running this on UNRAID which does not support docker-compose. I used the following parameters. Make sure to not append any slashes in your setup and always use HTTPS / SSL, otherwise this will not work: SOAP_URI=https://absproxy.mydomain.com ABS_URI=https://abs.mydomain.com ABS_LIBRARY_ID=b72235eb-6d3-4645-c6fd-91208189b1b6 ABS_TOKEN=eyJhGci......... (long string) LOG_LEVEL=info # set to debug, info, warn, error ports: 8082:80
  10. I ran my docker run command, but you can now use docker-compose up -d
  11. Now start your Sonos App. Not the old one with S1, but the one that is called "Sonos" in play store.
  12. Make sure your devices are migrated to S2.
  13. Follow README "Configuring a Custom Service Descriptor (CSD)" step 4 and 5.
fayeinmay commented 9 months ago

Current issue with getting updates back up to ABS is that the sonos side of things just doesn't seem to be trying to reach out to the update endpoint in server.js. I see it reaching out to /manifest, but nothing beyond that.

Was there any solution to this? Doesn't seem like it is doing for me either.

fayeinmay commented 9 months ago

Current issue with getting updates back up to ABS is that the sonos side of things just doesn't seem to be trying to reach out to the update endpoint in server.js. I see it reaching out to /manifest, but nothing beyond that.

Was there any solution to this? Doesn't seem like it is doing for me either.

I solved this by converting to /playback without any prefix.

jt196 commented 9 months ago

I solved this by converting to /playback without any prefix.

What exactly do you mean here?

fayeinmay commented 9 months ago

I solved this by converting to /playback without any prefix.

What exactly do you mean here?

There is EXPRESS_APP.post(`${SOAP_ENDPOINT}/playback... in the server.js source file. I removed the SOAP_ENDPOINT part as the calls were not registering for me otherwise

jmt-gh commented 9 months ago

@fayeinmay , glad to hear you've got it working, and thanks for sharing the steps you took. Definetly makes me feel like I've got a bit of a sanity check that things work outside of my environment haha. The reason you've needed to make those changes is because you didn't register the secure URL in the same way it's laid out in the README:

Input the following information:

    Service Name: audiobookshelf
    Secure Endpoint URL: https://<the_url_you_defined_for_this_server_above>/wsdl
    Polling interval: 10
    Authentication SOAP header policy: Anonymous
    Manifest 

In the end, you end up with the same result, but repo currently assuming you defined the URL with appended with the /wsdl path, so puts that in a few places (though maybe we should just look at doing it without for simplicity)

fayeinmay commented 9 months ago

@fayeinmay , glad to hear you've got it working, and thanks for sharing the steps you took. Definetly makes me feel like I've got a bit of a sanity check that things work outside of my environment haha. The reason you've needed to make those changes is because you didn't register the secure URL in the same way it's laid out in the README:

Input the following information:

    Service Name: audiobookshelf
    Secure Endpoint URL: https://<the_url_you_defined_for_this_server_above>/wsdl
    Polling interval: 10
    Authentication SOAP header policy: Anonymous
    Manifest 

In the end, you end up with the same result, but repo currently assuming you defined the URL with appended with the /wsdl path, so puts that in a few places (though maybe we should just look at doing it without for simplicity)

I'd say you're right, because I did redo the setup step twice and could've forgotten to append /wsdl, but I only needed to change the path on the http calls, not on the soap calls. Except you say for soap sonos does auto apply /wsdl as a suffix.