joeyhage / homebridge-spotify-speaker

Control Spotify playlists using a fake speaker accessory
MIT License
19 stars 3 forks source link

Unable to generate tokens: SyntaxError: Unexpected end of JSON input #24

Closed kesumin closed 1 year ago

kesumin commented 1 year ago

Describe Your Problem:

Unable to generate tokens. I have not been able to get this plugin working and have not found my own solution. I'm unable to find any issues looking through the files that generate these syntax errors. At one point the src directory didn't exist in /usr/local/lib/node_modules/@poblouin/homebridge-spotify-speaker/ which I had copied over from a repo download which didn't change the error message in any way.

Logs:

[HomebridgeSpotifySpeaker] Failed to fetch tokens:  SyntaxError: Unexpected end of JSON input
    at JSON.parse (<anonymous>)
    at SpotifyApiWrapper.fetchTokensFromStorage (/usr/local/lib/node_modules/@poblouin/homebridge-spotify-speaker/src/spotify-api-wrapper.ts:124:21)
    at SpotifyApiWrapper.authenticate (/usr/local/lib/node_modules/@poblouin/homebridge-spotify-speaker/src/spotify-api-wrapper.ts:29:16)
    at HomebridgeAPI.<anonymous> (/usr/local/lib/node_modules/@poblouin/homebridge-spotify-speaker/src/platform.ts:41:60)
    at HomebridgeAPI.emit (node:events:513:28)
    at HomebridgeAPI.signalFinished (/usr/local/lib/node_modules/homebridge/src/api.ts:275:10)
    at ChildBridgeFork.startBridge (/usr/local/lib/node_modules/homebridge/src/childBridgeFork.ts:189:14)

