Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Playblack control #150

Merged
merged 9 commits into from
Aug 31, 2017
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ It includes helper functions to do the following:
- Get a user's available devices
- Get information about the user's current playback
- Transfer a user's playback
- Resume a user's playback
- Skip a user's playback to next track
- Skip a user's playback to previous track
- Set a user's shuffle mode
- Set a user's repeat mode

All methods require authentication, which can be done using these flows:

Expand Down
181 changes: 181 additions & 0 deletions src/spotify-web-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -1672,6 +1672,187 @@ SpotifyWebApi.prototype = {
}
},

/**
* Resumes the Current User's Playback
* @param {Object} [options] Options, being context_uri, offset, uris.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example playbackResume({context_uri: 'spotify:album:5ht7ItJgpBH7W6vJ5BqpPr'}).then(...)
* @returns {Promise|undefined} A promise that if successful, resolves into a paging object of tracks,
* otherwise an error. Not returned if a callback is given.
*/
playbackResume: function(options, callback) {

var actualOptions = {};
if (typeof options === 'object') {
Object.keys(options).forEach(function(key) {
actualOptions[key] = options[key];
});
}

var request = WebApiRequest.builder()
.withPath('/v1/me/player/play')
.withHeaders({ 'Content-Type' : 'application/json' })
.withBodyParameters(actualOptions)
.build();

this._addAccessToken(request, this.getAccessToken());

var promise = this._performRequest(HttpManager.put, request);

if (callback) {
promise.then(function(data) {
callback(null, data);
}, function(err) {
callback(err);
});
} else {
return promise;
}
},

/**
* Pauses the Current User's Playback
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example playbackPause().then(...)
* @returns {Promise|undefined} A promise that if successful, resolves into a paging object of tracks,
* otherwise an error. Not returned if a callback is given.
*/
playbackPause: function(callback) {
var request = WebApiRequest.builder()
.withPath('/v1/me/player/pause')
.build();

this._addAccessToken(request, this.getAccessToken());

var promise = this._performRequest(HttpManager.put, request);

if (callback) {
promise.then(function(data) {
callback(null, data);
}, function(err) {
callback(err);
});
} else {
return promise;
}
},

/**
* Skip the Current User's Playback To Previous Track
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example playbackPrevious().then(...)
* @returns {Promise|undefined} A promise that if successful, resolves into a paging object of tracks,
* otherwise an error. Not returned if a callback is given.
*/
playbackPrevious: function(callback) {
var request = WebApiRequest.builder()
.withPath('/v1/me/player/previous')
.build();

this._addAccessToken(request, this.getAccessToken());

var promise = this._performRequest(HttpManager.post, request);

if (callback) {
promise.then(function(data) {
callback(null, data);
}, function(err) {
callback(err);
});
} else {
return promise;
}
},

/**
* Skip the Current User's Playback To Next Track
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example playbackNext().then(...)
* @returns {Promise|undefined} A promise that if successful, resolves into a paging object of tracks,
* otherwise an error. Not returned if a callback is given.
*/
playbackNext: function(callback) {
var request = WebApiRequest.builder()
.withPath('/v1/me/player/next')
.build();

this._addAccessToken(request, this.getAccessToken());

var promise = this._performRequest(HttpManager.post, request);

if (callback) {
promise.then(function(data) {
callback(null, data);
}, function(err) {
callback(err);
});
} else {
return promise;
}
},

/**
* Set Repeat Mode On The Current User's Playback
* @param {Object} [options] Options, being state (track, context, off).
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example playbackRepeat({state: 'context'}).then(...)
* @returns {Promise|undefined} A promise that if successful, resolves into a paging object of tracks,
* otherwise an error. Not returned if a callback is given.
*/
playbackRepeat: function(options, callback) {
var request = WebApiRequest.builder()
.withPath('/v1/me/player/repeat')
.withQueryParameters({
'state': options.state || 'off'
})
.build();

this._addAccessToken(request, this.getAccessToken());

var promise = this._performRequest(HttpManager.put, request);

if (callback) {
promise.then(function(data) {
callback(null, data);
}, function(err) {
callback(err);
});
} else {
return promise;
}
},

