We are integrating the Sonos API. We chose not to implement token refresh and so our tokens last for 1 year until when the user has to reauthorize again.
During my tests, I successfully get the reauthorize popup when the AuthTokenExpired fault is returned while browsing (in response to getMetadata).
But every time the Fault is returned from a call to getMediaMetadata, I get the default error message "Unable to play the radio station". I would expect to see the reauthorize popup instead.
Quoting from Sonos documentation about authentication tokens :
If you do not implement refresh tokens, when the token expires, return the Client.AuthTokenExpired fault to indicate the user must manually log in and authenticate again. The Log-Message is a string placed in the log messages for this fault code.
Here is the problematic dialog between our SMAPI server and Sonos application/speaker :
31/03/2020 14:24:27 641 SonosApi Request http://www.sonos.com/Services/1.1#getMediaMetadata "<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<credentials xmlns="http://www.sonos.com/Services/1.1">
<deviceId>78-28-CA-9F-86-8E:8</deviceId>
<deviceProvider>Sonos</deviceProvider>
<loginToken>
<token>1fa35465a-6bbc-4cf4-b46f-0e12be5b3216</token>
<householdId>Sonos_W6VyCDwgI8ZadAWceKQ1avPrtd</householdId>
</loginToken>
</credentials>
<To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://dev8.local.st-corp.fr:8001/SonosService.svc</To>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://www.sonos.com/Services/1.1#getMediaMetadata</Action>
</s:Header>
<s:Body>
<getMediaMetadata xmlns="http://www.sonos.com/Services/1.1">
<id>14740</id>
</getMediaMetadata>
</s:Body>
</s:Envelope>"
31/03/2020 14:24:27 875 SonosApi Reply "<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header />
<s:Body>
<s:Fault>
<faultcode>s:Client.AuthTokenExpired</faultcode>
<faultstring xml:lang="fr-FR">The token is expired</faultstring>
</s:Fault>
</s:Body>
</s:Envelope>"
Edit:
Refering to the updated documentation and your answer, I should only return AuthTokenExpired fault in calls to getMetadata and getMediaUri.
But what should I answer to a call to getMediaMetadata knowing that the access token is expired ?
Looking at my messages logs, I see that when a user click on a streamable item, the following calls are made in the following order :
Correct me if I am wrong, but in order to build the call to getMediaUri, the Sonos client use the id returned from the last call to getMediaMetadata, which I can't provide because the token is already expired. Wouldn't it be better to handle AuthTokenExpired first in getMediaMetadata ?
Regards
The browse (getMetadata
) and getMediaURI
calls will respect the AuthTokenExpired
fault. The re-authorization flow for these calls work as described in the Refresh expired authentication tokens section of the Use authentication tokens documentation. I'll update the documentation to reflect this.
If this does not work, submit a diagnostic to debug it. See support.sonos.com/s/article/141 for instructions. Copy your diagnostic number and email it to developer-feedback@sonos.com along with the time window, Sonos household ID, and your StackOverflow username.
You mentioned that when you send a fault in response to getMediaURI
, you get an error message, but your example shows a getMediaMetadata
call.
Sonos does not launch the re-authorization wizard when your server returns an AuthTokenExpired
fault for getLastUpdate
. When the Sonos speaker makes a getMediaMetadata
call and it fails, it does not start playback. The user will also see that playback failed.