6

我正在构建一个Alexa技能,它需要我存储用户的userId。我试图用event.session.user.userId来检索它。但是,当我拨打console.log(event.session.user.userId)时,输出字面上是amzn1.ask.account.[unique-value-here]。我查看了几个类似的问题,没有一个能够为我提供足够明确的答案。如何获取Alexa用户ID?

我不确定这是一个bug,一个开发人员唯一的事情,或者userId是匿名的。如果是这样,有没有办法获得实际的userId?我想可能会有,因为亚马逊已经在这里写完整的指南:

https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/linking-an-alexa-user-with-a-user-in-your-system

但是,经过漫长的一天的调试之后,我不确定什么是真的,什么是不再。

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": "abcdefghijklmnopqrstuvwxyz" 
        }, 
        "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 
} 

以下是对CloudWatch的日志输出:

 
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 

回答

2

那么,事实证明,我正在做的一切正确(一次)。 userId字面上为amzn1.ask.account。[unique-value-here]的原因是因为我在AWS Lambda控制台中的“Alexa Start Session”测试事件中进行了测试。当我要求我的Echo Dot启动该技能时,它会生成实际的密钥。问题解决了。

7

你这样做的权利。这amzn1.ask.account.[unique-value-here]实际上是完整的用户名。您可以通过在Echo中启用您的技能,将多个请求记录到您的alexa技能并观察这些请求之间的值是相同的值,从而为您自己观察。

JSON Reference

用户名:一个表示谁 发出请求的用户的唯一标识符的字符串。此标识符的长度可能会有所不同,但绝不会超过255个字符。当用户启用Alexa应用程序中的技能时,会自动生成userId。

注意:禁用和重新启用技能会生成新的标识符。

如果您只需要在会话之间保留用户属性,该值就足够了,您可以使用它来唯一标识此用户,只要他们具有启用的技能。

如果您需要关联一个帐户,那么您正在查找的值为accessToken,并且在成功建立帐户关联之后会存在于同一个user对象中。按照与上面相同的JSON参考:

accessToken:标识另一个系统中的用户的令牌。如果用户已成功链接其帐户,则仅提供 。有关更多详细信息,请参阅 Linking an Alexa User with a User in Your System

+0

首先,非常感谢您的回答!它非常详细。有一件事我不确定我的理解是,如果所有这些值都相同,我可以通过将其event.session.user.userId保存到Firebase来唯一标识用户。你能解释一下吗? –

+1

他们只对你的技能的个人用户是一样的;例如,在amzn1.ask.account之后,其他使用不同回声技能的人会拥有不同的唯一值。因此,对于任何给定的用户,您可以将此值保存到任何数据存储区 - 而不仅仅是Firebase - 并且该值对该用户是唯一的。 –

+0

那么为什么我的价值字面意思是“[unique-value-here]”,而不是一个随机的字符串?是因为我是开发人员吗? –