2016-12-31 5 views
2

私はAmazon AlexaのためのユニークなAlexaスキルを書こうとしています。次のapi(https://api.ense.nyc/latest)に含まれるオーディオコンテンツを再生するカスタムラムダ関数を記述したいと思います。Alexaスキルキット - 私たちのiOSアプリのAPIからオーディオを再生するカスタムスキル

私は、件名にAmazonの文書のすべてを読んだ:私はユニークなラムダ関数を書くことで進行する正確にどの程度混乱していますスキル

をFlashbriefing

+0

あなたがリンクされたページを読みましたあなたが言及した「カスタムスキルを構築する」ページの「ステップ2」からの「alexa-a-a-lambda-function」)文字通り、「ラムダ関数」の作成に関するステップバイステップのガイドがあります。また、あなたの質問に 'aws-lambda'タグを付けるべきです。 – gmiley

答えて

0

alexaでオーディオを再生するのは、通常のスキルよりも少しトリッキーです。あなたのJSON -parse

をし、オーディオURLおよびオーディオカードを保持するオブジェクトのいくつかの種類を作成します。あなたがする必要があるよう

が見えます。

-次に、スキルの状態をPLAY_MODEに設定すると、質問audioPlayerPlay()コマンドでオーディオを再生する必要があります。 (https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/custom-audioplayer-interface-reference#audioplayer-directives

-オーディオイベントハンドラを設定して、オーディオイベントを追跡する必要があります。

- ユーザーが次のまたは前のオーディオを再生できるようにインテントを設定する必要があります。

一覧はこちら...

に行く次のコードは、最初に再生するためにラムダ関数で動作するXMLフィードを解析するサンプルポッドキャストスキルで、オーディオ

https://github.com/bespoken/streamer

0

を果たしていますオーディオアイテム。楽しい! [スキルについてAWSラムダ関数の作成](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/developing-:

/** 
* App ID for the skill 
*/ 
//var APP_ID = undefined; //OPTIONAL: replace with "amzn1.echo-sdk-ams.app.[your-unique-value-here]"; 

/** 
* The AlexaSkill prototype and helper functions 
*/ 

var APP_ID = undefined; 

//var AlexaSkill = require('./AlexaSkill'); 

////// 
/** 
    Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. 

    Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at 

     http://aws.amazon.com/apache2.0/ 

    or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 
*/ 



////////////////////////////////////////////// 
//////////// /AlexaSkill.js File Starts ///// 
////////////////////////////////////////////// 




'use strict'; 

function AlexaSkill(appId) { 
    this._appId = appId; 
} 

AlexaSkill.speechOutputType = { 
    PLAIN_TEXT: 'PlainText', 
    SSML: 'SSML' 
} 

AlexaSkill.prototype.requestHandlers = { 
    LaunchRequest: function (event, context, response) { 
     this.eventHandlers.onLaunch.call(this, event.request, event.session, response); 
    }, 

    IntentRequest: function (event, context, response) { 
     this.eventHandlers.onIntent.call(this, event.request, event.session, response); 
    }, 

    SessionEndedRequest: function (event, context) { 
     this.eventHandlers.onSessionEnded(event.request, event.session); 
     context.succeed(); 
    } 
}; 

/** 
* Override any of the eventHandlers as needed 
*/ 
AlexaSkill.prototype.eventHandlers = { 
    /** 
    * Called when the session starts. 
    * Subclasses could have overriden this function to open any necessary resources. 
    */ 
    onSessionStarted: function (sessionStartedRequest, session) { 
    }, 

    /** 
    * Called when the user invokes the skill without specifying what they want. 
    * The subclass must override this function and provide feedback to the user. 
    */ 
    onLaunch: function (launchRequest, session, response) { 
     throw "onLaunch should be overriden by subclass"; 
    }, 

    /** 
    * Called when the user specifies an intent. 
    */ 
    onIntent: function (intentRequest, session, response) { 
     var intent = intentRequest.intent, 
      intentName = intentRequest.intent.name, 
      intentHandler = this.intentHandlers[intentName]; 
     if (intentHandler) { 
      console.log('dispatch intent = ' + intentName); 
      intentHandler.call(this, intent, session, response); 
     } else { 
      throw 'Unsupported intent = ' + intentName; 
     } 
    }, 

    /** 
    * Called when the user ends the session. 
    * Subclasses could have overriden this function to close any open resources. 
    */ 
    onSessionEnded: function (sessionEndedRequest, session) { 
    } 
}; 

/** 
* Subclasses should override the intentHandlers with the functions to handle specific intents. 
*/ 
AlexaSkill.prototype.intentHandlers = {}; 

AlexaSkill.prototype.execute = function (event, context) { 
    try { 
     console.log("session applicationId: " + event.session.application.applicationId); 

     // Validate that this request originated from authorized source. 
     if (this._appId && event.session.application.applicationId !== this._appId) { 
      console.log("The applicationIds don't match : " + event.session.application.applicationId + " and " 
       + this._appId); 
      throw "Invalid applicationId"; 
     } 

     if (!event.session.attributes) { 
      event.session.attributes = {}; 
     } 

     if (event.session.new) { 
      this.eventHandlers.onSessionStarted(event.request, event.session); 
     } 

     // Route the request to the proper handler which may have been overriden. 
     var requestHandler = this.requestHandlers[event.request.type]; 
     requestHandler.call(this, event, context, new Response(context, event.session)); 
    } catch (e) { 
     console.log("Unexpected exception " + e); 
     context.fail(e); 
    } 
}; 

var Response = function (context, session) { 
    this._context = context; 
    this._session = session; 
}; 

function createSpeechObject(optionsParam) { 
    if (optionsParam && optionsParam.type === 'SSML') { 
     return { 
      type: optionsParam.type, 
      ssml: optionsParam.speech 
     }; 
    } else { 
     return { 
      type: optionsParam.type || 'PlainText', 
      text: optionsParam.speech || optionsParam 
     } 
    } 
} 

Response.prototype = (function() { 
    var buildSpeechletResponse = function (options) { 
     var alexaResponse = { 
      outputSpeech: createSpeechObject(options.output), 
      shouldEndSession: options.shouldEndSession 
     }; 
     if (options.reprompt) { 
      alexaResponse.reprompt = { 
       outputSpeech: createSpeechObject(options.reprompt) 
      }; 
     } 
     if (options.cardTitle && options.cardContent) { 
      alexaResponse.card = { 
       type: "Simple", 
       title: options.cardTitle, 
       content: options.cardContent 
      }; 
     } 
     var returnResult = { 
       version: '1.0', 
       response: alexaResponse 
     }; 
     if (options.session && options.session.attributes) { 
      returnResult.sessionAttributes = options.session.attributes; 
     } 
     return returnResult; 
    }; 

    return { 
     tell: function (speechOutput) { 
      this._context.succeed(buildSpeechletResponse({ 
       session: this._session, 
       output: speechOutput, 
       shouldEndSession: true 
      })); 
     }, 
     tellWithCard: function (speechOutput, cardTitle, cardContent) { 
      this._context.succeed(buildSpeechletResponse({ 
       session: this._session, 
       output: speechOutput, 
       cardTitle: cardTitle, 
       cardContent: cardContent, 
       shouldEndSession: true 
      })); 
     }, 
     ask: function (speechOutput, repromptSpeech) { 
      this._context.succeed(buildSpeechletResponse({ 
       session: this._session, 
       output: speechOutput, 
       reprompt: repromptSpeech, 
       shouldEndSession: false 
      })); 
     }, 
     askWithCard: function (speechOutput, repromptSpeech, cardTitle, cardContent) { 
      this._context.succeed(buildSpeechletResponse({ 
       session: this._session, 
       output: speechOutput, 
       reprompt: repromptSpeech, 
       cardTitle: cardTitle, 
       cardContent: cardContent, 
       shouldEndSession: false 
      })); 
     } 
    }; 
})(); 




////////////////////////////////////////////// 
///////////// AlexaSkill.js File Ends ////// 
////////////////////////////////////////////// 










'use strict'; 

function AlexaSkill(appId) { 
    this._appId = appId; 
} 

AlexaSkill.speechOutputType = { 
    PLAIN_TEXT: 'PlainText', 
    SSML: 'SSML' 
} 

AlexaSkill.prototype.requestHandlers = { 
    LaunchRequest: function (event, context, response) { 
     this.eventHandlers.onLaunch.call(this, event.request, event.session, response); 
    }, 

    IntentRequest: function (event, context, response) { 
     this.eventHandlers.onIntent.call(this, event.request, event.session, response); 
    }, 

    SessionEndedRequest: function (event, context) { 
     this.eventHandlers.onSessionEnded(event.request, event.session); 
     context.succeed(); 
    } 
}; 

/** 
* Override any of the eventHandlers as needed 
*/ 
AlexaSkill.prototype.eventHandlers = { 
    /** 
    * Called when the session starts. 
    * Subclasses could have overriden this function to open any necessary resources. 
    */ 
    onSessionStarted: function (sessionStartedRequest, session) { 
    }, 

    /** 
    * Called when the user invokes the skill without specifying what they want. 
    * The subclass must override this function and provide feedback to the user. 
    */ 
    onLaunch: function (launchRequest, session, response) { 
     throw "onLaunch should be overriden by subclass"; 
    }, 

    /** 
    * Called when the user specifies an intent. 
    */ 
    onIntent: function (intentRequest, session, response) { 
     var intent = intentRequest.intent, 
      intentName = intentRequest.intent.name, 
      intentHandler = this.intentHandlers[intentName]; 
     if (intentHandler) { 
      console.log('dispatch intent = ' + intentName); 
      intentHandler.call(this, intent, session, response); 
     } else { 
      throw 'Unsupported intent = ' + intentName; 
     } 
    }, 

    /** 
    * Called when the user ends the session. 
    * Subclasses could have overriden this function to close any open resources. 
    */ 
    onSessionEnded: function (sessionEndedRequest, session) { 
    } 
}; 

/** 
* Subclasses should override the intentHandlers with the functions to handle specific intents. 
*/ 
AlexaSkill.prototype.intentHandlers = {}; 

AlexaSkill.prototype.execute = function (event, context) { 
    try { 
     console.log("session applicationId: " + event.session.application.applicationId); 

     // Validate that this request originated from authorized source. 
     if (this._appId && event.session.application.applicationId !== this._appId) { 
      console.log("The applicationIds don't match : " + event.session.application.applicationId + " and " 
       + this._appId); 
      throw "Invalid applicationId"; 
     } 

     if (!event.session.attributes) { 
      event.session.attributes = {}; 
     } 

     if (event.session.new) { 
      this.eventHandlers.onSessionStarted(event.request, event.session); 
     } 

     // Route the request to the proper handler which may have been overriden. 
     var requestHandler = this.requestHandlers[event.request.type]; 
     requestHandler.call(this, event, context, new Response(context, event.session)); 
    } catch (e) { 
     console.log("Unexpected exception " + e); 
     context.fail(e); 
    } 
}; 

var Response = function (context, session) { 
    this._context = context; 
    this._session = session; 
}; 

function createSpeechObject(optionsParam) { 
    if (optionsParam && optionsParam.type === 'SSML') { 
     return { 
      type: optionsParam.type, 
      ssml: optionsParam.speech 
     }; 
    } else { 
     return { 
      type: optionsParam.type || 'PlainText', 
      text: optionsParam.speech || optionsParam 
     } 
    } 
} 

Response.prototype = (function() { 
    var buildSpeechletResponse = function (options) { 
     var alexaResponse = { 
      outputSpeech: createSpeechObject(options.output), 
      shouldEndSession: options.shouldEndSession 
     }; 
     if (options.reprompt) { 
      alexaResponse.reprompt = { 
       outputSpeech: createSpeechObject(options.reprompt) 
      }; 
     } 
     if (options.cardTitle && options.cardContent) { 
      alexaResponse.card = { 
       type: "Simple", 
       title: options.cardTitle, 
       content: options.cardContent 
      }; 
     } 
     var returnResult = { 
       version: '1.0', 
       response: alexaResponse 
     }; 
     if (options.session && options.session.attributes) { 
      returnResult.sessionAttributes = options.session.attributes; 
     } 
     return returnResult; 
    }; 

    return { 
     tell: function (speechOutput) { 
      this._context.succeed(buildSpeechletResponse({ 
       session: this._session, 
       output: speechOutput, 
       shouldEndSession: true 
      })); 
     }, 
     tellWithCard: function (speechOutput, cardTitle, cardContent) { 
      this._context.succeed(buildSpeechletResponse({ 
       session: this._session, 
       output: speechOutput, 
       cardTitle: cardTitle, 
       cardContent: cardContent, 
       shouldEndSession: true 
      })); 
     }, 
     ask: function (speechOutput, repromptSpeech) { 
      this._context.succeed(buildSpeechletResponse({ 
       session: this._session, 
       output: speechOutput, 
       reprompt: repromptSpeech, 
       shouldEndSession: false 
      })); 
     }, 
     askWithCard: function (speechOutput, repromptSpeech, cardTitle, cardContent) { 
      this._context.succeed(buildSpeechletResponse({ 
       session: this._session, 
       output: speechOutput, 
       reprompt: repromptSpeech, 
       cardTitle: cardTitle, 
       cardContent: cardContent, 
       shouldEndSession: false 
      })); 
     }, 
     justUseThisJsonPlease: function(json) { 
      this._context.succeed(json); 
     } 
    }; 
})(); 
////// 
var https = require('https'); 
var Fact = function() { 
    AlexaSkill.call(this, APP_ID); 
}; 

// Extend AlexaSkill 
Fact.prototype = Object.create(AlexaSkill.prototype); 
Fact.prototype.constructor = Fact; 

Fact.prototype.eventHandlers.onSessionStarted = function (sessionStartedRequest, session) { 
    console.log("onSessionStarted requestId: " + sessionStartedRequest.requestId + ", sessionId: " + session.sessionId); 
    // any initialization logic goes here 
}; 

Fact.prototype.eventHandlers.onLaunch = function (launchRequest, session, response) { 
    console.log("onLaunch requestId: " + launchRequest.requestId + ", sessionId: " + session.sessionId); 
    //handleEnseFeed(response) 
}; 

/** 
* Overridden to show that a subclass can override this function to teardown session state. 
*/ 
Fact.prototype.eventHandlers.onSessionEnded = function (sessionEndedRequest, session) { 
    //console.log("onSessionEnded requestId: " + sessionEndedRequest.requestId + ", sessionId: " + session.sessionId); 
    // any cleanup logic goes here 
}; 

Fact.prototype.intentHandlers = { 
    "PlayAudio": function (event, context, response) { 
     //response.tell('ense is lit') 
     //handleEnseFeed(response) 
      fetchEnseParse("/latest", function(body) { 
      if(body == "error") { 
      } 
      else { 
       var directives = body.enses.map(function(ense) { 
        var a = ense[1].fileUrl; 
        return { 
         'playBehavior': 'REPLACE_ALL', 
         'audioItem': 
          { 
           'stream': 
            { 
             'url': 'https://s3.amazonaws.com/media.ense.nyc/enses/2017_01_13T16_57_20.190Z/30312/0', 
             'token': '33529', 
             'offsetInMilliseconds': 0 
            } 
          }, 
          'type': 'AudioPlayer.Play' 
        }; 
       }) 
      } 
      var jsonresponse = { 
       'outputSpeech': { 
        'text': '', 
        'type': 'PlainText' 
        }, 
       'directives': [directives[0]] 
      };  
      response.justUseThisJsonPlease({ response: jsonresponse }); 
      //queueNext(); 
     }); 
    }, 
    "AudioPlayer.PlaybackNearlyFinished" : function(event, context, response) { 
     //console.log(JSON.stringify(intent)); 
     //console.log(JSON.stringify(session)); 
     //console.log(JSON.stringify(response)); 
     // console.log("dog") 
     // var stream = { 
     //  "url": "https://s3.amazonaws.com/media.ense.nyc/enses/violetindigoviolet/30034/0", 
     //  "token": "some_token", 
     //  "expectedPreviousToken": "33529", 
     //  "offsetInMilliseconds": 0 
     // }; 
     // response.audioPlayerPlayStream("ENQUEUE", stream); 
     // response.justUseThisJsonPlease({ response: stream }); 
      var second = 
      { 
       "type": "AudioPlayer.Play", 
       "playBehavior": "REPLACE_ENQUEUED", 
       "audioItem": { 
       "stream": { 
        "url": "https://s3.amazonaws.com/media.ense.nyc/enses/violetindigoviolet/30034/0", 
        "token": "33530", 
       // "expectedPreviousToken": "33529", 
        "offsetInMilliseconds": 0 
       } 
       } 
      } 
      response.justUseThisJsonPlease({ response: second }); 
    }, 
     "AudioPlayer.PlaybackFinished" : function(event, context, response) { 
      var speechOutput = "Goodbye"; 
      response.tell(speechOutput); 
    }, 
    "AMAZON.HelpIntent": function (intent, session, response) { 
     response.ask("You can say play ense feed or, you can say exit... What can I help you with?", "What can I help you with?"); 
    }, 
    "AMAZON.StopIntent": function (intent, session, response) { 
     var speechOutput = "Goodbye"; 
     response.tell(speechOutput); 
    }, 
    "AMAZON.CancelIntent": function (intent, session, response) { 
     var speechOutput = "Goodbye"; 
     response.tell(speechOutput); 
    } 
}; 



function queueNext(event, second) { 
     console.log ('trains') 
     var response = { 

     'outputSpeech': 
     { 
     'text': '', 
     'type': 'PlainText' 
     }, 
      'directives': 
      [ 
       { 
        'playBehavior': 'REPLACE_ALL', 
        'audioItem': 
       { 
        'stream': 
        { 
         'url': 'https://s3.amazonaws.com/media.ense.nyc/enses/violetindigoviolet/30034/0', 
         'token': '33529', 
         'offsetInMilliseconds': 10000 
        } 
       }, 
       'type': 'AudioPlayer.Play'} 

      ] 
     }; 
    // second.succeed({ response: response }); 
} 

function handleEnseFeed(response) { 
    https.get('https://api.ense.nyc/latest', function (res) { 
     var body = ''; 

     if (res.statusCode != 200) 

     res.on('data', function (chunk) { 
      body += chunk; 
     }); 

     res.on('end', function (par1, par2) { 
      body = JSON.parse(body); 
      var enses = body.enses; 

      response._context.succeed(thisResponse); 

     }).on('error', function (e) { 

     }); 

    }); 
} 


function fetchEnseParse(url, handler) { 
    const getEnseOptions = { 
      host : "api.ense.nyc", 
      path : url 
     }; 
    const req = https.request(getEnseOptions, (res) => { 
      var body = ''; 
      res.setEncoding('utf8'); 
      res.on('data', (chunk) => body += chunk); 
      res.on('end',() => { 
       // If we know it's JSON, parse it 
       if (res.headers['content-type'] && res.headers['content-type'].indexOf('application/json') != -1) { 
        body = JSON.parse(body); 
        handler(body); 
       } else { 
        handler("error"); 
       } 

      }); 
     }); 

     req.on('error', function() { 
      handler("error"); 
     }); 
     req.end(); 
}; 


// Create the handler that responds to the Alexa Request. 
exports.handler = function (event, context) { 
    // Create an instance of the SpaceGeek skill. 
    var fact = new Fact(); 
    console.log("tractor") 
    // queueNext(); 
    // var api = testFuntion(); 
    fact.execute(event, context); 
}; 
関連する問題