Slide 1

Slide 1 text

LINE ClovaϋϯζΦϯ ˏαΠϘ΢ζେࡕΦϑΟε 2018.09.10

Slide 2

Slide 2 text

ϋϯζΦϯΛ։࢝͢Δલʹ • ࢿྉ͸ޙ΄Ͳެ։͠·͢ • ೖྗ಺༰΍ίϚϯυͳͲ͸ɺίϐϖ༻γʔτ ͕͋Γ·͢ͷͰదٓ͝ར༻͍ͩ͘͞ •https://bit.ly/2M57gGN

Slide 3

Slide 3 text

ࠓ೔Ͱ͖ΔΑ͏ʹͳΔ͜ͱ • Clova εΩϧ։ൃ • αʔόʔϨε։ൃ • CLI (Command Line Interface) Λۦ࢖ʂ ΋ͪΖΜ ᷿Ͱ͏Θ͞ͷ ࠇ͍ը໘ʂ 3

Slide 4

Slide 4 text

ϋϯζΦϯͰͭ͘ΔεΩϧ

Slide 5

Slide 5 text

େࡕͷ͝౰஍άϧϝΛڭ͑ͯ େࡕ෎ʹ͸݅ͷ͝౰஍άϧϝ ͕ొ࿥͞Ε͍ͯ·͢ɾɾɾ

Slide 6

Slide 6 text

Demo

Slide 7

Slide 7 text

εΩϧͷಈ࡞ϑϩʔ ʮେࡕͷ͝౰஍άϧϝΛڭ͑ͯʯ ʮେࡕ෎ʹ͸݅ͷ͝౰஍άϧϝ͕ొ࿥ ͞Ε͍ͯ·͢ɻɾɾɾʯ ͝౰஍άϧϝ ࠓ೔ͭ͘Δͱ͜Ζ 7

Slide 8

Slide 8 text

εΩϧͷγεςϜߏ੒ AWS Lambda Amazon DynamoDB Amazon API Gateway େࡕͷ͝౰஍άϧϝ Λڭ͑ͯ େࡕ෎ʹ͸݅ͷ͝౰஍άϧϝ ͕ొ࿥͞Ε͍ͯ·͢ɾɾɾ Ϣʔβʔͷൃ࿩Λղੳ εΩϧ༻ϓϩάϥϜ ͷ࣮ߦ ͝౰஍άϧϝ৘ใ 8

Slide 9

Slide 9 text

ϋϯζΦϯ։࢝ʂ

Slide 10

Slide 10 text

Ճ઒ ੅ኍʢ͔͕Θ ͢ΈͻΖʣ • ॴଐɿ΢ϧγεςϜζגࣜձࣾ • ࠷ۙͷΩʔϫʔυɿBOT, VUI, ϋοΧιϯ • ࡞඼ɿ
 https://protopedia.net/prototyper/sumihirokagawa • SNSɿ
 @sumihiro3
 https://www.facebook.com/sumihiro.kagawa 10

Slide 11

Slide 11 text

1. εΩϧͷ࡞੒

Slide 12

Slide 12 text

৽نνϟωϧ࡞੒ • Clova Developer Center Λ։͖ɺը໘தԝͷ ʮεΩϧΛ։ൃ͢ΔʯϘλϯΛΫϦοΫ 12

Slide 13

Slide 13 text

৽نνϟωϧ࡞੒ • εΩϧҰཡͷԼʹ͋ΔʮLINE DevelopersͰε ΩϧνϟωϧΛ৽ن࡞੒ʯϘλϯΛΫϦοΫ 13

Slide 14

Slide 14 text

৽نνϟωϧ࡞੒ • ϓϩόΠμʔΛબ୒͢Δɻະ࡞੒ͷ৔߹͸ʮ৽نϓ ϩόΠμʔ࡞੒ʯΛબ୒ͯ͠ɺϓϩόΠμʔ໊Λೖྗ 14

Slide 15

Slide 15 text

৽نνϟωϧ࡞੒ • νϟωϧ໊ʹεΩϧ໊ʢ͝౰஍άϧϝʣΛೖྗͯ͠ɺ ʮೖྗ಺༰Λ֬ೝ͢ΔʯϘλϯΛΫϦοΫ 15

