Upgrade to Pro — share decks privately, control downloads, hide ads and more …

LINE Clova ハンズオン 2018.09.10

sumihiro3
September 10, 2018

LINE Clova ハンズオン 2018.09.10

『LINE Clovaハンズオン@サイボウズ大阪オフィス』で使用した資料です。
https://code4osaka.connpass.com/event/98868/

Clova extension kit python SDK を使用しています。

sumihiro3

September 10, 2018
Tweet

More Decks by sumihiro3

Other Decks in Technology

Transcript

  1. εΩϧͷγεςϜߏ੒ AWS Lambda Amazon DynamoDB Amazon API Gateway େࡕͷ͝౰஍άϧϝ Λڭ͑ͯ

    େࡕ෎ʹ͸݅ͷ͝౰஍άϧϝ ͕ొ࿥͞Ε͍ͯ·͢ɾɾɾ Ϣʔβʔͷൃ࿩Λղੳ εΩϧ༻ϓϩάϥϜ ͷ࣮ߦ ͝౰஍άϧϝ৘ใ 8
  2. Ճ઒ ੅ኍʢ͔͕Θ ͢ΈͻΖʣ • ॴଐɿ΢ϧγεςϜζגࣜձࣾ • ࠷ۙͷΩʔϫʔυɿBOT, VUI, ϋοΧιϯ •

    ࡞඼ɿ
 https://protopedia.net/prototyper/sumihirokagawa • SNSɿ
 @sumihiro3
 https://www.facebook.com/sumihiro.kagawa 10
  3. جຊઃఆ߲໨ͷೖྗ ೖྗ߲໨ ೖྗ಺༰ λΠϓ ΧελϜ &YUFOTJPO*% ϦόʔευϝΠϯܗࣜͰೖྗ Α͘෼͔Βͳ͍৔߹͸ɺDPNϑϧωʔϜ-PDBM(PVSNFU4LJMM εΩϧ໊ ͝౰஍άϧϝ

    ݺͼग़໊͠ʢϝΠϯʣ ͝౰஍άϧϝ ݺͼग़໊͠ʢαϒʣ ͝ͱ͏͙ͪΔΊ ˞Ի੠ೝࣝͷͨΊදه͕༳ΕΔ͜ͱ͕͋ΔͷͰɺͻΒ͕ͳΛओମʹೖྗ ఏڙऀ໊ ࣗ͝෼ͷ໊͓લ΍νʔϜ໊ͳͲ ୲౰ऀϝʔϧΞυϨε ࣗ͝෼ͷϝʔϧΞυϨε 18
  4. ഑෍৘ใ߲໨ͷೖྗ ೖྗ߲໨ ೖྗ಺༰ ΧςΰϦ ஍Ҭ ৹ࠪ୲౰ऀ΁ͷίϝϯτ ೖྗྫ
 ֓ཁɿԻ੠Ͱ֤౎ಓ෎ݝͷ͝౰஍άϧϝΛݕࡧͰ͖·͢ &YUFOTJPOͷઆ໌ Ϣʔβʔ

    ޲͚ ೖྗྫ
 ֓ཁɿԻ੠Ͱ֤౎ಓ෎ݝͷ͝౰஍άϧϝΛݕࡧͰ͖·͢ ୅දαϯϓϧൃ࿩ w Ͷ͐$MPWBɺ͝౰஍άϧϝΛ։͍ͯ w ๺ւಓͷ͝౰஍άϧϝ͸ w βϯΪͷ͜ͱΛڭ͑ͯ w ݕࡧΩʔϫʔυ ͝౰஍άϧϝ ର৅σόΠε શ෦νΣοΫʢσϑΥϧτͷ··ʣ 21
  5. ର࿩Ϟσϧͱ͸ • ର࿩Ϟσϧ͸ɺΠϯςϯτɺεϩοτɺαϯϓϧൃ ࿩Ͱఆٛ͢Δɻ ཁૉ આ໌ Πϯςϯτʢ*OUFOUʣ ཁٻͷҙਤɾ۠෼ ྫɿϐβΛ஫จ͢Δɺܦ࿏Λݕࡧ͢ΔͳͲ εϩοτʢ4MPUʣ

    ΠϯςϯτΛॲཧ͢ΔͨΊʹඞཁͳ৘ใ ྫɿϐβ໊ɾ਺ྔɺग़ൃ஍ɾ໨త஍ɾग़ൃ࣌ؒͳͲ αϯϓϧൃ࿩ Πϯςϯτ΍εϩοτΛೝࣝ͢ΔͨΊͷൃ࿩ྫ w ##2ϐβΛຕཔΜͰ w ϚϧήϦʔλΛͭ஫จͯ͠ w ࣌ൃͰകా͔Βେࡕۭߓ·Ͱ w ࣌ؒޙʹകా͔Βେࡕۭߓ΁ߦ͖͍ͨ 25
  6. λʔϛφϧʗίϚϯυϓϩϯϓτ ىಈ • Mac • λʔϛφϧΛىಈ͢Δ • Windows • ίϚϯυϓϩϯϓτΛ؅ཧऀݖݶͰىಈ͢Δ

    • Windows7: 
 WinΩʔˠcmd ͱೖྗˠCtrl + Shift + Enter • Windows10ɿ
 WinΩʔˠcmd ͱೖྗˠʮίϚϯυϓϩϯϓτʯΛӈΫϦοΫ
 ˠʮ؅ཧऀͱ࣮ͯ͠ߦʯ 41
  7. εΩϧϓϩάϥϜͷ։ൃ৔ॴΛ ४උ͢Δ $ mkdir -p ~/ClovaSkills/LocalGourmetSkill $ cd ~/ClovaSkills/LocalGourmetSkill •

    Mac > mkdir c:¥tmp¥ClovaSkills¥LocalGourmetSkill > cd c:¥tmp¥ClovaSkills¥LocalGourmetSkill • Windows 42
  8. Python Ծ૝؀ڥΛ࡞੒͢Δ $ virtualenv -p python3 venv Using base prefix

    ‘/Library/Frameworks/Python.framework/Versions/3.6' Installing setuptools, pip, wheel...done. $ source venv/bin/activate (venv) $ • Mac > virtualenv -p python venv Running virtualenv with interpreter C: \Users\XXXXX\AppData\Local\Programs\Python\Python36\python.exe Installing setuptools, pip, wheel…done. > venv\Scripts\activate (venv) > • Windows ϓϩϯϓτͷઌ಄ʹ WFOW  ͕͍͍ͭͯΔ͜ͱΛ֬ೝ ϓϩϯϓτͷઌ಄ʹ WFOW  ͕͍͍ͭͯΔ͜ͱΛ֬ೝ 43
  9. Zappa ͷΠϯετʔϧ (venv) $ pip install zappa Collecting zappa Successfully

    installed PyYAML-3.12 Unidecode-1.0.22 Werkzeug-0.14.1 argcomplete-1.9.3 base58-1.0.0 boto3-1.7.72 botocore-1.10.72 certifi-2018.4.16 cfn-flip-1.0.3 chardet-3.0.4 click-6.7 docutils-0.14 durationpy-0.5 future-0.16.0 hjson-3.0.1 idna-2.7 jmespath-0.9.3 kappa-0.6.0 lambda-packages-0.20.0 pip-10.0.1 placebo-0.8.1 python-dateutil-2.6.1 python-slugify-1.2.4 requests-2.19.1 s3transfer-0.1.13 six-1.11.0 toml-0.9.4 tqdm-4.19.1 troposphere-2.3.1 urllib3-1.23 wsgi-request-logger-0.4.6 zappa-0.46.2 (venv) $ 45
  10. clova-cek-sdk for python ͷ
 Πϯετʔϧ (venv) $ pip install clova-cek-sdk

    Collecting clova-cek-sdk ʢதུʣ Successfully installed asn1crypto-0.24.0 cffi-1.11.5 clova-cek- sdk-1.0.0 cryptography-2.3 pycparser-2.18 (venv) $ 46
  11. Flask ͷΠϯετʔϧ (venv) $ pip install flask Collecting flask ʢதུʣ

    Successfully installed Jinja2-2.10 MarkupSafe-1.0 flask-1.0.2 itsdangerous-0.24 (venv) $ 47
  12. Zappa ΞϓϦΛ৽ن࡞੒ (venv) $ mkdir local-gourmet-skill (venv) $ cd local-gourmet-skill/

    (venv) $ zappa init ███████╗ █████╗ ██████╗ ██████╗ █████╗ ╚══███╔╝██╔══██╗██╔══██╗██╔══██╗██╔══██╗ ███╔╝ ███████║██████╔╝██████╔╝███████║ ███╔╝ ██╔══██║██╔═══╝ ██╔═══╝ ██╔══██║ ███████╗██║ ██║██║ ██║ ██║ ██║ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ Welcome to Zappa! • zappa init ίϚϯυΛ࢖ͬͯΞϓϦΛ࡞੒ˍηοτΞοϓ 49 ;BQQBͷઆ໌ ͸ޙ΄Ͳʂ
  13. ࣮ߦ؀ڥ໊ͷઃఆ Your Zappa configuration can support multiple production stages, like

    'dev', 'staging', and 'production'. What do you want to call this environment (default 'dev'): • ࣮ߦ؀ڥ໊͸σϑΥϧτΛબ୒ʢͦͷ··Enterʣ 50
  14. σϓϩΠ࣌ʹ࢖༻͢Δ
 S3όέοτ໊ͷઃఆ AWS Lambda and API Gateway are only available

    in certain regions. Let's check to make sure you have a profile set up in one that will work. Okay, using profile default! Your Zappa deployments will need to be uploaded to a private S3 bucket. If you don't have a bucket yet, we'll create one for you too. What do you want to call your bucket? (default 'zappa-xxxxxxxxx'): • σϑΥϧτΛબ୒ʢͦͷ··Enterʣ 51
  15. Ϟδϡʔϧύεͷࢦఆ What's the modular path to your app's function? This

    will likely be something like 'your_module.app'. Where is your app's function?: main.app • main.app Λࢦఆ 52
  16. Lambda ؔ਺ͷάϩʔόϧԽ You can optionally deploy to all available regions

    in order to provide fast global service. If you are using Zappa for the first time, you probably don't want to do this! Would you like to deploy this application globally? (default 'n') [y/n/(p)rimary]: n • σϑΥϧτͷϦʔδϣϯͷΈʹσϓϩΠ͢ΔΑ͏ʹ"n" Λࢦఆ 53
  17. ઃఆϑΝΠϧͷ֬ೝ Okay, heres your zappa_settings.json: { "dev": { "app_function": "main.app",

    "aws_region": "ap-northeast-1", "profile_name": "default", "project_name": "local-gourmet-s", "runtime": "python3.6", "s3_bucket": "zappa-xxxxxxxx" } } Does this look okay? (default 'y') [y/n]: y Done! Now you can deploy your Zappa application by executing: $ zappa deploy dev • σϑΥϧτ”y"ͰOK 54
  18. ϩʔΧϧ؀ڥͰͷ࣮ߦςετ (venv) $ python main.py • AWS ΁σϓϩΠ͢ΔલʹϩʔΧϧ؀ڥͰૄ௨֬ೝ $ curl

    http://localhost:5000 hello from Flask! • ผλʔϛφϧ΍ϒϥ΢βͳͲͰhttp://localhost:5000 ʹΞΫηε zIFMMPGSPN'MBTLz ͱ͍͏จࣈྻ͕දࣔ͞Ε͍ͯΔ ͜ͱΛ֬ೝ 56
  19. ॳظσϓϩΠˍૄ௨֬ೝ (venv) $ zappa deploy Calling deploy for stage dev..

    ʢதུʣ Deploying API Gateway.. Deployment complete!: https://xxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev (venv) $ • zappa deploy ίϚϯυͰAWS ΁σϓϩΠ $ curl https://xxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev hello from Flask! • ผλʔϛφϧ΍ϒϥ΢βͳͲͰ࣮ߦ༻URL ʹΞΫηε zIFMMPGSPN'MBTLz ͱ͍͏จࣈྻ͕දࣔ͞Ε͍ͯΔ ͜ͱΛ֬ೝ -BNCEBϑΝϯΫγϣϯͷ
 ࣮ߦ༻63- 57
  20. DynamoDB ςʔϒϧͷ࡞੒ $ cd ~/ClovaSkills/LocalGourmetSkill $ sh ./create_tables_to_dynamodb.sh • Mac

    > cd c:¥tmp¥ClovaSkills¥LocalGourmetSkill > create_tables_to_dynamodb.bat • Windows 1ZUIPOԾ૝؀ڥΛىಈ͍ͯ͠ΔίϚϯυϓϩϯϓτ ͱ͸ผʹ্ཱ࣮ͪ͛ͯߦ͍ͯͩ͘͠͞ 60
  21. Lambda ؀ڥม਺ͷઃఆ { "dev": { "app_function": "main.app", "aws_region": "ap-northeast-1", "profile_name":

    "default", "project_name": "local-gourmet-skill", "runtime": "python3.6", "s3_bucket": “zappa-xxxxxx", "log_level": "INFO", "environment_variables": { "TZ": "Asia/Tokyo", "CLOVA_APPLICATION_ID": “com.xxxxxx.LocalGourmetSkill”, "TABLE_GOURMET_INFO": "GourmetInfo" } } } • ϓϩάϥϜϦιʔε಺ͷ”local-gourmet-skill/zappa_settings.json”
 ͷ੺࿮಺༰Λɺ։ൃ༻σΟϨΫτϦͷಉϑΝΠϧʹ௥Ճ͢Δ εΩϧ࡞੒࣌ʹઃఆͨ͠ &YUFOTJPO*%zΛೖྗ͢Δ લߦͷΧϯϚ΋๨Εͣʹʂ 64
  22. εΩϧ༻ϓϩάϥϜͷσϓϩΠ (venv) $ zappa update Calling update for stage dev..

    Downloading and installing dependencies.. ʢதུʣ Your updated Zappa deployment is live!: https://xxxxxxxxxx.execute- api.ap-northeast-1.amazonaws.com/dev (venv) $ • ϓϩάϥϜߋ৽ίϚϯυʮzappa updateʯͰσϓϩΠ -BNCEB࣮ߦ༻63-Λίϐʔ͓ͯ͘͠ 65
  23. ϓϩάϥϜϩάͷදࣔ (venv) $ zappa tail dev Calling tail for stage

    dev.. [1536303341664] [INFO] 2018-09-07T06:55:41.651Z 08ed89fa-b26b-11e8-82bb-d527267a2776 find_gourmet_by_prefecture_intent_handler method called!! [1536303341666] [INFO] 2018-09-07T06:55:41.666Z 08ed89fa-b26b-11e8-82bb-d527267a2776 Prefecture: େࡕ෎ [1536303341666] [INFO] 2018-09-07T06:55:41.666Z 08ed89fa-b26b-11e8-82bb-d527267a2776 make_gourmet_info_message_by_prefecture method called!! [1536303341666] [INFO] 2018-09-07T06:55:41.666Z 08ed89fa-b26b-11e8-82bb-d527267a2776 inquiry_gourmet_info_list_for method called!! [1536303341874] [INFO] 2018-09-07T06:55:41.874Z 08ed89fa-b26b-11e8-82bb-d527267a2776 Found credentials in environment variables. [1536303341965] [INFO] 2018-09-07T06:55:41.965Z 08ed89fa-b26b-11e8-82bb-d527267a2776 Starting new HTTPS connection (1): dynamodb.ap-northeast-1.amazonaws.com [1536303342047] [INFO] 2018-09-07T06:55:42.47Z 08ed89fa-b26b-11e8-82bb-d527267a2776 147.92.129.235 - - [07/Sep/2018:06:55:42 +0000] "POST /clova HTTP/1.1" 200 813 "" "Apache-HttpClient/4.5.5 (Java/1.8.0_161)" 0/409.27599999999995 • ʮzappa tailʯίϚϯυͰσϓϩΠͨ͠ϓϩάϥϜͷϩάΛදࣔͰ͖·͢ ϩάදࣔදͷλʔϛφϧΛىಈ͓ͯ͘͠ ͱศརͰ͢ 68
  24. Clova ͔ΒͷϦΫΤετड෇෦ @app.route('/clova', methods=['POST']) def clova_service(): resp = clova.route(request.data, request.headers)

    resp = jsonify(resp) # make sure we have correct Content-Type that CEK expects resp.headers['Content-Type'] = 'application/json;charset-UTF-8' return resp • Clova ͰͷΠϯςϯτ൑ผޙʹ࣮ߦ͞ΕΔϝιου ඞͣ1045ͰϦΫΤετ͞ΕΔ $MPWBଆʹϨεϙϯεΛฦ͢ࡍ ͸ɺzBQQMPDBUJPOKTPOzͰฦ͢ 74
  25. εΩϧىಈ࣌ͷ࣮ߦ෦෼ @clova.handle.launch def launch_request_handler(clova_request): text = '͝౰஍άϧϝΛௐ΂͍ͨ౎ಓ෎ݝ໊͔ɺৄ͘͠஌Γ͍ͨ͝౰஍άϧϝͷ໊લ Λڭ͍͑ͯͩ͘͞ɻ' response =

    response_builder.simple_speech_text(text) response_builder.add_reprompt(response, text) return response σίϨʔλͰએݴ͢Δ͜ͱͰɺεΩϧىಈ࣌ ʹݺ͹ΕΔϝιουͱͳΔ 75
  26. Πϯςϯτ൑ผ࣌ͷ࣮ߦ෦෼ @clova.handle.intent('FindGourmetByPrefectureIntent') def find_gourmet_by_prefecture_intent_handler(clova_request): ''' ౎ಓ෎ݝʹԠͨ͡͝౰஍άϧϝ৘ใϝοηʔδΛฦ͢Πϯςϯτ ʢFindGourmetByPrefectureIntentʣ൑ผ࣌ʹݺ͹ΕΔϝιου ''' logger.info('find_gourmet_by_prefecture_intent_handler method

    called!!') prefecture = clova_request.slot_value(‘prefecture’) response = None if prefecture is not None: # ౎ಓ෎ݝ໊Λ൑ผͰ͖ͨ৔߹ response = make_gourmet_info_message_by_prefecture(prefecture) else: # ౎ಓ෎ݝ໊Λ൑ผͰ͖ͳ͔ͬͨ৔߹ text = '΋͏Ұ౓ɺ͝౰஍άϧϝΛௐ΂͍ͨ౎ಓ෎ݝ໊Λڭ͍͑ͯͩ͘͞ɻ' response = response_builder.simple_speech_text(text) response_builder.add_reprompt(response, '͝౰஍άϧϝΛௐ΂͍ͨ౎ಓ෎ݝ໊Λڭ͍͑ͯͩ͘͞ɻ') # retrun return response σίϨʔλͰએݴ͢Δ͜ͱͰɺ Πϯςϯτ൑ผ࣌ʹݺ͹ΕΔ ϝιουͱͳΔ Πϯςϯτͷεϩοτ͕ઃఆͰ͖ ͔ͨΛ൑ผ͢Δ εϩοτͷ஋ΛऔಘͰ͖Δɻ εϩοτͷ஋͸ɺϢʔβʔൃ࿩Ͱ ͸ͳ͘ɺ୅දޠΛऔಘͰ͖Δ 76
  27. Clova ʹฦ͢Response ੜ੒༻
 ϝιου [1/2] def make_gourmet_info_message_by_prefecture(prefecture): try: gourmet_info_list =

    inquiry_gourmet_info_list_for(prefecture) message = '' reprompt = None end_session = False if gourmet_info_list is None: # ͝౰஍άϧϝ৘ใ͕ొ࿥͞Ε͍ͯͳ͍৔߹ message = '{} ʹ͸͝౰஍άϧϝ৘ใ͕ొ࿥͞Ε͍ͯ·ͤΜͰͨ͠ɻଞͷ౎ಓ෎ݝͰࢼͯ͠ ͍ͩ͘͞ɻ'.format( prefecture ) reprompt = '͝౰஍άϧϝΛௐ΂͍ͨ౎ಓ෎ݝ໊Λڭ͍͑ͯͩ͘͞ɻ' response = response_builder.add_reprompt(response, reprompt) return response except Exception as e: logger.error('Exception at make_gourmet_info_message_by_prefecture: %s', e) raise e %#͔Β౎ಓ෎ݝ͝ͱͷ͝౰஍άϧ ϝ৘ใΛऔಘ͢Δϝιου ͝౰஍άϧϝ৘ใ͕ొ࿥͞Ε͍ͯͳ͍ ৔߹ͷॲཧ 77
  28. Clova ʹฦ͢Response ੜ੒༻
 ϝιου [2/2] elif len(gourmet_info_list) == 1: #

    ͝౰஍άϧϝ৘ใ͕1͚݅ͩొ࿥͞Ε͍ͯΔ৔߹ gourmet_info = gourmet_info_list[0] gourmet_info_detail = gourmet_info['detail'] if gourmet_info_detail.endswith('ɻ') == False: gourmet_info_detail += 'Ͱ͢ɻ' message = '{} ͷ͝౰஍άϧϝ͸ {} Ͱ͢ɻ{}'.format( prefecture, gourmet_info['yomi'], gourmet_info_detail ) # ͝౰஍άϧϝ৘ใΛฦͯ͠εΩϧͷηογϣϯΛ׬ྃͤ͞Δ end_session = True else: # ͝౰஍άϧϝ৘ใ͕ෳ਺݅ొ࿥͞Ε͍ͯΔ৔߹ gourmet_names = '' for info in gourmet_info_list: gourmet_names += info['yomi'] + 'ɺ' message = '{} ʹ͸ɺ{} ݅ͷ͝౰஍άϧϝ͕ొ࿥͞Ε͍ͯ·͢ɻ'.format( prefecture, len(gourmet_info_list) ) message += 'ৄ͘͠஌Γ͍ͨ͝౰஍άϧϝ͕͋Ε͹͓ௐ΂͠·͢ͷͰɺ͝౰஍άϧϝͷ໊લΛ͓஌Β͍ͤͩ͘͞ɻ' message += 'ొ࿥͞Ε͍ͯΔ͝౰஍άϧϝ͸ɺ{} Ͱ͢ɻ'.format(gourmet_names) # build response response = response_builder.simple_speech_text(message, end_session=end_session) ಡΈ͕೉ղͳ׽ࣈʢ౰ͯࣈͳͲʣ͕͋Δ ৔߹ʹඋ͑ͯɺಡΈԾ໊Λ׆༻ ฦ౴ޙʹεΩϧΛऴΘΒ͍ͤͨ৔߹ͷ ϑϥά 78
  29. Zappa ͱ͸ • AWS Lambda + API Gateway ͳͲΛ࢖ͬͨ։ൃɾσ ϓϩΠ͕༰қʹͰ͖Δ։ൃπʔϧ

    ✦ ਺ίϚϯυͰσϓϩΠ΍ߋ৽͕Ͱ͖Δ - zappa init / zappa deploy / zappa update • Flask΍DjangoͳͲWebϑϨʔϜϫʔΫ΋ར༻Ͱ͖ Δ 80
  30. Zappa ͱ͸ • εςʔδ෼͚ʢ։ൃɺςετɺຊ൪ ͳͲʣ͕؆୯ʹͰ ͖Δ ✦ zappa_settings.json Ͱεςʔδ͝ͱͷઃఆΛॻ͚ͩ͘ •

    Lambda ͷίʔϧυελʔτճආ΋؆୯ʹͰ͖Δ • Lambda ͷඇಉظ࣮ߦ΍ఆظ࣮ߦɺ༷ʑͳτϦΨʔ ʢS3/DynamoDB/SQS/SNS ͳͲʣʹ΋ରԠ 81