TooTallNate / node-spotify-web

Node.js implementation of the Spotify Web protocol
MIT License
695 stars 126 forks source link

TrackError: Account subscription status not Spotify Premium #111

Open ghost opened 8 years ago

ghost commented 8 years ago

Just started seeing these responses today

{ [TrackError: Account subscription status not Spotify Premium]
 domain: 12,
 code: 0,
 description: '',
 data: null,
 name: 'TrackError',
 message: 'Account subscription status not Spotify Premium' }

Is this a server side change by Spotify?

ghost commented 8 years ago

The error is happening even on accounts with Premium (at least, a freshly created one)

ghost commented 8 years ago

After updating to the latest commit, I'm getting Track is not playable in country

lucbernard commented 8 years ago

Same here, was working fine yesterday

vincentcox commented 8 years ago

same here

TooTallNate commented 8 years ago

Can you guys try latest master branch? I've reverted the problematic commit in 9ace59c

lucbernard commented 8 years ago

@TooTallNate I'd already reverted that change on my side

TooTallNate commented 8 years ago

@lucbernard and so which error are you seeing now?

lucbernard commented 8 years ago

"Account subscription status not Spotify Premium". On every track. With both premium & free accounts.

The problem is with Spotify.prototype.trackUri (called by Track.prototype.play)

this.sendCommand('sp/track_uri') returns the error "error":[12,0,""],"id":13} systematically

vincentcox commented 8 years ago

"Can you guys try latest master branch? I've reverted the problematic commit in 9ace59c" Noob question: if I just do "#npm install spotify-web", will I get updated to your latest branch commit? If yes: then my output is: TrackError: Account subscription status not Spotify Premium at Spotify._onmessage (/app/node_modules/spotify-web/lib/spotify.js:401:15)

TooTallNate commented 8 years ago

Noob question: if I just do "#npm install spotify-web", will I get updated to your latest branch commit?

No, since I haven't published a new version to npm yet, only pushed to this git repo.

"Account subscription status not Spotify Premium". On every track. With both premium & free accounts.

I'm not getting this error on my end, so you'll have to do some digging to find out what the culprit is I think...

LinusU commented 8 years ago

You can install it with npm install TooTallNate/node-spotify-web#master

vincentcox commented 8 years ago

thanks for clearing that up, Nathan and LinusU. I get the same error after updating

npresseault commented 8 years ago

Getting this with the samples as well:

node example/play.js

Playing: The Whispers - And the Beat Goes On

TrackError: Account subscription status not Spotify Premium

node --version

v0.10.28
ghost commented 8 years ago

So are we sure that the account types are as follows? Where do these values come from?

premium: 'SUBSCRIPTION',
unlimited: 'SUBSCRIPTION',
free: 'AD'
ghost commented 8 years ago

I got the idea to change the user agent, based on a few old issues centered around this same error. I tried setting it to a generic Chrome on OS X UA string, but it doesn't seem to have any impact one way or another.

juanmito commented 8 years ago

Hi guys

Any news?

I've just testing and, without TooTallNate commit, i've got "Account subscription status not Spotify Premium", and applying it, the other error: "Track is not playable in country"

I'm confused. This was working yesterday :(

juanmito commented 8 years ago

Hmm, I've done a lot of changes, but nothing appears to change. Any ideas?

Thanks

juanmito commented 8 years ago

Just a question. Can someone play one song right now?

I've just installed the latest NodeJS version for Mac OS X, and then, I've downloaded the last branch doing npm install TooTallNate/node-spotify-web#master

And it doesn't works. I've tried to modify some attributes bur nothing changed. Maybe, country codes have changed internally to numerical codes, so, could it be possible to try something like that? And, would it be possible to see any trace with wireshark or something like that stuff?

Thanks

TooTallNate commented 8 years ago

I'm getting it now too :(

ghost commented 8 years ago

@TooTallNate Anything we can do to help, or any avenues you have in mind to pursue? Much of this is currently above my head but I can certainly try

juanmito commented 8 years ago

@sciencepro +1 If @TooTallNate have any clue, please share, and if we can help..

12finger commented 8 years ago

maybe premium is now zero or "0" ?! or "201" ?!

      var accountTypeMap = {

        premium: '0',
        unlimited: 'premium',
        free: 'AD'
      };

spot_web

aaiyer commented 8 years ago

What's odd, IT IS working for me on my Arch Linux system, while on other Linux distros (tried Ubuntu & RHEL) and Windows it does not work... Tried to find the root cause, got lazy and installed my app in a docker container that has Arch running in it instead...

ghost commented 8 years ago

@aaiyer anything different about the configs? Node version? Module versions?

ghost commented 8 years ago

@aaiyer it works! Brand new arch install with Node v0.12.7

aaiyer commented 8 years ago

@sciencepro I took the same Node v0.12.7 and modules and put it in another distro, didn't work.. I suspected it was something in protobuf, so I upgraded the node module to use the latest stable sources of protobuf to no avail ... But doesn't matter, its easier to just use arch.

ghost commented 8 years ago

Thanks so much @aaiyer. I'm definitely fine using Arch since that seems to be the more reliable choice. Would still be interesting to know what the root cause was here.

alfs commented 8 years ago

I have the same auth problems. Trying to pinpoint what differs in the protocol, I tested a brand new Arch install (150701 dual iso), booted from iso, installed npm, and npm installed the git master.

Now I instead get error 'Track is not playable in country "SE"'.

ghost commented 8 years ago

@alfs very strange that there is such inconsistency. FYI, my setup process was to create a new VM on Digital Ocean running Debian 8, and then use this handy script to turn it into a fresh Arch install. Then I installed npm, nodejs, python 2.7, and I was up and running.

12finger commented 8 years ago

come on guys... arch is NOT a solution to this challenge!

aaiyer commented 8 years ago

@12finger That's why we've left the interesting parts of the challenge for you :)

12finger commented 8 years ago

well, @aaiyer i'd really love to help out, but i am afraid i am not anyway near a JS crack as nathan is!

... actually i think the folks at spotify simply made some minor changes, to the accountTypeMap mapping maybe only... often it simply is the dumbest, simplest change which makes the difference, not some magic super-duper engineering .. that said, i don't have a good clue about where to start debugging this .. looking into the websockets traffic was the best idea i could come up till date.

btw: this would be my first contribution to any open-source project. my first one! so please, have some noob-respect for my words.

edit: maybe spotify started to do some sort of "dynamic" accountTypeMap mapping !? ... like depending on the ID of the user... that would explain why some of us were getting the error before some others. hmm.. seems like they rolled out this "feature" slowly, not to everybody at the same time ..

alfs commented 8 years ago

@12finger, the web socket traffic is actually the best place to start debugging when there are some clients that are working, and some are not. If the traffic is identical, then there must be some server side/account/country issues that makes some clients work (and they will probably soon stop working). If the traffic differs, it's due to some library/protobuf/etc on the client side. That's why I was trying to get a functional client in Arch, to compare the network traffic versus my non-working client. Running Arch is of course not a solution per se :)

alfs commented 8 years ago

Some log output differences: With spotify-web 1.3.0, using export DEBUG=spotify-web* , I get

spotify-web trackUri()
spotify-web recurseAlternatives()
spotify-web isTrackAvailable()
spotify-web type: "SUBSCRIPTION"
spotify-web allowed: []
spotify-web forbidden: ["AF","AQ","AS","BQ","BT","CC","CK","CN","CU","CW","CX","GE","GU","GY","HM","IR","JP","KI","KP","LI","MH","MP","MV","NF","NR","NU","PS","PW","SB","SR","SX","SY","TK","TO","TV","UM","VI","VU","WS"]
spotify-web isAllowed: true
spotify-web isForbidden: false
spotify-web applicable: true
spotify-web available: true
spotify-web sp/track_uri args: ["mp3160","b1f5414986dd45fabb0af7105ad909ba"]
spotify-web sendCommand("sp/track_uri", ["mp3160","b1f5414986dd45fabb0af7105ad909ba"])
spotify-web storing callback function for message id 6
spotify-web sending command: {"name":"sp/track_uri","id":"6","args":["mp3160","b1f5414986dd45fabb0af7105ad909ba"]}
spotify-web WebSocket "message" event: {"error":[12,0,""],"id":6}

In Arch, with the spotify-web git master version, for the same track, I instead get

isAllowed: false
isForbidden: false
applicable: false
available: false

Then there are checks for alternative tracks, none which are allowed, applicable or available, and finally I get an error that no track is available in my country.

I therefore short-circuited these checks in spotify.js around line 960 (set them manually to true as expected) and now the track plays.

alfs commented 8 years ago

Some more observations:

The isAllowed: false is due to restriction.hasOwnProperty('countriesAllowed') is true, which is inverted and falls through has(allowed, country) which is false, since the allowed country array is empty ([]), which then causes available to be false as well. Don't know that could have caused this, since this code has been working previously.

I also noted that my restriction.catalogue was using numeric identifiers, so I did manual edits to fix this. I guess a double accountTypeMap check could be used until this change has been rolled out everywhere.

ghost commented 8 years ago

getting lots of [Error: Track is not playable in country "US"] even on Arch.

@alfs do you have a fork that's currently working?

alfs commented 8 years ago

@sciencepro , I don't have a fork, but the change is trivial. In spotify-web/lib/spotify.js, line 975, change return available; to return true;

Note that this is not a fix in any way (for a number of reasons), just a way to test and isolate the problem, which is in the matching code of allowed/forbidden countries, as well as in the subscription mapping/comparison.

sqrtroot commented 8 years ago

what request is made to get the account type and is it possible to get a sniff(wireshark or something) of that?

alfs commented 8 years ago

@sqrtroot , the requests are encoded so even though they can be captured by wireshark, they still need decoding (e.g. by protobuf).

It's easier to run an example client with debug enabled and get the output from there.

export USERNAME=x
export PASSWORD=y
DEBUG=spotify-web* node examples/play.js

Or just put debug('') statements in spotify.js and print the account type variable that is expected.

For the real client, see @12finger 's screenshot above how the WebSocket traffic can be inspected.

sqrtroot commented 8 years ago

hmm okay, in the spotify.web.client.js (from the official spotify web app.) i found this table. var f={free:0,unlimited:1,premium:2} using this table instead of the original. i get track is not available in this country error. any thoughts?

juanmito commented 8 years ago

Ok, lets show more examples:

Arch Linux, fresh installation with node 0.12.7 and python v2.7

[root@alarm spotify-web]# node server.js Playing: Kool & The Gang - Get Down On It - Single Version

events.js:85 throw er; // Unhandled 'error' event ^ TrackError: Account subscription status not Spotify Premium at Spotify._onmessage (/node_modules/spotify-web/lib/spotify.js:401:15) at WebSocket.emit (events.js:110:17) at Receiver.ontext (/node_modules/spotify-web/node_modules/ws/lib/WebSocket.js:798:10) at /node_modules/spotify-web/node_modules/ws/lib/Receiver.js:473:18 at Receiver.applyExtensions (/node_modules/spotify-web/node_modules/ws/lib/Receiver.js:360:5) at /node_modules/spotify-web/node_modules/ws/lib/Receiver.js:462:14 at Receiver.flush (/node_modules/spotify-web/node_modules/ws/lib/Receiver.js:336:3) at Receiver.opcodes.1.finish (/node_modules/spotify-web/node_modules/ws/lib/Receiver.js:478:12) at Receiver.expectHandler (/node_modules/spotify-web/node_modules/ws/lib/Receiver.js:453:31) at Receiver.add (/node_modules/spotify-web/node_modules/ws/lib/Receiver.js:91:24)

I change type subscription table, using number codes instead tags (premium=2, unlimited=1, free=0) and I get this:

[root@alarm spotify-web]# node server.js Playing: Kool & The Gang - Get Down On It - Single Version events.js:85 throw er; // Unhandled 'error' event ^ Error: Track is not playable in country "US" at /node_modules/spotify-web/lib/spotify.js:1011:8 at process._tickCallback (node.js:355:11)

And finally, if I change in line 975, available for true, I get again subscription error:

[root@alarm spotify-web]# node server.js Playing: Kool & The Gang - Get Down On It - Single Version