Slide 16

Slide 16 text

৽نνϟωϧ࡞੒ • νϟωϧ໊Λ֬ೝͯ͠ɺʮ࡞੒ͯ͠Clova Developer CenterʹҠಈʯϘλϯΛΫϦοΫ 16

Slide 17

Slide 17 text

جຊઃఆ 17

Slide 18

Slide 18 text

جຊઃఆ߲໨ͷೖྗ ೖྗ߲໨ ೖྗ಺༰ λΠϓ ΧελϜ &YUFOTJPO*% ϦόʔευϝΠϯܗࣜͰೖྗ Α͘෼͔Βͳ͍৔߹͸ɺDPNϑϧωʔϜ-PDBM(PVSNFU4LJMM εΩϧ໊ ͝౰஍άϧϝ ݺͼग़໊͠ʢϝΠϯʣ ͝౰஍άϧϝ ݺͼग़໊͠ʢαϒʣ ͝ͱ͏͙ͪΔΊ ˞Ի੠ೝࣝͷͨΊදه͕༳ΕΔ͜ͱ͕͋ΔͷͰɺͻΒ͕ͳΛओମʹೖྗ ఏڙऀ໊ ࣗ͝෼ͷ໊͓લ΍νʔϜ໊ͳͲ ୲౰ऀϝʔϧΞυϨε ࣗ͝෼ͷϝʔϧΞυϨε 18

Slide 19

Slide 19 text

αʔόʔઃఆ • ExtensionαʔόʔͷURLʹ͸ԾͷURLʢhttps:// hoge.comʣΛೖྗͯ͠ɺʮ࣍΁ʯϘλϯΛΫϦοΫ 19

Slide 20

Slide 20 text

഑෍৘ใ 20

Slide 21

Slide 21 text

഑෍৘ใ߲໨ͷೖྗ ೖྗ߲໨ ೖྗ಺༰ ΧςΰϦ ஍Ҭ ৹ࠪ୲౰ऀ΁ͷίϝϯτ ೖྗྫ
 ֓ཁɿԻ੠Ͱ֤౎ಓ෎ݝͷ͝౰஍άϧϝΛݕࡧͰ͖·͢ &YUFOTJPOͷઆ໌ Ϣʔβʔ ޲͚ ೖྗྫ
 ֓ཁɿԻ੠Ͱ֤౎ಓ෎ݝͷ͝౰஍άϧϝΛݕࡧͰ͖·͢ ୅දαϯϓϧൃ࿩ w Ͷ͐$MPWBɺ͝౰஍άϧϝΛ։͍ͯ w ๺ւಓͷ͝౰஍άϧϝ͸ w βϯΪͷ͜ͱΛڭ͑ͯ w ݕࡧΩʔϫʔυ ͝౰஍άϧϝ ର৅σόΠε શ෦νΣοΫʢσϑΥϧτͷ··ʣ 21

Slide 22

Slide 22 text

ݸਓ৘ใͷอޢ͓Αͼن໿ಉҙ • ͍͍͑Λબ୒ͯ͠ɺʮอଘʯϘλϯΫϦοΫ͠ɺʮର ࿩ϞσϧʯϘλϯΛΫϦοΫ 22

Slide 23

Slide 23 text

2. ର࿩Ϟσϧͷߏங

Slide 24

Slide 24 text

ର࿩Ϟσϧͱ͸ • εΩϧʹର͢ΔϢʔβʔͷཁٻΛత֬ʹಡΈ औͬͯॲཧ͢ΔͨΊͷॲཧఆٛ ✴ ΞϓϦʹ͓͚Δը໘ભҠɾGUIઃܭʹ
 ૬౰͢Δ ✴ Ϣʔβʔ͕త֬ʹεΩϧ͕ఏڙ͢ΔػೳΛ
 ࢖͑ΔΑ͏ઃܭ͢Δ
 ✴ VUI ͷ৔߹ɺਓʹΑͬͯ஻Γํ͕ҟͳΔ ͜ͱ΁ͷߟྀ͕ඞཁͱͳΔ 24

Slide 25

Slide 25 text

ର࿩Ϟσϧͱ͸ • ର࿩Ϟσϧ͸ɺΠϯςϯτɺεϩοτɺαϯϓϧൃ ࿩Ͱఆٛ͢Δɻ ཁૉ આ໌ Πϯςϯτʢ*OUFOUʣ ཁٻͷҙਤɾ۠෼ ྫɿϐβΛ஫จ͢Δɺܦ࿏Λݕࡧ͢ΔͳͲ εϩοτʢ4MPUʣ ΠϯςϯτΛॲཧ͢ΔͨΊʹඞཁͳ৘ใ ྫɿϐβ໊ɾ਺ྔɺग़ൃ஍ɾ໨త஍ɾग़ൃ࣌ؒͳͲ αϯϓϧൃ࿩ Πϯςϯτ΍εϩοτΛೝࣝ͢ΔͨΊͷൃ࿩ྫ w ##2ϐβΛຕཔΜͰ w ϚϧήϦʔλΛͭ஫จͯ͠ w ࣌ൃͰകా͔Βେࡕۭߓ·Ͱ w ࣌ؒޙʹകా͔Βେࡕۭߓ΁ߦ͖͍ͨ 25

Slide 26

Slide 26 text

ࠓճͷεΩϧͰͷର࿩Ϟσϧ • Πϯςϯτ1ɿ౎ಓ෎ݝͷ͝౰஍άϧϝΛௐ΂Δ ✴ εϩοτɿ ✤ ౎ಓ෎ݝ໊ʢϏϧτΠϯɾεϩοτλΠϓʣ ✴ αϯϓϧൃ࿩ɿ ✤ େࡕͷ͝౰஍άϧϝΛڭ͑ͯ ✤ ๺ւಓͷ͝౰஍άϧϝ͸ 26

Slide 27

Slide 27 text

Πϯςϯτͷ࡞੒
 ʮ౎ಓ෎ݝͷ͝౰஍άϧϝΛௐ΂Δʯ • ৽نͷΧελϜΠϯςϯτΛ࡞Δ • Πϯςϯτ໊ɿFindGourmetByPrefectureIntent 27

Slide 28

Slide 28 text

Πϯςϯτͷ࡞੒
 ʮ౎ಓ෎ݝͷ͝౰஍άϧϝΛௐ΂Δʯ • ౎ಓ෎ݝͷϏϧτΠϯ εϩοτλΠϓΛ༗ޮʹ͢Δ 28

Slide 29

Slide 29 text

Πϯςϯτͷ࡞੒
 ʮ౎ಓ෎ݝͷ͝౰஍άϧϝΛௐ΂Δʯ • ΠϯςϯτͷεϩοτΛઃఆ͢Δ • εϩοτ໊ɿprefecture 29

Slide 30

Slide 30 text

Πϯςϯτͷ࡞੒
 ʮ౎ಓ෎ݝͷ͝౰஍άϧϝΛௐ΂Δʯ • εϩοτʹεϩοτλΠϓΛઃఆ͢Δ • εϩοτλΠϓɿCLOVA.JP_ADDRESS_KEN 30

Slide 31

Slide 31 text

Πϯςϯτͷ࡞੒
 ʮ౎ಓ෎ݝͷ͝౰஍άϧϝΛௐ΂Δʯ • Πϯςϯτͷαϯϓϧൃ࿩Λొ࿥͢Δ • αϯϓϧൃ࿩ɿ๺ւಓͷ͝౰஍άϧϝ͸ 31

Slide 32

Slide 32 text

Πϯςϯτͷ࡞੒
 ʮ౎ಓ෎ݝͷ͝౰஍άϧϝΛௐ΂Δʯ • αϯϓϧൃ࿩಺ͷεϩοτΛࢦఆ͢Δ • ”๺ւಓ”ͱ͍͏จࣈྻΛυϥοάͯ͠ɺεϩοτΛબ୒ 32

Slide 33

Slide 33 text

Πϯςϯτͷ࡞੒
 ʮ౎ಓ෎ݝͷ͝౰஍άϧϝΛௐ΂Δʯ • ଞͷαϯϓϧൃ࿩΋ొ࿥ͯ͠ΈΔ • ྫɿେࡕͷ͝౰஍άϧϝΛڭ͑ͯ 33

Slide 34

Slide 34 text

ࠓճͷεΩϧͰͷର࿩Ϟσϧ • Πϯςϯτ2ɿ͝౰஍άϧϝͷৄࡉΛௐ΂Δ ✴ εϩοτɿ ✤ ͝౰஍άϧϝ໊ʢΧελϜɾεϩοτλΠϓʣ ✴ αϯϓϧൃ࿩ɿ ✤ େࡕͷ͝౰஍άϧϝΛڭ͑ͯ ✤ ๺ւಓͷ͝౰஍άϧϝ͸ 34

Slide 35

Slide 35 text

Πϯςϯτͷ࡞੒
 ʮ͝౰஍άϧϝͷৄࡉΛௐ΂Δʯ • ΧελϜ εϩοτΛొ࿥͢Δ • εϩοτλΠϓ໊ɿLOCAL_GOURMET_TYPE 35

Slide 36

Slide 36 text

Πϯςϯτͷ࡞੒
 ʮ͝౰஍άϧϝͷৄࡉΛௐ΂Δʯ • ΧελϜεϩοτͷࣙॻσʔλΛొ࿥͢Δ • TSVϑΝΠϧʢGOURMET_LIST.tsvʣͰ·ͱΊͯొ࿥͢Δ 36

Slide 37

Slide 37 text

Πϯςϯτͷ࡞੒
 ʮ͝౰஍άϧϝͷৄࡉΛௐ΂Δʯ • ৽نͷΧελϜΠϯςϯτΛ࡞Δ • Πϯςϯτ໊ɿFindGourmetByNameIntent 37

Slide 38

Slide 38 text

Πϯςϯτͷ࡞੒
 ʮ͝౰஍άϧϝͷৄࡉΛௐ΂Δʯ • ৽نͷεϩοτΛઃఆ͢Δ • Πϯςϯτ໊ɿgourmet • εϩοτλΠϓɿLOCAL_GOURMET_TYPE 38

Slide 39

Slide 39 text

Πϯςϯτͷ࡞੒
 ʮ͝౰஍άϧϝͷৄࡉΛௐ΂Δʯ • αϯϓϧൃ࿩ͷొ࿥ͱϏϧυ • βϯΪͷ͜ͱΛڭ͑ͯ • ۲Χπ͸ͲΜͳྉཧ 39

Slide 40

Slide 40 text

3. ։ൃ؀ڥͷߏங

Slide 41

Slide 41 text

λʔϛφϧʗίϚϯυϓϩϯϓτ ىಈ • Mac • λʔϛφϧΛىಈ͢Δ • Windows • ίϚϯυϓϩϯϓτΛ؅ཧऀݖݶͰىಈ͢Δ • Windows7: 
 WinΩʔˠcmd ͱೖྗˠCtrl + Shift + Enter • Windows10ɿ
 WinΩʔˠcmd ͱೖྗˠʮίϚϯυϓϩϯϓτʯΛӈΫϦοΫ
 ˠʮ؅ཧऀͱ࣮ͯ͠ߦʯ 41

Slide 42

Slide 42 text

εΩϧϓϩάϥϜͷ։ൃ৔ॴΛ ४උ͢Δ $ mkdir -p ~/ClovaSkills/LocalGourmetSkill $ cd ~/ClovaSkills/LocalGourmetSkill • Mac > mkdir c:¥tmp¥ClovaSkills¥LocalGourmetSkill > cd c:¥tmp¥ClovaSkills¥LocalGourmetSkill • Windows 42

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

Python Ծ૝؀ڥΛ࡞੒͢Δ (venv) $ python —version Python 3.6.5 1ZUIPOͷόʔδϣϯ͕ ͱͳ͍ͬͯΔ͜ͱΛ֬ೝ 44

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

Flask ͷΠϯετʔϧ (venv) $ pip install flask Collecting flask ʢதུʣ Successfully installed Jinja2-2.10 MarkupSafe-1.0 flask-1.0.2 itsdangerous-0.24 (venv) $ 47

Slide 48

Slide 48 text

4. εΩϧ༻ϓϩάϥϜͷ։ൃ

Slide 49

Slide 49 text

Zappa ΞϓϦΛ৽ن࡞੒ (venv) $ mkdir local-gourmet-skill (venv) $ cd local-gourmet-skill/ (venv) $ zappa init ███████╗ █████╗ ██████╗ ██████╗ █████╗ ╚══███╔╝██╔══██╗██╔══██╗██╔══██╗██╔══██╗ ███╔╝ ███████║██████╔╝██████╔╝███████║ ███╔╝ ██╔══██║██╔═══╝ ██╔═══╝ ██╔══██║ ███████╗██║ ██║██║ ██║ ██║ ██║ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ Welcome to Zappa! • zappa init ίϚϯυΛ࢖ͬͯΞϓϦΛ࡞੒ˍηοτΞοϓ 49 ;BQQBͷઆ໌ ͸ޙ΄Ͳʂ

Slide 50

Slide 50 text

࣮ߦ؀ڥ໊ͷઃఆ 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

Slide 51

Slide 51 text

σϓϩΠ࣌ʹ࢖༻͢Δ
 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

Slide 52

Slide 52 text

Ϟδϡʔϧύεͷࢦఆ 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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

ઃఆϑΝΠϧͷ֬ೝ 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

Slide 55

Slide 55 text

ϩʔΧϧ؀ڥͰͷ࣮ߦςετ • ࣄલʹμ΢ϯϩʔυ͍͍ͨͩͨϓϩάϥϜϦιʔ εͷ
 ”local-gourmet-skill/main_initial.py”Λɺ
 ։ൃ༻σΟϨΫτϦʹ
 “local-gourmet-skill/main.py”ͱͯ͠഑ஔ͢Δ
 55

Slide 56

Slide 56 text

ϩʔΧϧ؀ڥͰͷ࣮ߦςετ (venv) $ python main.py • AWS ΁σϓϩΠ͢ΔલʹϩʔΧϧ؀ڥͰૄ௨֬ೝ $ curl http://localhost:5000 hello from Flask! • ผλʔϛφϧ΍ϒϥ΢βͳͲͰhttp://localhost:5000 ʹΞΫηε zIFMMPGSPN'MBTLz ͱ͍͏จࣈྻ͕දࣔ͞Ε͍ͯΔ ͜ͱΛ֬ೝ 56

Slide 57

Slide 57 text

ॳظσϓϩΠˍૄ௨֬ೝ (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

Slide 58

Slide 58 text

5. ͝౰஍άϧϝ৘ใͷ
 Πϯϙʔτ

Slide 59

Slide 59 text

ϓϩάϥϜϦιʔεͷίϐʔ • ϓϩάϥϜϦιʔε͔ΒɺԼهͷϑΝΠϧΛ։ൃ༻ σΟϨΫτϦʢLocalGourmetSkillʣ௚Լʹίϐʔ ✦ tables/table_GourmetInfo.json ✦ create_tables_to_dynamodb.bat ✦ create_tables_to_dynamodb.sh ✦ GOURMET_LIST.tsv ✦ gourmet_info_importer.py ✦ gourmet_info_list_db.csv 59

Slide 60

Slide 60 text

DynamoDB ςʔϒϧͷ࡞੒ $ cd ~/ClovaSkills/LocalGourmetSkill $ sh ./create_tables_to_dynamodb.sh • Mac > cd c:¥tmp¥ClovaSkills¥LocalGourmetSkill > create_tables_to_dynamodb.bat • Windows 1ZUIPOԾ૝؀ڥΛىಈ͍ͯ͠ΔίϚϯυϓϩϯϓτ ͱ͸ผʹ্ཱ࣮ͪ͛ͯߦ͍ͯͩ͘͠͞ 60

Slide 61

Slide 61 text

ςʔϒϧ΁ͷσʔλΠϯϙʔτ (venv) $ python gourmet_info_importer.py (venv) $ • Python ΞϓϦΛ࢖ͬͯ͝౰஍άϧϝ৘ใΛςʔϒϧ΁Πϯϙʔτ 61

Slide 62

Slide 62 text

6. εΩϧ༻ϓϩάϥϜͷ
 σϓϩΠ

Slide 63

Slide 63 text

εΩϧ༻ϓϩάϥϜ΁ͷೖସ͑ • ࣄલʹμ΢ϯϩʔυ͍͍ͨͩͨϓϩάϥϜϦιʔ εͷ
 ”local-gourmet-skill/main.py”Λɺ
 ։ൃ༻σΟϨΫτϦͷ
 “local-gourmet-skill/main.py”ͱͯ͠഑ஔ͢Δ
 ʢ্ॻ͖ɺ಺༰ೖସ͑ͰOKʂʣ ϓϩάϥϜͷղઆ͸ ޙ΄Ͳʂ 63

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

εΩϧ༻ϓϩάϥϜͷσϓϩΠ (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

Slide 66

Slide 66 text

εΩϧͷαʔόʔઃఆมߋ • Clova Developer Center ͷεΩϧઃఆը໘Λ։͖ɺ εΩϧҰཡʹ͋Δجຊ৘ใΛमਖ਼͢Δ 66

Slide 67

Slide 67 text

εΩϧͷαʔόʔઃఆมߋ • ʮαʔόʔઃఆʯը໘·ͰਐΈɺʮExtensionαʔόʔͷ URLʯཝʹ
 Lambda࣮ߦ༻URL + /clova
 Λೖྗͯ͠ ʮอଘʯϘλϯΛΫϦοΫ 67

Slide 68

Slide 68 text

ϓϩάϥϜϩάͷදࣔ (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

Slide 69

Slide 69 text

7. εΩϧͷςετ

Slide 70

Slide 70 text

ର࿩Ϟσϧͷςετ • αϯϓϧൃ࿩Λೖྗͯ͠ςετ͢Δ 70

Slide 71

Slide 71 text

ର࿩Ϟσϧͷςετ • ૝ఆͲ͓Γʹಈ͍͍ͯΔ͔Λ֬ೝ͢Δ ϦΫΤετ࣌ͷ+40/΋දࣔ͞ ΕΔͷͰ୯ମςετͳͲʹར༻ Ͱ͖Δ 71

Slide 72

Slide 72 text

”Clova, ͝౰஍άϧϝΛ։͍ͯ”
 ͱ࿩͔͚͍ͯͩ͘͠͞ Let’s try!

Slide 73

Slide 73 text

8. εΩϧ༻ϓϩάϥϜͷղઆ

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

εΩϧىಈ࣌ͷ࣮ߦ෦෼ @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

Slide 76

Slide 76 text

Πϯςϯτ൑ผ࣌ͷ࣮ߦ෦෼ @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

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

9. αʔόʔϨε։ൃ༻πʔϧ
 ʮZappaʯʹ͍ͭͯ

Slide 80

Slide 80 text

Zappa ͱ͸ • AWS Lambda + API Gateway ͳͲΛ࢖ͬͨ։ൃɾσ ϓϩΠ͕༰қʹͰ͖Δ։ൃπʔϧ ✦ ਺ίϚϯυͰσϓϩΠ΍ߋ৽͕Ͱ͖Δ - zappa init / zappa deploy / zappa update • Flask΍DjangoͳͲWebϑϨʔϜϫʔΫ΋ར༻Ͱ͖ Δ 80

Slide 81

Slide 81 text

Zappa ͱ͸ • εςʔδ෼͚ʢ։ൃɺςετɺຊ൪ ͳͲʣ͕؆୯ʹͰ ͖Δ ✦ zappa_settings.json Ͱεςʔδ͝ͱͷઃఆΛॻ͚ͩ͘ • Lambda ͷίʔϧυελʔτճආ΋؆୯ʹͰ͖Δ • Lambda ͷඇಉظ࣮ߦ΍ఆظ࣮ߦɺ༷ʑͳτϦΨʔ ʢS3/DynamoDB/SQS/SNS ͳͲʣʹ΋ରԠ 81

Slide 82

Slide 82 text

Thank you!!