/**
* Set Shuffle Mode On The Current User's Playback
* @param {Object} [options] Options, being state (true, false).
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example playbackShuffle({state: 'false'}).then(...)
* @returns {Promise|undefined} A promise that if successful, resolves into a paging object of tracks,
* otherwise an error. Not returned if a callback is given.
*/
playbackShuffle: function(options, callback) {
var request = WebApiRequest.builder()
.withPath('/v1/me/player/shuffle')
.withQueryParameters({
'state': options.state || 'false'
})
.build();

this._addAccessToken(request, this.getAccessToken());

var promise = this._performRequest(HttpManager.put, request);

if (callback) {
promise.then(function(data) {
callback(null, data);
}, function(err) {
callback(err);
});
} else {
return promise;
}
},

/**
* Add the current user as a follower of one or more other Spotify users.
* @param {string[]} userIds The IDs of the users to be followed.
Expand Down
152 changes: 152 additions & 0 deletions test/spotify-web-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -1332,6 +1332,158 @@ describe('Spotify Web API', function() {

});

it('should resume the user\'s playback', function(done) {

sinon.stub(HttpManager, '_makeRequest', function(method, options, uri, callback) {
method.should.equal(superagent.put);
uri.should.equal('https://api.spotify.com/v1/me/player/play');
should.not.exist(options.query);
callback();
});

var accessToken = 'myAccessToken';

var api = new SpotifyWebApi({
accessToken : accessToken
});

api.playbackResume()
.then(function(data) {
done();
}, function(err) {
console.log(err);
done(err);
});

});

it('should pause the user\'s playback', function(done) {

sinon.stub(HttpManager, '_makeRequest', function(method, options, uri, callback) {
method.should.equal(superagent.put);
uri.should.equal('https://api.spotify.com/v1/me/player/pause');
should.not.exist(options.query);
callback();
});

var accessToken = 'myAccessToken';

var api = new SpotifyWebApi({
accessToken : accessToken
});

api.playbackPause()
.then(function(data) {
done();
}, function(err) {
console.log(err);
done(err);
});

});

it('should skip the user\'s playback to next track', function(done) {

sinon.stub(HttpManager, '_makeRequest', function(method, options, uri, callback) {
method.should.equal(superagent.post);
uri.should.equal('https://api.spotify.com/v1/me/player/next');
should.not.exist(options.query);
callback();
});

var accessToken = 'myAccessToken';

var api = new SpotifyWebApi({
accessToken : accessToken
});

api.playbackNext()
.then(function(data) {
done();
}, function(err) {
console.log(err);
done(err);
});

});

it('should skip the user\'s playback to previous track', function(done) {

sinon.stub(HttpManager, '_makeRequest', function(method, options, uri, callback) {
method.should.equal(superagent.post);
uri.should.equal('https://api.spotify.com/v1/me/player/previous');
should.not.exist(options.query);
callback();
});

var accessToken = 'myAccessToken';

var api = new SpotifyWebApi({
accessToken : accessToken
});

api.playbackPrevious()
.then(function(data) {
done();
}, function(err) {
console.log(err);
done(err);
});

});

it('should set the user\'s playback repeat mode', function(done) {

sinon.stub(HttpManager, '_makeRequest', function(method, options, uri, callback) {
method.should.equal(superagent.put);
uri.should.equal('https://api.spotify.com/v1/me/player/repeat');
should.exist(options.query);
should.not.exist(options.body);
callback();
});

var accessToken = 'myAccessToken';

var api = new SpotifyWebApi({
accessToken : accessToken
});

api.playbackRepeat({state: 'off'})
.then(function(data) {
done();
}, function(err) {
console.log(err);
done(err);
});

});

it('should set the user\'s playback shuffle mode', function(done) {

sinon.stub(HttpManager, '_makeRequest', function(method, options, uri, callback) {
method.should.equal(superagent.put);
uri.should.equal('https://api.spotify.com/v1/me/player/shuffle');
should.exist(options.query);
should.not.exist(options.body);
callback();
});

var accessToken = 'myAccessToken';

var api = new SpotifyWebApi({
accessToken : accessToken
});

api.playbackShuffle({state: 'false'})
.then(function(data) {
done();
}, function(err) {
console.log(err);
done(err);
});

});

it.skip("should retrieve an access token using the client credentials flow", function(done) {
var clientId = 'someClientId',
clientSecret = 'someClientSecret';
Expand Down