node.js - react /Node : Spotify API Error: 404 - No Active Device Found

标签 node.js reactjs spotify

我创建了一个仅适用于 Spotify Premium 用户的应用程序(根据 Spotify 的文档,PUT 方法不适用于非高级用户)。这是一个包含 10 个问题的互动测验,其中会在您的 Spotify 帐户中生成一个播放列表,播放它,您必须猜测每首歌曲的名称。它是使用 NodeJS 后端生成的,并通过 ReactJS 显示。游戏可以在这里演示:https://am-spotify-quiz.herokuapp.com/

可以在下面查看代码:

server.js

const express = require('express');
const request = require('request');
const cors = require('cors');
const querystring = require('querystring');
const cookieParser = require('cookie-parser');

const client_id = ''; // Hiding for now
const client_secret = ''; // Hiding
const redirect_uri =  'https://am-spotify-quiz-api.herokuapp.com/callback/'; 
const appUrl = 'https://am-spotify-quiz.herokuapp.com/#';

/**
 * Generates a random string containing numbers and letters
 * @param  {number} length The length of the string
 * @return {string} The generated string
 */
var generateRandomString = function(length) {
  var text = '';
  var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

  for (var i = 0; i < length; i++) {
    text += possible.charAt(Math.floor(Math.random() * possible.length));
  }
  return text;
};

var stateKey = 'spotify_auth_state';

var app = express();

app.use(express.static(__dirname + '/public'))
   .use(cors())
   .use(cookieParser());

app.get('/login', function(req, res) {

  var state = generateRandomString(16);
  res.cookie(stateKey, state);

  // scopes needed to make required functions work
  var scope = 'user-read-private ' + 
              'user-read-email ' + 
              'user-read-playback-state ' + 
              'user-top-read ' +
              'playlist-modify-public ' +
              'playlist-modify-private ' +
              'user-modify-playback-state ' +
              'user-read-playback-state';
  res.redirect('https://accounts.spotify.com/authorize?' +
    querystring.stringify({
      response_type: 'code',
      client_id: client_id,
      scope: scope,
      redirect_uri: redirect_uri,
      state: state
    }));
});

app.get('/callback/', function(req, res) {

  // your application requests refresh and access tokens
  // after checking the state parameter

  var code = req.query.code || null;
  var state = req.query.state || null;
  var storedState = req.cookies ? req.cookies[stateKey] : null;

  if (state === null || state !== storedState) {
    res.redirect(appUrl +
      querystring.stringify({
        access_token: access_token,
        refresh_token: refresh_token
      }));
  } else {
    res.clearCookie(stateKey);
    var authOptions = {
      url: 'https://accounts.spotify.com/api/token',
      form: {
        code: code,
        redirect_uri: redirect_uri,
        grant_type: 'authorization_code'
      },
      headers: {
        'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64')),
      },
      json: true
    };

    request.post(authOptions, function(error, response, body) {
      if (!error && response.statusCode === 200) {

        var access_token = body.access_token,
            refresh_token = body.refresh_token;

        var options = {
          url: 'https://api.spotify.com/v1/me',
          headers: { 
            'Authorization': 'Bearer ' + access_token,
            'Content-Type': 'application/json' // May not need
          },
          body: { // Likely don't need this anymore!
            'name': 'Test Playlist', 
            'public': false
          },
          json: true
        };

        // use the access token to access the Spotify Web API
        request.get(options, function(error, response, body) {
          console.log(body);
        });

        // we can also pass the token to the browser to make requests from there
        res.redirect(appUrl +
          querystring.stringify({
            access_token: access_token,
            refresh_token: refresh_token
          }));
      } else {
        res.redirect(appUrl +
          querystring.stringify({
            error: 'invalid_token'
          }));
      }
    });
  }
});

// AM - May not even need this anymore!
app.get('/refresh_token', function(req, res) {

  // requesting access token from refresh token
  var refresh_token = req.query.refresh_token;
  var authOptions = {
    url: 'https://accounts.spotify.com/api/token',
    headers: { 'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64')) },
    form: {
      grant_type: 'refresh_token',
      refresh_token: refresh_token
    },
    json: true
  };

  request.post(authOptions, function(error, response, body) {
    if (!error && response.statusCode === 200) {
      var access_token = body.access_token;
      res.send({
        'access_token': access_token
      });
    }
  });
});

