Accessing Spotify Metadata API from within a Spotify app? - spotify

I want to run Spotify searches from within a Spotify app (to find tracks for an artist, for which I do not have a Spotify URI, only the name).
I have not found functionality in the App API to run searches. An alternative is to talk to ws.spotify.com to get to Spotify's search, but these web services do not support jsonp which is required for their use in a Spotify app.
What are my options?

You can use sp.core.search
sp.core.search("query",
{onSuccess: function(result) {
// parse result
}
}
);
sp.core.getMetadata if you have the uri
sp.core.getMetadata("uri", {
onSuccess: function(data){
console.debug(data);
},
onFailure: function(){
//...
},
});

This is not the finest way to solve your problem. There is a direct API for searching within your app. See Juan's solution.
But you could also talk to ws.spotify.com directly when you add the domain to your app's manifest.json.
"RequiredPermissions": ["http://ws.spotify.com" ]
e.g. http://ws.spotify.com/search/1/track.json?q=kaizers+orchestra, see their
Developer Site. The response contains the header "Access-Control-Allow-Origin: *", so you should be able to query from within your app.

Related

Trying to use oauth flow in Electron desktop app (with spotify API)?

I have a React app in Electron, and I'm trying to access the spotify API using the spotify-web-api-node library. However, I'm not sure exactly how the oauth flow is meant to work inside of an Electron app... Firstly, for the redirect URL, I used this question and added a registerFileProtocol call to my file. Then I added a specific ipcMain.on handler for receiving the spotify login call from a page, which I've confirmed works with console logs. However, when I get to actually calling the authorizeURL, nothing happens?
This is part of my main.js:
app.whenReady().then(() => {
...
protocol.registerFileProtocol(
"oauthdesktop",
(request, callback) => {
console.log("oauthdesktop stuff: ", request, callback);
//parse authorization code from request
},
(error) => {
if (error) console.error("Failed to register protocol");
}
);
});
ipcMain.on("spotify-login", (e, arg) => {
const credentials = {
clientId: arg.spotifyClientId,
clientSecret: arg.spotifySecret,
redirectUri: "oauthdesktop://test",
};
const spotifyApi = new SpotifyWebApi(credentials);
console.log("spapi: ", spotifyApi);
const authorizeURL = spotifyApi.createAuthorizeURL(
["user-read-recently-played", "playlist-modify-private"],
"waffles"
);
console.log("spurl: ", authorizeURL);
axios.get(authorizeURL);
}
I'd expect the typical spotify login page popup to show up, but that doesn't happen. I'd also expect (possibly) the registerFileProtocol callback to log something, but it doesn't. What am I meant to be doing here? The authorization guide specifically mentions doing a GET request on the auth url, which is what I'm doing here...
In a desktop app it is recommended to open the system browser, and the Spotify login page will render there, as part of creating a promise. The opener library can be used to invoke the browser.
When the user has finished logging in, the technique is to receive the response via a Private URI Scheme / File Protocol, then to resolve the promise, get an authorization code, then swap it for tokens. It is tricky though.
RESOURCES OF MINE
I have some blog posts on this, which you may be able to borrow some ideas from, and a couple of code samples you can run on your PC:
Initial Desktop Sample
Final Desktop Sample
The second of these is a React app and uses a Private URI scheme, so is fairly similar to yours. I use the AppAuth-JS library and not Spotify though.

Empty request from Google Smart Home SDK

I'm creating web server to connect my DIY smart home devices to Google Home app.
After authorisation and token request Google server makes POST request to fullfillment URL, but request is empty for some reason. According to documentation, it must be SYNC request, but it does not contain any values, even request ID.
There is error "Couldn't update the setting. Check your Internet connection." on my phone after request.
So why does it happen and how I can fix it?
const app=smarthome({ debug: true, });
app.onSync( async (body) => {
return {
requestId: body.requestId,
payload: {
agentUserId: "agentUserId",
devices // devices list
}
};
});
server.post("/request", app);
Oh, I forgot to include body-parser 'cause I'm using general web server instead of actions-on-google API. LOL
Case closed.

Node.js and Twitter API 1.1

I had a small web app that was using the Twitter API 1.0 user_timeline function to quickly get a user's recent tweets without authentication. However, now every call requires oAuth which I'm terrible at. I know there's an application only authentication method, which is what I want since this is an automated app and not a user based one.
The application was built in node.js so a suggestion for a module that supports app-based oAuth would be great. The main thing is I don't have nor need a callback page, which most assume, since all I'm trying to do is get the last few tweets from a handful of specific Twitter accounts which the app tracks. Likewise any links to good oAuth educational resources or, better yet, Twitter 1.1 HTTP request walkthroughs would be much appreciated.
Thank you for your time.
Twitter API 1.1 allows only authenticated requests. But the good news is that the oAuth based authentication is not that difficult. To use it:
Generate the four oAuth keys you need. Go to https://dev.twitter.com/apps/new and register your app.
Install package ntwitter on your machine.
Configure the four keys in your app. See the package page on how to do it.
Construct request and get results. See this page on how to make requests.
I find oAuth to be easier and prefer this way.
The package EveryAuth does authentication pretty well, too. Also, ntwitter isn't being updated very regularly right now; I found mtwitter to be much better. I suck at explaining stuff, so I'll just show you how I did it:
var mtwitter = require('mtwitter');
var twit = new mtwitter({
consumer_key: { your app consumer key },
consumer_secret: { your app consumer secret },
access_token_key: { get this from oauth or everyauth or whatever },
access_token_secret: { get this from oauth or everyauth or whatever }
});
twit.get('/statuses/user_timeline', { include_entities: true },
function (err, data) {
if (err) {
console.log(err.toString());
}
else console.log(JSON.stringify(data));
});

Google Spreadsheet Creation - Node.js

I am trying to create new google spreadsheet using the google spreadsheet api using node.js
I have managed to get the Google OAuth 2.0 working, where I am getting the access tokens for the clients.
Now on searching the Google API docs there are example using the gData client library but nothing giving me pointers to node.js
Here are my findings for creating a new google spreadhseet
Upload a spreadsheet manually OR
Use a resumable upload link
There is not much information on the resumable upload link.
I can see the HTTP Post Request and Response but I do not understand how to construct the post request in node.js
EDIT--
I am reading Google Apps Platform
Here is how to do it with the create method of the Google Sheets API (currently v4).
This code examples does not use any 3rd party libraries, it uses googleapis: Google API's official Node.js client
const google = require('googleapis');
const sheets = google.sheets('v4');
// authenticate, and store that authentication, in this example
// it is stored in a variable called `auth`. I am using JWT
// authentication, but you can use the any form of authentication
const auth = new google.auth.JWT(
key.client_email,
null,
key.private_key,
['https://www.googleapis.com/auth/spreadsheets'], // make sure that your auth scope includes `spreadsheets`, `drive` or `drive.file`
null
);
sheets.spreadsheets.create({
auth: auth,
resource: {
properties: {
title: 'Title of your new spreadsheet'
}
}
}, (err, response) => {
if (err) {
console.log(`The API returned an error: ${err}`);
return;
}
console.log('Created a new spreadsheet:')
console.log(response);
});
If all you want to know is how to construct post request, then check this example
http://nodejs.org/api/http.html#http_http_request_options_callback
Checkout
https://github.com/EastCloud/node-spreadsheets/
EastCloud has written a friendly-ish wrapper around the Google Docs/Drive API
If you are new and want to get and add data to Google spreadsheets, please refer below link to get step-by-step guide.
https://www.twilio.com/blog/2017/03/google-spreadsheets-and-javascriptnode-js.html
I was tested same in recent nodejs project

Upload a photo to facebook album

I have a nodejs (+express + mongodb,gridstore) backend, and want to upload a photo to a facebook album.
I came across 2 methods. the first ( https://developers.facebook.com/blog/post/526/ ) needs to get the full url resource of my picture, which I don't have as it is data that I pull from gridstore,
and the second ( https://developers.facebook.com/docs/reference/api/album/ ) is very poorly documented, via the Graph API, where I can't figure out what my request should look like. (the form-data, what fields should it have, how to convert my data blob\stream from gridstore to it)
Here is what I currently have, and doesn't work:
facebook.uploadPhoto = function (token, albumId, photo, callback) {
var fb = fermata.json('https://graph.facebook.com/' + albumId);
fb.photos({access_token:token}).post({'Content-Type':"multipart/form-data"}, {source:{data:photo}}, callback);
};
Any help would be much appreciated
There is a good chance the file is not properly serialized. Fermata will take a node File buffer via data. Have you tried passing that instead?
fs.readFile("/path/to/photo.jpg", function (err, data) {
fermata.json("https://graph.facebook.com/graph/api").post({"Content-Type":"multipart/form-data"}, {fileField: {data:data, name:"", type:""} }, callback);
});
Adding your access token etc..
I solved this problem by using a simple POST to the facebook graph API using the poster module.
var options = {
uploadUrl: 'https://graph.facebook.com/'+user+'/photos?access_token='+accessToken,
method: 'POST',
fileId: 'source',
fields: {'message':''} // Additional fields according to graph API
};
var fileName = ''; // Local or remote url where to find the image
poster.post(fileName, options, function(err, data) {
if (err) {
//Something went wrong
} else {
// Everything ok
}
});
Honestly, I've got limited experience working with the Facebook graph API and mostly using PHP and Java.
Here is some streams that you might find helpful:
Upload Photo To Album with Facebook's Graph API
Facebook Graph API - upload photo using JavaScript
Basically, I recommend you punt a little in your implementation and code it in the following way:
Create a REST web service function call in Node.js to output a single image from gridstore using an internal UID.
Code your uploadToFacebook function to use an image URL that calls the REST web service function.
Basically, this would allow you to validate the image output by pointing your browser to the REST web service and avoid any blob\stream conversions inside your uploadToFacebook function. I'm assuming you store the image in gridstore vs. mongodb.
hope that helps...

Resources