![](https://habrastorage.org/getpro/habr/upload_files/87f/b97/ddf/87fb97ddfebcba28ae99eea99b44f025.jpeg)
Предыстория
В сентябре 2020 года Сбер анонсировал семейство виртуальных ассистентов:
Сбер — мужской голос. Общается официально, к пользователю обращается на "Вы";
Афина — женский голос. Общается официально, к пользователю обращается на "Вы";
Джой — женский голос. Общается неофициально, к пользователю обращается на "Ты";
Тогда же запущен инструментарий разработчика SmartApp Studio - интерфейс для размещения собственного SmartApp в платформе SmartMarket.
SmartApp (смартап или в простонародии навык) — это приложение, которое расширяет возможности виртуального ассистента и может дать пользователю не только красивый интерфейс, но и множество способов взаимодействия с ним: голосом, касанием, текстовым вводом, пультом и даже виртуальным геймпадом.
В SmartApp Studio собраны инструменты для создания смартапа:
Graph — это визуальный конструктор для создания смартапов. Полезен тем разработчикам у которых нет опыта в программировании;
Code — среда разработки на языках SmartApp DSL и JavaScript. Для тех кто уже имеет опыт в программировании;
API — возможность вынести свой навык за пределы платформы;
24 сентября для сторонних разработчиков Сбером была запущена группа в ТГ @smartmarket_community. 3-го октября я сам присоединился к этой группе.
Выяснилось, что смартапы разделяются на типы:
Chat App - самый обычный и привычный сейчас тип. Текстовый чат между навыком и пользователем;
Canvas App - графический интерфейс. Пользователь взаимодействует с веб-интерфейсом;
Native App - Android-приложение;
Provider App - для нативного подключения контента и услуг;
Прочитав, к тому моменту, совсем скудную документацию всё же решил попробовать развернуть свой Chat App на SmartApp API.
Хоть я по профессии не программист, но у меня уже были свои навыки на другой платформе и API обеих платформ имеет сходство.
Мои навыки работают как раз по API, так как он даёт большую гибкость, ведь всё в твоих руках.
Что сразу понравилось
Не стану описывать процесс портирования навыка, так как это уже даже в документации есть (плюс можете посмотреть вот этот пример), а лишь опишу некоторые вещи, которые я тогда для себя отметил:
Голос выбирает ПОЛЬЗОВАТЕЛЬ, а не разработчик. Моё мнение как раз такое же, что выбор должен быть за пользователем. Ведь это он взаимодействует с ассистентом и навыком и ему лучше знать какой голос ему комфортнее слушать. Более того, голос ассистента можно сменить налету (даже внутри смартапа) просто позвав нужного вам ассистента. Для этого нужно сказать "позови <ИМЯ АССИСТЕНТА>" и всё. Узнать какой голос используется пользователем можно из объекта character.
У каждого ассистента не только свой голос, но и своя цветовая гамма.
auto_listening - возможность попросить ассистента включать или не включать микрофон после того как он озвучит ответ. Очень полезная штука.
emotion - возможность анимировать иконку ассистента. На текущий момент уже доступно 22 эмоции.
Отдельные типы сообщений при входе (RUN_APP) и при выходе (CLOSE_APP) пользователя из смартапа, а также сообщить платформе об ошибке (ERROR).
Возможность разбивать текст на экране на несколько блоков (bubble) для улучшения визуализации информации.
Для тестирования смартапов можно использовать приложение Сбер Салют (App Store, Google Play) на смартфоне или тестировать смартапы прямо на устройствах SberBox и SberPortal.
Даже если смартап ещё не прошел модерацию, то всегда есть возможность запустить его на том устройстве где вход выполнен под тем же Сбер ID, который использовался при создании навыка в SmartApp Studio. Также относительно недавно появилась возможность давать доступ к неопубликованному смартапу и другим людям. Для этого нужно просто скинуть им сгенерированную ссылку.
Совсем недавно была добавлена ещё одна классная фишка, которая тоже стала отличительной особенностью платформы - asr_hints.
Возможность подсказывать системе ASR (Automatic Speech Recognition) чего смартап ожидает от пользователя и исходить из этого при построении гипотез:
"asr_hints":{"words":["карту","достаточно","себе","беру","возьму","еще","передаю","ход"]}
С подсказками система распознавания работает значительно лучше. Проверено - работает!
Chat App
Выбор chat app был обусловлен тем, что на момент запуска платформы сanvas app ещё не был доступен для сторонних разработчиков.
Как сейчас пока ещё недоступен Native App (но уже скоро должен и он быть в доступе).
Не мало времени пришлось потратить на фразы смартапа, которые озвучивает ассистент. Ведь голос ассистента, а значит его пол, выбирается пользователем, а не разработчиком. Плюс к этом обращения на "Вы/Ты" тоже заняло некоторое время, но вот уже 12.10.2020 мой первый chat app прошёл модерацию, а затем был добавлен в каталог приложений.
![chat app chat app](https://habrastorage.org/getpro/habr/upload_files/749/c10/5f9/749c105f981e32189d7d727a7f8ca441.jpg)
Но, на тот момент у chat app не было возможности проигрывать звуки или показывать картинки. Поэтому я очень ждал запуска и возможности использовать canvas app, так как там такой проблемы не существовало. И вот уже в конце октября canvas app стал доступен для сторонних разработчиков.
Что такое Canvas App?
Canvas App – это web-приложение (среда исполнения браузер), управление которым реализуется через assistant-client.
Canvas App открывается внутри WebView (Android, iOS). HTML, CSS и JS (это frontend) загружается непосредственно в WebView на клиенте (SberBox, SberPortal, мобильное приложение Сбер Салют).
Чтобы не рисовать и не дублировать картинку-схему я взял её из этой статьи:
![](https://habrastorage.org/getpro/habr/upload_files/93f/86d/df5/93f86ddf5b36907e5595575fb0787e82.png)
Простыми словами как это работает:
пользователь запускает смартап;
его запрос через платформу прилетает в webhook смартапа (который был указан в настройках SmartApp Studio) в виде текста;
параллельно этому устройство пользователя загружает страницу (которая также была указан в настройках SmartApp Studio — Frontend Endpoint);
webhook и frontend между собой «общаются» посредством assistant-client;
frontend, реагируя на команды от webhook, меняет что-то на экране пользователя, а также сам может передать что-то на webhook, если пользователь совершит некое действие на странице;
Вот так выглядит создание canvas app (с использованием API) в SmartApp Studio:
![](https://habrastorage.org/getpro/habr/upload_files/927/7ad/eb2/9277adeb26af71d6d2e4a92895aaf1b0.png)
Что внутри у canvas app?
Webhook может передать данные в frontend с помощью объекта command:
"payload":{
"items":[
{
"command":{
"type":"smart_app_data",
"smart_app_data":{"myTest":"data"}
}
}
]
}
Данные, которые указаны значении ключа smart_app_data, будут переданы на frontend. Порекомендую обмениваться именно объектами, а не строками.
Существует две версии assistant-client:
версия для подключения на странице через script (пример можно увидеть тут)
Если ReactJS Вам не знаком, то самый быстрый способ подключить и попробовать assistant-client на frontend это использовать script:
<html>
<head>
<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@sberdevices/assistant-client@2.6.0/umd/assistant.min.js"></script>
</head>
<body>Это тест canvas app</body>
</html>
Такой способ подключения тоже был добавлен позднее запуска canvas app и Вы можете о нём не знать, но теперь он есть.
В этом примере подключение ReactJS нужно для работы самого assistant-client.
Как было сказано ранее assistant-client это "мост" между webhook и frontend и он не только обеспечивает работу canvas app, но и даёт нам возможность локального тестирования своих canvas app прямо в браузере на своём компьютере без использования SberBox, SberPortal или приложения Сбер Салют.Assistant-client как бы эмулирует конечное устройство пользователя в вашем браузере.
Добавим на страницу в body:
<div id="command"></div>
<script type="text/javascript">
var state = { };
const url = new URL(window.location.href);
if (url.searchParams.get('devel') === 'true'){
console.info('Start devel version');
var token = ''; // <- сюда вставляем токен из smartapp-studio (https://github.com/sberdevices/assistant-client/tree/main/examples/umd-example)
var initPhrase = 'запусти НАЗВАНИЕ ВАШЕГО СМАРТАПА'; // <- сюда вставляем активационную фразу своего canvas app
var ac = assistant.createSmartappDebugger({ getState: () => state, token, initPhrase });
}else{
console.info('Start production version');
var ac = assistant.createAssistant({ getState: () => state });
}
var processData = function(command){
console.info('got command',command);
document.getElementById('command').innerHTML = JSON.stringify(command);
}
ac.on('start', (command) => {
let initialData = ac.getInitialData();
for(let i=0; i < initialData.length; i++){
processData(initialData[i]);
}
});
ac.on('data', (command) => {
processData(command);
});
</script>
Благодаря assistant.createSmartappDebugger мы и получаем возможность использовать эту страницу локально и тестировать используя реального ассистента.
Открываем своим браузером URL (где расположена страница) и указываем параметр devel. Например: https://example.ru/frontend.html?devel=true
И если Вы всё сделали правильно, то открывшись страница запустит "мост" с платформой и Ваш смартап.
Ваш webhook получив запрос отправит smart_app_data и Вы увидите его содержимое на своём экране в div с id "command":
![](https://habrastorage.org/getpro/habr/upload_files/912/0a5/ed8/9120a5ed8e8ad0da626869f9e8ef9ade.png)
Вместо "покажи что-нибудь" можно ввести любой текст и он отправится на webhook точно так же если бы мы сказали это голосом.
ac.on('start',...) используется только на старте смартапа. Там мы получаем начальные данные. Например, какой ассистент используется пользователем и smart_app_data от нашего webhook.
Далее всё будет приходить в ac.on('data',...).
ВАЖНО:
Помните, что assistant.createSmartappDebugger используется ТОЛЬКО для тестирования. Во всех остальных случаях должен использоваться assistant.createAssistant.
Так наша страница стала реагировать на данные, которые получены от webhook в ac.on('data',...) и в функции processData вы можете их обрабатывать и менять что-то на странице в зависимости от пришедших данных. Например проиграть звук (с помощью Audio()) или отобразить картинку/видео.
Теперь нужно сделать обратную связь от frontend к webhook. Нужно это для того, чтобы мы смогли обработать какое-то действие пользователя на этой странице.
Например нажатие на кнопку. В приложении Сбер Салют и на Sberportal пользователь может нажать на кнопку пальцем (touch), а на SberBox пультом.
Добавляем кнопку в body страницы:
<button id="next">Далее</button>
В script делаем обработчик по нажатию этой кнопки с отправкой на webhook команды (для примера) в виде названия id элемента кнопки:
var el = document.getElementById("next");
el.addEventListener(
"click",
function(){
ac.sendData({ action: { action_id: el.id} });
},
false
);
Если пользователь нажмёт на такую кнопку, то согласно коду выше в webhook придет сообщение с типом SERVER_ACTION:
{
"messageId":1612645866245327000,
"sessionId":"130618ec-8cf5-4a64-83e6-29e0dc6deeb1",
"messageName":"SERVER_ACTION",
"payload":{
"server_action":{"action_id":"next"},
"message":{"original_message_name":"SERVER_ACTION"}
}
}
И таким образом можно обработать это сообщение на webhook согласно логике смартапа и webhook отправит на frontend свой ответ на эту команду.
В canvas app ограничений практически нет (на сегодняшний день известно лишь об ограничениях на использование localstorage, а также камеры и микрофона устройства).
Для одного из своих canvas app я даже применил websocket и это работает. Проблем с созданием многопользовательских сетевых canvas app у Вас не должно возникать.
Поле для вашего творчества практически безгранично.
Исходный код примера, который описан мной выше, можно скачать на github.
Отмечу, что благодаря существованию github pages Ваш frontend может быть размещён на github.
Так я создал canvas версию для своего chat app и при этом webhook у них один и тот же.
![canvas app canvas app](https://habrastorage.org/getpro/habr/upload_files/606/26c/965/60626c965bebf7f6833b20a1840d5b54.png)
Очевидно, что canvas app уже совсем другой уровень взаимодействия с пользователем и делает смартап более реалистичным.
Помните, что смартапы типа canvas app должны корректно отображаться на разных устройствах (SberBox, SberPortal и другие). Для этого необходимо проверять смартап на следующих разрешениях: 559x568, 768x400, 959x400, 1920x1080.
Настроить и протестировать эти разрешения можно в Chrome на вкладке Devices.
Планы
Мои дальнейшие планы это не только создать ещё несколько canvas app, но попробовать монетизировать смартап. SmartMarket предоставляет возможность встроить в смартап приём платежей от пользователей посредством API.
Заключение
В заключении хочу сказать несколько вещей:
при отладке canvas app не забывайте посматривать в консоль браузера (F12);
клиенты (устройства) кешируют страницу и поэтому рекомендую всегда выводить на экран номер версии;
на данный момент canvas app нельзя запустить только в приложении СберБанк Онлайн, но вскоре эта возможность появится и там;
стали появляться первые видео уроки от Сбера;
есть система тикетов где Вы можете заявить о проблеме или сделать запрос на новый функционал;
есть Community roadmap где можно посмотреть статусы тикетов;
напомню про само сообщество - @smartapp_studio;
Хочу сказать спасибо команде SberDevices за открытость (особенно за общие встречи с сообществом в zoom) и конечно за то, что прислушиваетесь к мнению сообщества. Это безусловно ваше преимущество перед другими.
Также хочу поблагодарить пользователей моего смартапа, благодаря которым я смог выиграть в первом этапе конкурса. Спасибо, что оценили мои старания.
Желаю всем успехов !