events.js:85 throw er; // Unhandled 'error' event ^ TrackError: Account subscription status not Spotify Premium at Spotify._onmessage (/node_modules/spotify-web/lib/spotify.js:401:15) at WebSocket.emit (events.js:110:17) at Receiver.ontext (/node_modules/spotify-web/node_modules/ws/lib/WebSocket.js:798:10) at /node_modules/spotify-web/node_modules/ws/lib/Receiver.js:473:18 at Receiver.applyExtensions (/node_modules/spotify-web/node_modules/ws/lib/Receiver.js:360:5) at /node_modules/spotify-web/node_modules/ws/lib/Receiver.js:462:14 at Receiver.flush (/node_modules/spotify-web/node_modules/ws/lib/Receiver.js:336:3) at Receiver.opcodes.1.finish (/node_modules/spotify-web/node_modules/ws/lib/Receiver.js:478:12) at Receiver.expectHandler (/node_modules/spotify-web/node_modules/ws/lib/Receiver.js:453:31) at Receiver.add (/node_modules/spotify-web/node_modules/ws/lib/Receiver.js:91:24) [root@alarm spotify-web]#

Hope this info will be valuable for someone.

PD: Sorry for the tagging, I'm using a smartphone PD2: My account subscription is premium

alfs commented 8 years ago

@sqrtroot there is some bug in parsing the country access. You could try initializing the allowed array with your country code, like var allowed = ["US"]; (or whatever). Note that this will probably give errors later on if the track actually is unavailable, even though it's faked for now. Long-term fix is to look at the contry comparison logic and see why it fails.

