Nodejs - Spotify API 检查曲目是否存在于播放列表中
Nodejs - Spotify API check if track exists in playlist
我正在 Discord 中创建一个机器人,它可以在特定频道中添加共享歌曲并将其添加到相应的播放列表中。该函数按预期工作,因此我将那部分代码省略了。但如果需要我可以添加。
使用下面的代码,我希望能够评估播放列表是否已包含共享歌曲,如果包含则不要添加。 基本上跳过重复。
const playlists = new Map();
const spectrumPlaylist = {
channelid: '948177541414404116',
name: 'spectrum',
id: '2SDsHpVc7yfQhGg0tS0RQ0'
}
playlists.set('948177541414404116', {
name: 'spectrum',
id: '2SDsHpVc7yfQhGg0tS0RQ0'
})
playlists.set('948185709037121566', {
name: 'indie',
id: '0JxWP48wGTRJrijEzg41fD'
})
playlists.set('948185876909936661', {
name: 'instrumental',
id: '37IIwZg5ek7mEYa2Ulmy85'
})
client.on('messageCreate', async message => {
const playlist = playlists.get(message.channel.id);
spotifyApi.getPlaylistTracks(playlist.id, {
offset: 0,
limit: 20,
fields: 'items'
})
.then(
function(data) {
console.log('The playlist contains these tracks', data.body.items);
},
function(err) {
console.log('Something went wrong!', err);
}
);
});
上面的代码记录了以下内容:
The playlist contains these tracks [
{
added_at: '2022-04-18T20:25:51Z',
added_by: {
external_urls: [Object],
href: 'https://api.spotify.com/v1/users/<userid>',
id: '<userid>',
type: 'user',
uri: 'spotify:user:<userid>'
},
is_local: false,
primary_color: null,
track: {
album: [Object],
artists: [Array],
available_markets: [Array],
disc_number: 1,
duration_ms: 285122,
episode: false,
explicit: false,
external_ids: [Object],
external_urls: [Object],
href: 'https://api.spotify.com/v1/tracks/04wZnll09OSLNgvOEpWNHF',
id: '04wZnll09OSLNgvOEpWNHF',
is_local: false,
name: 'Pacifica (Sultan + Shepard Remix)',
popularity: 53,
preview_url: 'https://p.scdn.co/mp3-preview/0fc9fadef348ded977208eea4a16135f497ecaa6?cid=d447a9a0d3d14fab83523430649b6c39',
track: true,
track_number: 1,
type: 'track',
uri: 'spotify:track:04wZnll09OSLNgvOEpWNHF'
},
video_thumbnail: { url: null }
},
{
added_at: '2022-04-18T20:25:57Z',
added_by: {
external_urls: [Object],
href: 'https://api.spotify.com/v1/users/<userid>',
id: '<userid>',
type: 'user',
uri: 'spotify:user:<userid>'
},
is_local: false,
primary_color: null,
track: {
album: [Object],
artists: [Array],
available_markets: [Array],
disc_number: 1,
duration_ms: 265506,
episode: false,
explicit: false,
external_ids: [Object],
external_urls: [Object],
href: 'https://api.spotify.com/v1/tracks/5pEmeoMUW38w1oU3kPelvR',
id: '5pEmeoMUW38w1oU3kPelvR',
is_local: false,
name: 'Spectrum',
popularity: 46,
preview_url: 'https://p.scdn.co/mp3-preview/5d9104b4cb82e3879867e2dc65997ab19b0f501b?cid=d447a9a0d3d14fab83523430649b6c39',
track: true,
track_number: 3,
type: 'track',
uri: 'spotify:track:5pEmeoMUW38w1oU3kPelvR'
},
video_thumbnail: { url: null }
},
{
added_at: '2022-04-18T20:26:04Z',
added_by: {
external_urls: [Object],
href: 'https://api.spotify.com/v1/users/<userid>',
id: '<userid>',
type: 'user',
uri: 'spotify:user:<userid>'
},
is_local: false,
primary_color: null,
track: {
album: [Object],
artists: [Array],
available_markets: [Array],
disc_number: 1,
duration_ms: 244186,
episode: false,
explicit: false,
external_ids: [Object],
external_urls: [Object],
href: 'https://api.spotify.com/v1/tracks/1AA3ZjLo9tD2iSZAs2svyj',
id: '1AA3ZjLo9tD2iSZAs2svyj',
is_local: false,
name: 'Chinatown (feat. Bruce Springsteen)',
popularity: 54,
preview_url: 'https://p.scdn.co/mp3-preview/993c6eecf44d181f50146c9cbf0d9e316d5c6cf8?cid=d447a9a0d3d14fab83523430649b6c39',
track: true,
track_number: 2,
type: 'track',
uri: 'spotify:track:1AA3ZjLo9tD2iSZAs2svyj'
},
video_thumbnail: { url: null }
}
]
我想检索每个曲目的 ID,看看是否有任何匹配已解析为 ID 的 message.content
。
另外,不确定如何处理限制,因为我不能将它设置得太高。
我正在使用 spotify-web-api-node。
嗯,您有一个播放列表中所有曲目的数据数组。您的用户将 Spotify link 发送到您的频道,以便将它们添加到播放列表中。曲目的 Spotify link 在其 URL 中肯定有曲目的 ID,正如您在曲目数据数组中所见,曲目数据中提供了曲目 ID。让我们以播放列表中的第一首歌曲 'Pacifica (Sultan + Shepard Remix)'
为例。这就是那首歌的曲目数据的相关部分:
{
track: {
album: [Object],
artists: [Array],
available_markets: [Array],
disc_number: 1,
duration_ms: 285122,
episode: false,
explicit: false,
external_ids: [Object],
external_urls: [Object],
href: 'https://api.spotify.com/v1/tracks/04wZnll09OSLNgvOEpWNHF',
id: '04wZnll09OSLNgvOEpWNHF', // <- Notice this
is_local: false,
name: 'Pacifica (Sultan + Shepard Remix)',
popularity: 53,
preview_url: 'https://p.scdn.co/mp3-preview/0fc9fadef348ded977208eea4a16135f497ecaa6?cid=d447a9a0d3d14fab83523430649b6c39',
track: true,
track_number: 1,
type: 'track',
uri: 'spotify:track:04wZnll09OSLNgvOEpWNHF'
}
}
这就是 user-sent Spotify link 的样子:
"https://open.spotify.com/track/04wZnll09OSLNgvOEpWNHF?si=FEomY7F6T_WAXwgLqIhhEw"
如您所见,ID "04wZnll09OSLNgvOEpWNHF"
存在于 link 和曲目数据中。这是我们可以用来确定曲目是否已经在播放列表中的东西。首先,让我们从 link:
中解析 ID
// Replace 'url' with the actual link from the message content
const url = "https://open.spotify.com/track/04wZnll09OSLNgvOEpWNHF?si=FEomY7F6T_WAXwgLqIhhEw";
const trackId = url.split("/").slice(-1)[0].split("?")[0];
以上示例的作用如下。首先,它将 url
拆分为 "/"
之间所有字符串的数组,如下所示:["https:", "", "open.spotify.com", "track", "04wZnll09OSLNgvOEpWNHF?si=FEomY7F6T_WAXwgLqIhhEw"]
。然后我们使用 .slice(-1)
来获取数组的“切片”,特别是数组的最后一个切片(.slice()
接受索引作为参数,而 returns 所有元素的新数组在索引和数组末尾之间;如果给它一个负索引,它将从数组末尾向后移动;因此 -1 表示从数组末尾向后移动 1 项,即只是数组中的最后一项).完成此切片后,我们通过 [0]
获得切片数组的第一个元素,现在剩下以下字符串:"04wZnll09OSLNgvOEpWNHF?si=FEomY7F6T_WAXwgLqIhhEw"
。现在,我们使用 .split("?")
将数组拆分为问号之间的字符串,并获取这些字符串中的第一个(即曲目 ID:"04wZnll09OSLNgvOEpWNHF"
)。希望这解释了它是如何工作的。这是基本的 javascript 字符串解析。
现在我们有了曲目 ID,我们需要看看是否可以在曲目数据项数组中的某处找到曲目 ID。我们可以使用 Array.some()
来实现这一点。该方法循环遍历数组,并且 returns true
如果您将回调函数作为其参数 returns true
传递给数组中的任何项目。以下是它在您的情况下的工作方式:
const hasTrack = data.body.items.some(item => item.track.id == trackId);
if (hasTrack) {
// Track is already in playlist
}
else {
// Add track to playlist
}
再加上之前解析曲目 ID 的代码片段,就是您的答案的解决方案。请记住,每个单独的跟踪数据项如下所示:
{
added_at: '2022-04-18T20:25:51Z',
added_by: {
external_urls: [Object],
href: 'https://api.spotify.com/v1/users/<userid>',
id: '<userid>',
type: 'user',
uri: 'spotify:user:<userid>'
},
is_local: false,
primary_color: null,
track: {
album: [Object],
artists: [Array],
available_markets: [Array],
disc_number: 1,
duration_ms: 285122,
episode: false,
explicit: false,
external_ids: [Object],
external_urls: [Object],
href: 'https://api.spotify.com/v1/tracks/04wZnll09OSLNgvOEpWNHF',
id: '04wZnll09OSLNgvOEpWNHF',
is_local: false,
name: 'Pacifica (Sultan + Shepard Remix)',
popularity: 53,
preview_url: 'https://p.scdn.co/mp3-preview/0fc9fadef348ded977208eea4a16135f497ecaa6?cid=d447a9a0d3d14fab83523430649b6c39',
track: true,
track_number: 1,
type: 'track',
uri: 'spotify:track:04wZnll09OSLNgvOEpWNHF'
},
video_thumbnail: { url: null }
}
因此我们需要执行 item.track.id
才能在 .some()
回调中获取曲目的 ID。此解决方案应该适合您。如果您对我以任何方式使用的流程、逻辑或代码感到困惑,请随时发表评论。
至于你提到的最后一件事:
not sure how to handle the limit as I couldn't set it too high
如果您无法从 Spotify 检索播放列表中的所有歌曲,请考虑在您自己的数据库中跟踪每个播放列表的歌曲列表(在将每首歌曲添加到播放列表时添加到数据库) , 而不是从那里检索数据。这可能比试图绕过限制更容易。
我正在 Discord 中创建一个机器人,它可以在特定频道中添加共享歌曲并将其添加到相应的播放列表中。该函数按预期工作,因此我将那部分代码省略了。但如果需要我可以添加。
使用下面的代码,我希望能够评估播放列表是否已包含共享歌曲,如果包含则不要添加。 基本上跳过重复。
const playlists = new Map();
const spectrumPlaylist = {
channelid: '948177541414404116',
name: 'spectrum',
id: '2SDsHpVc7yfQhGg0tS0RQ0'
}
playlists.set('948177541414404116', {
name: 'spectrum',
id: '2SDsHpVc7yfQhGg0tS0RQ0'
})
playlists.set('948185709037121566', {
name: 'indie',
id: '0JxWP48wGTRJrijEzg41fD'
})
playlists.set('948185876909936661', {
name: 'instrumental',
id: '37IIwZg5ek7mEYa2Ulmy85'
})
client.on('messageCreate', async message => {
const playlist = playlists.get(message.channel.id);
spotifyApi.getPlaylistTracks(playlist.id, {
offset: 0,
limit: 20,
fields: 'items'
})
.then(
function(data) {
console.log('The playlist contains these tracks', data.body.items);
},
function(err) {
console.log('Something went wrong!', err);
}
);
});
上面的代码记录了以下内容:
The playlist contains these tracks [
{
added_at: '2022-04-18T20:25:51Z',
added_by: {
external_urls: [Object],
href: 'https://api.spotify.com/v1/users/<userid>',
id: '<userid>',
type: 'user',
uri: 'spotify:user:<userid>'
},
is_local: false,
primary_color: null,
track: {
album: [Object],
artists: [Array],
available_markets: [Array],
disc_number: 1,
duration_ms: 285122,
episode: false,
explicit: false,
external_ids: [Object],
external_urls: [Object],
href: 'https://api.spotify.com/v1/tracks/04wZnll09OSLNgvOEpWNHF',
id: '04wZnll09OSLNgvOEpWNHF',
is_local: false,
name: 'Pacifica (Sultan + Shepard Remix)',
popularity: 53,
preview_url: 'https://p.scdn.co/mp3-preview/0fc9fadef348ded977208eea4a16135f497ecaa6?cid=d447a9a0d3d14fab83523430649b6c39',
track: true,
track_number: 1,
type: 'track',
uri: 'spotify:track:04wZnll09OSLNgvOEpWNHF'
},
video_thumbnail: { url: null }
},
{
added_at: '2022-04-18T20:25:57Z',
added_by: {
external_urls: [Object],
href: 'https://api.spotify.com/v1/users/<userid>',
id: '<userid>',
type: 'user',
uri: 'spotify:user:<userid>'
},
is_local: false,
primary_color: null,
track: {
album: [Object],
artists: [Array],
available_markets: [Array],
disc_number: 1,
duration_ms: 265506,
episode: false,
explicit: false,
external_ids: [Object],
external_urls: [Object],
href: 'https://api.spotify.com/v1/tracks/5pEmeoMUW38w1oU3kPelvR',
id: '5pEmeoMUW38w1oU3kPelvR',
is_local: false,
name: 'Spectrum',
popularity: 46,
preview_url: 'https://p.scdn.co/mp3-preview/5d9104b4cb82e3879867e2dc65997ab19b0f501b?cid=d447a9a0d3d14fab83523430649b6c39',
track: true,
track_number: 3,
type: 'track',
uri: 'spotify:track:5pEmeoMUW38w1oU3kPelvR'
},
video_thumbnail: { url: null }
},
{
added_at: '2022-04-18T20:26:04Z',
added_by: {
external_urls: [Object],
href: 'https://api.spotify.com/v1/users/<userid>',
id: '<userid>',
type: 'user',
uri: 'spotify:user:<userid>'
},
is_local: false,
primary_color: null,
track: {
album: [Object],
artists: [Array],
available_markets: [Array],
disc_number: 1,
duration_ms: 244186,
episode: false,
explicit: false,
external_ids: [Object],
external_urls: [Object],
href: 'https://api.spotify.com/v1/tracks/1AA3ZjLo9tD2iSZAs2svyj',
id: '1AA3ZjLo9tD2iSZAs2svyj',
is_local: false,
name: 'Chinatown (feat. Bruce Springsteen)',
popularity: 54,
preview_url: 'https://p.scdn.co/mp3-preview/993c6eecf44d181f50146c9cbf0d9e316d5c6cf8?cid=d447a9a0d3d14fab83523430649b6c39',
track: true,
track_number: 2,
type: 'track',
uri: 'spotify:track:1AA3ZjLo9tD2iSZAs2svyj'
},
video_thumbnail: { url: null }
}
]
我想检索每个曲目的 ID,看看是否有任何匹配已解析为 ID 的 message.content
。
另外,不确定如何处理限制,因为我不能将它设置得太高。
我正在使用 spotify-web-api-node。
嗯,您有一个播放列表中所有曲目的数据数组。您的用户将 Spotify link 发送到您的频道,以便将它们添加到播放列表中。曲目的 Spotify link 在其 URL 中肯定有曲目的 ID,正如您在曲目数据数组中所见,曲目数据中提供了曲目 ID。让我们以播放列表中的第一首歌曲 'Pacifica (Sultan + Shepard Remix)'
为例。这就是那首歌的曲目数据的相关部分:
{
track: {
album: [Object],
artists: [Array],
available_markets: [Array],
disc_number: 1,
duration_ms: 285122,
episode: false,
explicit: false,
external_ids: [Object],
external_urls: [Object],
href: 'https://api.spotify.com/v1/tracks/04wZnll09OSLNgvOEpWNHF',
id: '04wZnll09OSLNgvOEpWNHF', // <- Notice this
is_local: false,
name: 'Pacifica (Sultan + Shepard Remix)',
popularity: 53,
preview_url: 'https://p.scdn.co/mp3-preview/0fc9fadef348ded977208eea4a16135f497ecaa6?cid=d447a9a0d3d14fab83523430649b6c39',
track: true,
track_number: 1,
type: 'track',
uri: 'spotify:track:04wZnll09OSLNgvOEpWNHF'
}
}
这就是 user-sent Spotify link 的样子:
"https://open.spotify.com/track/04wZnll09OSLNgvOEpWNHF?si=FEomY7F6T_WAXwgLqIhhEw"
如您所见,ID "04wZnll09OSLNgvOEpWNHF"
存在于 link 和曲目数据中。这是我们可以用来确定曲目是否已经在播放列表中的东西。首先,让我们从 link:
// Replace 'url' with the actual link from the message content
const url = "https://open.spotify.com/track/04wZnll09OSLNgvOEpWNHF?si=FEomY7F6T_WAXwgLqIhhEw";
const trackId = url.split("/").slice(-1)[0].split("?")[0];
以上示例的作用如下。首先,它将 url
拆分为 "/"
之间所有字符串的数组,如下所示:["https:", "", "open.spotify.com", "track", "04wZnll09OSLNgvOEpWNHF?si=FEomY7F6T_WAXwgLqIhhEw"]
。然后我们使用 .slice(-1)
来获取数组的“切片”,特别是数组的最后一个切片(.slice()
接受索引作为参数,而 returns 所有元素的新数组在索引和数组末尾之间;如果给它一个负索引,它将从数组末尾向后移动;因此 -1 表示从数组末尾向后移动 1 项,即只是数组中的最后一项).完成此切片后,我们通过 [0]
获得切片数组的第一个元素,现在剩下以下字符串:"04wZnll09OSLNgvOEpWNHF?si=FEomY7F6T_WAXwgLqIhhEw"
。现在,我们使用 .split("?")
将数组拆分为问号之间的字符串,并获取这些字符串中的第一个(即曲目 ID:"04wZnll09OSLNgvOEpWNHF"
)。希望这解释了它是如何工作的。这是基本的 javascript 字符串解析。
现在我们有了曲目 ID,我们需要看看是否可以在曲目数据项数组中的某处找到曲目 ID。我们可以使用 Array.some()
来实现这一点。该方法循环遍历数组,并且 returns true
如果您将回调函数作为其参数 returns true
传递给数组中的任何项目。以下是它在您的情况下的工作方式:
const hasTrack = data.body.items.some(item => item.track.id == trackId);
if (hasTrack) {
// Track is already in playlist
}
else {
// Add track to playlist
}
再加上之前解析曲目 ID 的代码片段,就是您的答案的解决方案。请记住,每个单独的跟踪数据项如下所示:
{
added_at: '2022-04-18T20:25:51Z',
added_by: {
external_urls: [Object],
href: 'https://api.spotify.com/v1/users/<userid>',
id: '<userid>',
type: 'user',
uri: 'spotify:user:<userid>'
},
is_local: false,
primary_color: null,
track: {
album: [Object],
artists: [Array],
available_markets: [Array],
disc_number: 1,
duration_ms: 285122,
episode: false,
explicit: false,
external_ids: [Object],
external_urls: [Object],
href: 'https://api.spotify.com/v1/tracks/04wZnll09OSLNgvOEpWNHF',
id: '04wZnll09OSLNgvOEpWNHF',
is_local: false,
name: 'Pacifica (Sultan + Shepard Remix)',
popularity: 53,
preview_url: 'https://p.scdn.co/mp3-preview/0fc9fadef348ded977208eea4a16135f497ecaa6?cid=d447a9a0d3d14fab83523430649b6c39',
track: true,
track_number: 1,
type: 'track',
uri: 'spotify:track:04wZnll09OSLNgvOEpWNHF'
},
video_thumbnail: { url: null }
}
因此我们需要执行 item.track.id
才能在 .some()
回调中获取曲目的 ID。此解决方案应该适合您。如果您对我以任何方式使用的流程、逻辑或代码感到困惑,请随时发表评论。
至于你提到的最后一件事:
not sure how to handle the limit as I couldn't set it too high
如果您无法从 Spotify 检索播放列表中的所有歌曲,请考虑在您自己的数据库中跟踪每个播放列表的歌曲列表(在将每首歌曲添加到播放列表时添加到数据库) , 而不是从那里检索数据。这可能比试图绕过限制更容易。