The story of creating (probably) the smallest skill that implements personalization and in-skill billing

Well, I saw Miso Tanaka's twitter and tried to participate in alexa's advent calender, but I was in a hurry because it was just before the event without preparing any material. ..

I was wondering what to do, but let me simply make it an explanatory article about the skills I recently created.

target

――I want to use the personalization function completely --I want to see the source of in-skill billing in python --I want to use python with ask cli

Is it a place like this?

What to say

-** "My Santa Claus" ** About Skills

** "My Santa Claus" ** About Skills

https://www.amazon.co.jp/dp/B081YJTLJS/

Not long ago, I released a little skill called "My Santa Claus". The purpose of this skill is ...

-~~ To participate in the campaign where you can get echo show 5 if you implement and publish the in-skill billing function ~~ ―― ~~ I wanted to implement a personalization function because anything is fine ~~ -~~ ask-cli for python I wanted to use ~~ --I want to bring happiness to pure children and families who believe in Santa

... It was like this. It's simple. Roughly speaking

  1. The role of Santa registers for skill
  2. The side who wants a gift makes a wish
  3. The role of Santa confirms the wish

It is a skill. The point is that you are using the personalization function to identify the role of Santa. The person who makes a wish also uses it if personalization is effective. In addition, the billing function is quite forcibly implemented, and if you bill, the upper limit of your wishes will increase.

ask-cli for python

I've used ask-cli, but I've always used node. I thought I'd try using python once, so this time I'm using python.

What is ask-cli

It uses the alexa skill kit on the command line. With it, you can create skills without opening the developer console. It's insanely useful when you want to drop the code for an existing skill with ʻask clone` or share the code between teams. Well, there are many things that are convenient for the console, and at the time of application, I end up opening the console.

As for how to use it, the tutorial below is as it is.

