问题
I'm building an Alexa Skill, and it requires that I store the userId of a user. I've tried to retrieve it with event.session.user.userId
. However, when I call console.log(event.session.user.userId)
the output is literally amzn1.ask.account.[unique-value-here]
. I've looked at several similar questions, and none of them provide a clear enough answer for me.
I'm not sure if this is a bug, a developer-only thing, or if the userId is simply anonymized. If so, is there a way to get the actual userId? I imagine there would be, since Amazon has written an entire guide on it here:
https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/linking-an-alexa-user-with-a-user-in-your-system.
However, after a long day of debugging, I'm not sure what's real and what's not anymore.
var request = require('request');
var firebase = require('firebase');
var config = {
apiKey: "my-api-key",
authDomain: "stuff...",
databaseURL: "more stuff...",
storageBucket: "even more stuff...",
};
firebase.initializeApp(config);
// Get a reference to the database
var database = firebase.database();
exports.handler = (event, context) => {
try {
// New session
if (event.session.new) {
// New Session
console.log("NEW SESSION");
}
// Launch Request
switch (event.request.type) {
case "LaunchRequest":
var url = "https://api.random.org/json-rpc/1/invoke";
var myRequest = {
"jsonrpc": "2.0",
"method": "generateStrings",
"params": {
"apiKey": "another-api-key",
"n": "1",
"length": "3",
"characters": "abcdefghijklmnopqrstuvwxyz0123456789"
},
"id": 24
}
var pin;
request.post(
url,
{json: myRequest},
function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(event.session.user.userId); // **Here**, output is literally amzn1.ask.account.[unique-value-here]
pin = body.result.random.data[0];
writeUserPin(pin);
var welcome = "Welcome";
var pinStatement = "Your 3 letter or number pin is: " + processPinForSpeech(pin);
context.succeed(
generateResponse(
buildSpeechletReponse(welcome + pinStatement, true),
{}
)
);
console.log(pin);
}
else {
console.log(error);
}
}
);
console.log("LAUNCH REQUEST");
break;
// Intent Request
case "IntentRequest":
console.log("INTENT REQUEST");
break;
// Session Ended Request
case "SessionEndedRequest":
console.log("SESSION ENDED REQUEST");
break;
default:
context.fail(`INVALID REQUEST TYPE: ${event.request.type}`);
}
}
catch (error) {
context.fail(`Exception: ${error}`);
}
}
// Helpers
buildSpeechletReponse = (outputText, shouldEndSession) => {
return {
outputSpeech : {
type: "PlainText",
text: outputText
},
shouldEndSession: shouldEndSession
};
}
generateResponse = (speechletResponse, sessionAttributes) => {
return {
version: "1.0",
sessionAttributes: sessionAttributes,
response: speechletResponse
};
}
function writeUserPin(pin) {
console.log("writing stuff");
firebase.database().ref('newPins/' + pin).set({
num : ""
});
}
function processPinForSpeech(pin) {
var wordNumArr = ["zero", "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine"];
processedPin = "";
for (i = 0; i < pin.length; i++){
var currentChar = pin.charAt(i);
if (isNaN(Number(currentChar))){
processedPin += currentChar + ". ";
}
else {
processedPin += wordNumArr[Number(currentChar)] + ". ";
}
}
return processedPin
}
The following is the output on the CloudWatch logs:
16:16:19
START RequestId: 48e335c5-d819-11e6-bc01-a939911adc24 Version: $LATEST
16:16:19
2017-01-11T16:16:19.639Z 48e335c5-d819-11e6-bc01-a939911adc24 NEW SESSION
16:16:19
2017-01-11T16:16:19.758Z 48e335c5-d819-11e6-bc01-a939911adc24 LAUNCH REQUEST
16:16:20
2017-01-11T16:16:20.457Z 48e335c5-d819-11e6-bc01-a939911adc24 amzn1.ask.account.[unique-value-here]
16:16:20
2017-01-11T16:16:20.457Z 48e335c5-d819-11e6-bc01-a939911adc24 writing stuff
16:16:20
2017-01-11T16:16:20.520Z 48e335c5-d819-11e6-bc01-a939911adc24 dd2
16:16:20
END RequestId: 48e335c5-d819-11e6-bc01-a939911adc24
16:16:20
REPORT RequestId: 48e335c5-d819-11e6-bc01-a939911adc24 Duration: 1005.48 ms Billed Duration: 1100 ms Memory Size: 128 MB Max Memory Used: 38 MB
回答1:
You are doing it right. This amzn1.ask.account.[unique-value-here]
is in-fact the full userid. You can observe this for yourself by enabling your skill from an Echo, logging several requests to your alexa skill, and observing that the userid
between these requests is the same value.
Per the JSON Reference:
userId: A string that represents a unique identifier for the user who made the request. The length of this identifier can vary, but is never more than 255 characters. The userId is automatically generated when a user enables the skill in the Alexa app.
Note: Disabling and re-enabling a skill generates a new identifier.
If you only need to persist user attributes between sessions, this value will be sufficient and you can use it to uniquely identify this user so long as they have the skill enabled.
If you need to link an account, the value you're looking for is accessToken
and lives in that same user
object following successful account link. Per the same JSON Reference as above:
accessToken: a token identifying the user in another system. This is only provided if the user has successfully linked their account. See Linking an Alexa User with a User in Your System for more details.
回答2:
Well, turns out I was doing everything correctly (for once). The reason why the userId was literally amzn1.ask.account.[unique-value-here] was because I was testing it on a "Alexa Start Session" test event in the AWS Lambda console. When I asked my Echo Dot to launch the skill, it generated the actual key. Problem solved.
回答3:
You should try to read the request that is displayed in the Test console of ASK. From there, you can access the different variables that are being sent to your lambda function. Also, you can manipulate or use them as per your requirement.
来源:https://stackoverflow.com/questions/41582708/how-to-get-an-alexa-userid