import { AlexaContext } from "./alexa-context" ; import { AudioPlayerActivity } from "./audio-player" ; const uuid = require ( "uuid" ) ; export class RequestType { public static IntentRequest = "IntentRequest" ; public static LaunchRequest = "LaunchRequest" ; public static SessionEndedRequest = "SessionEndedRequest" ; public static AudioPlayerPlaybackFinished = "AudioPlayer.PlaybackFinished" ; public static AudioPlayerPlaybackNearlyFinished = "AudioPlayer.PlaybackNearlyFinished" ; public static AudioPlayerPlaybackStarted = "AudioPlayer.PlaybackStarted" ; public static AudioPlayerPlaybackStopped = "AudioPlayer.PlaybackStopped" ; } export enum SessionEndedReason { ERROR , EXCEEDED_MAX_REPROMPTS , USER_INITIATED } /**
 * Creates a the JSON for a Service Request programmatically
 */ export class ServiceRequest { private requestJSON : any = null ; private requestType : string ; public constructor ( private context ) { } param intentName returns { ServiceRequest } public intentRequest ( intentName ) { let isBuiltin = intentName . startsWith ( "AMAZON" ) ; if ( ! isBuiltin ) { if ( ! this . context . interactionModel ( ) . hasIntent ( intentName ) ) { throw new Error ( "Interaction model has no intentName named: " + intentName ) ; } } this . requestJSON = this . baseRequest ( RequestType . IntentRequest ) ; this . requestJSON . request . intent = { name : intentName } ; if ( ! isBuiltin ) { let intent = this . context . interactionModel ( ) . intentSchema . intent ( intentName ) ; if ( intent . slots !== null && intent . slots . length > 0 ) { this . requestJSON . request . intent . slots = { } ; for ( let slot of intent . slots ) { this . requestJSON . request . intent . slots [ slot . name ] = { name : slot . name } ; } } } return this ; } public audioPlayerRequest ( requestType , token , offsetInMilliseconds ) { this . requestJSON = this . baseRequest ( requestType ) ; this . requestJSON . request . token = token ; this . requestJSON . request . offsetInMilliseconds = offsetInMilliseconds ; return this ; } public launchRequest ( ) { this . requestJSON = this . baseRequest ( RequestType . LaunchRequest ) ; return this ; } public sessionEndedRequest ( reason , errorData ? ) { this . requestJSON = this . baseRequest ( RequestType . SessionEndedRequest ) ; this . requestJSON . request . reason = SessionEndedReason [ reason ] ; if ( errorData !== undefined && errorData !== null ) { this . requestJSON . request . error = errorData ; } return this ; } param slotName param slotValue returns { ServiceRequest } public withSlot ( slotName , slotValue ) { if ( this . requestJSON . request . type !== "IntentRequest" ) { throw Error ( "Adding slot to non-intentName request - not allowed!" ) ; } this . requestJSON . request . intent . slots [ slotName ] = { "name" : slotName , "value" : slotValue } ; return this ; } public requiresSession ( ) { let requireSession = false ; if ( this . requestType === RequestType . LaunchRequest || this . requestType === RequestType . IntentRequest ) { requireSession = true ; } return requireSession ; } private baseRequest ( requestType ) { this . requestType = requestType ; const applicationID = this . context . applicationID ( ) ; const requestID = ServiceRequest . requestID ( ) ; const userID = this . context . userID ( ) ; const timestamp = ServiceRequest . timestamp ( ) ; const baseRequest = { request : { type : requestType , locale : "en-US" , requestId : requestID , timestamp : timestamp } , context : { System : { application : { applicationId : applicationID } , device : { supportedInterfaces : { AudioPlayer : { } } } , user : { userId : userID } , } } , version : "1.0" } ; if ( this . context . accessToken ( ) !== null ) { baseRequest . context . System . user [ "accessToken" ] = this . context . accessToken ( ) ; } return baseRequest ; } /**
     * The timestamp is a normal JS timestamp without the milliseconds
     */ private static timestamp ( ) { let timestamp = new Date ( ) . toISOString ( ) ; return timestamp . substring ( 0 , 19 ) + "Z" ; } private static requestID ( ) { return "amzn1.echo-api.request." + uuid . v4 ( ) ; } returns { boolean } private includeSession ( ) { let include = false ; if ( this . requestType === RequestType . IntentRequest || this . requestType === RequestType . LaunchRequest || this . requestType === RequestType . SessionEndedRequest ) { include = true ; } return include ; } public toJSON ( ) { const applicationID = this . context . applicationID ( ) ; const userID = this . context . userID ( ) ; if ( this . includeSession ( ) && this . context . activeSession ( ) ) { const session = this . context . session ( ) ; let newSession = session . isNew ( ) ; let sessionID = session . id ( ) ; let attributes = session . attributes ( ) ; this . requestJSON . session = { sessionId : sessionID , application : { applicationId : applicationID } , user : { userId : userID } , "new" : newSession } ; if ( this . requestType !== RequestType . LaunchRequest ) { this . requestJSON . session . attributes = attributes ; } if ( this . context . accessToken ( ) !== null ) { this . requestJSON . session . user [ "accessToken" ] = this . context . accessToken ( ) ; } } if ( this . requestType === RequestType . IntentRequest || this . requestType === RequestType . LaunchRequest || this . requestType === RequestType . SessionEndedRequest ) { if ( this . context . audioPlayerEnabled ( ) ) { const activity = AudioPlayerActivity [ this . context . audioPlayer ( ) . activity ( ) ] ; this . requestJSON . context . AudioPlayer = { playerActivity : activity } ; if ( this . context . audioPlayer ( ) . activity ( ) !== AudioPlayerActivity . IDLE ) { const playing = this . context . audioPlayer ( ) . playing ( ) ; this . requestJSON . context . AudioPlayer . token = playing . stream . token ; this . requestJSON . context . AudioPlayer . offsetInMilliseconds = playing . stream . offsetInMilliseconds ; } } } return this . requestJSON ; } }