我已经被这个问题困扰了一段时间,无论我如何努力搜索,我都找不到答案。我正在尝试将自定义播放列表封面添加到 Spotify 播放列表,但我不断收到 401 响应。我已多次检查是否传递了正确的访问令牌和播放列表 ID。我也添加了 Spotify API 上指出的所有必需范围。我什至测试了具有不同 KB 大小的不同图像。下面是我的代码
const url = `https://api.spotify.com/v1/playlists/${playlist.id}/images`;
let imgFile = process.env.COVER_PHOTO;
axios.put(url, imgFile, {
headers: {
'Authorization': "Bearer " + token,
'Content-Type': 'image/jpeg'
}
})
网址
PUT /playlists/{playlist_id}/images
范围
ugc-image-upload
playlist-modify-public
playlist-modify-private
在这里
demo.js
const fs = require('fs'); - 添加在程序中读写文件的功能。
const imageData = fs.readFileSync('car.jpg', { 编码: 'base64' }); - 读取“car.jpg”文件并将其转换为 Base64 字符串。
const accessToken = 等待 getToken(code); - 使用提供的代码检索访问令牌。
const updateStatus = 等待 updatePlaylistCoverImage(accessToken, imageData); - 将编码图像发送到 Spotify 以更新播放列表封面。
response.send(图片更新状态: ${updateStatus}); - 响应图像上传过程的状态。
const express = require("express");
const axios = require('axios');
const cors = require("cors");
const fs = require('fs'); // Required to read files
const app = express();
app.use(cors());
const CLIENT_ID = "{your client ID}";
const CLIENT_SECRET = "{your client secret}";
const PORT = 3000; // {your redirect URI port number}
const REDIRECT_URI = `http://localhost:${PORT}/callback`;
const SCOPE = 'ugc-image-upload playlist-modify-public playlist-modify-private';
const PLAYLIST_ID = '{Your playlist ID}'; // Your playlist ID
const getToken = async (code) => {
try {
const resp = await axios.post(
'https://accounts.spotify.com/api/token',
new URLSearchParams({
'grant_type': 'authorization_code',
'redirect_uri': REDIRECT_URI,
'code': code
}),
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
auth: {
username: CLIENT_ID,
password: CLIENT_SECRET
}
})
return Promise.resolve(resp.data.access_token);
} catch (err) {
console.error(err)
return Promise.reject(err)
}
}
const updatePlaylistCoverImage = async (accessToken, imageData) => {
try {
const response = await axios.put(
`https://api.spotify.com/v1/playlists/${PLAYLIST_ID}/images`,
imageData,
{
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'image/jpeg'
}
}
);
return response.status;
} catch (error) {
console.error(error);
return error.response.status;
}
}
app.get("/login", (request, response) => {
const redirect_url = `https://accounts.spotify.com/authorize?response_type=code&client_id=${CLIENT_ID}&scope=${encodeURIComponent(SCOPE)}&state=123456&redirect_uri=${REDIRECT_URI}&prompt=consent`
response.redirect(redirect_url);
});
app.get("/callback", async (request, response) => {
const code = request.query["code"];
try {
const accessToken = await getToken(code);
const imageData = fs.readFileSync('car.jpg', { encoding: 'base64' });
const updateStatus = await updatePlaylistCoverImage(accessToken, imageData);
response.send(`Image Update Status: ${updateStatus}`);
} catch (error) {
response.status(500).send(`Error: ${error.message}`);
}
});
app.listen(PORT, () => {
console.log(`Listening on :${PORT}`);
});
custom image
car.jpg
Base64 编码的 JPEG 图像数据,最大有效负载大小为 256 KB。
Access
http://localhost:{your port}/login
Before
After