diff --git a/clients/MalojaScrobbler.js b/clients/MalojaScrobbler.js index dc59d542..9fc33777 100644 --- a/clients/MalojaScrobbler.js +++ b/clients/MalojaScrobbler.js @@ -16,13 +16,26 @@ export default class MalojaScrobbler extends AbstractScrobbleClient { const { artists, title, + album, + duration, time, } = obj; - let artistString = artists.reduce((acc, curr) => acc.concat(curr.name), []).join(','); + let artistStrings = artists.reduce((acc, curr) => { + let aString; + if(typeof curr === 'string') { + aString = curr; + } else if(typeof curr === 'object') { + aString = curr.name; + } + const aStrings = aString.split(','); + return [...acc, ...aStrings]; + }, []); return { data: { - artist: artistString, + artists: [...new Set(artistStrings)], track: title, + album, + duration, playDate: dayjs.unix(time), }, meta: { @@ -145,6 +158,7 @@ export default class MalojaScrobbler extends AbstractScrobbleClient { const lowerTitle = track.toLocaleLowerCase(); const largeDiffs = []; // TODO add a runtime config option for verbose debugging for commented log statements + // TODO check artists as well const existingScrobble = this.recentScrobbles.find((x) => { const {data: {playDate: scrobbleTime, track: scrobbleTitle} = {}} = x; const lowerScrobbleTitle = scrobbleTitle.toLocaleLowerCase(); @@ -189,9 +203,10 @@ export default class MalojaScrobbler extends AbstractScrobbleClient { const { data: { - artist, + artists, album, track, + duration, playDate } = {}, meta: { @@ -206,7 +221,10 @@ export default class MalojaScrobbler extends AbstractScrobbleClient { await this.callApi(request.post(`${url}/apis/mlj_1/newscrobble`) .type('json') .send({ - artist, + // maloja seems to detect this deliminator much better than commas + // also less likely artist has a forward slash in their name than a comma + artist: artists.join(' / '), + seconds: duration, title: track, album, key: apiKey, diff --git a/sources/PlexSource.js b/sources/PlexSource.js index 85851640..f0b4b7f0 100644 --- a/sources/PlexSource.js +++ b/sources/PlexSource.js @@ -43,7 +43,7 @@ export default class PlexSource { } = obj; return { data: { - artist, + artists: [artist], album, track, playDate: dayjs(), @@ -64,23 +64,23 @@ export default class PlexSource { mediaType, event, user }, data: { - artist, + artists, track, } = {} } = playObj; if (this.users !== undefined && user !== undefined && !this.users.includes(user)) { - this.logger.debug(`Will not scrobble webhook event because author was not an allowed user: ${user}`, { artist, track }) + this.logger.debug(`Will not scrobble webhook event because author was not an allowed user: ${user}`, { artists, track }) return false; } if (event !== 'media.scrobble') { - this.logger.debug(`Will not scrobble webhook event because it is not media.scrobble (${event})`, { artist, track }) + this.logger.debug(`Will not scrobble webhook event because it is not media.scrobble (${event})`, { artists, track }) return false; } if (mediaType !== 'track') { - this.logger.debug(`Will not scrobble webhook event because media type was not a track (${mediaType})`, { artist, track }); + this.logger.debug(`Will not scrobble webhook event because media type was not a track (${mediaType})`, { artists, track }); return false; } diff --git a/sources/SpotifySource.js b/sources/SpotifySource.js index 4534d152..a9455f27 100644 --- a/sources/SpotifySource.js +++ b/sources/SpotifySource.js @@ -51,17 +51,22 @@ export default class SpotifySource { name, id, duration_ms, + album: { + name: albumName, + } = {}, external_urls: { spotify, } = {} } = {}, played_at } = obj; - let artistString = artists.reduce((acc, curr) => acc.concat(curr.name), []).join(','); + //let artistString = artists.reduce((acc, curr) => acc.concat(curr.name), []).join(','); return { data: { - artist: artistString, + artists: artists.map(x => x.name), + album: albumName, track: name, + duration: duration_ms / 1000, playDate: dayjs(played_at), }, meta: { diff --git a/sources/TautulliSource.js b/sources/TautulliSource.js index 5f6c3aff..73719e23 100644 --- a/sources/TautulliSource.js +++ b/sources/TautulliSource.js @@ -19,13 +19,13 @@ export default class TautulliSource extends PlexSource { duration, username, } = obj; - let artist = artist_name; + let artists = [artist_name]; if (track_artist !== undefined && track_artist !== artist_name) { - artist = `${artist},${track_artist}`; + artists.push(track_artist); } return { data: { - artist, + artists, album: album_name, track: track_name, playDate: dayjs(), @@ -48,17 +48,17 @@ export default class TautulliSource extends PlexSource { mediaType, user }, data: { - artist, + artists, track, } = {} } = playObj; if (this.users !== undefined && user !== undefined && !this.users.includes(user)) { - this.logger.debug(`Will not scrobble webhook event because author was not an allowed user: ${user}`, artist, track) + this.logger.debug(`Will not scrobble webhook event because author was not an allowed user: ${user}`, artists, track) return false; } if (mediaType !== 'track') { - this.logger.debug(`Will not scrobble webhook event because media type was not a track (${mediaType})`, artist, track); + this.logger.debug(`Will not scrobble webhook event because media type was not a track (${mediaType})`, artists, track); return false; } return true; diff --git a/utils.js b/utils.js index bc2feb48..0bdd306a 100644 --- a/utils.js +++ b/utils.js @@ -80,7 +80,7 @@ export const buildTrackString = (playObj, options = {}) => { const { include = ['time'], transformers: { - artist: artistFunc = defaultTransformer, + artists: artistsFunc = a => a.join(' / '), track: trackFunc = defaultTransformer, time: timeFunc = t => t.local().format(), timeFromNow = t => t.local().fromNow(), @@ -88,14 +88,14 @@ export const buildTrackString = (playObj, options = {}) => { } = options; const { data: { - artist, + artists, album, track, playDate } = {} } = playObj; - let str = `${artistFunc(artist)} - ${trackFunc(track)}`; + let str = `${artistsFunc(artists)} - ${trackFunc(track)}`; if (include.includes('time')) { str = `${str}, played at ${timeFunc(playDate)}` }