@juanmito are you using the 1.3.0 release (npm install spotify-web) or the git master? I got the same error as you from the 1.3.0 release, the git master worked ( npm uninstall spotify-web && npm install TooTallNate/node-spotify-web#master )

juanmito commented 8 years ago

@alfs Just installed git master. I'll try again :expressionless:

After installing git master, did you do anything else? I mean, change line 975 or anything more?

juanmito commented 8 years ago

I've just tried ( npm uninstall spotify-web && npm install TooTallNate/node-spotify-web#master ) and got the same error (changing line 975). Here is my debug:

[root@alarm spotify-web]# DEBUG=* node server.js
  lame:encoder processing prop "lame_get_id3v1_tag" as "id3v1Tag" +0ms
  lame:encoder processing prop "lame_get_id3v2_tag" as "id3v2Tag" +13ms
  lame:encoder processing prop "lame_get_num_samples" as "numSamples" +10ms
  lame:encoder processing prop "lame_set_num_samples" as "numSamples" +1ms
  lame:encoder processing prop "lame_get_in_samplerate" as "sampleRate" +1ms
  lame:encoder processing prop "lame_set_in_samplerate" as "sampleRate" +1ms
  lame:encoder processing prop "lame_get_num_channels" as "channels" +1ms
  lame:encoder processing prop "lame_set_num_channels" as "channels" +0ms
  lame:encoder processing prop "lame_get_scale" as "scale" +0ms
  lame:encoder processing prop "lame_set_scale" as "scale" +1ms
  lame:encoder processing prop "lame_get_scale_left" as "scaleLeft" +1ms
  lame:encoder processing prop "lame_set_scale_left" as "scaleLeft" +0ms
  lame:encoder processing prop "lame_get_scale_right" as "scaleRight" +1ms
  lame:encoder processing prop "lame_set_scale_right" as "scaleRight" +0ms
  lame:encoder processing prop "lame_get_out_samplerate" as "outSampleRate" +1ms
  lame:encoder processing prop "lame_set_out_samplerate" as "outSampleRate" +0ms
  lame:encoder processing prop "lame_get_analysis" as "analysis" +1ms
  lame:encoder processing prop "lame_set_analysis" as "analysis" +0ms
  lame:encoder processing prop "lame_get_bWriteVbrTag" as "writeVbrTag" +1ms
  lame:encoder processing prop "lame_set_bWriteVbrTag" as "writeVbrTag" +0ms
  lame:encoder processing prop "lame_get_quality" as "quality" +0ms
  lame:encoder processing prop "lame_set_quality" as "quality" +1ms
  lame:encoder processing prop "lame_get_mode" as "mode" +0ms
  lame:encoder processing prop "lame_set_mode" as "mode" +1ms
  lame:encoder processing prop "lame_get_brate" as "bitRate" +0ms
  lame:encoder processing prop "lame_set_brate" as "bitRate" +0ms
  lame:encoder processing prop "lame_get_compression_ratio" as "compressionRatio" +1ms
  lame:encoder processing prop "lame_set_compression_ratio" as "compressionRatio" +1ms
  lame:encoder processing prop "lame_get_copyright" as "copyright" +0ms
  lame:encoder processing prop "lame_set_copyright" as "copyright" +0ms
  lame:encoder processing prop "lame_get_original" as "original" +1ms
  lame:encoder processing prop "lame_set_original" as "original" +1ms
  lame:encoder processing prop "lame_get_error_protection" as "errorProtection" +1ms
  lame:encoder processing prop "lame_set_error_protection" as "errorProtection" +0ms
  lame:encoder processing prop "lame_get_extension" as "extension" +1ms
  lame:encoder processing prop "lame_set_extension" as "extension" +0ms
  lame:encoder processing prop "lame_get_strict_ISO" as "strictISO" +1ms
  lame:encoder processing prop "lame_set_strict_ISO" as "strictISO" +0ms
  lame:encoder processing prop "lame_get_disable_reservoir" as "disableReservoir" +1ms
  lame:encoder processing prop "lame_set_disable_reservoir" as "disableReservoir" +0ms
  lame:encoder processing prop "lame_get_quant_comp" as "quantComp" +1ms
  lame:encoder processing prop "lame_set_quant_comp" as "quantComp" +0ms
  lame:encoder processing prop "lame_get_quant_comp_short" as "quantCompShort" +1ms
  lame:encoder processing prop "lame_set_quant_comp_short" as "quantCompShort" +0ms
  lame:encoder processing prop "lame_get_exp_nspsytune" as "expNspsytune" +1ms
  lame:encoder processing prop "lame_set_exp_nspsytune" as "expNspsytune" +0ms
  lame:encoder processing prop "lame_get_VBR" as "VBR" +1ms
  lame:encoder processing prop "lame_set_VBR" as "VBR" +0ms
  lame:encoder processing prop "lame_get_VBR_q" as "VBRQ" +1ms
  lame:encoder processing prop "lame_set_VBR_q" as "VBRQ" +0ms
  lame:encoder processing prop "lame_get_VBR_quality" as "VBRQuality" +1ms
  lame:encoder processing prop "lame_set_VBR_quality" as "VBRQuality" +0ms
  lame:encoder processing prop "lame_get_VBR_mean_bitrate_kbps" as "VBRMeanBitrateKbps" +2ms
  lame:encoder processing prop "lame_set_VBR_mean_bitrate_kbps" as "VBRMeanBitrateKbps" +0ms
  lame:encoder processing prop "lame_get_VBR_min_bitrate_kbps" as "VBRMinBitrateKbps" +1ms
  lame:encoder processing prop "lame_set_VBR_min_bitrate_kbps" as "VBRMinBitrateKbps" +1ms
  lame:encoder processing prop "lame_get_VBR_max_bitrate_kbps" as "VBRMaxBitrateKbps" +0ms
  lame:encoder processing prop "lame_set_VBR_max_bitrate_kbps" as "VBRMaxBitrateKbps" +1ms
  lame:encoder processing prop "lame_get_VBR_hard_min" as "VBRHardMin" +0ms
  lame:encoder processing prop "lame_set_VBR_hard_min" as "VBRHardMin" +1ms
  lame:encoder processing prop "lame_get_lowpassfreq" as "lowpassfreq" +0ms
  lame:encoder processing prop "lame_set_lowpassfreq" as "lowpassfreq" +1ms
  lame:encoder processing prop "lame_get_lowpasswidth" as "lowpasswidth" +0ms
  lame:encoder processing prop "lame_set_lowpasswidth" as "lowpasswidth" +1ms
  lame:encoder processing prop "lame_get_highpassfreq" as "highpassfreq" +0ms
  lame:encoder processing prop "lame_set_highpassfreq" as "highpassfreq" +1ms
  lame:encoder processing prop "lame_get_highpasswidth" as "highpasswidth" +0ms
  lame:encoder processing prop "lame_set_highpasswidth" as "highpasswidth" +1ms
  spotify-web:schemas loadMessage("mercury", "MercuryMultiGetRequest") [protobuf] +649ms
  spotify-web:schemas loadPackage("mercury") [protobuf] +2ms
  spotify-web:schemas loadMessage("mercury", "MercuryMultiGetReply") [protobuf] +3ms
  spotify-web:schemas loadPackage("mercury") [protobuf, cached] +1ms
  spotify-web:schemas loadMessage("mercury", "MercuryRequest") [protobuf] +1ms
  spotify-web:schemas loadPackage("mercury") [protobuf, cached] +0ms
  spotify-web:schemas loadMessage("metadata", "Artist") [protobuf] +3ms
  spotify-web:schemas loadPackage("metadata") [protobuf] +1ms
  spotify-web:schemas loadMessage("metadata", "Album") [protobuf] +4ms
  spotify-web:schemas loadPackage("metadata") [protobuf, cached] +1ms
  spotify-web:schemas loadMessage("metadata", "Track") [protobuf] +4ms
  spotify-web:schemas loadPackage("metadata") [protobuf, cached] +1ms
  spotify-web:schemas loadMessage("metadata", "Image") [protobuf] +3ms
  spotify-web:schemas loadPackage("metadata") [protobuf, cached] +1ms
  spotify-web:schemas loadMessage("metadata", "Restriction") [protobuf] +3ms
  spotify-web:schemas loadPackage("metadata") [protobuf, cached] +0ms
  spotify-web:schemas loadMessage("playlist4", "SelectedListContent") [protobuf] +1ms
  spotify-web:schemas loadPackage("playlist4") [protobuf] +1ms
  spotify-web:schemas loadMessage("bartender", "StoryRequest") [protobuf] +9ms
  spotify-web:schemas loadPackage("bartender") [protobuf] +1ms
  spotify-web:schemas loadMessage("bartender", "StoryList") [protobuf] +2ms
  spotify-web:schemas loadPackage("bartender") [protobuf, cached] +1ms
  spotify-web Spotify#login("XXXXXXX", "******") +113ms
  spotify-web GET "https://play.spotify.com/" +2ms
  superagent max redirects 5 +1ms
  superagent set User-Agent "Mozilla/5.0 (Chrome/13.37 compatible-ish) spotify-web/1.3.0" +10ms
  superagent GET https://play.spotify.com/ +145ms
  superagent GET https://play.spotify.com/ -> 200 +240ms
  superagent end GET https://play.spotify.com/ +47ms
  superagent clear timeout GET https://play.spotify.com/ +4ms
  spotify-web landing page: 200 status code, "text/html" content-type +1ms
  spotify-web Spotify.Web.Login() +240ms
  spotify-web login CSRF token: "66062e874820288c6355bbacc4d899ad", tracking ID: "0b83fc94e4db988a0f4f09d4dbf216c57d09e14a" +1ms
  spotify-web POST "https://play.spotify.com/xhr/json/auth.php" +0ms
  superagent max redirects 5 +2ms
  superagent set User-Agent "Mozilla/5.0 (Chrome/13.37 compatible-ish) spotify-web/1.3.0" +4ms
  superagent set Content-Type "application/x-www-form-urlencoded" +23ms
  superagent POST https://play.spotify.com/xhr/json/auth.php +2ms
  superagent set Content-Length "141" +4ms
  superagent clear timeout GET https://play.spotify.com/ +12ms
  superagent POST https://play.spotify.com/xhr/json/auth.php -> 200 +436ms
  superagent end POST https://play.spotify.com/xhr/json/auth.php +24ms
  superagent clear timeout POST https://play.spotify.com/xhr/json/auth.php +5ms
  spotify-web auth 200 status code, "application/json; charset=utf-8" content-type +1ms
  spotify-web ap resolver {"hostname":"apresolve.spotify.com","site":null,"override":null} +1ms
  spotify-web GET "http://apresolve.spotify.com" +0ms
  superagent max redirects 5 +3ms
  superagent set User-Agent "Mozilla/5.0 (Chrome/13.37 compatible-ish) spotify-web/1.3.0" +4ms
  superagent GET http://apresolve.spotify.com +10ms
  superagent clear timeout POST https://play.spotify.com/xhr/json/auth.php +6ms
  superagent GET http://apresolve.spotify.com -> 200 +116ms
  superagent end GET http://apresolve.spotify.com +9ms
  superagent clear timeout GET http://apresolve.spotify.com +1ms
  spotify-web ap resolver 200 status code, "application/json; charset=utf-8" content-type +1ms
  spotify-web WS "wss://lon2-linkap-a2.ap.spotify.com:443/" +0ms
  superagent clear timeout GET http://apresolve.spotify.com +19ms
  spotify-web WebSocket "open" event +422ms
  spotify-web connect() +1ms
  spotify-web sendCommand("connect", ["201","4fe3a646c1e24ed3237330401fea7692a6c6e4f0","{\"ip\":\"83.47.200.110\",\"timestamp\":1438015346,\"ttl\":900,\"useragent\":\"Mozilla\\/5.0 (Chrome\\/13.37 compatible-ish) spotify-web\\/1.3.0\",\"version\":62300485,\"token\":\"NApjCksKDVNwb3RpZnktdXNlcnMSDGp1YW5taXRvMTk4MhoDmAEBJfZitlUyIgoIaXzGlEhkbjwSFnK2aAfKre9M7FH1ihRm0N9gtAaztqwSFJMRyk_dCEuVzAn6Ut7mtNdt7cB0\"}"]) +1ms
  spotify-web storing callback function for message id 0 +0ms
  spotify-web sending command: {"name":"connect","id":"0","args":["201","4fe3a646c1e24ed3237330401fea7692a6c6e4f0","{\"ip\":\"83.47.200.110\",\"timestamp\":1438015346,\"ttl\":900,\"useragent\":\"Mozilla\\/5.0 (Chrome\\/13.37 compatible-ish) spotify-web\\/1.3.0\",\"version\":62300485,\"token\":\"NApjCksKDVNwb3RpZnktdXNlcnMSDGp1YW5taXRvMTk4MhoDmAEBJfZitlUyIgoIaXzGlEhkbjwSFnK2aAfKre9M7FH1ihRm0N9gtAaztqwSFJMRyk_dCEuVzAn6Ut7mtNdt7cB0\"}"]} +1ms
  spotify-web WebSocket "message" event: {"id":0,"result":"ok"} +207ms
  spotify-web starting heartbeat every 180 seconds +1ms
  spotify-web WebSocket "message" event: {"message":["do_work","var t2=0; try{ for(var i=0; i<7200941293..toString(32<<0).length;i++) t2 = t2+(~-~-~-~-~-~-~-~-~-~-~-~'X'['XXX']);}catch(_) {}; this.reply('' + t2);"]} +9ms
  spotify-web got "do_work" payload: "var t2=0; try{ for(var i=0; i<7200941293..toString(32<<0).length;i++) t2 = t2+(~-~-~-~-~-~-~-~-~-~-~-~'X'['XXX']);}catch(_) {}; this.reply('' + t2);" +2ms
  spotify-web reply(["-84"]) +4ms
  spotify-web sendCommand("sp/work_done", ["-84"]) +0ms
  spotify-web storing callback function for message id 1 +1ms
  spotify-web sending command: {"name":"sp/work_done","id":"1","args":["-84"]} +0ms
  spotify-web WebSocket "message" event: {"message":["ping_flash2","3 237 183 83 141 183 3 230 82 9 79 42 162 156 82 224 68 96 248 192"]} +6ms
  superagent max redirects 5 +1ms
  superagent set User-Agent "Mozilla/5.0 (Chrome/13.37 compatible-ish) spotify-web/1.3.0" +2ms
  superagent GET http://ping-pong.spotify.nodestuff.net/3-237-183-83-141-183-3-230-82-9-79-42-162-156-82-224-68-96-248-192 +3ms
  spotify-web WebSocket "message" event: {"id":1,"result":"ok"} +36ms
  spotify-web "sp/work_done" ACK +1ms
  superagent GET http://ping-pong.spotify.nodestuff.net/3-237-183-83-141-183-3-230-82-9-79-42-162-156-82-224-68-96-248-192 -> 200 +186ms
  superagent end GET http://ping-pong.spotify.nodestuff.net/3-237-183-83-141-183-3-230-82-9-79-42-162-156-82-224-68-96-248-192 +4ms
  superagent clear timeout GET http://ping-pong.spotify.nodestuff.net/3-237-183-83-141-183-3-230-82-9-79-42-162-156-82-224-68-96-248-192 +2ms
  spotify-web sendCommand("sp/pong_flash2", ["63 46 2 42 180 168 254 254 201 16"]) +1ms
  spotify-web sending command: {"name":"sp/pong_flash2","id":"2","args":["63 46 2 42 180 168 254 254 201 16"]} +0ms
  superagent clear timeout GET http://ping-pong.spotify.nodestuff.net/3-237-183-83-141-183-3-230-82-9-79-42-162-156-82-224-68-96-248-192 +2ms
  spotify-web WebSocket "message" event: {"message":["login_complete"]} +47ms
  spotify-web sendCommand("sp/log", [41,1,0,0,0,0]) +1ms
  spotify-web sending command: {"name":"sp/log","id":"3","args":[41,1,0,0,0,0]} +0ms
  spotify-web sendCommand("sp/user_info", []) +2ms
  spotify-web storing callback function for message id 4 +0ms
  spotify-web sending command: {"name":"sp/user_info","id":"4","args":[]} +0ms
  spotify-web WebSocket "message" event: {"id":3,"result":null} +44ms
  spotify-web WebSocket "message" event: {"id":4,"result":{"ab_collection_union":"1","ab_test_group":"707","ads":"0","app_developer":"0","catalogue":"premium","country":"ES","head_files":"0","head_files_url":"http://heads-ec.spotify.com/head/{file_id}","lastfm_session":"","license_agreements":"0.8.8-ES","link_tutorial_completed":"1","post_open_graph":"1","preferred_locale":"es","product":"premium","publish_playlist":"1","user":"XXXX","wanted_licenses":"0.8.8-ES"}} +3ms
  spotify-web metadata("spotify:track:6tdp8sdXrXlPV6AZZN2PE8") +1ms
  spotify-web sendProtobufRequest({"header":{"method":"GET","uri":"hm://metadata/track/d49fcea60d1f450691669b67af3bda24"},"payload":null,"isMultiGet":false,"responseSchema":{}}) +7ms
  spotify-web sendCommand("sp/hm_b64", [0,"CjRobTovL21ldGFkYXRhL3RyYWNrL2Q0OWZjZWE2MGQxZjQ1MDY5MTY2OWI2N2FmM2JkYTI0EgAaA0dFVCoA"]) +2ms
  spotify-web storing callback function for message id 5 +1ms
  spotify-web sending command: {"name":"sp/hm_b64","id":"5","args":[0,"CjRobTovL21ldGFkYXRhL3RyYWNrL2Q0OWZjZWE2MGQxZjQ1MDY5MTY2OWI2N2FmM2JkYTI0EgAaA0dFVCoA"]} +0ms
  spotify-web WebSocket "message" event: {"id":5,"result":["CjRobTovL21ldGFkYXRhL3RyYWNrL2Q0OWZjZWE2MGQxZjQ1MDY5MTY2OWI2N2FmM2JkYTI0Ehp2bmQuc3BvdGlmeS9tZXRhZGF0YS10cmFjayCQAzIYCgpNRC1WZXJzaW9uEgoxNDM4MDA1NjAzMg8KBk1DLVRUTBIFNzY2NDUyGQoPTUMtQ2FjaGUtUG9saWN5EgZwdWJsaWMyDwoHTUMtRVRhZxIE2vBDSQ==","ChDUn86mDR9FBpFmm2evO9okEh9HZXQgRG93biBPbiBJdCAtIFNpbmdsZSBWZXJzaW9uGqwCChCO0qf1uS5I8I6Nyp9l4u95EgpOdW1iZXIgMSdzGiMKEIEz4+uoyUblhz1ntdSAkjgSD0tvb2wgJiBUaGUgR2FuZyodVW5pdmVyc2FsIFN0cmF0ZWdpYyBNYXJrZXRpbmcyBwiuHxAQGDhKHgoUfFpONx0yKr7zWqLYKmllGnMStzgQABjYBCCYBEodChRSViE2qNPWF1Zp9mB5jtgzkho62hABGIABIHJKHgoUtPs3+DigVohvC4EjlJ7BI0uF3rIQAhiACiD2CIoBXwoeChR8Wk43HTIqvvNaotgqaWUacxK3OBAAGNgEIJgECh0KFFJWITao09YXVmn2YHmO2DOSGjraEAEYgAEgcgoeChS0+zf4OKBWiG8LgSOUnsEjS4XeshACGIAKIPYIIiMKEIEz4+uoyUblhz1ntdSAkjgSD0tvb2wgJiBUaGUgR2FuZygMMAI4uogaQD5SFAoEaXNyYxIMVVNQUjM4MTAwMDQ0WgoIAAgBCAMSAlVTWgQIBBIAYhgKFGCePs5v2dCYFeaspD5qHhI+L8yQEAJiGAoUT4E+Tha/KW/ir/C0Oyn0114B04QQAWIYChRIunAAyhB0A8QZwpPsBLupwY9x2RAAYhgKFIaR7ooPGZT3hY2wpFqmbnE9kZ9hEAdiAhAFYhgKFHPICNM/dlr/IoW7UYWmFD2oFUZDEAhqqgEKEBRlh5G2YETzj+w7MX3Oz6JaCggACAEIAxICRVNaBAgEEgBiGAoUp+6h+8swDW+5wvHDumWwQGIVLj4QAmIYChQPS3KljGtEejseghIxyJAF51P8+BABYhgKFDjqbzGBQJt6jDdN9WZTKYvs1pmQEABiGAoUHluOFJKXbH1AzWj8Yvk5MYoKTmMQB2ICEAViGAoU7JCQXP2Ks4+avlcMgHn37J+7X8kQCGqsAQoQDBDMfWGqQQ2/dWioO3teAloMCAAIAQgDEgRDQVVTWgQIBBIAYhgKFFzPpDUjuj5ow4glym/Zcp8upNZPEAJiGAoU3E1jElVUEM/R5VBtqPKcjbeBreMQAWIYChQam4wrpSzhdubzw8RG84ZJfSKH1RAAYhgKFFQLz0Y9i1U6Vx2UJQpWfGyD+0gHEAdiAhAFYhgKFBj+73kp8U+0sTESQk9zAy8ILEnPEAhqygIKEDuZV62mcES4spx2jo0+QZRaqQEIAAgBCAMSoAFBREFHQVJBVEFVQkJCRUJHQk9CUkJTQlpDSENMQ05DT0NSQ1lDWkRFREtETURPRUNFRUVTRklGUkdCR0RHUkdUR1lIS0hOSFJIVEhVSURJRUlMSU5JU0lUSk1KUEtOTENMSUxUTFVMVk1DTVRNWU5JTkxOT05aUEFQRVBIUExQVFBZUk9SVVNFU0dTSVNLU1ZUSFRSVFRUV1VBVVlWQ1pBWgQIBBIAYhgKFN2TvaHG60Rea9+tplRRuESXhxTcEAJiGAoUWonETDuXKw26UgbIVDBwXymjcc0QAWIYChTdm03Jfqr7aUFtfwtju1lB2SHvwRAAYgIQBWIYChTMKF2JL1UCHpKNdHc4Nwz7YrdSwxAHYhgKFFqiDGhFvmCMbiI/J+UpXr9g8LZaEAhqqgEKEJLM8I8YgUKantWS1o4ZUwNaCggACAEIAxICTVhaBAgEEgBiGAoUzy/nbF2Q0HK1q05+MsSGTBlP/8YQAmIYChSdXLQo2OJCWZ2UmEezyhmXC7CdzBABYhgKFGc+6zPT1vnFeGVUMIB48snSqYDjEABiGAoUFCmG1iwuB+sVXX6wDeMaNzN2X8cQB2ICEAViGAoUa7k/XCL9y02wfg4iuoBDhjPi9TcQCHoYChRM+uF4+SrZUsB/OQCZM68jjkeqgBAG"]} +50ms
  spotify-web response header: {"uri":"hm://metadata/track/d49fcea60d1f450691669b67af3bda24","contentType":"vnd.spotify/metadata-track","statusCode":200,"userFields":[{"name":"MD-Version","value":{"type":"Buffer","data":[49,52,51,56,48,48,53,54,48,51]}},{"name":"MC-TTL","value":{"type":"Buffer","data":[55,54,54,52,53]}},{"name":"MC-Cache-Policy","value":{"type":"Buffer","data":[112,117,98,108,105,99]}},{"name":"MC-ETag","value":{"type":"Buffer","data":[218,240,67,73]}}]} +4ms
  spotify-web parsed response: [ "vnd.spotify/metadata-track" ] {"gid":{"type":"Buffer","data":[212,159,206,166,13,31,69,6,145,102,155,103,175,59,218,36]},"name":"Get Down On It - Single Version","album":{"gid":{"type":"Buffer","data":[142,210,167,245,185,46,72,240,142,141,202,159,101,226,239,121]},"name":"Number 1's","artist":[{"gid":{"type":"Buffer","data":[129,51,227,235,168,201,70,229,135,61,103,181,212,128,146,56]},"name":"Kool & The Gang"}],"label":"Universal Strategic Marketing","date":{"year":2007,"month":8,"day":28},"cover":[{"fileId":{"type":"Buffer","data":[124,90,78,55,29,50,42,190,243,90,162,216,42,105,101,26,115,18,183,56]},"size":"DEFAULT","width":300,"height":268},{"fileId":{"type":"Buffer","data":[82,86,33,54,168,211,214,23,86,105,246,96,121,142,216,51,146,26,58,218]},"size":"SMALL","width":64,"height":57},{"fileId":{"type":"Buffer","data":[180,251,55,248,56,160,86,136,111,11,129,35,148,158,193,35,75,133,222,178]},"size":"LARGE","width":640,"height":571}],"coverGroup":{"image":[{"fileId":{"type":"Buffer","data":[124,90,78,55,29,50,42,190,243,90,162,216,42,105,101,26,115,18,183,56]},"size":"DEFAULT","width":300,"height":268},{"fileId":{"type":"Buffer","data":[82,86,33,54,168,211,214,23,86,105,246,96,121,142,216,51,146,26,58,218]},"size":"SMALL","width":64,"height":57},{"fileId":{"type":"Buffer","data":[180,251,55,248,56,160,86,136,111,11,129,35,148,158,193,35,75,133,222,178]},"size":"LARGE","width":640,"height":571}]}},"artist":[{"gid":{"type":"Buffer","data":[129,51,227,235,168,201,70,229,135,61,103,181,212,128,146,56]},"name":"Kool & The Gang"}],"number":6,"discNumber":1,"duration":213533,"popularity":31,"externalId":[{"type":"isrc","id":"USPR38100044"}],"restriction":[{"catalogue":["AD","SUBSCRIPTION","SHUFFLE"],"countriesAllowed":"US"},{"countriesAllowed":""}],"file":[{"fileId":{"type":"Buffer","data":[96,158,62,206,111,217,208,152,21,230,172,164,62,106,30,18,62,47,204,144]},"format":"OGG_VORBIS_320"},{"fileId":{"type":"Buffer","data":[79,129,62,78,22,191,41,111,226,175,240,180,59,41,244,215,94,1,211,132]},"format":"OGG_VORBIS_160"},{"fileId":{"type":"Buffer","data":[72,186,112,0,202,16,116,3,196,25,194,147,236,4,187,169,193,143,113,217]},"format":"OGG_VORBIS_96"},{"fileId":{"type":"Buffer","data":[134,145,238,138,15,25,148,247,133,141,176,164,90,166,110,113,61,145,159,97]}},{"format":"MP3_160"},{"fileId":{"type":"Buffer","data":[115,200,8,211,63,118,90,255,34,133,187,81,133,166,20,61,168,21,70,67]}}],"alternative":[{"gid":{"type":"Buffer","data":[20,101,135,145,182,96,68,243,143,236,59,49,125,206,207,162]},"restriction":[{"catalogue":["AD","SUBSCRIPTION","SHUFFLE"],"countriesAllowed":"ES"},{"countriesAllowed":""}],"file":[{"fileId":{"type":"Buffer","data":[167,238,161,251,203,48,13,111,185,194,241,195,186,101,176,64,98,21,46,62]},"format":"OGG_VORBIS_320"},{"fileId":{"type":"Buffer","data":[15,75,114,165,140,107,68,122,59,30,130,18,49,200,144,5,231,83,252,248]},"format":"OGG_VORBIS_160"},{"fileId":{"type":"Buffer","data":[56,234,111,49,129,64,155,122,140,55,77,245,102,83,41,139,236,214,153,144]},"format":"OGG_VORBIS_96"},{"fileId":{"type":"Buffer","data":[30,91,142,20,146,151,108,125,64,205,104,252,98,249,57,49,138,10,78,99]}},{"format":"MP3_160"},{"fileId":{"type":"Buffer","data":[236,144,144,92,253,138,179,143,154,190,87,12,128,121,247,236,159,187,95,201]}}]},{"gid":{"type":"Buffer","data":[12,16,204,125,97,170,65,13,191,117,104,168,59,123,94,2]},"restriction":[{"catalogue":["AD","SUBSCRIPTION","SHUFFLE"],"countriesAllowed":"CAUS"},{"countriesAllowed":""}],"file":[{"fileId":{"type":"Buffer","data":[92,207,164,53,35,186,62,104,195,136,37,202,111,217,114,159,46,164,214,79]},"format":"OGG_VORBIS_320"},{"fileId":{"type":"Buffer","data":[220,77,99,18,85,84,16,207,209,229,80,109,168,242,156,141,183,129,173,227]},"format":"OGG_VORBIS_160"},{"fileId":{"type":"Buffer","data":[26,155,140,43,165,44,225,118,230,243,195,196,70,243,134,73,125,34,135,213]},"format":"OGG_VORBIS_96"},{"fileId":{"type":"Buffer","data":[84,11,207,70,61,139,85,58,87,29,148,37,10,86,124,108,131,251,72,7]}},{"format":"MP3_160"},{"fileId":{"type":"Buffer","data":[24,254,239,121,41,241,79,180,177,49,18,66,79,115,3,47,8,44,73,207]}}]},{"gid":{"type":"Buffer","data":[59,153,87,173,166,112,68,184,178,156,118,142,141,62,65,148]},"restriction":[{"catalogue":["AD","SUBSCRIPTION","SHUFFLE"],"countriesAllowed":"ADAGARATAUBBBEBGBOBRBSBZCHCLCNCOCRCYCZDEDKDMDOECEEESFIFRGBGDGRGTGYHKHNHRHTHUIDIEILINISITJMJPKNLCLILTLULVMCMTMYNINLNONZPAPEPHPLPTPYRORUSESGSISKSVTHTRTTTWUAUYVCZA"},{"countriesAllowed":""}],"file":[{"fileId":{"type":"Buffer","data":[221,147,189,161,198,235,68,94,107,223,173,166,84,81,184,68,151,135,20,220]},"format":"OGG_VORBIS_320"},{"fileId":{"type":"Buffer","data":[90,137,196,76,59,151,43,13,186,82,6,200,84,48,112,95,41,163,113,205]},"format":"OGG_VORBIS_160"},{"fileId":{"type":"Buffer","data":[221,155,77,201,126,170,251,105,65,109,127,11,99,187,89,65,217,33,239,193]},"format":"OGG_VORBIS_96"},{"format":"MP3_160"},{"fileId":{"type":"Buffer","data":[204,40,93,137,47,85,2,30,146,141,116,119,56,55,12,251,98,183,82,195]}},{"fileId":{"type":"Buffer","data":[90,162,12,104,69,190,96,140,110,34,63,39,229,41,94,191,96,240,182,90]}}]},{"gid":{"type":"Buffer","data":[146,204,240,143,24,129,66,154,158,213,146,214,142,25,83,3]},"restriction":[{"catalogue":["AD","SUBSCRIPTION","SHUFFLE"],"countriesAllowed":"MX"},{"countriesAllowed":""}],"file":[{"fileId":{"type":"Buffer","data":[207,47,231,108,93,144,208,114,181,171,78,126,50,196,134,76,25,79,255,198]},"format":"OGG_VORBIS_320"},{"fileId":{"type":"Buffer","data":[157,92,180,40,216,226,66,89,157,148,152,71,179,202,25,151,11,176,157,204]},"format":"OGG_VORBIS_160"},{"fileId":{"type":"Buffer","data":[103,62,235,51,211,214,249,197,120,101,84,48,128,120,242,201,210,169,128,227]},"format":"OGG_VORBIS_96"},{"fileId":{"type":"Buffer","data":[20,41,134,214,44,46,7,235,21,93,126,176,13,227,26,55,51,118,95,199]}},{"format":"MP3_160"},{"fileId":{"type":"Buffer","data":[107,185,63,92,34,253,203,77,176,126,14,34,186,128,67,134,51,226,245,55]}}]}],"preview":[{"fileId":{"type":"Buffer","data":[76,250,225,120,249,42,217,82,192,127,57,0,153,51,175,35,142,71,170,128]},"format":"MP3_96"}]} +11ms
Playing: Kool & The Gang - Get Down On It - Single Version
  spotify-web trackUri() +8ms
  spotify-web recurseAlternatives() +1ms
  spotify-web isTrackAvailable() +1ms
  spotify-web type: "SUBSCRIPTION" +1ms
  spotify-web allowed: ["US"] +1ms
  spotify-web forbidden: [] +0ms
  spotify-web isAllowed: false +0ms
  spotify-web isForbidden: false +1ms
  spotify-web applicable: true +0ms
  spotify-web available: false +0ms
  spotify-web type: "SUBSCRIPTION" +1ms
  spotify-web allowed: ["US"] +1ms
  spotify-web forbidden: [] +0ms
  spotify-web isAllowed: false +0ms
  spotify-web isForbidden: false +1ms
  spotify-web applicable: false +0ms
  spotify-web available: false +0ms
  lame:decoder created new Decoder instance +4ms
  speaker format(object keys = [ 'lowWaterMark', 'highWaterMark' ]) +4ms
  speaker _pipe() +10ms
  speaker format(object keys = [ '_readableState', 'readable', 'domain', '_events', '_maxListeners', '_writableState', 'writable', 'allowHalfOpen', '_transformState', 'mh' ]) +0ms
  spotify-web sp/track_uri args: ["mp3160","d49fcea60d1f450691669b67af3bda24"] +6ms
  spotify-web sendCommand("sp/track_uri", ["mp3160","d49fcea60d1f450691669b67af3bda24"]) +0ms
  spotify-web storing callback function for message id 6 +0ms
  spotify-web sending command: {"name":"sp/track_uri","id":"6","args":["mp3160","d49fcea60d1f450691669b67af3bda24"]} +1ms
  spotify-web WebSocket "message" event: {"error":[12,0,""],"id":6} +101ms

events.js:85
      throw er; // Unhandled 'error' event
            ^
TrackError: Account subscription status not Spotify Premium
    at Spotify._onmessage (/spotify-app/node_modules/spotify-web/lib/spotify.js:401:15)
    at WebSocket.emit (events.js:110:17)
    at Receiver.ontext (/spotify-app/node_modules/spotify-web/node_modules/ws/lib/WebSocket.js:798:10)
    at /spotify-app/node_modules/spotify-web/node_modules/ws/lib/Receiver.js:473:18
    at Receiver.applyExtensions (/spotify-app/node_modules/spotify-web/node_modules/ws/lib/Receiver.js:360:5)
    at /spotify-app/node_modules/spotify-web/node_modules/ws/lib/Receiver.js:462:14
    at Receiver.flush (/spotify-app/node_modules/spotify-web/node_modules/ws/lib/Receiver.js:336:3)
    at Receiver.opcodes.1.finish (/spotify-app/node_modules/spotify-web/node_modules/ws/lib/Receiver.js:478:12)
    at Receiver.expectHandler (/spotify-app/node_modules/spotify-web/node_modules/ws/lib/Receiver.js:453:31)
    at Receiver.add (/spotify-app/node_modules/spotify-web/node_modules/ws/lib/Receiver.js:91:24)
alfs commented 8 years ago

Ok, now I also get event: {"error":[12,0,""],"id":6} a.k.a. subscription status not premium.

juanmito commented 8 years ago

So, Arch is not working now, isn't it? Hmmm

Any news?

juanmito commented 8 years ago

Hi again. I've been testing on differents environments, and, finally, all of them answer at the same way. I think the problem is isolated, but, not the solution :(

@TooTallNate did you find anything??

I hope we can find a fix. This is the only way I can listen to spotify music in my ARM-based computer

vincentcox commented 8 years ago

@juanmito can you post which platforms you tested? :red_circle: So Arch doesn't work anymore? :red_circle:

juanmito commented 8 years ago

Yes

I've tested on:

Arch over x86 Arch over arm Mac osx Ubuntu over arm

El 31/7/2015, a las 16:45, Vincent Cox notifications@github.com escribió:

@juanmito can you post which platforms you tested? So Arch doesn't work anymore?

— Reply to this email directly or view it on GitHub.

amuaamua commented 8 years ago

Hi everybody, I have seen some more changes they have made: 1: In play.spotify.com the track uri doesn't exist anymore. It just redirects you to the album page. 2: In the album page, now, of course, the websocket sends a lot of hm_b64 messages. I don't know if they will keep them as a security measure, apart from requesting information. 3: The websocket also sends many sp/log and sp/log_view messages that don't exist in the node project. 4: Some of the messages encoded in base64 carry some non-readable characters that I cannot decrypt.

I love the way the project has been coded. It's very high coding level! ^^

Kisses 4 all