console.log('Listening on 8888');
app.listen(process.env.PORT || 8888);

我有一个在用户登录后立即显示的 react 组件,称为premium.js。如果您需要所有代码,可以查看 here 。以下是我的游戏所需的两个 PUT 方法;一个用于关闭随机播放功能,另一个用于播放播放列表:

 removeShuffle() {
    axios({
      url: 'https://api.spotify.com/v1/me/player/shuffle?state=false',
      method: "PUT",
      headers: {
        'Authorization': 'Bearer ' + this.state.accesstoken
      }
    })
      .then((response) => {
        console.log(response)
      })
      .catch((error) => {
        console.log(error)
      })

  }

  // Then... play the playlist to get started
  playPlaylist(contextUri) {
    axios({
      url: 'https://api.spotify.com/v1/me/player/play',
      method: "PUT",
      data: {
        context_uri: contextUri
      },
      headers: {
        'Authorization': 'Bearer ' + this.state.accesstoken
      }
    })
      .then((response) => {
        console.log(response)
      })
      .catch((error) => {
        console.log(error)
      })
  }

当我(游戏的创建者)尝试时,这些效果非常好;但是,我让另一位高级用户尝试了一下,发现了这个错误:

404: No Active Device Found

这似乎没有多大意义,因为我发现其他用户也会发生此错误,无论他们使用的是 Windows 还是 Mac。有谁知道这意味着什么,我该如何解决?提前致谢!

最佳答案

我也一直在使用 Spotify 的 API,在不活动期后尝试 PUT https://api.spotify.com/v1/me/player/play 时,我最终遇到了同样的错误,其中没有设备被标记为事件(我不知 Prop 体多长时间,但不超过几个小时)。

显然,必须将一台设备设置为事件,以便您可以成功调用play端点。

如果您想将设备的状态更改为事件,请按照their documentation ,您可以首先尝试GET https://api.spotify.com/v1/me/player/devices以获取可用设备列表:

// Example response
{
  "devices" : [ {
    "id" : "5fbb3ba6aa454b5534c4ba43a8c7e8e45a63ad0e",
    "is_active" : false,
    "is_private_session": true,
    "is_restricted" : false,
    "name" : "My fridge",
    "type" : "Computer",
    "volume_percent" : 100
  } ]
}

然后通过调用 player endpoint 选择可用设备之一PUT https://api.spotify.com/v1/me/player,包括:

  • device_ids Required. A JSON array containing the ID of the device on which playback should be started/transferred. For example: {device_ids:["74ASZWbe4lXaubB36ztrGX"]} Note: Although an array is accepted, only a single device_id is currently supported. Supplying more than one will return 400 Bad Request
  • play with value true if you want to start playing right away.

您自己很可能没有收到该错误,因为您的其中一台设备在测试时已经处于事件状态。如果您自己的帐户在几个小时内没有任何事件,然后尝试调用 v1/me/player/play 端点,我希望您会收到相同的错误。

确保这确实是您的问题的一个简单解决方法是要求您的测试用户开始在 Spotify 应用程序上播放歌曲(无论是哪个),然后暂停它,然后触发您的功能调用 v1/me/player/play 端点的应用程序。这样就不会再返回未找到事件设备错误。

关于node.js - react /Node : Spotify API Error: 404 - No Active Device Found,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52268847/

相关文章:

node.js - Sec-WebSocket-Accept 值的 Base64 编码

node.js - Node 请求抛出 : Error: Invalid URI "www.urlworksinbrowser.com" or options. uri 是必需的参数

javascript - 在 ScrollView 的 onscroll 属性中调用函数

html - Spotify iframe 嵌入白色主题加载黑色主题播放器和白色主题播放列表

java - 如何修复 '"com.spotify.error.client_authentication_failed”

javascript - 滑动面板,如何复制它们?

javascript - Gulp Node.js Istanbul 尔 伊斯帕尔塔

node.js - 带附件的电子邮件无法正常使用 gmail api

css - 如何在 reactjs 中删除第三方 js 文件的特定 css 样式

javascript - 对多个字段进行数组过滤