Plugin Config:

        {
            "name": "HomebridgeSpotifySpeaker",
            "spotifyClientId": "xxx",
            "spotifyClientSecret": "xxx",
            "spotifyRedirectUri": "https://example.com/callback", (this was previously http://localhost:3005/ and is also used in my Spotify API)
            "spotifyAuthCode": "xxx",
            "devices": [
                {
                    "deviceType": "speaker",
                    "spotifyPlaylistUrl": ""
                }
            ],
            "_bridge": {
                "username": "xxx",
                "port": xxx
            },
            "platform": "HomebridgeSpotifySpeaker"
        },

Screenshots:

Environment:

poblouin commented 1 year ago

Hello @kesumin

Do you see any other errors? Because that SyntaxError itself is not preventing the plugin from working. This one is thrown and handled in the method fetchTokensFromStorage which tries to fetch saved tokens. If there are no saved tokens (e.g. the first time you launch this plugin), the JSON.parse call will fail and this unexpected end of JSON error is catched and logged. Then the plugin tries to authenticate using the code grant you provided in the config (spotifyAuthCode).

If the call to authWithCodeGrant fails, now the plugin will stop working since we can't log in to Spotify. Could you take another look at your logs and see if this error is raised at some point? https://github.com/poblouin/homebridge-spotify-speaker/blob/62ceacc99c4b3e3be2487e63c18cdbd1475599f4/src/spotify-api-wrapper.ts#LL115C23-L115C50

kesumin commented 1 year ago

I don't see any other errors including /src/spotify-api-wrapper.ts#LL115C23-L115C50. Here are all logs relating to this plugin at startup:

[1/10/2023, 1:36:17 PM] [AdvancedTimer] [INFO] timer disabled.
[1/10/2023, 1:36:17 PM] [HomebridgeSpotifySpeaker] Launched child bridge with PID 70780
[1/10/2023, 1:36:17 PM] Registering platform '@poblouin/homebridge-spotify-speaker.HomebridgeSpotifySpeaker'
[1/10/2023, 1:36:17 PM] [HomebridgeSpotifySpeaker] Loaded @poblouin/homebridge-spotify-speaker v1.2.1 child bridge successfully
[1/10/2023, 1:36:18 PM] Loaded 1 cached accessories from cachedAccessories.xxx.
[1/10/2023, 1:36:18 PM] [HomebridgeSpotifySpeaker] Finished initializing platform: HomebridgeSpotifySpeaker
[1/10/2023, 1:36:18 PM] [HomebridgeSpotifySpeaker] Loading accessory from cache: MM-MEDIA
[1/10/2023, 1:36:18 PM] Publishing bridge accessory (name: HomebridgeSpotifySpeaker, publishInfo: {
  username: 'xxx',
  port: xxx,
  pincode: '***-**-***',
  category: 2,
  bind: undefined,
  mdns: undefined,
  addIdentifyingMaterial: true,
  advertiser: undefined
}).
[1/10/2023, 1:36:18 PM] [HomebridgeSpotifySpeaker] Executed didFinishLaunching callback
[1/10/2023, 1:36:18 PM] [HomebridgeSpotifySpeaker] Attempting to fetch tokens saved in the storage
[1/10/2023, 1:36:18 PM] [HomebridgeSpotifySpeaker] Failed to fetch tokens:  SyntaxError: Unexpected end of JSON input
    at JSON.parse (<anonymous>)
    at SpotifyApiWrapper.fetchTokensFromStorage (/usr/local/lib/node_modules/@poblouin/homebridge-spotify-speaker/src/spotify-api-wrapper.ts:124:21)
    at SpotifyApiWrapper.authenticate (/usr/local/lib/node_modules/@poblouin/homebridge-spotify-speaker/src/spotify-api-wrapper.ts:29:16)
    at HomebridgeAPI.<anonymous> (/usr/local/lib/node_modules/@poblouin/homebridge-spotify-speaker/src/platform.ts:41:60)
    at HomebridgeAPI.emit (node:events:513:28)
    at HomebridgeAPI.signalFinished (/usr/local/lib/node_modules/homebridge/src/api.ts:275:10)
    at ChildBridgeFork.startBridge (/usr/local/lib/node_modules/homebridge/src/childBridgeFork.ts:189:14)
[1/10/2023, 1:36:18 PM] [HomebridgeSpotifySpeaker] Attempting the code grant authorization flow
[1/10/2023, 1:36:18 PM] Homebridge v1.6.0 (HAP v0.11.0) (HomebridgeSpotifySpeaker) is running on port 37171.

I'm also unable to see any devices created by the plugin in iOS Home.

kesumin commented 1 year ago

Upon reinstalling Homebridge, I'm noting the steps I took to get to this state:

  1. Standard UI install
  2. Config import
  3. Plugin reports error stating missing file or directory. Log reports as following:
    [1/10/2023, 4:30:51 PM] [HomebridgeSpotifySpeaker] Launched child bridge with PID xxx
    [1/10/2023, 4:30:51 PM] Registering platform '@poblouin/homebridge-spotify-speaker.HomebridgeSpotifySpeaker'
    [1/10/2023, 4:30:51 PM] [HomebridgeSpotifySpeaker] Loaded @poblouin/homebridge-spotify-speaker v1.2.1 child bridge successfully
    [1/10/2023, 4:30:51 PM] Loaded 0 cached accessories from cachedAccessories.xxx.
    [1/10/2023, 4:30:51 PM] [HomebridgeSpotifySpeaker] Finished initializing platform: HomebridgeSpotifySpeaker
    [1/10/2023, 4:30:51 PM] Publishing bridge accessory (name: HomebridgeSpotifySpeaker, publishInfo: {
    username: 'xxx',
    port: xxx,
    pincode: '***-**-***',
    category: 2,
    bind: undefined,
    mdns: undefined,
    addIdentifyingMaterial: true,
    advertiser: undefined
    }).
    [1/10/2023, 4:30:51 PM] [HomebridgeSpotifySpeaker] Executed didFinishLaunching callback
    [1/10/2023, 4:30:51 PM] [HomebridgeSpotifySpeaker] Attempting to fetch tokens saved in the storage
    [1/10/2023, 4:30:51 PM] [HomebridgeSpotifySpeaker] Failed to fetch tokens:  Error: ENOENT: no such file or directory, open '/root/.homebridge/persist/.homebridge-spotify-speaker'
    at Object.openSync (node:fs:590:3)
    at Object.readFileSync (node:fs:458:35)
    at SpotifyApiWrapper.fetchTokensFromStorage (/usr/local/lib/node_modules/@poblouin/homebridge-spotify-speaker/src/spotify-api-wrapper.ts:124:30)
    at SpotifyApiWrapper.authenticate (/usr/local/lib/node_modules/@poblouin/homebridge-spotify-speaker/src/spotify-api-wrapper.ts:29:16)
    at HomebridgeAPI.<anonymous> (/usr/local/lib/node_modules/@poblouin/homebridge-spotify-speaker/src/platform.ts:41:60)
    at HomebridgeAPI.emit (node:events:513:28)
    at HomebridgeAPI.signalFinished (/usr/local/lib/node_modules/homebridge/src/api.ts:275:10)
    at ChildBridgeFork.startBridge (/usr/local/lib/node_modules/homebridge/src/childBridgeFork.ts:189:14) {
    errno: -2,
    syscall: 'open',
    code: 'ENOENT',
    path: '/root/.homebridge/persist/.homebridge-spotify-speaker'
    }
    [1/10/2023, 4:30:51 PM] [HomebridgeSpotifySpeaker] Attempting the code grant authorization flow
    [1/10/2023, 4:30:51 PM] Homebridge v1.6.0 (HAP v0.11.0) (HomebridgeSpotifySpeaker) is running on port xxx.
  4. touch /root/.homebridge/persist/.homebridge-spotify-speaker
  5. Reproduced error msg reports as following:
[1/10/2023, 4:27:59 PM] [HomebridgeSpotifySpeaker] Launched child bridge with PID 
[1/10/2023, 4:27:59 PM] Registering platform '@poblouin/homebridge-spotify-speaker.HomebridgeSpotifySpeaker'
[1/10/2023, 4:28:00 PM] [HomebridgeSpotifySpeaker] Loaded @poblouin/homebridge-spotify-speaker v1.2.1 child bridge successfully
[1/10/2023, 4:28:00 PM] [HomebridgeSpotifySpeaker] Finished initializing platform: HomebridgeSpotifySpeaker
[1/10/2023, 4:28:00 PM] Publishing bridge accessory (name: HomebridgeSpotifySpeaker, publishInfo: {
  username: 'xxx',
  port: xxx,
  pincode: '***-**-***',
  category: 2,
  bind: undefined,
  mdns: undefined,
  addIdentifyingMaterial: true,
  advertiser: undefined
}).
[1/10/2023, 4:28:00 PM] [HomebridgeSpotifySpeaker] Executed didFinishLaunching callback
[1/10/2023, 4:28:00 PM] [HomebridgeSpotifySpeaker] Attempting to fetch tokens saved in the storage
[1/10/2023, 4:28:00 PM] [HomebridgeSpotifySpeaker] Failed to fetch tokens:  SyntaxError: Unexpected end of JSON input
    at JSON.parse (<anonymous>)
    at SpotifyApiWrapper.fetchTokensFromStorage (/usr/local/lib/node_modules/@poblouin/homebridge-spotify-speaker/src/spotify-api-wrapper.ts:124:21)
    at SpotifyApiWrapper.authenticate (/usr/local/lib/node_modules/@poblouin/homebridge-spotify-speaker/src/spotify-api-wrapper.ts:29:16)
    at HomebridgeAPI.<anonymous> (/usr/local/lib/node_modules/@poblouin/homebridge-spotify-speaker/src/platform.ts:41:60)
    at HomebridgeAPI.emit (node:events:513:28)
    at HomebridgeAPI.signalFinished (/usr/local/lib/node_modules/homebridge/src/api.ts:275:10)
    at ChildBridgeFork.startBridge (/usr/local/lib/node_modules/homebridge/src/childBridgeFork.ts:189:14)
[1/10/2023, 4:28:00 PM] [HomebridgeSpotifySpeaker] Attempting the code grant authorization flow
[1/10/2023, 4:28:00 PM] Homebridge v1.6.0 (HAP v0.11.0) (HomebridgeSpotifySpeaker) is running on port xxx.
poblouin commented 1 year ago

I just realize that you are using Homebridge 1.6.0, that might be the issue here because looking at the logs it seems to be behaving as expected. The file in .persist will only exist and be populated only if the code grant authentication works. In your logs I see the plugin is attempting to do it, but nothing happens afterward, we should see more logs

[1/10/2023, 4:28:00 PM] [HomebridgeSpotifySpeaker] Attempting the code grant authorization flow

Maybe the api changed between 1.5 and 1.6, I'll need to test. I'm still running on 1.5 here since the docker image is not updated yet

kesumin commented 1 year ago

Ah, once I get a chance I'll try to deploy a container for 1.5. Thanks for letting me know.

poblouin commented 1 year ago

Sorry it took me so long to see it 😅

I’ll get back to you as soon as I can, most likely this weekend!

poblouin commented 1 year ago

Hey @kesumin

I just tested with homebridge 1.6.0 and it works good on my end. I tested both locally (macOS) and on my homebridge server which is running on the official homebridge ubuntu docker image.

Here's my logs when I boot the the plugin after deleting the persist path /root/homebridge/.persist/.homebridge-spotify-speaker. Notice that the first error you posted is there, like I said this one is normal.

[1/11/2023, 8:53:48 PM] [HomebridgeSpotifySpeaker] Executed didFinishLaunching callback
[1/11/2023, 8:53:48 PM] [HomebridgeSpotifySpeaker] Attempting to fetch tokens saved in the storage
[1/11/2023, 8:53:48 PM] [HomebridgeSpotifySpeaker] Failed to fetch tokens:  Error: ENOENT: no such file or directory, open '/root/.homebridge/persist/.homebridge-spotify-speaker'
    at Object.openSync (node:fs:600:3)
    at Object.readFileSync (node:fs:468:35)
    at SpotifyApiWrapper.fetchTokensFromStorage (/root/homebridge-spotify-speaker/src/spotify-api-wrapper.ts:124:30)
    at SpotifyApiWrapper.authenticate /root/homebridge-spotify-speaker/src/spotify-api-wrapper.ts:29:16)
    at HomebridgeAPI.<anonymous> (/root/homebridge-spotify-speaker/src/platform.ts:41:60)
    at HomebridgeAPI.emit (node:events:513:28)
    at HomebridgeAPI.signalFinished (/root/homebridge-spotify-speaker/node_modules/homebridge/src/api.ts:275:10)
    at Server.start (/root/homebridge-spotify-speaker/node_modules/homebridge/src/server.ts:190:14) {
  errno: -2,
  syscall: 'open',
  code: 'ENOENT',
  path: '/root/.homebridge/persist/.homebridge-spotify-speaker'
}
[1/11/2023, 8:53:48 PM] [HomebridgeSpotifySpeaker] Attempting the code grant authorization flow
[1/11/2023, 8:53:49 PM] Publishing bridge accessory (name: Homebridge, publishInfo: {
  username: 'EE:22:3D:E6:CE:35',
  port: undefined,
  pincode: '***-**-***',
  category: 2,
  bind: undefined,
  mdns: undefined,
  addIdentifyingMaterial: true,
  advertiser: undefined
}).
[1/11/2023, 8:53:49 PM] [HomebridgeSpotifySpeaker] Spotify auth success using authorization code flow

In your case, we see the line [HomebridgeSpotifySpeaker] Attempting the code grant authorization flow, what I don't understand is why there's nothing after that. We should see either [HomebridgeSpotifySpeaker] Spotify auth success using authorization code flow (like in my logs exampe above) or an error message 🤔

Could you try using the default redirectUri and see if that helps? Otherwise I'm not sure what could be the issue. The only thing I never tested is running it on FreeBSD, the node, npm, homebridge versions are fine.

Also, in the config, the device name and device ID are missing. That's not the issue, but if you don't put one it will fail creating the accessory. Maybe you remove those when you posted your config, just pointing this out just in case.

            "devices": [
                {
                    "deviceName": "Some Name",
                    "deviceType": "speaker",
                    "spotifyPlaylistUrl": "",
                    "spotifyDeviceId": "xxx"
                }
            ],
kesumin commented 1 year ago

Thanks for the follow-up! I'm not seeing anything change with FreeBSD so I've started an instance in Ubuntu Server 22.04.1 LTS.

Using the same config as my FreeBSD installation, I'm now getting an Invalid authorization code error instead despite it 'working' with the FreeBSD installation. I've attempted changing every variable as well as a completely new API app on Spotify with no luck.

Here is the link I am using to get my code: https://accounts.spotify.com/authorize?client_id=xxx&response_type=code&redirect_uri=http://mysite.com/callback/&scope=user-read-playback-state user-modify-playback-state user-read-currently-playing

