Skip to content

▶️ Add track.updateNowPlaying #76

Description

@ansango

Parent epic: #67

User story

As a consumer of lastfm-client-ts, I want track.updateNowPlaying to announce the current track with the complete documented metadata, so that players can update Last.fm state without abusing scrobble or hand-signing requests.

Official Last.fm contract

  • Docs: https://www.last.fm/api/show/track.updateNowPlaying
  • Historical issue: track.updateNowPlaying #44
  • Transport: HTTPS signed POST with authenticated session.
  • Required functional params: artist, track.
  • Optional functional params: album, trackNumber, context, mbid, duration (seconds), albumArtist.
  • Generated/auth params: method, api_key, api_sig, sk, format=json.
  • Response root: nowplaying, including corrected text fields for track/artist/album/albumArtist and ignoredMessage with code/text.
  • Documentation ambiguities:
    • ignored codes mention timestamp even though this endpoint does not document timestamp; do not add it;
    • context is available only to some API keys;
    • optional request values are not all echoed in the sample response;
    • corrected/code values may be strings in JSON.

Public TypeScript API

track.updateNowPlaying(
  params: {
    artist: string;
    track: string;
    album?: string;
    trackNumber?: number | string;
    context?: string;
    mbid?: string;
    duration?: number | string;
    albumArtist?: string;
    sk?: string;
  },
  init?: RequestInit
): Promise<TrackUpdateNowPlayingResponse>;

Export request/response schemas, inferred types, and small corrected-text/ignored-message components when reusable with verified scrobble wire shapes.

Implementation standard

Primary files:

Requirements:

  1. Require non-empty artist/track and validate optional scalar fields using compatible base schemas.
  2. Preserve exact public/wire names trackNumber and albumArtist; do not silently rename to snake case.
  3. Omit undefined optional values from body and signature.
  4. Resolve request/config session and delegate to shared signed POST.
  5. Build a faithful endpoint-specific response schema for nowplaying, corrected attributes/text, and ignored message.
  6. Reuse scrobble corrected-field components only after confirming identical JSON shape; otherwise keep them separate.
  7. Do not introduce a timestamp parameter.
  8. Add official JSDoc and verify root/track/track-schema exports.
  9. Preserve all existing track methods/aliases.

Security and side effects

The method mutates the account's current now-playing state. Do not log session/signature/body/signed URL. Unit tests are mocked. The later manual workflow documents this transient state and uses a stable test track; there is no official undo endpoint.

Out of scope

  • Scrobbling the play or adding a timestamp.
  • Guaranteeing access to restricted context for every API key.
  • Polling Last.fm until now-playing expires.
  • Track tag/love/correction methods owned by other child issues.

Dependencies

Blocked by #68 — Unify signed POST transport and migrate track.scrobble shared signed POST transport.

Acceptance criteria

  • Canonical track.updateNowPlaying exists with required/optional params above.
  • Undefined options are absent from body/signature; minimum and full requests are covered.
  • Exact wire casing for trackNumber/albumArtist is retained.
  • timestamp is not accepted/emitted.
  • Request/config/missing session behavior is shared and tested.
  • URL has no write fields; body contains method/API/session/signature/format.
  • Response schema parses corrected fields and ignored message from a verified fixture.
  • Invalid-session/API errors are normalized.
  • Public exports work and existing track methods do not regress.

Verification

Mock tests inspect minimum/full bodies and signatures, omission of undefined, numeric/string duration/track number, Unicode, response corrected/ignored fields, invalid session, and exports. Future manual workflow calls the real endpoint using the dedicated account and sanitized logs.

Historical context

Supersedes closed issue #44. See #63 and parent #67. Do not reopen/edit #44.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions