Запускайте приложения Alexa из командной строки. Запустите их в Slack. Запускайте их где угодно! Поддерживает навыки и намерения Amazon Alexa.
$ npm install chatskills
Chatskills — это быстрый и простой способ запускать приложения Alexa за пределами Amazon. Легко создавайте свои навыки и намерения и запускайте их прямо из командной строки!
Chatskills не требует сервера и может работать прямо в консоли. Он также может работать в Интернете, в Slack или где угодно. Он обрабатывает запросы от нескольких пользователей и поддерживает память сеанса. Когда пользователь начинает разговор с одним из навыков, навык продолжает выполняться в контексте сеанса до тех пор, пока навык не завершится.
Вот как выглядит приложение Amazon Alexa, работающее из командной строки.
> chatskills, ask hello to say hi.
Hello, World!
> chatskills, ask horoscope for Scorpio.
Things are looking up today for Scorpio.
> chatskills, ask funny to tell me a joke
Knock knock.
> who's there?
Banana.
> banana who
Knock knock.
> whos there
Orange.
> orange who?
Orange you glad I didn't say banana?
В этом примере пользователь получает доступ к трем различным навыкам: «Привет», «Гороскоп» и «Забавно».
Использовать навыки чата легко. Используйте синтаксис Alexa, чтобы добавить новый навык, а затем создайте несколько намерений. Вот простой пример.
var chatskills = require ( 'chatskills' ) ;
// Create a skill.
var hello = chatskills . app ( 'hello' ) ;
// Create an intent.
hello . intent ( 'helloWorld' , {
'slots' : { } ,
'utterances' : [ '{to |}{say|speak|tell me} {hi|hello|howdy|hi there|hiya|hi ya|hey|hay|heya}' ]
} ,
function ( req , res ) {
res . say ( 'Hello, World!' ) ;
}
) ;
// Respond to input.
chatskills . respond ( 'chatskills, ask hello to say hi' , function ( response ) {
console . log ( response ) ;
} ) ;
В приведенном выше примере грамматика высказываний автоматически расширяется, чтобы соответствовать следующим фразам:
helloWorld to say hi
helloWorld say hi
helloWorld to speak hi
helloWorld speak hi
helloWorld to tell me hi
helloWorld tell me hi
helloWorld to say hello
helloWorld say hello
helloWorld to speak hello
helloWorld speak hello
helloWorld to tell me hello
helloWorld tell me hello
helloWorld to say howdy
...
Чтобы взаимодействовать с чат-ботом с помощью этого навыка, произнесите любую из целевых фраз. В приведенном выше примере мы использовали фразу «поздороваться», но вы можете сопоставить любую из сгенерированных фраз. Например:
> chatskills, ask hello to tell me hi
Hello, World!
> chatskills, ask hello to say hello
Hello, World!
> chatskills, ask hello to say howdy
Hello, World!
Чтобы создать чат-бота, который работает локально на консоли, просто включите цикл для чтения ввода.
var readlineSync = require ( 'readline-sync' ) ;
// Console client.
var text = ' ' ;
while ( text . length > 0 && text != 'quit' ) {
text = readlineSync . question ( '> ' ) ;
// Respond to input.
chatskills . respond ( text , function ( response ) {
console . log ( response ) ;
} ) ;
}
Если вы используете асинхронные вызовы в своих навыках (например, запрос и т. д.), тогда вам нужно использовать асинхронный цикл вместо цикла while, описанного выше. Вот пример.
Вам не обязательно использовать только консоль! Вы можете запустить своего чат-бота где угодно, например в Slack. Полный пример см. здесь.
var SlackBot = require ( 'slackbots' ) ;
var bot = new SlackBot ( { token : token , name : 'awesome' } ) ;
// Listen to slack messages.
bot . on ( 'message' , function ( message ) {
// Reply to humans.
if ( message . type == 'message' && message . text && message . subtype != 'bot_message' ) {
var author = getUserById ( message . user ) ;
var channel = getChannelById ( message . channel ) ;
// Respond to input, use author.name as the session id.
chatskills . respond ( message . text , author . name , function ( response ) {
if ( channel ) {
// Public channel message.
bot . postMessageToChannel ( channel . name , response ) ;
}
else {
// Private message.
bot . postMessageToUser ( author . name , response ) ;
}
} ) ;
}
} ) ;
Навыки — это программы, которые может запускать ваш чат-бот. Они состоят из намерений, которые состоят из высказываний (фраз, соответствующих пользовательскому вводу), ответов и памяти сеанса. Каждый навык имеет доступ к памяти сеанса, поэтому вы можете сохранять и извлекать переменные, которые помогут разумно реагировать на запросы пользователя.
Вот пример создания нового навыка под названием «гороскоп».
var horoscope = chatskills . app ( 'horoscope' ) ;
Навыки состоят из намерений. Здесь вводимые пользователем данные сопоставляются с массивом высказываний. Когда совпадение найдено, это намерение выполняется. Намерение может получить/установить переменные в пользовательском сеансе, вызвав req.get('variable')
и req.set('variable', value)
. Намерение может вывести ответ, вызвав res.say('hello')
.
Вот пример создания нового намерения для навыка «гороскоп».
horoscope . intent ( 'predict' , {
'slots' : { 'SIGN' : 'LITERAL' } ,
'utterances' : [ 'for {signs|SIGN}' ]
} ,
function ( req , res ) {
res . say ( 'Things are looking up today for ' + req . get ( 'SIGN' ) + '.' ) ;
}
) ;
С этим намерением можно взаимодействовать следующим образом:
> chatskills, ask horoscope for Scorpio
Things are looking up today for Scorpio.
Есть два способа начать использовать навык.
Первый способ активировать навык — создать намерение, например «бежать». Это позволит вам ввести: «Навыки чата, попросите [имя навыка] запустить». Если намерение имеет возвращаемое значение true (чтобы сохранить сеанс), ваш навык теперь будет работать.
Пример навыка «бега» можно найти в игре в угадайку.
app . intent ( 'run' , {
"slots" : { } ,
"utterances" : [ "{to|} {run|start|go|launch}" ]
} , function ( req , res ) {
var prompt = "Guess a number between 1 and 100!" ;
res . say ( prompt ) . reprompt ( prompt ) . shouldEndSession ( false ) ;
}
) ;
Второй способ запуска навыка — создать метод запуска, который будет автоматически запускаться при запуске приложения. Затем просто chatskills.launch(app)
чтобы начать свой навык. Вы можете передать навык или название навыка. Вы также можете указать необязательный уникальный идентификатор сеанса.
Пример: chatskills.launch(app)
chatskills.launch('horoscope')
chatskills.launch('horoscope', 'some-unique-id')
.
Вот полный пример.
var chatskills = require ( './lib/chatskills' ) ;
var readlineSync = require ( 'readline-sync' ) ;
// Create a skill.
var hello = chatskills . app ( 'hello' ) ;
// Launch method to run at startup.
hello . launch ( function ( req , res ) {
res . say ( "Ask me to say hi!" ) ;
// Keep session open.
res . shouldEndSession ( false ) ;
} ) ;
// Create an intent.
hello . intent ( 'helloWorld' , {
'slots' : { } ,
'utterances' : [ '{to |}{say|speak|tell me} {hi|hello|howdy|hi there|hiya|hi ya|hey|hay|heya}' ]
} ,
function ( req , res ) {
res . say ( 'Hello, World!' ) ;
}
) ;
// Start running our skill.
chatskills . launch ( hello ) ;
// Console client.
var text = ' ' ;
while ( text . length > 0 && text != 'quit' ) {
text = readlineSync . question ( '> ' ) ;
// Respond to input.
chatskills . respond ( text , function ( response ) {
console . log ( response ) ;
} ) ;
}
Когда пользователь предоставляет входные данные, они сопоставляются с каждым навыком и их списком намерений. Когда совпадение найдено, начинается новый сеанс и начинает выполняться навык.
Когда для пользователя начался сеанс, намерение активированного навыка может получить/установить значения переменных внутри сеанса. Это позволяет хранить и извлекать данные.
Пока сеанс открыт для пользователя, все вводимые пользователем данные направляются на активированный навык. Таким образом, пользователю не нужно повторно запрашивать навык («навыки чата, поздороваться, поздороваться»). Вместо этого пользователь может просто предоставить текст, который будет сопоставляться с намерениями текущего навыка.
Намерение может оставить сеанс открытым, вернув true
или вызвав res.shouldEndSession(false)
и завершить сеанс, вернув false
или вызвав res.shouldEndSession(true)
. В намерении также может быть опущен оператор return, что аналогично возврату false.
Пример использования сеанса см. в разделе «Навык гороскопа». Обратите внимание: намерение задает пользователю вопрос, а затем возвращает true, чтобы сеанс продолжился. Намерение возвращает false только после получения действительного ответа, тем самым завершая сеанс.
Таким образом, когда сеанс пользователя открыт, все вводимые пользователем данные направляются в навык. Когда сеанс пользователя завершается, ввод от пользователя должен быть получен в формате «навыки чата, спросите текст [НАВЫК]», чтобы применить новый навык.
Тайм-аут сеанса по умолчанию составляет 1 час без ввода данных от пользователя. Чтобы изменить таймаут сеанса, установитеchatskills.timeout chatskills.timeout = 3600
, где значение указывается в секундах. Чтобы отключить тайм-аут сеанса, установите значение 0.
Имя чат-бота по умолчанию — «chatskills». Все запросы на выполнение навыка должны начинаться с имени чат-бота. Например, «Навыки общения, поздороваться, поздороваться». Чтобы настроить имя чат-бота, используйте следующее:
chatskills . name ( 'awesome' ) ;
Чтобы отображать предупреждения и ошибки, установитеchatskills.verbose chatskills.verbose = true
.
Chatskills использует приложение Alexa для генерации множества примеров высказываний на основе ваших намерений. Более подробное описание высказываний смотрите здесь.
Передайте объект с двумя свойствами: слотами и высказываниями.
app . intent ( 'sampleIntent' ,
{
"slots" : { "NAME" : "LITERAL" , "AGE" : "NUMBER" } ,
"utterances" : [ "my {name is|name's} {names|NAME} and {I am|I'm} {1-100|AGE}{ years old|}" ]
} ,
function ( request , response ) { ... }
) ;
Объект slots представляет собой простое сопоставление Имя:Тип. Тип должен быть одним из поддерживаемых Amazon типов слотов: LITERAL, NUMBER, DATE, TIME, DURATION.
В качестве замены типа слота LITERAL
, который больше не поддерживается Amazon, рекомендуется использовать вместо него специальные типы слотов. Вот пример определения пользовательского типа слота для DragonType
.
app . intent ( 'attack' ,
{
'slots' : { 'DragonType' : 'DRAGONTYPE' } ,
'utterances' : [ '{attack|fight|hit|use} {sword|dagger|wand} on {-|DragonType} dragon' ]
} , function ( request , response ) {
response . say ( 'You are attacking the ' + request . slot ( 'DragonType' ) + ' dragon!' ) ;
}
) ;
Вы можете включать в высказывания пользовательские типы слотов, используя синтаксис {-|CustomTypeName}
. Это означает, что термин должен быть взят из списка значений для типа пользовательского слота. В приведенном выше примере в высказывании используется термин {-|DragonType}
, указывающий, что термин должен быть взят из списка значений (показанного ниже). Для навыков чата не требуется предоставлять список значений — любое слово будет принято в качестве пользовательского типа слота и использовано в качестве его значения.
При публикации в сервисе Amazon Alexa вы должны предоставить пользовательские типы слотов для DragonType
указав имя типа и список значений. Например:
Тип: DRAGONTYPE
Ценности:
golden
fire
ice
water
snow
Обратите внимание: навыки чата и Amazon Alexa фактически принимают любое слово в качестве значения пользовательского слота. Оно не обязательно должно совпадать со словом из списка значений. В этом смысле пользовательские типы слотов аналогичны LITERAL
.
Синтаксис высказываний позволяет генерировать множество (сотни или даже тысячи) образцов высказываний, используя всего несколько образцов, которые автоматически расширяются. В массив высказываний можно передать любое количество образцов высказываний. Ниже приведены некоторые примеры макросов высказываний и то, до чего они будут расширены.
"my favorite color is {red|green|blue|NAME}"
=>
"my favorite color is {red|NAME}"
"my favorite color is {green|NAME}"
"my favorite color is {blue|NAME}"
Это позволяет вам определить несколько способов произнесения фразы, но объединить их в один образец высказывания.
"{what is the|what's the|check the} status"
=>
"what is the status"
"what's the status"
"check the status"
При захвате числового значения слота полезно сгенерировать множество образцов высказываний с разными числовыми значениями.
"buy {2-5|NUMBER} items"
=>
"buy {two|NUMBER} items"
"buy {three|NUMBER} items"
"buy {four|NUMBER} items"
"buy {five|NUMBER} items"
Диапазоны номеров также могут увеличиваться поэтапно.
"buy {5-20 by 5|NUMBER} items"
=>
"buy {five|NUMBER} items"
"buy {ten|NUMBER} items"
"buy {fifteen|NUMBER} items"
"buy {twenty|NUMBER} items"
"what is your {favorite |}color"
=>
"what is your color"
"what is your favorite color"
Несколько намерений могут использовать один и тот же список возможных значений, поэтому вам нужно определить их в одном месте, а не в каждой схеме намерений. Используйте словарь приложения.
app.dictionary = {"colors":["red","green","blue"]};
...
"my favorite color is {colors|FAVEORITE_COLOR}"
"I like {colors|COLOR}"
Вы можете отображать домашние карточки Amazon Alexa, обрабатывая объект карты, возвращаемый в методе ответа. При использовании приложения Alexa домашняя карточка будет отображаться в приложении Amazon Alexa на вашем мобильном устройстве. При использовании навыков чата домашняя карточка может обрабатываться в методе обратного вызоваchatskills.respond chatskills.respond()
, который возвращает два аргумента: response
и card
.
Используя объект карты, вы можете отображать текст и изображение карты любым удобным для вас способом. Например, если вы размещаете приложение для общения в Slack, вы можете захотеть отображать изображение как встроенный медиафайл. Аналогично, если вы размещаете текстовый чат-бот на консоли, вы можете просто вывести карточку в виде текста.
Ниже приведен пример.
app . intent ( 'example' , {
"slots" : { } ,
"utterances" : [ "show a card" ]
} , function ( req , res ) {
// Show home card in Alexa app.
res . card ( {
type : 'Standard' ,
title : 'My Awesome Card' , // this is not required for type Simple or Standard
text : 'This is an example of an Alexa home card.' ,
image : { // image is optional
smallImageUrl : 'http://www.yoursite.com/image.jpg' , // required
largeImageUrl : null
}
} ) ;
} ) ;
// Respond to input.
chatskills . respond ( text , function ( response , card ) {
if ( ! card ) {
// Text response from res.say() method.
console . log ( response ) ;
}
else {
// Home card response from res.card() method.
console . log ( '[DISPLAYING CARD: Title=' + card . title + ', Text=' + card . text + ']' ) ;
}
} ) ;
Массачусетский технологический институт
Кори Беккер http://www.primaryobjects.com/kory-becker