I still don't have a clue why there isn't any error message at all on my FreeBSD instance. I also don't have a clue where I went wrong generating my code. 💀

I'm only having an issue with the token and persist file generation.

Here are my new plugin logs:

[1/12/2023, 9:13:28 AM] Loaded plugin: @poblouin/homebridge-spotify-speaker@1.2.2
[1/12/2023, 9:13:28 AM] Registering platform '@poblouin/homebridge-spotify-speaker.HomebridgeSpotifySpeaker'

[1/12/2023, 9:13:28 AM] [HomebridgeSpotifySpeaker] Initializing HomebridgeSpotifySpeaker platform...
[1/12/2023, 9:13:28 AM] [HomebridgeSpotifySpeaker] Initializing child bridge xxx

[1/12/2023, 9:13:30 AM] [HomebridgeSpotifySpeaker] Launched child bridge with PID 4996
[1/12/2023, 9:13:30 AM] Registering platform '@poblouin/homebridge-spotify-speaker.HomebridgeSpotifySpeaker'
[1/12/2023, 9:13:30 AM] [HomebridgeSpotifySpeaker] Loaded @poblouin/homebridge-spotify-speaker v1.2.2 child bridge successfully

[1/12/2023, 9:13:30 AM] Homebridge v1.6.0 (HAP v0.11.0) (HomebridgeSpotifySpeaker) is running on port 37171.
[1/12/2023, 9:13:30 AM] [HomebridgeSpotifySpeaker] Could not authorize Spotify:

 {"body":{"error":"invalid_grant","error_description":"Authorization code expired"},"headers":{"date":"Thu, 12 Jan 2023 09:13:30 GMT","content-type":"application/json","set-cookie":["__Host-device_id=xxx;Version=1;Path=/;Max-Age=2147483647;Secure;HttpOnly;SameSite=Lax","sp_tr=false;Version=1;Domain=accounts.spotify.com;Path=/;Secure;SameSite=Lax"],"sp-trace-id":"a598fbbf006be2a2","x-envoy-upstream-service-time":"12","server":"envoy","strict-transport-security":"max-age=31536000","x-content-type-options":"nosniff","content-encoding":"gzip","vary":"Accept-Encoding","via":"HTTP/2 edgeproxy, 1.1 google","alt-svc":"h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000","connection":"close","transfer-encoding":"chunked"},"statusCode":400}
[1/12/2023, 9:13:30 AM] [HomebridgeSpotifySpeaker] We could not fetch the Spotify tokens nor authenticate using the code grant flow.
        Please redo the manual login step, provide the new auth code in the config then try again.

Please let me know if there's anything else you could use or if I missed sanitizing anything!

poblouin commented 1 year ago

Hello @kesumin, sorry for the late reply, I missed your last message for some reason.

For that error message, let's start with the most basic question before going deeper: Do you have a free or premium account?

joeyhage commented 1 year ago

Closing due to no activity from OP.