Documentation ¶
Overview ¶
Package marusia для создания скилла Маруси.
Для голосового помощника Маруси теперь можно создавать скиллы, которые пополнят её базу навыков. Пользователям будет удобнее общаться с Марусей, а разработчики и владельцы бизнеса смогут сделать голосовой интерфейс для своих продуктов.
Документация: https://dev.vk.com/ru/marusia/getting-started
Регистрация приложения ВКонтакте ¶
Скилл можно создать в разделе для разработчиков: https://vk.com/editapp?act=create. В день можно создать не более 3-х скиллов, и не более 10-и за 5 дней.
Для этого:
1. Выберите «Скилл Маруси» в типах приложения;
2. Добавьте название, которое будет совпадать с командой для активации скилла;
3. Введите в поле Webhook URL адрес сервера, по которому будет размещен навык, например https://example.com/test-webhook;
4. Подтвердите действие.
Вы попадёте в интерфейс администрирования Вашего скилла.
Обратите внимание: имя является первой фразой-триггером для вызова скилла.
Фразы ¶
Фразы для вызова скилла должны быть специфичны и уникальны, чтобы мы могли использовать их для внешних скиллов. Например, фразу «Расскажи анекдот» добавить не сможем, т.к. она уже используется во внутренних скиллах Маруси. А вот фразу «Давай сделаем кодревью» — пока можно использовать для внешнего скилла.
Длина фразы активации не может превышать 64 символа.
Фраза вызова скилла строится по следующей схеме:
Слово «Маруся» + любая из дефолтных фраз вызова скилла + фраза активации.
Дефолтные фразы вызова скилла:
хочу скилл/навык запусти скилл/навык включи скилл/навык открой скилл/навык
Примеры: «Маруся, запусти навык шутка дня», «Маруся, включи скилл шутка дня».
Схема взаимодействия со скиллом ¶
1. Пользователь произносит фразу для вызова скилла.
2. Получив и распознав выражение, сервер Маруси отправляет POST-запрос на Webhook URL, который вы указали в настройках.
3. Обработчик скилла должен ответить на полученный от сервера Маруси запрос. Таймаут ожидания ответа — 5 секунд, после чего сервер Маруси завершит сессию.
При создании скилла по умолчанию доступ к нему имеют только его администраторы. Для того, чтобы проверить скилл, авторизуйтесь в приложении Маруси для Android или iOS через VK Connect, используя номер, привязанный к учётной записи ВКонтакте.
Запустить скилл можно как голосовой командой, так и при помощи чата в приложении.
Также протестировать и отладить скилл можно в отладчике скиллов https://skill-debugger.marusia.mail.ru/
Если тестируется навык, развернутый локально, отладчик скорее всего столкнется с ограничениями, накладываемыми браузером на выполнение CORS.
В этом случае необходимо добавить в webhook поддержку предварительного запроса (метод OPTIONS) и проброс CORS-заголовков:
wh.EnableDebuging()
Пример ¶
Пример скилла.
type myPayload struct { Text string marusia.DefaultPayload } wh := marusia.NewWebhook() // wh.EnableDebuging() wh.OnEvent(func(r marusia.Request) (resp marusia.Response) { switch r.Request.Type { case marusia.SimpleUtterance: switch r.Request.Command { case marusia.OnStart: resp.Text = "Скилл запущен" resp.TTS = "Скилл запущен, жду команд" case "картинка": resp.Card = marusia.NewBigImage( "Заголовок", "Описание", 457239017, ) case "картинки": resp.Card = marusia.NewImageList( 457239017, 457239018, ) case "кнопки": resp.Text = "Держи кнопки" resp.TTS = "Жми на кнопки" resp.AddURL("ссылка", "https://vk.com") resp.AddButton("подсказка без нагрузки", nil) resp.AddButton("подсказка с нагрузкой", myPayload{ Text: "test", }) case "ссылка": resp.Text = marusia.CreateDeepLink( "e7a7d540-3928-4f11-87bf-a0de1244c096", map[string]string{"Text": "нагрузка из ссылки"}, ) resp.TTS = "Держи диплинк" case "пуш": resp.Text = `Держи пуш` resp.TTS = `Отправила пуш на устройство` resp.Push.PushText = "Hello, i am push" case marusia.OnInterrupt: resp.Text = "Скилл закрыт" resp.TTS = "Пока" resp.EndSession = true default: resp.Text = "Неизвестная команда" resp.TTS = "Я вас не поняла" } case marusia.ButtonPressed: var p myPayload err := json.Unmarshal(r.Request.Payload, &p) if err != nil { resp.Text = "Что-то пошло не так" return } resp.Text = "Кнопка нажата. Полезная нагрузка: " + p.Text resp.TTS = "Вы нажали на кнопку" case marusia.DeepLink: var p myPayload err := json.Unmarshal(r.Request.Payload, &p) if err != nil { resp.Text = "Что-то пошло не так" return } resp.Text = "Специальная ссылка. Полезная нагрузка: " + p.Text resp.TTS = "Вы перешли по ссылке" } return }) http.HandleFunc("/", wh.HandleFunc) http.ListenAndServe(":8080", nil)
Index ¶
- Constants
- func CreateDeepLink(marusiaID string, params map[string]string) string
- func SpeakerAudio(name string) string
- func SpeakerAudioVKID(id string) string
- type Application
- type ArrayResponse
- type AudioMeta
- type AudioPlayer
- type AudioPlaylist
- type AudioStream
- type BindingType
- type Button
- type Card
- type CardItem
- type CardType
- type ClientPlayerStatus
- type DefaultPayload
- type Interfaces
- type Meta
- type NLU
- type Push
- type Request
- type RequestIn
- type RequestType
- type Response
- type Screen
- type Session
- type State
- type User
- type Webhook
Examples ¶
Constants ¶
const ( // OnStart команда запуска скилла. В скилл будет передана пустая строка // Command = "". OnStart = "" // OnInterrupt команда завершении скилла по команде "стоп", "выход" и т.д. в // скилл будет передано Command = "on_interrupt", чтобы у скилла была // возможность попрощаться с пользователем. OnInterrupt = "on_interrupt" )
Типичные команды голосового ввода.
const Version = "1.0"
Version версия протокола.
Variables ¶
This section is empty.
Functions ¶
func CreateDeepLink ¶ added in v2.11.0
CreateDeepLink returns a link to go to the skill, as well as transfer data to your skill.
func SpeakerAudio ¶ added in v2.10.0
SpeakerAudio произносимый Марусей текст можно разнообразить звуковыми эффектами, которые входят в её библиотеку звуков.
Список звуков можно найти на странице https://dev.vk.com/ru/marusia/sound
Example ¶
package main import ( "fmt" "github.com/SevereCloud/vksdk/v2/marusia" ) func main() { tts := fmt.Sprintf( "Поздравляю! %s Вы правильно ответили на все мои вопросы!", marusia.SpeakerAudio("marusia-sounds/game-win-1"), ) fmt.Println(tts) }
Output: Поздравляю! <speaker audio="marusia-sounds/game-win-1"> Вы правильно ответили на все мои вопросы!
func SpeakerAudioVKID ¶ added in v2.10.0
SpeakerAudioVKID существует возможность вставлять в произносимую речь собственные звуки. Для этого необходимо на странице редактирования скилла воспользоваться формой загрузки медиафайлов. Загруженный аудиофайл будет доступен только для использования в вашем навыке.
Example ¶
package main import ( "fmt" "github.com/SevereCloud/vksdk/v2/marusia" ) func main() { tts := "Угадайте, чей это голос? " + marusia.SpeakerAudioVKID("-2000000002_123456789") fmt.Println(tts) }
Output: Угадайте, чей это голос? <speaker audio_vk_id="-2000000002_123456789">
Types ¶
type Application ¶ added in v2.10.0
type Application struct { // Идентификатор экземпляра приложения, в котором пользователь общается // с Марусей (максимум 64 символа). Уникален в разрезе: скилл + приложение // (устройство). ApplicationID string `json:"application_id"` // Тип приложения (устройства). Возможные варинты: mobile, speaker, other. ApplicationType string `json:"application_type"` }
Application данные об экземпляре приложения.
type ArrayResponse ¶ added in v2.16.1
type ArrayResponse struct { Text []string `json:"text"` TTSType string `json:"tts_type,omitempty"` SSML string `json:"ssml,omitempty"` TTS string `json:"tts,omitempty"` Buttons []Button `json:"buttons,omitempty"` Push Push `json:"push,omitempty"` EndSession bool `json:"end_session"` Card *Card `json:"card,omitempty"` AudioPlayer *AudioPlayer `json:"audio_player,omitempty"` SessionState json.RawMessage `json:"session_state,omitempty"` UserStateUpdate json.RawMessage `json:"user_state_update,omitempty"` }
ArrayResponse данные для ответа пользователю с массивом строк. Является копией Response, но имеет отличия в поле Text.
type AudioMeta ¶ added in v2.11.0
type AudioMeta struct { // Заголовок аудиозаписи. Title string `json:"title"` // Подзаголовок аудиозаписи. SubTitle string `json:"sub_title"` // ссылка на обложку композиции Art struct { URL string `json:"url"` } `json:"art"` }
AudioMeta описание дополнительной информации об аудиозаписи (название аудио, обложка и тд.).
type AudioPlayer ¶ added in v2.11.0
type AudioPlayer struct { // Номер начального аудио (нумерация с 0). SeekTrack int `json:"seek_track,omitempty"` // С какой секунды аудио под номером seek_track начинать SeekSecond int `json:"seek_second,omitempty"` Playlist []AudioPlaylist `json:"playlist"` }
AudioPlayer структура аудиоплеера состоит из плейлиста, в котором содержатся объекты для описания каждого трека внутри плейлиста, а также двух опциональных полей, в которых указывается с какого трека и с какой секунды начинать.
Важно: в плейлисте могут содержаться объекты только с одинаковым source_type, т.е не может быть плейлиста, состоящего из аудио из вк и получаемых по url.
type AudioPlaylist ¶ added in v2.11.0
type AudioPlaylist struct { Stream AudioStream `json:"stream"` Meta AudioMeta `json:"meta,omitempty"` }
AudioPlaylist структура, отвечающая за описание того откуда брать информацию о треке.
type AudioStream ¶ added in v2.11.0
type AudioStream struct { // ID аудио внутри плейлиста, должен быть уникальным для каждого аудио. TrackID string `json:"track_id"` // Тип источника аудиозаписи. Может иметь 2 значения url и vk. // source_type url доступен только после одобрения со стороны // разработчиков Маруси. source_type vk доступен для любых скиллов // // В случае передачи аудио через source_type vk, meta информация будет // взята из VK, если поле meta не передано и непосредственно из поля meta, // если оно передано. SourceType string `json:"source_type"` // Источник аудиозаписи. В случае source_type url представляет ссылку на // аудиозапись, в случае source_type vk представляет собой audio_vk_id // аудиозаписи VK. Source string `json:"source"` }
AudioStream описание информации об аудиозаписи.
type BindingType ¶
type BindingType string
BindingType тип для DefaultPayload.
const (
BindingTypeSuggest BindingType = "suggest"
)
Возможные значения.
type Button ¶
type Button struct { // Текст кнопки, максимум 64 символа. Title string `json:"title"` // URL, который откроется при нажатии на кнопку, максимум 1024 байта. // Если свойство url не указано, по нажатию на кнопку навыку будет // отправлен текст кнопки. Пока кнопки с url поддерживаются только // на Android, на iOS появятся совсем скоро. URL string `json:"url,omitempty"` // Любой JSON, который нужно отправить скиллу, если данная кнопка будет // нажата, максимум 4096 байт. Payload interface{} `json:"payload,omitempty"` }
Button кнопка.
type Card ¶
type Card struct { // Тип карточки. Type CardType `json:"type"` // Заголовок изображения или ссылки. Title string `json:"title,omitempty"` // Описание ссылки. Text string `json:"text,omitempty"` // Описание изображения. // // Deprecated: исчезло из документации. Description string `json:"description,omitempty"` // ID изображения из раздела "Медиа-файлы" в настройках скилла // (игнорируется для типа ItemsList). ImageID int `json:"image_id,omitempty"` // Список изображений, каждый элемент является объектом формата BigImage. Items []CardItem `json:"items,omitempty"` // Ссылка для карточки типа Link. Для карточки типа MiniApp адрес мини-приложения. URL string `json:"url,omitempty"` }
Card описание карточки — сообщения с поддержкой изображений.
func NewBigImage ¶
NewBigImage возвращает карточку с картинкой.
func NewImageList ¶ added in v2.1.0
NewImageList возвращает карточку с набором картинок.
func NewItemsList ¶ added in v2.1.0
NewItemsList возвращает карточку с набором картинок.
func NewMiniApp ¶ added in v2.10.0
NewMiniApp возвращает карточку vk miniapp'а.
type CardItem ¶ added in v2.1.0
type CardItem struct { // ID изображения из раздела "Медиа-файлы" в настройках скилла. ImageID int `json:"image_id"` }
CardItem элемент карточки.
type ClientPlayerStatus ¶ added in v2.11.0
type ClientPlayerStatus struct { TrackNumber int `json:"track_number"` Elapsed float64 `json:"elapsed"` Duration float64 `json:"duration"` TrackID int `json:"track_id"` }
ClientPlayerStatus плеер статус.
type DefaultPayload ¶
type DefaultPayload struct { BindingType BindingType `json:"binding_type"` Index int `json:"index"` TargetPhraseID string `json:"target_phrase_id"` }
DefaultPayload дефолтная нагрузка.
type Interfaces ¶
type Interfaces struct { // Пользователь может видеть ответ скилла на экране и открывать ссылки // в браузере. Screen *Screen `json:"screen,omitempty"` }
Interfaces интерфейсы, доступные на устройстве пользователя.
func (*Interfaces) IsScreen ¶
func (i *Interfaces) IsScreen() bool
IsScreen пользователь может видеть ответ скилла на экране и открывать ссылки в браузере.
type Meta ¶
type Meta struct { // Идентификатор клиентского приложения ClientID string `json:"client_id"` // Язык в POSIX-формате, максимум 64 символа. Locale string `json:"locale"` // Название часового пояса, включая алиасы, максимум 64 символа Timezone string `json:"timezone"` // Интерфейсы, доступные на устройстве пользователя. Interfaces Interfaces `json:"interfaces"` // Город пользователя на русском языке. CityRu string `json:"_city_ru,omitempty"` // Плеер статус. ClientPlayerStatus ClientPlayerStatus `json:"client_player_status,omitempty"` // Если true, то запрос к скиллу технический (не от реального пользователя) Test bool `json:"test,omitempty"` }
Meta информация об устройстве, с помощью которого пользователь общается с Марусей.
type Push ¶ added in v2.12.0
type Push struct { // Текст пуша, максимум 64 символа. PushText string `json:"push_text"` // Любой JSON, который нужно отправить скиллу, если данный пуш будет // нажат, максимум 4096 байт. Payload interface{} `json:"payload,omitempty"` }
Push уведомления это удобный механизм для передачи сообщений пользователю, к примеру, если пользователь использует умную колонку с Марусей, вы можете послать ему push, при нажатии на который, откроется любой ответ от вашего навыка (к примеру картинка).
При клике на push, в навык придет запрос с указанным payload по протоколу диплинка.
type Request ¶
type Request struct { // Информация об устройстве, с помощью которого пользователь общается с Марусей. Meta Meta `json:"meta"` // Данные, полученные от пользователя. Request RequestIn `json:"request"` // Данные о сессии. Session Session `json:"session"` // Хранение состояния. State State `json:"state"` // Версия протокола. Version string `json:"version"` }
Request структура запроса.
type RequestIn ¶
type RequestIn struct { // Служебное поле: запрос пользователя, преобразованный для внутренней // обработки Марусей. В ходе преобразования текст, в частности, очищается // от знаков препинания, а числительные преобразуются в числа. При // завершении скилла по команде "стоп", "выход" и т.д. в скилл будет // передано "on_interrupt", чтобы у скилла была возможность попрощаться с // пользователем. Command string `json:"command"` // Полный текст пользовательского запроса, максимум 1024 символа. OriginalUtterance string `json:"original_utterance"` // Тип ввода. Type RequestType `json:"type"` // JSON, полученный с нажатой кнопкой от обработчика скилла (в ответе на // предыдущий запрос), максимум 4096 байт. Передаётся, только если была // нажата кнопка с payload. Payload json.RawMessage `json:"payload,omitempty"` // Объект, содержащий слова и именованные сущности, которые Маруся // извлекла из запроса пользователя. NLU *NLU `json:"nlu"` }
RequestIn данные, полученные от пользователя.
type RequestType ¶
type RequestType string
RequestType тип ввода.
const ( SimpleUtterance RequestType = "SimpleUtterance" // голосовой ввод ButtonPressed RequestType = "ButtonPressed" // нажатие кнопки DeepLink RequestType = "DeepLink" )
Возможные значения.
type Response ¶
type Response struct { // Текст, который следует показать и сказать пользователю. Максимум 1024 // символа. В тексте ответа можно указать переводы // строк последовательностью «\n». Используется, если вам не нужен // массив строк. Text string `json:"text"` // Текст, который следует показать пользователю. Максимум 1024 // символа в элементе массива. Должен быть заполнен при пустом Text. // В тексте ответа можно указать переводы строк последовательностью «\n». // Используется, если вам нужен массив строк. Если в массиве более // одного элемента, то сообщения разобьются на баблы. TextArray []string `json:"text_array,omitempty"` // Для того, чтобы передать SSML в ответе из внешнего скилла, // необходимо передать "ssml". TTSType string `json:"tts_type,omitempty"` // Speech Synthesis Markup Language представляет собой основанный // на XML язык разметки для приложений синтеза речи. SSML string `json:"ssml,omitempty"` // Ответ в формате TTS (text-to-speech), максимум 1024 символа. // Поддерживается расстановка ударений с помощью '+'. TTS string `json:"tts,omitempty"` // Кнопки (suggest'ы), которые следует показать пользователю. Кнопки можно // использовать как релевантные ответу ссылки или подсказки для // продолжения разговора. Buttons []Button `json:"buttons,omitempty"` // Push уведомление. Push Push `json:"push,omitempty"` // Признак конца разговора: // // true — сессию следует завершить, // // false — сессию следует продолжить. EndSession bool `json:"end_session"` // Описание карточки — сообщения с поддержкой изображений. // Важно! Если указано данное поле, то поле text игнорируется. Card *Card `json:"card,omitempty"` // Плеер. AudioPlayer *AudioPlayer `json:"audio_player,omitempty"` // Для сохранения состояния внутри сессии. // При этом, если в очередном ответе не записать данные, даже если они не // изменились, то они затрутся, и в следующем запросе поле будет пустым. // Помимо этого, состояние потеряется если: // // Пользователь выходит из скилла; // // Скилл сам явно завершает работу, передав EndSession: true; // // Выход происходит по таймауту, когда пользователь не отвечает некоторое // время (1 минуту). // // Лимит размера json-объекта - 5 КБ. SessionState json.RawMessage `json:"session_state,omitempty"` // Для персистентного хранения данных о юзере. // Чтобы удалить конкретное поле из сохранённого json-объекта, нужно // положить null в это поле. // Лимит размера json-объекта - 5 КБ. UserStateUpdate json.RawMessage `json:"user_state_update,omitempty"` }
Response данные для ответа пользователю.
func (*Response) AddButton ¶
AddButton добавляет к ответу кнопку с полезной нагрузкой.
Если полезная нагрузка не нужна, можно передать nil.
func (*Response) ResponseWithTextArray ¶ added in v2.16.1
func (r *Response) ResponseWithTextArray() (ArrayResponse, error)
ResponseWithTextArray возвращает измененную структуру Response
Функция реализована для поддержки массива строк в тексте с учётом обратной совместимости, она изменяет итоговую структуру так, чтобы в `json:"text" оказался массив строк и пользователь получил несколько баблов с текстом. При условии, что поле Text оригинальной структуры не задано.
type Session ¶
type Session struct { // Уникальный идентификатор сессии, максимум 64 символа. SessionID string `json:"session_id"` // Идентификатор экземпляра приложения, в котором пользователь общается с // Марусей, максимум 64 символа. // // Deprecated: Важно! Это поле устарело, вместо него стоит использовать // Session.Application.ApplicationID. UserID string `json:"user_id"` // Идентификатор вызываемого скилла, присвоенный при создании. // Соответствует полю "Маруся ID" в настройках скилла. SkillID string `json:"skill_id"` // Признак новой сессии: // // true — пользователь начинает новый разговор с навыком, // // false — запрос отправлен в рамках уже начатого разговора. New bool `json:"new"` // Идентификатор сообщения в рамках сессии, максимум 8 символов. // Инкрементируется с каждым следующим запросом. MessageID int `json:"message_id"` // Данные о пользователе. Передаётся, только если пользователь // авторизован. User User `json:"user"` // Данные об экземляре приложения. Application Application `json:"application"` }
Session данные о сессии.
type State ¶ added in v2.10.0
type State struct { // Хранение данных в сессии. Session json.RawMessage `json:"session"` // Персистентное хранение данных. User json.RawMessage `json:"user"` }
State данные состояния.
type User ¶ added in v2.10.0
type User struct { // Идентификатор аккаунта пользователя (максимум 64 символа). // Уникален в разрезе: скилл + аккаунт. UserID string `json:"user_id"` }
User данные о пользователе.
type Webhook ¶
type Webhook struct {
// contains filtered or unexported fields
}
Webhook структура.
func (*Webhook) EnableDebuging ¶ added in v2.11.0
func (wh *Webhook) EnableDebuging()
EnableDebuging включает CORS для https://skill-debugger.marusia.mail.ru
func (*Webhook) HandleFunc ¶
func (wh *Webhook) HandleFunc(w http.ResponseWriter, r *http.Request)
HandleFunc обработчик http запросов.