Slide 1

Slide 1 text

SSMLͷϚʔΫΞοϓΛ ޮ཰Խ͢ΔͨΊʹ TypeScriptͱJSXʹखΛग़ͨ͠࿩ AAJUG Online 2020/05/29 Hidetaka Okamoto #aajug

Slide 2

Slide 2 text

֓ཁ • SSMLͷϚʔΫΞοϓΛจࣈྻͰ΍Δͷ͸ΩπΠ • JSXΛ͔ͭ͑͹ɺReactͷΑ͏ʹSSML͕ॻ͚Δ • TypeScript (TSX)ͳΒ͹ɺϓϩύςΟͷݕূ·Ͱ͍͚Δ • ask-sdk޲͚ͷϥούʔΛ࡞ͬͯΈͨ

Slide 3

Slide 3 text

֓ཁ • SSMLͷϚʔΫΞοϓΛจࣈྻͰ΍Δͷ͸ΩπΠ • JSXΛ͔ͭ͑͹ɺReactͷΑ͏ʹSSML͕ॻ͚Δ • TypeScript (TSX)ͳΒ͹ɺϓϩύςΟͷݕূ·Ͱ͍͚Δ • ask-sdk޲͚ͷϥούʔΛ࡞ͬͯΈͨ

Slide 4

Slide 4 text

Α͋͘ΔSSMLͷॻ͖ํ handlerInput.responseBuilder .speak( [ “

͜Ε͸SSMLͷαϯϓϧͰ͢ɻ

”, “”, “࣍͸ԿΛ͠·͔͢ʁ” ].join(‘’)) .getResponse();

Slide 5

Slide 5 text

จࣈྻͰMarkup LanguageΛॻ͘ͱ͍͏͜ͱ • จࣈྻͷதʹɺSSMLλάΛهड़͢Δ • ASK SDKΛͦͷ··࢖͏৔߹ͷఆੴ • speakλά͸ASK SDK͕ࣗಈͰηοτͯ͘͠ΕΔ • λάͷ਺͕૿͑Δͱϛε͕ੜ͡΍͍͢

Slide 6

Slide 6 text

ؒҧ͍୳͠ handlerInput.responseBuilder .speak( [ “

͜Ε͸SSMLͷαϯϓϧͰ͢ɻ

”, “”, “࣍͸ԿΛ͠·͔͢ʁ” ].join(‘’)) .getResponse();

Slide 7

Slide 7 text

ਖ਼ղɿ։࢝λά͕ͳ͍ handlerInput.responseBuilder .speak( [ “

͜Ε͸SSMLͷαϯϓϧͰ͢ɻ

”, “”, “࣍͸ԿΛ͠·͔͢ʁ” ].join(‘’)) .getResponse();

Slide 8

Slide 8 text

SSMLΛ͍͔ʹޮ཰Α͘ॻ͚ΔΑ͏ʹ͢Δ͔ʁ • SSMLΛจࣈྻͱͯ͠ѻ͏͜ͱ͕໰୊ • จࣈྻҎ֎Ͱهड़Ͱ͖ΔΑ͏ʹ͢Δ • Solution A: SSML BuilderΫϥε • Solution B: MarkdownͳͲͷϑΥʔϚοτΛ࢖͏

Slide 9

Slide 9 text

npm i -S ssml-builder var Speech = require('ssml-builder'); var speech = new Speech(); speech.say('Hello') .pause('1s') .say('fellow Alexa developers') .pause('500ms') .say('Testing phone numbers') .sayAs({ word: "+1-377-777-1888", interpret: "telephone" }); var speechOutput = speech.ssml(true); • ϝιουܗࣜͰSSMLΛදݱ • ม׵݁ՌΛϨεϙϯε΁ ௥ՃͰ͖Δ • ϝιουνΣʔϯͰ ॊೈʹ௥ՃՄೳ

Slide 10

Slide 10 text

