[PYTHON] Live a typingless Twitter life with Alexa

** Amazon Echo dot (3rd generation) ** was available for 999 yen (219 yen if you look only at the main unit price), so I made a Twitter client with the intention of developing Alexa.

Introduction

In Alexa skill development, first of all, you can choose the language to use in ** Node.js **, ** Python **, ** Other ** (custom), but I myself am only as decent as Python Since it can not be used, we will proceed with the one developed with Python this time.

I think that there are many parts that can only be roughly talked about, such as for beginners and just move for the time being, but please understand that.

In this article, we will not deal with details related to Twitter operations such as tweeting to Twitter via API.

As a premise to proceed

Is required.

final goals

To Alexa so that she can tweet with her account.

I will actually make it

We will start development work from here. You don't need an editor because all the work can be done with a browser.

Create a skill

Log in to and access the Alexa Developer Console (https://developer.amazon.com/alexa/console/ask "Alexa Developer Console"). There is a button called Create Skill, so click it.

Skill name and language

Choose your favorite skill name and default language. The skill name cannot be changed later, so I think it's a good idea to make it easy to understand.

Model and backend resources

Select ** Custom ** for the model. If you read this and want to make smart home skills, please choose it. Choosing Custom will probably be a basic preset.

As for the backend resource, as mentioned at the beginning, this time, select ** Alexa-Hosted (Python) **. It's easy because it manages AWS Lambda hosting within the Alexa Developer Console. I can't explain Node.js because I haven't touched it because I wanted to do it. sorry. Also, by choosing Alexa-Hosted, it seems that you will be billed to the account logged in to Amazon Developer. If you are using shopping, you will be billed from the billing address in the same account.

modelandberesource.png

Supplement (OK even if you skip it)

By the way, if you select user-defined provisioning in the backend resource, you will not be able to use the code editor on the Alexa Developer Console. Instead, you'll have to build your own Lambda on your own Amazon Web Services account and write the code here from scratch. You'll also have to set up endpoints and IAM roles to communicate with each other on Alexa Skills and AWS Lambda. Since you can build the backend side yourself, you can create more advanced skills, but of course you have to know how to use everything, so it is for advanced users.

Creation completed

After selecting the above, all you have to do is press Create Skill at the top right of the page. It will take a few minutes to complete the creation, but let's say "Alexa, play the recommended jazz" to Alexa and wait gracefully with a cup of coffee.

Once created, it will ** do all the settings ** for you, including Hello World. If it's just Hello World, you can do it just by creating a skill (although there are some parts to play with). Easy!

Call name

The first thing I want to do is change the call name. By default, it contains the same Alexa Skill name that you set at the beginning, but when you call it, you may want to call it more easily. As a goal, I want to be able to tweet by saying ** "Alexa, tweet XX on Twitter." **. in this case

  1. Alexa
  2. Twitter
  3. ○○ (Muttering content)
  4. Tweet.

And in order from the top

  1. Alexa launch word
  2. Activation word for self-made skills
  3. Content variables
  4. Instruction

It will be.

So this time, it's reasonable to include "Twitter" as the ** name to call the skill **. Of course, you can enter your favorite word.

This call name is just a call name, so if you make a mistake, don't just enter "on Twitter". This will probably be interesting because it won't start unless you say "on Twitter". If you enter one word, Alexa will automatically determine the startup word that follows. (For example, if you set the call name to "Twitter", you can also go with "Alexa, start Twitter and tweet XX.") There are other naming requirements, but please read them as they are written on the page for deciding the call name.

For more details, see the official document [Determine the call name of the custom skill](https://developer.amazon.com/en/docs/custom-skills/choose-the-invocation-name-for-a-custom -skill.html) is on board.

HelloWorld

By default, the Alexa Skill created has HelloWorldIntent and the corresponding code. For the time being, I'll just use this to do HelloWorld. If you don't care about Hello World, please skip it.

Open the Test tab and select Under Development for the private part in the upper left. I think there is an input field below that, so first enter and send only the call name there. (Here, my call name is "Test Twitter")

HWtest1.png

Then, I think that English text will be returned. To put it very simply, "Hello or help?"

So let's return Hello.

HWtest2.png

Then Alexa returned Hello World!

It's easy! !!

If you look at HelloWorldIntent on the build tab, there are about 7 types of utterances listed by default. I typed Hello now, but when I speak the words in this intent, it also returns Hello World !.

By the way, you can also say Hello World! Without splitting the words.

HWtest3.png

In the first method, it was divided into calling by name → issuing an instruction, but in the other method, it was called and issuing an instruction.

If you look at the code editor and compare it with the reply from Alexa and the intent name, you can see how it works.

Basically, the class corresponding to the registered intent is executed, and the one processed in the handle function in the class speaks with return. In the HelloWorldIntentHandler class, the speak_output variable contains the words you want to speak and the return contains the variable.

I will implement

I will start implementing it when I somehow understand how it works.

Intent

Creating an intent

From the Build tab, press the Add button next to the intent. Choose Create Custom Intent, choose a name of your choice and create it. Here I named the intent ʻEchoTweetIntent`.

Next, we will enter the utterance to execute this intent, but before that, there is necessary work, so let's do it.

Addition of slot type

Press the add button next to the slot type. Select Use existing slot type from Alexa's built-in library. Press the Add Slot Type button to the right of ʻAMAZON.SearchQuery` from the numbers, dates, and times.

Slots are now used to listen to what you want to tweet and treat it like a variable. Other built-in libraries only recognize place names, personal names, numbers, etc., so I thought it would not be suitable for tweeting with my favorite words, so I chose ʻAMAZON.SearchQuery`. .. It seems that anything can be done because it contains words for searching. (Please tell me any other good method or mistake)

Addition of intent slots

Once you've added the slot type, you'll be back to the intent you created earlier. Create an intent slot that looks like a variable before you enter the utterance.

Enter a name you like and press the + button next to it to add it. (I used msg.)

Once created, click "Choose Slot Type" and select the ʻAMAZON.SearchQuery` you just added. Now you can treat it like a variable.

Added call utterance

In the input field of the sample utterance, enter the utterance of what to say to tweet. This time

We will add three types as an example. The content of the mutter (msg) is entered in 〇〇.

To use what you have prepared as a slot, enclose the intent slot name in {}. If you enter the first {, prediction candidates will appear, but since only one is created, pressing the TAB key as it is will automatically insert the intent slot.

intentresult1.png

I think it will be like this if you can add 3 types correctly.

This time, there are only these three types, but I think that this alone will probably not make your Twitter life comfortable, so please add various original utterances as appropriate.

When you're done, press Save Model to build your model. The build will take some time.

Write code

Now that the intent is ready, it's time to write the corresponding code in Python. From here on, we'll use the code editor. It says that it has neither a source nor a child, but basically it is quite a copy and paste modification of the code that exists by default.

I'll write the Twitter code from now on in my own way, so if you have your own way, read it as you like.

Add module

Add the following to use the Twitter API. Since the 1st and 2nd lines are from the beginning, only the 3rd line is added.

requirements.txt


boto3==1.9.216
ask-sdk-core==1.11.0
requests_oauthlib

If you want to use a new module, you can install it by writing to this text file.

Add import to the python code as well. The import on the second line is needed to get the spoken content (in the slot) obtained from the intent created earlier in the code.

lambda_function.py


from requests_oauthlib import OAuth1Session
from ask_sdk_core.utils import get_slot_value

Make a class

Create a class by imitating an existing class. The intent name I created was ʻEchoTweetIntent, so I'd like to name the class ʻEchoTweetIntentHandler. For the time being, I created a new class under the HelloWorldIntentHandler class.

Since we only write the process in the handle function, we also write the process for posting on Twitter.

lambda_function.py


class EchoTweetIntentHandler(AbstractRequestHandler):
    def can_handle(self, handler_input):
        return ask_utils.is_intent_name("EchoTweetIntent")(handler_input)

    def handle(self, handler_input):
        URL = 'https://api.twitter.com/1.1/statuses/update.json'
        CK = 'key' # Consumer Key
        CS = 'key' # Consumer Secret
        AT = 'token' # Access Token
        ATS = 'token' # Access Token Secret
        twitter = OAuth1Session(CK, CS, AT, ATS)
        tweetmsg = ask_utils.get_slot_value(handler_input=handler_input, slot_name="msg")
        if tweetmsg:
            params = {'status': tweetmsg + "\n(Tweet from Alexa)"}
            post_response = twitter.post(URL, params=params)
            if post_response.status_code == 200:
                speak_output = tweetmsg + "Tweeted."
            else:
                speak_output = "I'm sorry. Failed to send the tweet."
        else:
            speak_output = "I'm sorry. I didn't know what to say."
        return handler_input.response_builder.speak(speak_output).response

For the code to get the slot value, I referred to the one in the official document. [Process requests sent by Alexa | Alexa Skills Kit](https://developer.amazon.com/en/docs/custom-skills/handle-requests-sent-by-alexa.html#get-slot- values)

I put a token for OAuth in twitter. Please add your own token etc. to each variable. tweetmsg contains the contents of the slot (what you said) that can be obtained with ʻask.utils.get_slot_value. Change the msg part of slot_name =" msg "at the end of the line to match the slot name you created. The message posted on Twitter contains\ n (tweet from Alexa)`, but as it is written, it is easy to understand that it is a tweet from Alexa.

After that, I put it in the speak_output variable so that if I POST and 200 is returned, I will say that I tweeted.

Register (?) Class

Once the class and post process is complete, we have to add it so that the class works. At the bottom of the code editor, you'll find a lot of things similar to sb.add_request_handler (LaunchRequestHandler ()).

In the vicinity, add sb.add_request_handler (class name you created ()).

lambda_function.py


sb.add_request_handler(EchoTweetIntentHandler())

Please note that the class you created should be written ** above sb.add_request_handler (IntentReflectorHandler ()) **. This so-called reflector triggered the intent of 〇〇 by the spoken words. Will be returned as a response. So if this comes first, all the code that was picked up and written earlier will not be executed.

When the process is completed so far, press save and then deploy.

Testing

Use the test tab that was also used for Hello World.

In my case ** Test Twitter ** is the call name, so Enter and send "Test with test Twitter and tweet" in the input form.

If you get a reply from Alexa saying "I tweeted a test" and it's posted on the Twitter timeline, it's a success! !! !!

Try it with the method you tried during Hello World, or with other triggering intent utterances.

When you actually talk to Alexa, it says "Alexa, test on test Twitter and tweet."

Doesn't it move differently? If you think so, please review the code, or review the space or indentation.

Complete!

With Development selected in the Test tab, you are free to use your skills only with Alexa linked to your Amazon account. If it is under development, it will not be disclosed to others. (Another work is required to publish) In addition to typing in the test tab, try talking to an Echo that actually contains Alexa.

All you have to do now is do the same work as before and fine-tune the intents and slots to your liking. It's easy.

Now you can work on Twitter life while reading rumbling comics at home! !! !! **let's! twitter! !! ** **

At the end

What I often tweet Alexa is either "sleepy" or "hungry", but it's fun. Above all, you can tweet with "Alexa, tweet that you're hungry on Twitter"! ?? pleasant.

I first touched the Alexa Skills Kit, but at first I was confused because there were only words I didn't understand. What is an intent? When I tried it, it was surprisingly easy to do various things, so it was fun.

Anything can be executed by writing the process in the blunt handle, so I think that Alexa can handle anything other than Twitter, such as Discord and Slack, which has an open API. I think that something that can be operated programmatically without an API can be handled as a matter of course. If you do your best, playing Iron Man's Jarvis is not a dream.

The fact that I could access the Internet and do something without the process of "manipulating" was really satisfying because I felt that the times had progressed within me.

Thank you for reading this far. I couldn't talk about it roughly, but I would appreciate it if you could comment if you have any suggestions.

Recommended Posts

Live a typingless Twitter life with Alexa
Live a Haml life with Django1.8 + Jinja2 + hamlish-jinja (Python3)
I made a life game with Numpy
Let's make a Twitter Bot with Python!
Make a Twitter trend bot with heroku + Python
Mute Twitter trends and have a comfortable Twitter life! !!
Try to draw a life curve with python
I made a Twitter fujoshi blocker with Python ①
Steps to create a Twitter bot with python
How to live a decent life on 2017 Windows
I made a Twitter BOT with GAE (python) (with a reference)
[Piyopiyokai # 1] Let's play with Lambda: Get a Twitter account
A4 size with python-pptx
Twitter OAuth with Django
Decorate with a decorator
Create a list in Python with all followers on twitter
Create a life game that is manually updated with tkinter
Create a Twitter BOT with the GoogleAppEngine SDK for Python