Calling Alexa Service APIs


The Alexa Skills Kit (ASK) provides multiple service APIs that you can use to personalize your skill experience. The SDK includes service clients which make it easy to call Alexa APIs from within your skill logic.

ServiceClientFactory

The ServiceClientFactory is available to the handlers via the HandlerInput container object. It takes care of creating individual service client and configuring the ApiAccessToken and ApiEndpoint.

Available Methods

getDeviceAddressServiceClient() : deviceAddress.DeviceAddressServiceClient;
getDirectiveServiceClient() : directive.DirectiveServiceClient;
getEndpointEnumerationServiceClient() : endpointEnumeration.EndpointEnumerationServiceClient;
getMonetizationServiceClient() : monetization.MonetizationServiceClient;
getReminderManagementServiceClient(): reminderManagement.ReminderManagementServiceClient;
getUpsServiceClient() : ups.UpsServiceClient;

ApiClient

The ApiClient is used by ServiceClientFactory when making API calls to Alexa services. You can register any customized ApiClient that conforms to the following interface with the SDK.

Interface

interface ApiClient {
  invoke(request: ApiClientRequest): Promise<ApiClientResponse>;
}

interface ApiClientMessage {
  headers: Array<{key: string; value: string;}>;
  body?: string;
}

interface ApiClientRequest extends ApiClientMessage {
  url: string;
  method: string;
}

interface ApiClientResponse extends ApiClientMessage {
  statusCode: number;
}

DefaultApiClient

ask-sdk-core package provides a DefaultApiClient which is an implementation of ApiClient using the Node.js native https client.

Constructor Details

new DefaultApiClient() => object

Constructs a DefaultApiClient object. ServiceClient uses the DefaultApiClient to make API calls to individual Alexa services.

StandardSkillBuilder registers the ApiClient by default. Alternatively, you can register the ApiClient to the CustomSkillBuilder.

Register ApiClient to CustomSkillBuilder

Use the withApiClient function to register ApiClient to CustomSkillBuilder.

const skillBuilder = Alexa.SkillBuilders.custom();
skillBuilder.withApiClient(new DefaultApiClient());

DeviceAddressServiceClient

DeviceAddressServiceClient can be used to query Device Settings API for address data associated with the customer's Alexa device. You can then use this address data to provide key functionality for the skill, or to enhance the customer experience. For example, your skill could provide a list of nearby store locations or provide restaurant recommendations by using this address information.

Type Definition

class DeviceAddressServiceClient {
  getCountryAndPostalCode(deviceId: string): Promise<services.deviceAddress.ShortAddress>;
  getFullAddress(deviceId: string): Promise<services.deviceAddress.Address>;
};

interface ShortAddress {
  countryCode?: string;
  postalCode?: string;
}

interface Address {
  addressLine1?: string;
  addressLine2?: string;
  addressLine3?: string;
  countryCode?: string;
  stateOrRegion?: string;
  city?: string;
  districtOrCounty?: string;
  postalCode?: string;
}

Code Sample

The following example shows a request handler that creates an instance of the DeviceAddressServiceClient and retrieves customer's full address.

Copied to clipboard.

const GetAddressIntent = {
  canHandle(handlerInput) {
    const { request } = handlerInput.requestEnvelope;

    return request.type === 'IntentRequest' && request.intent.name === 'GetAddressIntent';
  },
  async handle(handlerInput) {
    const { requestEnvelope, serviceClientFactory, responseBuilder } = handlerInput;
    const consentToken = requestEnvelope.context.System.user.permissions
        && requestEnvelope.context.System.user.permissions.consentToken;
    if (!consentToken) {
      return responseBuilder
        .speak('Please enable Location permissions in the Amazon Alexa app.')
        .withAskForPermissionsConsentCard(['read::alexa:device:all:address'])
        .getResponse();
    }

    try {
      const { deviceId } = requestEnvelope.context.System.device;
      const deviceAddressServiceClient = serviceClientFactory.getDeviceAddressServiceClient();
      const address = await deviceAddressServiceClient.getFullAddress(deviceId);

      console.log('Address successfully retrieved, now responding to user.');

      let response;
      if (address.addressLine1 === null && address.stateOrRegion === null) {
        response = responseBuilder
          .speak(`It looks like you don't have an address set. You can set your address from the companion app.`)
          .getResponse();
      } else {
        const ADDRESS_MESSAGE = `Here is your full address: ${address.addressLine1}, ${address.stateOrRegion}, ${address.postalCode}`;
        response = responseBuilder
          .speak(ADDRESS_MESSAGE)
          .getResponse();
      }
      return response;
    } catch (error) {
      if (error.name !== 'ServiceError') {
        const response = responseBuilder
          .speak('Uh Oh. Looks like something went wrong.')
          .getResponse();

        return response;
      }
      throw error;
    }
  },
};

Copied to clipboard.

import {
  HandlerInput,
  RequestHandler,
} from 'ask-sdk-core';
import {
  Response,
  services,
} from 'ask-sdk-model';
import Address = services.deviceAddress.Address;

const GetAddressIntent : RequestHandler = {
  canHandle(handlerInput : HandlerInput) : boolean {
    const { request } = handlerInput.requestEnvelope;

    return request.type === 'IntentRequest' && request.intent.name === 'GetAddressIntent';
  },
  async handle(handlerInput : HandlerInput) : Promise<Response> {
    const { requestEnvelope, serviceClientFactory, responseBuilder } = handlerInput;

    const consentToken = requestEnvelope.context.System.user.permissions
                         && requestEnvelope.context.System.user.permissions.consentToken;
    if (!consentToken) {
      return responseBuilder
        .speak('Please enable Location permissions in the Amazon Alexa app.')
        .withAskForPermissionsConsentCard(['read::alexa:device:all:address'])
        .getResponse();
    }
    try {
      const { deviceId } = requestEnvelope.context.System.device;
      const deviceAddressServiceClient = serviceClientFactory.getDeviceAddressServiceClient();
      const address : Address = await deviceAddressServiceClient.getFullAddress(deviceId);

      console.log('Address successfully retrieved, now responding to user.');

      let response;
      if (address.addressLine1 === null && address.stateOrRegion === null) {
        response = responseBuilder
          .speak(`It looks like you don't have an address set. You can set your address from the companion app.`)
          .getResponse();
      } else {
        const ADDRESS_MESSAGE = `Here is your full address: ${address.addressLine1}, ${address.stateOrRegion}, ${address.postalCode}`;
        response = responseBuilder
          .speak(ADDRESS_MESSAGE)
          .getResponse();
      }

      return response;
    } catch (error) {
      if (error.name !== 'ServiceError') {
        const response = responseBuilder
          .speak('Uh Oh. Looks like something went wrong.')
          .getResponse();

        return response;
      }
      throw error;
    }
  },
};

DirectiveServiceClient

DirectiveServiceClient can be used to send directives to Progressive Response API. Progressive responses can be used to keep the user engaged while your skill prepares a full response to the user's request.

Type Definition

class DirectiveServiceClient {
  enqueue(sendDirectiveRequest: services.directive.SendDirectiveRequest): Promise<void>;
}

interface SendDirectiveRequest {
  header: services.directive.Header;
  directive: services.directive.Directive;
}

interface Header {
  requestId: string;
}

type Directive = services.directive.SpeakDirective;

interface SpeakDirective {
  type: 'VoicePlayer.Speak';
  speech?: string;
}

Code Sample

The following example shows a function that creates an instance of the DirectiveServiceClient and sends a progressive response.

Copied to clipboard.

function callDirectiveService(handlerInput, date) {
  const requestEnvelope = handlerInput.requestEnvelope;
  const directiveServiceClient = handlerInput.serviceClientFactory.getDirectiveServiceClient();

  const requestId = requestEnvelope.request.requestId;
  const directive = {
    header: {
      requestId,
    },
    directive: {
      type: 'VoicePlayer.Speak',
      speech: `$Please wait while I look up information about ${date}...`,
    },
  };

  return directiveServiceClient.enqueue(directive);
}

Copied to clipboard.

import { HandlerInput } from 'ask-sdk-core';
import { services } from 'ask-sdk-model';
import SendDirectiveRequest = services.directive.SendDirectiveRequest;

function callDirectiveService(handlerInput : HandlerInput, date : string) : Promise<void> {
  const requestEnvelope = handlerInput.requestEnvelope;
  const directiveServiceClient = handlerInput.serviceClientFactory.getDirectiveServiceClient();

  const requestId = requestEnvelope.request.requestId;

  const directive : SendDirectiveRequest = {
      header: {
          requestId,
      },
      directive: {
          type: 'VoicePlayer.Speak',
          speech: `$Please wait while I look up information about ${date}...`,
      },
  };

  return directiveServiceClient.enqueue(directive);
}

EndpointEnumerationServiceClient

Skills can use EndpointEnumerationServiceClient to retrieve the user's connected endpoints that the skill can interact with.

Type Definition

class EndpointEnumerationServiceClient extends BaseServiceClient {
  getEndpoints(): Promise<services.endpointEnumeration.EndpointEnumerationResponse>; 
}

interface EndpointEnumerationResponse {
  endpoints?: Array<services.endpointEnumeration.EndpointInfo>; 
}

Code Sample

The following example shows a function that gets the connected endpoints.

Copied to clipboard.

skill = Alexa.SkillBuilders.custom()
    ....
    .withApiClient(new Alexa.DefaultApiClient())

....

function getConnectedEndpointsResponse(handlerInput)
{
  return handlerInput.serviceClientFactory.getEndpointEnumerationServiceClient().getEndpoints();
}

MonetizationServiceClient

The MonetizationServiceClient invokes the In-Skill Purchase Service API to retrieve information about in-skill products associated with the current skill or information about paid skills. The response indicates if the product or skill is purchasable and/or already purchased by the current customer. For details about in-skill purchases, see Understand In-Skill Purchasing. For details about paid skills, see Understand Paid Skills.

In-Skill Purchase Service

The in-skill product service includes the following methods:

getInSkillProducts(acceptLanguage : string, purchasable? : string, entitled? : string, productType? : string, nextToken? : string, maxResults? : number) : Promise<services.monetization.InSkillProductsResponse>
getInSkillProduct(acceptLanguage : string, productId : string) : Promise<services.monetization.InSkillProduct>
getInSkillProductsTransactions(acceptLanguage: string, productId?: string, status?: string, fromLastModifiedTime?: string, toLastModifiedTime?: string, nextToken?: string, maxResults?: number): Promise<services.monetization.InSkillProductTransactionsResponse>;
getVoicePurchaseSetting(): Promise<boolean>; 
  • acceptLanguage can be retrieved from the request at handlerInput.requestEnvelope.request.locale.
  • purchasable can be provided as null to retrieve all in-skill products and as PURCHASABLE or NOT_PURCHASABLE to filter the response on purchasability.
  • entitled can be provided as null to retrieve all in-skill products and as ENTITLED or NOT_ENTITLED to filter the response on entitlement status.
  • productType can be provided as null to retrieve in-skill products of all types or as ENTITLEMENT, CONSUMABLE or SUBSCRIPTION to filter by product type.
  • nextToken is required for paginated queries.
  • maxResults allows skills to control records retrieved per API call. The default page size is 50 records.
  • status can be PENDING_APPROVAL_BY_PARENT, APPROVED_BY_PARENT, DENIED_BY_PARENT, EXPIRED_NO_ACTION_BY_PARENT, or ERROR to filter the response on transaction status. A status value of null retrieves all transactions.
  • fromLastModifiedTime and toLastModifiedTime can be provided in UTC ISO 8601 format to filter transactions based on the last-modified timestamp. Example: yyyy-MM-ddTHH:mm:ss.SSSZ. A value of null retrieves all transactions.

getInSkillProducts

The getInSkillProducts method retrieves all associated in-skill products for the current skill along with purchasability and entitlement indications for each in-skill product for the current skill and customer.

const LaunchRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
  },
  handle(handlerInput) {
    console.log("In LaunchRequest");

    const acceptLanguage = handlerInput.requestEnvelope.request.locale;
    const ms = handlerInput.serviceClientFactory.getMonetizationServiceClient();

    return ms.getInSkillProducts(acceptLanguage).then(function(result) {
      // Code to handle result.inSkillProducts goes here
       const totalProducts = result.inSkillProducts.length;
       const purchasableProducts = result.inSkillProducts.filter(record => record.purchasable == 'PURCHASABLE');
       const entitledProducts = result.inSkillProducts.filter(record => record.entitled == 'ENTITLED');

       return handlerInput.responseBuilder
        .speak('Found total ' + result.inSkillProducts.length + ' products of which ' + purchasableProducts.length + ' are purchasable and ' + entitledProducts.length + ' are entitled.')
        .getResponse();
    });
  },
}

The API response contains an array of in-skill product records.

{
  "inSkillProducts":[
    {
      "productId": "amzn1.adg.product....",
      "referenceName": "<Product Reference Name as defined by the developer>",
      "type": "SUBSCRIPTION",               // Or ENTITLEMENT
      "name": "<locale specific product name as defined by the developer>",
      "summary": "<locale specific product summary, as provided by the developer>",
      "entitled": "ENTITLED",              // Or NOT_ENTITLED
      "purchasable": "PURCHASABLE",        // Or NOT_PURCHASABLE
      "purchaseMode": "TEST"               // Or LIVE
      "activeEntitlementCount": 1
    }
  ],
  "isTruncated": true,
  "nextToken": "string"
 }

getInSkillProduct

The getInSkillProduct API retrieves the product record for a single in-skill product or a single paid skill identified by a given productId. For a paid skill, set productId to the skill ID.

const LaunchRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
  },
  handle(handlerInput) {
    console.log("In LaunchRequest");

    const acceptLanguage = handlerInput.requestEnvelope.request.locale;
    const productId = 'amzn1.adg.product.<GUID>';
    const ms = handlerInput.serviceClientFactory.getMonetizationServiceClient();

    return ms.getInSkillProduct(acceptLanguage, productId).then(function(result) {
       // Code to handle result.inSkillProduct goes here
    });
  },
}

The API response contains a single in-skill product record or paid skill record.

{
  "productId": "amzn1.adg.product....",
  "referenceName": "<Product Reference Name as defined by the developer>",
  "type": "SUBSCRIPTION",               // Or ENTITLEMENT
  "name": "<locale specific product name as defined by the developer>",
  "summary": "<locale specific product summary, as provided by the developer>",
  "entitled": "ENTITLED",              // Or NOT_ENTITLED
  "purchasable": "PURCHASABLE",        // Or NOT_PURCHASABLE
  "purchaseMode": "TEST"               // Or LIVE
  "activeEntitlementCount": 1
}

For more details, see Add In-Skill Purchases to a Custom Skill and Paid Skills Interface Reference.

getInSkillProductsTransactions

The getInSkillProductsTransactions method provides information about in-skill product transactions, such as if a previous purchase request was denied. You can query transactions by transaction status or date. This API only returns recent results for transactions in kid skills.

  const LaunchRequestHandler = {
    canHandle(handlerInput) {
      return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
    },
    handle(handlerInput) {
      console.log("In LaunchRequest");
 
      const locale = handlerInput.requestEnvelope.request.locale;
      const ms = handlerInput.serviceClientFactory.getMonetizationServiceClient();
 
      return ms.getInSkillProductsTransactions(locale).then(function(response) {
         // Code to handle response.results(List of Transactions) goes here
         const totalTransaction = response.results.length;
         const pendingTransactions = response.results.filter(record => record.status == 'PENDING_APPROVAL_BY_PARENT');
         const approvedTransactions = response.results.filter(record => record.status == 'APPROVED_BY_PARENT');
         const deniedTransactions = response.results.filter(record => record.status == 'DENIED_BY_PARENT');
         return handlerInput.responseBuilder
          .speak('Found total ' + totalTransaction + ' transaction of which ' + pendingTransactions.length + ' are pending, ' + approvedTransactions.length + ' are approved and ' + deniedTransactions.length + ' are denied');
          .getResponse();
      });
    },
  }

A successful response contains a list of transactions sorted by lastModifiedTime. The latest transaction is at index 0. By default, the list truncates to 50 transactions.

 
  {
      "results": [
          {
              "status": "PENDING_APPROVAL_BY_PARENT",
              "productId": "amzn1.adg.product.unique-id-4",
              "createdTime": "2018-11-23T12:23:10.52Z",
              "lastModifiedTime": "2018-11-23T12:23:10.52Z"
          },
          {
              "status": "PENDING_APPROVAL_BY_PARENT",
              "productId": "amzn1.adg.product.unique-id-3",
              "createdTime": "2018-11-23T11:21:10.52Z",
              "lastModifiedTime": "2018-11-23T11:21:10.52Z"
          },
          {
              "status": "EXPIRED_NO_ACTION_BY_PARENT",
              "productId": "amzn1.adg.product.unique-id-3",
              "createdTime": "2018-11-20T12:23:10.52Z",
              "lastModifiedTime": "2018-11-21T12:23:10.52Z"
          },
          {
              "status": "DENIED_BY_PARENT",
              "productId": "amzn1.adg.product.unique-id-2",
              "createdTime": "2018-11-15T11:03:07.52Z",
              "lastModifiedTime": "2018-11-15T11:03:08.52Z"
          },
          {
              "status": "APPROVED_BY_PARENT",
              "productId": "amzn1.adg.product.unique-id-1",
              "createdTime": "2018-11-14T22:21:00.52Z",
              "lastModifiedTime": "2018-11-14T22:22:00.52Z"
          }
      ],
      "metadata": {
          "resultSet": {
              "nextToken": "EXAMPLE123456789ABCDEFGHI"
          }
      }
  }