[Quick Start: Alexa Skills Kit Command Line Interface (ASK CLI)](https://developer.amazon.com/ja-JP/docs/alexa/smapi/quick-start-alexa-skills-kit-command-line- interface.html)

  1. ask init
  2. ask new
  3. ask deploy

Just do it. You can clone the sample skill code with ʻask new`, so you can quickly create something.

ask-cli for python

If you select python3 at the time of ʻask new`, you can create alexa skill with python.

$ ask new
? Please select the runtime Python3
? List of templates you can choose Hello World (using Classes)
? Please type in your skill name:  skill-sample-python-helloworld-classes
Skill "skill-sample-python-helloworld-classes" has been created based on the chosen template

(↑ As of 19/12/18, if you do not change python3.6 in .ask / config to python3.7, an error will occur in deploy.)

By the way, you can create a hosted skill by doing something like $ ask create-hosted-skill --runtime python3.7 --skill-name ExampleSkill --auto-clone true. In short, the skill that hosts resources (lambda, DynamoDb, etc.) on the alexa side. This is enough for a little skill. Originally, it is a hosted skill that you have to write code using a browser, but if you use cli, you can develop it locally, which is super convenient.

Code excerpt and commentary

This is my Santa Claus code. (I'm sorry for the chords, even though I'm talking about chords.)

https://github.com/ikegam1/alexa-myhomesanta-ask-python37

--Lamb / py / lambda_function.py Skill backend processing in general --lambda / py / vendor / alexa / data.py Word of the utterance part of the skill --isps / subscription / my-home-santa.json Billing item settings --models / ja-JP.json Skill front part intent, etc.

I'll explain the lambda_function.py part.

Flow (of description name)

I will explain along the flow like this

  1. Flow at the first startup
  2. Flow when registering a wish
  3. Flow of wish confirmation
  4. Billing-related flow

List of functions, etc.

A list of classes and functions. I'm omitting help and normal processing

Item number name Contents
1 class LaunchRequestHandler(AbstractRequestHandler) Launch intent. Processed when the skill is activated
2 class WishAddInIntentHandler(AbstractRequestHandler) Intent when registering a wish. After this, transition to confirmation processing
3 class WishDeleteIntentHandler(AbstractRequestHandler) An intent that deletes a wish. Personalization required. You can delete what you registered
4 class WishListIntentHandler(AbstractRequestHandler) An intent to confirm your wishes. Personalization required. You can check what you registered
5 class AnswerClassIntentHandler(AbstractRequestHandler) Intent for registering users as Santa
6 class PremiumInfoIntentHandler(AbstractRequestHandler) Introduction of billing items
7 class YesIntentHandler(AbstractRequestHandler) The main process is confirmation when registering a wish
8 class ShoppingIntentHandler(AbstractRequestHandler) Whether you have purchased a billing item
9 class BuyIntentHandler(AbstractRequestHandler) Intent when purchasing billable items
10 class CancelSubscriptionIntentHandler(AbstractRequestHandler) Intent when canceling a billing item
11 class CancelResponseHandler(AbstractRequestHandler) Pick up the response when canceling a billing item
12 class BuyResponseHandler(AbstractRequestHandler) Pick up the response when purchasing a billing item
13 def is_santa(santa, person_id) Determine if you are Santa
14 def is_skill_product(handler_input) Determine if it is a billing item or valid
15 def in_skill_product_response(handler_input) Get valid or billing item information through api on alexa side

Flow at the first startup

1.LaunchIntent The parameters are persisted in DynamoDB. If persistence_attr ['santa'] is empty, it is considered the first boot.

Check if personalization is enabled. The check can be determined by whether there is a personId in request_envelope.context.system.person. If Personalization Disable-> Exit with "Enable" If personalization enabled-> "Do you want to register as Santa?" Flow. Let me say "I'm Santa" and lead to ʻAnswer Class Intent`

  1. AnswerClassIntent First check if personalization is enabled.

If personalization enabled-> Register this user's ID in persistence_attr ['santa'] ['id']. After that, this personId is treated as Santa.

Flow of wish registration

1.LaunchIntent If person_id is registered in persistence_attr ['santa'] ['id'] and it is the person himself, it is judged as Santa. If not ** General users who make a wish **. The check is determined by 13. def is_santa (santa, person_id).

If not Santa-> Let me say "make a wish" and lead to WishAddInIntent

2.WishAddInIntent An intent to pick up your wishes. Since the wishes are picked up in Dialog, ** wishes ** are picked up at the timing when they are processed by this intent. However, I want to confirm it, so I repeat it and ask for "yes" or "no". If yes, go to Yes Intent. In addition, 3 wishes will be Max when there is no charge. Check persistence_attr ['msg'] and if 3 items have already been registered, recommend the billing item and finish.

7.YesIntent It comes in by returning confirm when registering a wish. I wanted to use Dialog, but it seems to be complicated, so I used Build in Intent. If there is a value in persistence_attr ['session'] ['msg'] and it is within 1 minute from registration, it is considered as a transition from WishAddInIntent.

The message is registered in persistence_attr ['msg'], but if personalization is enabled, the personId is registered in persistence_attr ['msg'] [idx] ['person_id'] and used for identity verification. If you can verify your identity, you can delete your wish

Flow of wish confirmation

  1. WishListIntentHandler

"Confirm your wish" There is a branch if Santa or not.

If Santa-> Speak the registered ** wishes ** in order. Also, "Delete the ○ th wish" will lead to the deletion of the wish. If General User-> Personalization must be enabled to confirm, and if enabled, you can confirm your registered wishes. Also, connect to deletion like "Please say 4-digit password 1234 to delete"

  1. WishDeleteIntent

If Santa-> message_number Check slot. ** Delete the wish ** If General User-> password Check slot. If the passwords match, delete your wish

Billing flow

A subscription product called "My Santa Claus Premium Features" is set.

9.BuyIntentHandler Transition from "Purchase premium features".

Using the productId of this product as a key, I just throw the process to the alexa side.

            return handler_input.response_builder.add_directive(
                SendRequestDirective(
                    name="Buy",
                    payload={
                        "InSkillProduct": {
                            "productId": product[0].product_id
                        }
                    },
                    token="correlationToken")
            ).response

The following intent receives this

  1. BuyResponseHandler

It returns Connections.Response instead of the usual Intent.

        return (ask_utils.is_request_type("Connections.Response")(handler_input) and
                handler_input.request_envelope.request.name == "Buy")

After purchase, it will be returned with the parameter name "Buy", but the status is PurchaseResult.ACCEPTED, PurchaseResult.DECLINED, PurchaseResult.ALREADY_PURCHASED, or not, originally. I get back the utterances that correspond to the fact that I have already purchased it. The processing in case of cancellation is almost the same as just changing Buy to Cancel.

The end

That's it. I personally think it's about the volume of a little tutorial.

Also, to be honest, personalization is difficult to use, and when this becomes essential, I think that the number of users will decrease sharply. ** It can be used even if it is disabled, but it is still convenient if it is enabled **. Expectations for the future. In-skill billing ... It seems that Japanese skills are still quite strict. I think it's a pretty niche area to live in.

Recommended Posts

The story of creating (probably) the smallest skill that implements personalization and in-skill billing
The story of Python and the story of NaN
The story of creating a site that lists the release dates of books
The story of trying deep3d and losing
The story of making a box that interconnects Pepper's AL Memory and MQTT
The story of Django creating a library that might be a little more useful
A story that reduces the effort of operation / maintenance
The story of Python without increment and decrement operators.
The story that the return value of tape.gradient () was None
A story that analyzed the delivery of Nico Nama.
Now in Singapore The story of creating a LineBot and wanting to do a memorable job
The story of creating a "spirit and time chat room" exclusively for engineers in the company
The story of sys.path.append ()
The story of creating a VIP channel for in-house chatwork
The story of creating a database using the Google Analytics API
The story of making a tool that runs on Mac and Windows at the game development site
The story of creating a bot that displays active members in a specific channel of slack with python