spotify-profile-monitor 2.5.1__tar.gz → 2.5.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spotify_profile_monitor
3
- Version: 2.5.1
3
+ Version: 2.5.3
4
4
  Summary: Tool implementing real-time tracking of Spotify users activities and profile changes including playlists
5
5
  Author-email: Michal Szymanski <misiektoja-pypi@rm-rf.ninja>
6
6
  License-Expression: GPL-3.0-or-later
@@ -28,7 +28,7 @@ Dynamic: license-file
28
28
 
29
29
  # spotify_profile_monitor
30
30
 
31
- spotify_profile_monitor is an OSINT tool for real-time monitoring of Spotify users' activities and profile changes including playlists.
31
+ OSINT tool for real-time monitoring of Spotify users' activities and profile changes including playlists.
32
32
 
33
33
  NOTE: If you want to track Spotify friends' music activity, check out another tool I developed: [spotify_monitor](https://github.com/misiektoja/spotify_monitor).
34
34
 
@@ -246,6 +246,8 @@ If you store the `SP_DC_COOKIE` in a dotenv file you can update its value and se
246
246
 
247
247
  This is the alternative method used to obtain a Spotify access token which simulates a login from the real Spotify desktop app using credentials intercepted from a real session.
248
248
 
249
+ **NOTE**: Spotify appears to have changed something in client versions released after June 2025 (likely a switch to HTTP/3 and/or certificate pinning). You may need to use an older version of the Spotify desktop client for this method to work.
250
+
249
251
  - Run an intercepting proxy of your choice (like [Proxyman](https://proxyman.com)).
250
252
 
251
253
  - Launch the Spotify desktop client and look for POST requests to `https://login{n}.spotify.com/v3/login`
@@ -1,6 +1,6 @@
1
1
  # spotify_profile_monitor
2
2
 
3
- spotify_profile_monitor is an OSINT tool for real-time monitoring of Spotify users' activities and profile changes including playlists.
3
+ OSINT tool for real-time monitoring of Spotify users' activities and profile changes including playlists.
4
4
 
5
5
  NOTE: If you want to track Spotify friends' music activity, check out another tool I developed: [spotify_monitor](https://github.com/misiektoja/spotify_monitor).
6
6
 
@@ -218,6 +218,8 @@ If you store the `SP_DC_COOKIE` in a dotenv file you can update its value and se
218
218
 
219
219
  This is the alternative method used to obtain a Spotify access token which simulates a login from the real Spotify desktop app using credentials intercepted from a real session.
220
220
 
221
+ **NOTE**: Spotify appears to have changed something in client versions released after June 2025 (likely a switch to HTTP/3 and/or certificate pinning). You may need to use an older version of the Spotify desktop client for this method to work.
222
+
221
223
  - Run an intercepting proxy of your choice (like [Proxyman](https://proxyman.com)).
222
224
 
223
225
  - Launch the Spotify desktop client and look for POST requests to `https://login{n}.spotify.com/v3/login`
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "spotify_profile_monitor"
7
- version = "2.5.1"
7
+ version = "2.5.3"
8
8
  description = "Tool implementing real-time tracking of Spotify users activities and profile changes including playlists"
9
9
  readme = "README.md"
10
10
  license = "GPL-3.0-or-later"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spotify_profile_monitor
3
- Version: 2.5.1
3
+ Version: 2.5.3
4
4
  Summary: Tool implementing real-time tracking of Spotify users activities and profile changes including playlists
5
5
  Author-email: Michal Szymanski <misiektoja-pypi@rm-rf.ninja>
6
6
  License-Expression: GPL-3.0-or-later
@@ -28,7 +28,7 @@ Dynamic: license-file
28
28
 
29
29
  # spotify_profile_monitor
30
30
 
31
- spotify_profile_monitor is an OSINT tool for real-time monitoring of Spotify users' activities and profile changes including playlists.
31
+ OSINT tool for real-time monitoring of Spotify users' activities and profile changes including playlists.
32
32
 
33
33
  NOTE: If you want to track Spotify friends' music activity, check out another tool I developed: [spotify_monitor](https://github.com/misiektoja/spotify_monitor).
34
34
 
@@ -246,6 +246,8 @@ If you store the `SP_DC_COOKIE` in a dotenv file you can update its value and se
246
246
 
247
247
  This is the alternative method used to obtain a Spotify access token which simulates a login from the real Spotify desktop app using credentials intercepted from a real session.
248
248
 
249
+ **NOTE**: Spotify appears to have changed something in client versions released after June 2025 (likely a switch to HTTP/3 and/or certificate pinning). You may need to use an older version of the Spotify desktop client for this method to work.
250
+
249
251
  - Run an intercepting proxy of your choice (like [Proxyman](https://proxyman.com)).
250
252
 
251
253
  - Launch the Spotify desktop client and look for POST requests to `https://login{n}.spotify.com/v3/login`
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
3
  Author: Michal Szymanski <misiektoja-github@rm-rf.ninja>
4
- v2.5.1
4
+ v2.5.3
5
5
 
6
6
  OSINT tool implementing real-time tracking of Spotify users activities and profile changes including playlists:
7
7
  https://github.com/misiektoja/spotify_profile_monitor/
@@ -18,7 +18,7 @@ python-dotenv (optional)
18
18
  spotipy (optional, needed when the token source is set to oauth_app)
19
19
  """
20
20
 
21
- VERSION = "2.5.1"
21
+ VERSION = "2.5.3"
22
22
 
23
23
  # ---------------------------
24
24
  # CONFIGURATION SECTION START
@@ -1392,10 +1392,13 @@ def fetch_server_time(session: req.Session, ua: str) -> int:
1392
1392
  def generate_totp():
1393
1393
  import pyotp
1394
1394
 
1395
- secret_cipher_bytes = [
1396
- 12, 56, 76, 33, 88, 44, 88, 33,
1397
- 78, 78, 11, 66, 22, 22, 55, 69, 54,
1398
- ]
1395
+ secret_cipher_dict = {
1396
+ "8": [37, 84, 32, 76, 87, 90, 87, 47, 13, 75, 48, 54, 44, 28, 19, 21, 22],
1397
+ "7": [59, 91, 66, 74, 30, 66, 74, 38, 46, 50, 72, 61, 44, 71, 86, 39, 89],
1398
+ "6": [21, 24, 85, 46, 48, 35, 33, 8, 11, 63, 76, 12, 55, 77, 14, 7, 54],
1399
+ "5": [12, 56, 76, 33, 88, 44, 88, 33, 78, 78, 11, 66, 22, 22, 55, 69, 54]
1400
+ }
1401
+ secret_cipher_bytes = secret_cipher_dict["8"]
1399
1402
 
1400
1403
  transformed = [e ^ ((t % 33) + 9) for t, e in enumerate(secret_cipher_bytes)]
1401
1404
  joined = "".join(str(num) for num in transformed)
@@ -1424,7 +1427,7 @@ def refresh_access_token_from_sp_dc(sp_dc: str) -> dict:
1424
1427
  "productType": "web-player",
1425
1428
  "totp": otp_value,
1426
1429
  "totpServer": otp_value,
1427
- "totpVer": 5,
1430
+ "totpVer": 8,
1428
1431
  "sTime": server_time,
1429
1432
  "cTime": client_time,
1430
1433
  "buildDate": time.strftime("%Y-%m-%d", time.gmtime(server_time)),
@@ -3775,14 +3778,14 @@ def spotify_profile_monitor_uri(user_uri_id, csv_file_name, playlists_to_skip):
3775
3778
  SP_CACHED_ACCESS_TOKEN = None
3776
3779
 
3777
3780
  client_errs = ['access token', 'invalid client token', 'expired client token', 'refresh token has been revoked', 'refresh token has expired', 'refresh token is invalid', 'invalid grant during refresh']
3778
- cookie_errs = ['access token', 'unauthorized']
3781
+ cookie_errs = ['access token', 'unauthorized', 'unsuccessful token request']
3779
3782
  oauth_app_errs = ['invalid_client', 'invalid_client_id', 'could not authenticate you', '401']
3780
3783
  oauth_user_errs = ['invalid_client', 'invalid_grant', 'invalid_scope', 'authorization_required', 'refresh token has been revoked', 'refresh token has expired']
3781
3784
 
3782
3785
  if TOKEN_SOURCE == 'client' and any(k in err for k in client_errs):
3783
3786
  print(f"* Error: client or refresh token may be invalid or expired!\n{str(e)}")
3784
3787
  elif TOKEN_SOURCE == 'cookie' and any(k in err for k in cookie_errs):
3785
- print(f"* Error: sp_dc may be invalid or expired!\n{str(e)}")
3788
+ print(f"* Error: sp_dc may be invalid/expired or Spotify has broken sth again!\n{str(e)}")
3786
3789
  elif TOKEN_SOURCE == 'oauth_app' and any(k in err for k in oauth_app_errs):
3787
3790
  print(f"* Error: OAuth-app client_id/client_secret may be invalid or expired!\n{str(e)}")
3788
3791
  elif TOKEN_SOURCE == 'oauth_user' and any(k in err for k in oauth_user_errs):
@@ -4105,7 +4108,7 @@ def spotify_profile_monitor_uri(user_uri_id, csv_file_name, playlists_to_skip):
4105
4108
  SP_CACHED_ACCESS_TOKEN = None
4106
4109
 
4107
4110
  client_errs = ['access token', 'invalid client token', 'expired client token', 'refresh token has been revoked', 'refresh token has expired', 'refresh token is invalid', 'invalid grant during refresh']
4108
- cookie_errs = ['access token', 'unauthorized']
4111
+ cookie_errs = ['access token', 'unauthorized', 'unsuccessful token request']
4109
4112
  oauth_app_errs = ['invalid_client', 'invalid_client_id', 'could not authenticate you', '401']
4110
4113
  oauth_user_errs = ['invalid_client', 'invalid_grant', 'invalid_scope', 'authorization_required', 'refresh token has been revoked', 'refresh token has expired']
4111
4114
 
@@ -4120,11 +4123,11 @@ def spotify_profile_monitor_uri(user_uri_id, csv_file_name, playlists_to_skip):
4120
4123
  email_sent = True
4121
4124
 
4122
4125
  elif TOKEN_SOURCE == 'cookie' and any(k in err for k in cookie_errs):
4123
- print(f"* Error: sp_dc may be invalid or expired!")
4126
+ print(f"* Error: sp_dc may be invalid/expired or Spotify has broken sth again!")
4124
4127
  if ERROR_NOTIFICATION and not email_sent:
4125
- m_subject = f"spotify_profile_monitor: sp_dc may be invalid or expired! (uri: {user_uri_id})"
4126
- m_body = f"sp_dc may be invalid or expired!\n{e}{get_cur_ts(nl_ch + nl_ch + 'Timestamp: ')}"
4127
- m_body_html = f"<html><head></head><body>sp_dc may be invalid or expired!<br>{escape(str(e))}{get_cur_ts('<br><br>Timestamp: ')}</body></html>"
4128
+ m_subject = f"spotify_profile_monitor: sp_dc may be invalid/expired or Spotify has broken sth again! (uri: {user_uri_id})"
4129
+ m_body = f"sp_dc may be invalid/expired or Spotify has broken sth again!\n{e}{get_cur_ts(nl_ch + nl_ch + 'Timestamp: ')}"
4130
+ m_body_html = f"<html><head></head><body>sp_dc may be invalid/expired or Spotify has broken sth again!<br>{escape(str(e))}{get_cur_ts('<br><br>Timestamp: ')}</body></html>"
4128
4131
  print(f"Sending email notification to {RECEIVER_EMAIL}")
4129
4132
  send_email(m_subject, m_body, m_body_html, SMTP_SSL)
4130
4133
  email_sent = True
@@ -5566,7 +5569,8 @@ def main():
5566
5569
  print(f"* Ignore listed playlists:\t{bool(PLAYLISTS_TO_SKIP_FILE)}" + (f" ({PLAYLISTS_TO_SKIP_FILE})" if PLAYLISTS_TO_SKIP_FILE else ""))
5567
5570
  print(f"* Display profile pics:\t\t{bool(imgcat_exe)}" + (f" (via {imgcat_exe})" if imgcat_exe else ""))
5568
5571
  print(f"* Output logging enabled:\t{not DISABLE_LOGGING}" + (f" ({FINAL_LOG_PATH})" if not DISABLE_LOGGING else ""))
5569
- print(f"* Spotify token cache file:\t{({'oauth_app': SP_APP_TOKENS_FILE, 'oauth_user': SP_USER_TOKENS_FILE}.get(TOKEN_SOURCE) or 'None (memory only)')}")
5572
+ if TOKEN_SOURCE in ('oauth_user', 'oauth_app'):
5573
+ print(f"* Spotify token cache file:\t{({'oauth_app': SP_APP_TOKENS_FILE, 'oauth_user': SP_USER_TOKENS_FILE}.get(TOKEN_SOURCE) or 'None (memory only)')}")
5570
5574
  print(f"* Configuration file:\t\t{cfg_path}")
5571
5575
  print(f"* Dotenv file:\t\t\t{env_path or 'None'}")
5572
5576
  print(f"* Local timezone:\t\t{LOCAL_TIMEZONE}\n")