For more information about this API, see Build Premium Experiences for Kid Skills in the US.

getVoicePurchaseSetting

The getVoicePurchaseSetting method gets the purchase control setting that the account holder chose in the Alexa app.

  const LaunchRequestHandler = {
    canHandle(handlerInput) {
      return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
    },
    handle(handlerInput) {
      console.log("In LaunchRequest");
 
      const ms = handlerInput.serviceClientFactory.getMonetizationServiceClient();
 
      return ms.getVoicePurchaseSetting().then(function(response) {
         // Code to handle response (true or false) goes here
         return handlerInput.responseBuilder
          .speak('Customer\'s purchase preference value is ' + response);
          .getResponse();
      });
    },
  }

The API response contains a Boolean value. The value is true if the account holder has enabled voice purchasing in the Alexa app.

For more details, see Build Premium Experiences for Kid Skills in the US.

In-Skill Purchase Interface

The addDirective() method initiates purchase and cancellation flows for in-skill purchases and paid skills. Alexa manages the voice interaction with customers, handles the purchase transaction, and returns a status response to the requesting skill. This interface supports the following tasks:

  • Upsell
  • Buy
  • Cancel

For details about these tasks and recommended use cases, see Add In-Skill Purchases to a Custom Skill and Steps to Implement Paid Skills.

Upsell

Your skill can invoke the Upsell task to present an in-skill product contextually when the user didn't explicitly ask for it, such as, during or after your skill serves free content. The Upsell task requires a productId and upsell message. The upsell message allows developers to specify how Alexa can present the in-skill product to the user before beginning the purchase offer.

// In the skill flow, once a decision is made to offer an in-skill product to a
// customer without an explicit ask from the customer

return handlerInput.responseBuilder
  .addDirective({
    'type': 'Connections.SendRequest',
    'name': 'Upsell',
    'payload': {
      'InSkillProduct': {
          'productId': '<productId for the ISP which you wish to upsell>'
      },
      'upsellMessage': '<introductory upsell description for the in-skill product>'
    },
    'token': 'correlationToken'
  })
  .getResponse();

Buy

Your skill should invoke the Buy task when a customer asks to buy a specific product or paid skill. This task requires a productId for in-skill purchases. For a paid skill, set productId to the skill ID.

The following example shows a Buy request for an in-skill purchase.

// Skills implement a custom intent (buyProductIntent below) that captures
// user's intent to buy an in-skill product and then initiate the Buy request to Alexa.
// For example, 'Alexa, buy <product name>'

const buyProductIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'buyProductIntent';
  },
  handle(handlerInput) {
    // Obtain the corresponding productId for the requested in-skill product by invoking inSkillProducts API.
    // Below, the slot variable productName is only for demonstration.

    const acceptLanguage = handlerInput.requestEnvelope.request.locale;
    const ms = handlerInput.serviceClientFactory.getMonetizationServiceClient();

    return ms.getInSkillProducts(acceptLanguage).then(function(res) {
      const slots = handlerInput.requestEnvelope.request.intent.slots;
      const productReferenceName = slots['productName'].value;
      const product_record = res.inSkillProducts.filter(record => record.referenceName == productRef);
      if (product_record.length > 0)  {
        return handlerInput.responseBuilder
          .addDirective({
            'type': 'Connections.SendRequest',
            'name': 'Buy',
            'payload': {
              'InSkillProduct': {
                'productId': product_record[0].productId
              }
            },
           'token': 'correlationToken'
          })
          .getResponse();
      }
      else {
        return handlerInput.responseBuilder
          .speak('I am sorry. That product is not available for purchase')
          .getResponse();
      }
    });
  }
};

Cancel

Your skill should invoke the Cancel task when a customer asks to cancel an existing entitlement or subscription for an in-skill product or paid skill. This task requires a productId for in-skill purchases. For a paid skill, set productId to the skill ID.

The following example shows a Cancel request for an in-skill purchase.

const cancelIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'cancelProductIntent';
  },
  handle(handlerInput) {
    // Obtain the corresponding productId for the requested in-skill product by invoking inSkillProducts API.
    // Below, the slot variable productName is only for demonstration.

    const acceptLanguage = handlerInput.requestEnvelope.request.locale;
    const ms = handlerInput.serviceClientFactory.getMonetizationServiceClient();

    return ms.getInSkillProducts(acceptLanguage).then(function(res) {
      const slots = handlerInput.requestEnvelope.request.intent.slots;
      const productReferenceName = slots['productName'].value;
      const product_record = res.inSkillProducts.filter(record => record.referenceName == productReferenceName);

      if (product_record.length > 0)  {
        return handlerInput.responseBuilder
          .addDirective({
            'type': 'Connections.SendRequest',
            'name': 'Cancel',
            'payload': {
              'InSkillProduct': {
                'productId': product_record[0].productId
              }
            },
            'token': 'correlationToken'
          })
          .getResponse();
      }
      else  {
        return handlerInput.responseBuilder
          .speak('I am sorry. I don\'t know that one.');
          .getResponse();
      }
    });
  }
};

UpsServiceClient

UpsServiceClient can be used to query Alexa Customer Profile API for customer contact information and Device Settings for customer preferences of time zone, distance measuring and temperature measurement unit.

Type Definition

class UpsServiceClient {
  getProfileEmail(): Promise<string>;
  getProfileGivenName(): Promise<string>;
  getProfileMobileNumber(): Promise<services.ups.PhoneNumber>;
  getProfileName(): Promise<string>;
  getSystemDistanceUnits(deviceId: string): Promise<services.ups.DistanceUnits>;
  getSystemTemperatureUnit(deviceId: string): Promise<services.ups.TemperatureUnit>;
  getSystemTimeZone(deviceId: string): Promise<string>;
}

ReminderManagementServiceClient

Use the ReminderManagementServiceClient to query the Reminders API to create and manage reminders from your skill.

Type Definition

class ReminderManagementServiceClient extends BaseServiceClient {
  deleteReminder(alertToken: string): Promise<void>;
  getReminder(alertToken: string): Promise<services.reminderManagement.GetReminderResponse>;
  updateReminder(alertToken: string, reminderRequest: services.reminderManagement.ReminderRequest): Promise<services.reminderManagement.ReminderResponse>;
  getReminders(): Promise<services.reminderManagement.GetRemindersResponse>;
  createReminder(reminderRequest: services.reminderManagement.ReminderRequest): Promise<services.reminderManagement.ReminderResponse>;
}

Code Sample

The following example shows a request handler that creates an instance of the ReminderManagementServiceClient and creates a new reminder.

const CreateReminderIntent = {
  canHandle(handlerInput) {
    const { request } = handlerInput.requestEnvelope;
    return request.type === 'IntentRequest' && request.intent.name === 'CreateReminderIntent';
  },
  async handle(handlerInput) {
    const { requestEnvelope, serviceClientFactory, responseBuilder } = handlerInput;
    const consentToken = requestEnvelope.context.System.user.permissions
      && requestEnvelope.context.System.user.permissions.consentToken;
    if (!consentToken) {
      return responseBuilder
        .speak('Please enable Reminder permissions in the Amazon Alexa app.')
        .withAskForPermissionsConsentCard(['alexa::alerts:reminders:skill:readwrite'])
        .getResponse();
    }

    try {
      const speechText = "Great! I've scheduled a reminder for you.";

      const ReminderManagementServiceClient = serviceClientFactory.getReminderManagementServiceClient();
      const reminderPayload = {
        "trigger": {
          "type": "SCHEDULED_RELATIVE",
          "offsetInSeconds": "30",
          "timeZoneId": "America/Los_Angeles"
        },
        "alertInfo": {
          "spokenInfo": {
            "content": [{
              "locale": "en-US",
              "text": "walk the dog"
            }]
          }
        },
        "pushNotification": {
          "status": "ENABLED"
        }
      };

      await ReminderManagementServiceClient.createReminder(reminderPayload);
      return responseBuilder
        .speak(speechText)
        .getResponse();

    } catch (error) {
      console.error(error);
      return responseBuilder
        .speak('Uh Oh. Looks like something went wrong.')
        .getResponse();
    }
  }
};

TimerManagementServiceClient

Use the TimerManagementServiceClient to query the Alexa Timer API to create and manage timers from your skill. For more details about using the Timers API with the ASK SDK for Node.js, see the TimerManagementServiceClient API reference.


Was this page helpful?

Last updated: Jul 15, 2024