npm i -S speechmarkdow n-js const smd = require('speechmarkdown-js'); const markdown = `Sample [3s] speech [250ms] markdown`; const options = { platform: 'amazon-alexa' }; const speech = new smd.SpeechMarkdown(); const ssml = speech.toSSML(markdown, options); === RESULT === Sample speech markdown • MarkdownͰSSMLΛهड़ • ϚϧνϓϥοτϑΥʔϜରԠ • fsͳͲΛ૊Έ߹Θͤͯ .mdϑΝΠϧʹهड़΋Մೳ

Slide 11

Slide 11 text

One more things…

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

֓ཁ • SSMLͷϚʔΫΞοϓΛจࣈྻͰ΍Δͷ͸ΩπΠ • JSXΛ͔ͭ͑͹ɺReactͷΑ͏ʹSSML͕ॻ͚Δ • TypeScript (TSX)ͳΒ͹ɺϓϩύςΟͷݕূ·Ͱ͍͚Δ • ask-sdk޲͚ͷϥούʔΛ࡞ͬͯΈͨ

Slide 14

Slide 14 text

ReactͷΑ͏ʹ SSMLΛॻ͖͍ͨ import React from 'react'; import { CopyToClipboard } from 'react-copy-to- clipboard'; const CopyLink = ({param}: {param: string}) => ( {param} ); export default () => { return } • ॻ͖׳ΕͨϑΥʔϚοτ • View (Speech)΁ͷϑΥʔΧε Λڧ੍Ͱ͖Δ • JSΒ͍͠ಈతͳॲཧ΋Մೳ

Slide 15

Slide 15 text

ϥΠϒϥϦ͸͋Δ ߟ͑Δ͜ͱ͸օಉ͡ JSXΛstringʹม׵͢Δπʔϧ ϝϯς͞Ε͍ͯͳ͍΋ͷଟΊ ssml-tsxҰ୒ঢ়ଶ

Slide 16

Slide 16 text

npm i -S ssml-tsx /** @jsx ssml */ import ssml, { rendetToString, FC } from "ssml-tsx"; const Foo= ({ name }) => ( {name}

What would you like to do today?

); console.log(renderToString()); • SSMLΛJSXͰॻ͚Δ • from TimeTree • GitHubͷϨεϙϯε΋ૣ͍ • ݱঢ়͜ΕҰ୒

Slide 17

Slide 17 text

JSX / TSX͸ ม׵ඞਢ // Example for Babel { "plugins": [ ["transform-jsx", { "function": "ssml", "useVariables": true }] ] } • JSX / TSX͸JSͰಈ͔ͳ͍ • BabelͰͷม׵͕Ұൠత • ४උͷҰखؒΛڐ༰Ͱ͖Δ͔ ͕෼ਫྮ • Ͳ͏ͤ΍ΔͳΒTypeScript

Slide 18

Slide 18 text

֓ཁ • SSMLͷϚʔΫΞοϓΛจࣈྻͰ΍Δͷ͸ΩπΠ • JSXΛ͔ͭ͑͹ɺReactͷΑ͏ʹSSML͕ॻ͚Δ • TypeScript (TSX)ͳΒ͹ɺϓϩύςΟͷݕূ·Ͱ͍͚Δ • ask-sdk޲͚ͷϥούʔΛ࡞ͬͯΈͨ

Slide 19

Slide 19 text

JSX΍ΔͳΒ TypeScript { "compilerOptions": { ..., + "jsx": "react", } } • tscίϚϯυͰ·ͱΊͯ ίϯύΠϧ • ܕݕূͷԸܙ͸େ͖͍ • ASK SDK΋TypeScriptରԠ

Slide 20

Slide 20 text

IDEͰϛε͕Θ͔Γ΍͍͢

Slide 21

Slide 21 text

֓ཁ • SSMLͷϚʔΫΞοϓΛจࣈྻͰ΍Δͷ͸ΩπΠ • JSXΛ͔ͭ͑͹ɺReactͷΑ͏ʹSSML͕ॻ͚Δ • TypeScript (TSX)ͳΒ͹ɺϓϩύςΟͷݕূ·Ͱ͍͚Δ • ask-sdk޲͚ͷϥούʔΛ࡞ͬͯΈͨ

