I try to get the current user with cloud code.
var verificationCode = (Math.floor(Math.random()*900000)) + 100000 ;
var user = Parse.User.current();
user.set("phoneVerificationCode", verificationCode);
user.save();
when I called the method in Xcode.
PFCloud.callFunctionInBackground("sendVerificationCode", withParameters:["phoneNumber": phoneNumberText])
it send but I get this error:
Error: TypeError: Cannot call method 'set' of null
what should I do?
The current user is available, if they are logged in. The user is passed in via the request object to your cloud function.
Parse.Cloud.define("myFunction", function(request, response) {
var verificationCode = (Math.floor(Math.random()*900000)) + 100000 ;
var user = request.user();
user.set("phoneVerificationCode", verificationCode);
user.save();
});
If you are logged in (have active session) then you can do following:
Parse.Cloud.define('get-current-user', async (request) => {
return request.user;
});
Once you call above end-point, it will return current user.
curl -X POST \
-H "X-Parse-Application-Id: test-app" \
-H "Content-Type: application/json" \
-H "X-Parse-Session-Token: r:8729a7099f8c3d87979f4dfd2e5b59df" \
http://localhost:1337/functions/get-current-user
Related
I'm using parse server cloud function to query a class using master key.
The class object has the ACL to allow read only to the user who created the object.
The query gives me zero results.
But as soon as I change ACL on my test object to public read/write, the cloud function query gives me the desired object.
As far as I know, using master key I should have got the objects on query.
Anyone knows what the issue here is?
const mQuery = new Parse.Query('MyClass');
mQuery.equalTo('objectId', mObjectId);
const result = await mQuery.first(null, {useMasterKey : true});
console.log("mQuery",mQuery);
console.log("result",result);
if (!result) {
throw new Error('no data found.');
}
Here the result is logged as undefined. Once the object is made public, the result is the public object. I'm using parse server 3.x.
first only takes a single argument, so re-write to:
const result = await mQuery.first({ useMasterKey : true });
Using Parse Server version equal to 3.x, you can do something like:
Parse.Cloud.define("TestCloudCode", async (request) => {
const query = new Parse.Query(Parse.User);
const objectId = request.params.objectId;
const results = await query.get(objectId, {useMasterKey:true});
return results;
});
To call it:
curl -X POST \
-H "X-Parse-Application-Id: ${APPLICATION_ID}" \
-H "X-Parse-REST-API-Key: ${REST_API_KEY}" \
-H "Content-Type: application/json" \
-d '{ "objectId": "${Replace_with_your_objectId}" }' \
https://parseapi.back4app.com/functions/TestCloudCode
I'm getting issue when I try to claim the token throught cli. In the normal way you access https://www.plex.tv/claim/ and get the token, if not logged you'll need to log in with your account. I'm wondering it it's possible to get the claim token giving the username and password.
First, I need to log in and get the auth token. I have made this command in cURL :
curl -X "POST" "https://plex.tv/users/sign_in.json" -H "X-Plex-Version: 1.0.0" -H "X-Plex-Product: WHATEVER" -H "X-Plex-Client-Identifier: YOUR-PRODUCT-ID" -H "Content-Type: application/x-www-form-urlencoded; charset=utf-8" --data-urlencode "user[password]=PASSWORD" --data-urlencode "user[login]=LOGIN-OR-EMAIL"
It output something like :
{
"user":{
"id":234612345,
"uuid":"c59ae6a4785ea41",
"email":"mail#domain",
"joined_at":"2019-01-13T14:20:05.000Z",
"username":"userA",
"title":"userA",
"thumb":"https://plex.tv/users/c19ae7c44546aa41/avatar?c=1557225551",
"hasPassword":true,
"authToken":"ysdfzerk47qnCSm7zYqzEAZIds4VF3b",
"authentication_token":"ysdfzerk47qnCSm7zYqzEAZIds4VF3b",
"subscription":{
"active":false,
"status":"Inactive",
"plan":null,
"features":[
"adaptive_bitrate",
"collections",
"photos-metadata-edition",
"radio",
"photos-favorites",
"federated-auth",
"Android - PiP",
"publishing_platform",
"news",
"kevin-bacon",
"client-radio-stations",
"TREBLE-show-features",
"web_server_dashboard",
"conan_redirect_qa",
"conan_redirect_alpha",
"conan_redirect_beta",
"conan_redirect_public",
"news_local_now",
"transcoder_cache",
"artist-tv"
]
},
"roles":{
"roles":[
]
},
"entitlements":[
],
"confirmedAt":null,
"forumId":null,
"rememberMe":false
}
}
How can I claim the token now ? I don't found any api to get that token. We can only get from the website https://www.plex.tv/claim/
The token is like : claim-XXXXXXXXXXXXXXXXXXXX
I can't find the token in the source page
I found it looking at source of plex. Here is a sample script:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<span>Token: <span id="token"></span></span>
<script>
var TokenIdentifier = ""
var ClientIdentifier = ""
var i = {
"X-Plex-Product": "Plex SSO",
"X-Plex-Token": TokenIdentifier,
"X-Plex-Client-Identifier": ClientIdentifier
};
$.ajax({
dataType: "json",
type: "GET",
headers: i,
url: "https://plex.tv/api/claim/token.json",
crossDomain: !0,
success: function(e) {
$.each(e, function(index, element) {
document.getElementById("token").innerHTML = element;
});
}
})
</script>
I'm doing the tutorial for IBM Watson Speech-to-text. In the section "Using the WebSocket interface", subsection "Opening a connection and passing credentials", I copied the following code:
var token = watsonToken;
console.log(token); // token looks good
var wsURI = 'wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize?watson-token=' +
token + '&model=es-ES_BroadbandModel';
var websocket = new WebSocket(wsURI);
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
I'm using Angular so I made a value for the token:
app.value('watsonToken', 'Ln%2FV...');
I get back an error message:
WebSocket connection to 'wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize?watson-toke...&model=es-ES_BroadbandModel' failed: HTTP Authentication failed; no valid credentials available
I tried hardcoding the token:
var wsURI = 'wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize?watson-token=Ln%2FV2...&model=es-ES_BroadbandModel';
Same error message.
IBM's documentation on tokens says that an expired or invalid token will return a 401 error, which I didn't get, so I presume that my token is neither expired nor invalid. Any suggestions?
I think you can see the Official Example from IBM Developers here.
The error is because the authentication does not work fine before you send the request to recognize, try to follow the same step inside this repository, like:
const QUERY_PARAMS_ALLOWED = ['model', 'X-Watson-Learning-Opt-Out', 'watson-token', 'customization_id'];
/**
* pipe()-able Node.js Readable/Writeable stream - accepts binary audio and emits text in it's `data` events.
* Also emits `results` events with interim results and other data.
* Uses WebSockets under the hood. For audio with no recognizable speech, no `data` events are emitted.
* #param {Object} options
* #constructor
*/
function RecognizeStream(options) {
Duplex.call(this, options);
this.options = options;
this.listening = false;
this.initialized = false;
}
util.inherits(RecognizeStream, Duplex);
RecognizeStream.prototype.initialize = function() {
const options = this.options;
if (options.token && !options['watson-token']) {
options['watson-token'] = options.token;
}
if (options.content_type && !options['content-type']) {
options['content-type'] = options.content_type;
}
if (options['X-WDC-PL-OPT-OUT'] && !options['X-Watson-Learning-Opt-Out']) {
options['X-Watson-Learning-Opt-Out'] = options['X-WDC-PL-OPT-OUT'];
}
const queryParams = extend({ model: 'en-US_BroadbandModel' }, pick(options, QUERY_PARAMS_ALLOWED));
const queryString = Object.keys(queryParams)
.map(function(key) {
return key + '=' + (key === 'watson-token' ? queryParams[key] : encodeURIComponent(queryParams[key])); // our server chokes if the token is correctly url-encoded
})
.join('&');
const url = (options.url || 'wss://stream.watsonplatform.net/speech-to-text/api').replace(/^http/, 'ws') + '/v1/recognize?' + queryString;
const openingMessage = extend(
{
action: 'start',
'content-type': 'audio/wav',
continuous: true,
interim_results: true,
word_confidence: true,
timestamps: true,
max_alternatives: 3,
inactivity_timeout: 600
},
pick(options, OPENING_MESSAGE_PARAMS_ALLOWED)
);
This code is from IBM Developers and for my project I'm using and works perfectly.
You can see in the code line #53, set the listening to true, otherwise it will eventually timeout and close automatically with inactivity_timeout applies when you're sending audio with no speech in it, not when you aren't sending any data at all.
Have another example, see this example from IBM Watson - Watson Developer Cloud using Javascript for Speech to Text.
Elementary, my dear Watson! There are three or four things to pay attention to with IBM Watson tokens.
First, you won't get a token if you use your IBMid and password. You have to use the username and password that were provided for a project. That username is a string of letters and numbers with hyphens.
Second, the documentation for tokens gives you code for getting a token:
curl -X GET --user {username}:{password}
--output token
"https://stream.watsonplatform.net/authorization/api/v1/token?url=https://stream.watsonplatform.net/text-to-speech/api"
Part of that code is hidden on the webpage, specifically the part that says /text-to-speech/. You need to change that to the Watson product or service you want to use, e.g., /speech-to-text/. Tokens are for specific projects and specific services.
Third, tokens expire in one hour.
Lastly, I had to put in backslashes to get the code to run in my terminal:
curl -X GET --user s0921i-s002d-dh9328d9-hd923:wy928ye98e \
--output token \
"https://stream.watsonplatform.net/authorization/api/v1/token?url=https://stream.watsonplatform.net/speech-to-text/api"
I'm looking a method to automatically updating data using cloud code.
Let say I have a class Table.
inside of it, I have three column : firstname, lastname, and fullname.
Currently, I only have firstname and lastname data only. Column fullname is still empty.
Is it possible to fill the fullname automatically, by just combining the value in firstname and lastname?
Thank you,
#RoyH is 100% right to maintain your computed column as new objects are created. To do an initial migration, try a cloud function, like:
var _ = require("underscore");
Parse.Cloud.define("addFullnames", function(request, response) {
// useMasterKey if the calling user doesn't have permissions read or write to Table
Parse.Cloud.useMasterKey();
var query = new Parse.Query("Table");
// we'll call tables > 1000 an 'advanced topic'
query.limit = 1000;
query.find().then(function(results) {
_.each(results, function(result) {
var firstname = result.get("firstname") || "";
var lastname = result.get("lastname") || "";
result.set("fullname", (firstname + " " + lastname).trim());
});
return Parse.Object.saveAll(results);
}).then(function(results) {
response.success(results);
}, function(error) {
response.error(error);
});
});
Call it like this:
curl -X POST \
-H "X-Parse-Application-Id: your_app_id_here" \
-H "X-Parse-REST-API-Key: your_rest_key_here" \
-H "Content-Type: application/json" \
https://api.parse.com/1/functions/addFullnames
You can factor out the code inside _.each() to make a function that's called here and by a beforeSave hook to maintain the data as it is added.
Yes, you can either just put a value for "fullname" when you are saving "firstname" and "lastname" (before cloudcode). Alternately, you can use the before save/ after save cloudcode functions to insert a value into that column:
Take a look at:
https://parse.com/docs/cloud_code_guide#webhooks-beforeSave
https://parse.com/docs/cloud_code_guide#webhooks-afterSave
I noticed that Google removed the Finance API for Google App Engine. All I want is a list of stock tickers that they have in their Google Finance portfolio. Is there any way to still pull this data from the end user's portfolio, given that the API has been removed? I'm trying to manually retrieve it given that I know the login and password (e.g., it's my own).
Is there any way to retrieve it manually through curl, by logging in to the Google services? It seems like it should be possible to log in and go to my portfolio page, retrieving the source.
I have tried the following code:
#!/bin/bash
function ClientLogin() {
read -p 'Email> ' email
read -p 'Password> ' -s password
local service=$1
curl -s -d Email=$email -d Passwd=$password -d service=$service https://www.google.com/accounts/ClientLogin | tr ' ' \n | grep Auth= | sed -e 's/Auth=//'
}
function GetFinance() {
curl -L -s -H "Authorization: GoogleLogin auth=$(ClientLogin finance)" "http://www.google.com/finance/portfolio?action=view&pid=1" &> output.html
}
GetFinance
However, this code only retrieves a page that tells me to log in. The solution does not need to use curl, but it must be an automated retrieval using some scripting language.
Thanks to x4avier, I learned about casperjs and was able to write a quick script to load the Google services login page, enter the username and password, and then fetch the Google Finance portfolio. I'm sure this would work with any other google service and page. I save the html of the portfolio to portfolio.html. Hopefully this helps someone else also.
var fs = require('fs');
var failed = [];
var links = [
"https://www.google.com/finance/portfolio?action=view&pid=13"
];
var casper = require('casper').create({
verbose: true,
logLevel: 'debug',
pageSettings: {
loadImages: false, // The WebPage instance used by Casper will
loadPlugins: false, // use these settings
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537
}
});
// print out all the messages in the headless browser context
casper.on('remote.message', function(msg) {
this.echo('remote message caught: ' + msg);
});
// print out all the messages in the headless browser context
casper.on("page.error", function(msg, trace) {
this.echo("Page Error: " + msg, "ERROR");
});
var url = 'https://accounts.google.com/ServiceLogin?service=finance';
casper.start(url, function() {
// search for 'casperjs' from google form
console.log("page loaded");
this.test.assertExists('form#gaia_loginform', 'form is found');
this.fill('form#gaia_loginform', {
Email: 'youraccount#gmail.com',
Passwd: 'yourpass'
}, true);
});
casper.each(links, function(casper, link) {
this.then(function() {
this.test.comment("Loading " + link);
start = new Date();
this.open(link);
});
this.then(function() {
var message = this.requestUrl + " loaded";
if (failed.indexOf(this.requestUrl) === -1) {
this.test.pass(message);
fs.write('portfolio.html',this.getPageContent(),'w');
}
});
});
casper.run();
You should consider using an headless browser like casper.js.
With it you can login to google, go to google finance and get the html of a page or of a particular css selector.
To login you will to use the fill() function, it works like this :
casper.start('http://admin.domain.tld/login/', function() {
this.fill('form[id="login-form"]', {
'username': 'chuck',
'password': 'n0rr1s'
}, true);
});
casper.run();
Then you can parse the page and the specific content with getHTML(), work as below :
casper.then(function() {
this.echo(this.getHTML('h1#foobar')); // => 'The text included in the <h1 id=foobar>'
});
CasperJs works with cookies and explore more than one page, it should fit your needs.
Hope it helps :)
What information do you want to retrieve exactly?
It's pretty easy to do that using python urllib and beautifulsoup
http://docs.python.org/2/library/urllib2.html
http://www.crummy.com/software/BeautifulSoup/bs4/doc/
I've done it myself to post and retrieve messages on different forums website. The only thing that is not cool is that you have to hardcode the id of some elements you want to retrieve.
Here's a sample of what I did for the login part
#!/usr/bin/python
import urllib
import urllib2
import cookielib
import BeautifulSoup
url = "https://accounts.google.com/ServiceLogin?hl=en";
values = {'Email': 'me#mymail.fr', 'Passwd' : '', 'signIn' : 'Sign in', 'PersistentCookie' : 'yes'} # The form data 'name' : 'value'
cookie = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
data = urllib.urlencode(values)
response = self.opener.open(url, data)
print response
I filled some of the required info for the google login. But when I checked the POST request there was some others values you might need to add too in the values dict.
Here's the POST request I captured:
dsh:5606788993588
hl:en
checkedDomains:youtube
checkConnection:youtube:47:1,youtube:46:1
pstMsg:1
GALX:YU6dyLz2tHE
pstMsg:0
dnConn:
checkConnection:
checkedDomains:youtube
timeStmp:
secTok:
_utf8:☃
bgresponse:!A0LP9ks4H06eS0R0GKgonCCotgIAAAAiUgAAAAkqAOjHBiH2qA-EIczqcDooax5q8bxis...
Email:****#gmail.com
Passwd:mypassword
signIn:Sign in
PersistentCookie:yes
rmShown:1
I guess you will have to parse the login page using Beautifulsoup to get this values before you can actually send the form. I wonder if the casper example given above does that automatically, if it does you'd rather use it and then parse the portfolio page using Beatifulsoup of whatever you want.