Slide 22

Slide 22 text

@ask-utils/speech- script ssml-tsxͷϥούʔ ASK SDKͰͷར༻ʹಛԽ ஋ͷऔΓճ͠Λޮ཰Խ

Slide 23

Slide 23 text

࣮૷αϯϓϧ ʢSSMLʣ /** @jsx ssml */ import { ssml, SpeechScriptJSX } from '@ask-utils/speech-script' class LaunchRequestScriptForEnglish extends SpeechScriptJSX { speech() { return ( Hello! How are you? ) } reprompt() { return ( How are you? I hope you to have a good day. ) } } • speech / repromptͦΕͧΕʹ JSXͰϚʔΫΞοϓ • this.props͔ΒϦΫΤετ಺༰ ͕ͱΕΔ • ReactϥΠΫʹهड़Մೳ

Slide 24

Slide 24 text

࣮૷αϯϓϧ ʢHandlerʣ const handler = { canHandle(handlerInput) { return handlerInput.requestEnvelope.request.type === 'LaunchRequest' }, handle(handlerInput) { const Speech = new LaunchRequestScript(handlerInput) return Speech.createResponse() } } • SSMLΛॻ͍ͨΫϥεΛར༻͢ Δ • responseBuilder಺ଂͳͷͰɺ ͦͷ··return͢Ε͹OK

Slide 25

Slide 25 text

SSML-TSX Λಋೖͯ͠มΘͬͨ͜ͱ • RequestHandlerͷਆΦϒδΣΫτԽΛ્ࢭ • View (SSML)ͱσʔλͷॲཧͷ੹຿Λ෼཭͠ɺςελϒϧʹ • ࢠίϯϙʔωϯτΛར༻ͨ͠࠶ར༻ੑͷ޲্ • ReactͰॻ͍ͯΔϊϦͰAlexaͷൃ࿩Λॻ͚Δ

Slide 26

Slide 26 text

ViewΛ੾Γ཭ͨ͠RequestHandler

Slide 27

Slide 27 text

ΑΓॊೈͳ Viewͷදݱʹ

Slide 28

Slide 28 text

Next Step: Localization class LaunchRequestScriptForJapanse extends LaunchRequestScript { speech() { return ( ͜Μʹͪ͸ ) } } class LaunchRequestScriptForEnglish extends LaunchRequestScript { speech() { return ( Hello! How are you? ) } } export const createLaunchRequestScript = (handlerInput: HandlerInput, options?: LaunchRequestProps): SpeechScriptJSX => { const factory = new L11NSpeechScriptJSXFactory({ allowLanguageMatcher: true }).putLocales({ locale: 'ja-JP', script: new LaunchRequestScriptForJapanese(handlerInput, options) }, { locale: 'en-US', script: new LaunchRequestScriptForEnglish(handlerInput, options) }) return factory.create(handlerInput) } • ݴޠ͝ͱʹSSMLΛهड़͢Δ • en-USͳͲͷݫີͳ੔߹ͱɺ en͚ͩͰ·ΔΊΔ؇͍੔߹ ྆ํΛαϙʔτʢ༧ఆʣ

Slide 29

Slide 29 text

͓ΘΓʹ • RequestHandler͸ͦͷ··࢖͏ʹ͸ॏ͗͢Δ • MVC΍FluxͳͲͷ֓೦͕ͳ͍ੈքͰઓ͏ʹ͸ɺձ࿩͸ෳࡶ͗͢Δ • ͤΊͯSSMLͱAPL͸ந৅Խ͠Α͏ • speechmarkdown-js / ssml-tsx͕ݸਓతʹ͸͓͢͢Ί • ͩΕ͔ASK SDK on Railsͭͬͯ͘͘Εʢ੾࣮ʣ