alice

package module
v0.3.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 27, 2022 License: MIT Imports: 14 Imported by: 0

README

alice GoDoc Go Report Card

Библиотека для создания навыков, расширяющих функциональность голосового помощника Алиса. Упрощает разработку навыков, оставляя возможность тонкой настройки. Преимущества библиотеки:

  • поддержка связки аккаунтов
  • объединение методов в цепочки при конструировании ответа
  • вспомогательные методы для оживления диалога
  • автоответ на служебные ping-пакеты

Установка или обновление

go get -u github.com/azzzak/alice

Пример

Простейший навык — говорит "привет", после чего повторяет каждую реплику пользователя.

package main

import (
  "net/http"

  "github.com/azzzak/alice"
)

func main() {
  updates := alice.ListenForWebhook("/hook")
  go http.ListenAndServe(":3000", nil)

  updates.Loop(func(k alice.Kit) *alice.Response {
    req, resp := k.Init()
    if req.IsNewSession() {
      return resp.Text("привет")
    }
    return resp.Text(req.OriginalUtterance())
  })
}

Детальный разбор примера смотрите в руководстве.

Цепочки методов

Позволяют конструировать ответ со всеми возможностями, которые предлагает Алиса: кнопки, картинки и звуки.

Пример. Ответ с текстом и TTS с паузой и звуком из библиотеки Алисы:

resp.Text("творог").
  TTS("твор+ог").
  Pause(3).
  Sound(sounds.Harp1)

Пример. Ответ со случайно выбранной строкой и двумя кнопками:

resp.RandomText("привет", "алоха").
  Button("хай", "", false).
  Button("отстань", "", false)

Пример. При любом num ответ остается согласованным:

resp.Text(fmt.Sprintf("%d %s пива %s на столе", num,
  alice.Plural(num, "бутылка", "бутылки", "бутылок"),
  alice.Plural(num, "стояла", "стояли", "стояло")).
  Sound(sounds.ThingsGlass1)

Навыки на базе библиотеки

Дневник здоровья
Дневник здоровья

Полезный Ждун
Полезный Ждун

Присылайте свои навыки на azzzak@yandex.ru

Documentation

Overview

Package alice реализует библиотеку для создания навыков, расширяющих функциональность голосового помощника Алиса от Яндекса.

Example
package main

import (
	"net/http"

	"github.com/azzzak/alice"
)

func main() {
	updates := alice.ListenForWebhook("/hook")
	go http.ListenAndServe(":3000", nil)

	updates.Loop(func(k alice.Kit) *alice.Response {
		req, resp := k.Init()
		if req.IsNewSession() {
			return resp.Text("привет")
		}
		return resp.Text(req.OriginalUtterance())
	})
}
Output:

Index

Examples

Constants

View Source
const (
	// NENameType именованная сущность с ФИО.
	NENameType = "YANDEX.FIO"

	// NELocationType именованная сущность с топонимом.
	NELocationType = "YANDEX.GEO"

	// NEDataTimeType именованная сущность с датой и временем.
	NEDataTimeType = "YANDEX.DATETIME"

	// NENumberType именованная сущность с числом.
	NENumberType = "YANDEX.NUMBER"
)
View Source
const (
	// BigImageType одна большая картинка.
	BigImageType = "BigImage"

	// ItemsListType список с картинками.
	ItemsListType = "ItemsList"
)
View Source
const (
	// SimpleUtterance простая реплика.
	SimpleUtterance = "SimpleUtterance"

	// ButtonPressed нажатие кнопки.
	ButtonPressed = "ButtonPressed"
)

Variables

This section is empty.

Functions

func AutoPong

func AutoPong(b bool) func(*Options)

AutoPong автоматический ответ на технические сообщения ping, проверяющие работоспособность навыка. По умолчанию включено.

func Debug

func Debug(b bool) func(*Options)

Debug показывает в консоле содержимое входящих и исходящих пакетов. По умолчанию отключено.

func Plural

func Plural(n int, singular, plural1, plural2 string) string

Plural помогает согласовать слово с числительным.

Example
package main

import (
	"fmt"

	"github.com/azzzak/alice"
)

func main() {
	num := 5
	fmt.Printf("%d %s пива %s на столе", num,
		alice.Plural(num, "бутылка", "бутылки", "бутылок"),
		alice.Plural(num, "стояла", "стояли", "стояло"))
}
Output:

5 бутылок пива стояло на столе

func Timeout

func Timeout(t int) func(*Options)

Timeout таймаут обработки запроса в миллисекундах. По истечении запрос перестает обрабатываться и навык отправляет ошибку. Значение по умолчанию 3000 мс — официальное время ожидания ответа навыка.

Types

type Button

type Button struct {
	Title   string      `json:"title"`
	URL     string      `json:"url,omitempty"`
	Payload interface{} `json:"payload,omitempty"`
	Hide    bool        `json:"hide,omitempty"`
}

Button структура кнопки.

func NewButton

func NewButton(title, url string, hide bool, payload ...interface{}) Button

NewButton создает кнопку. Payload может быть проигнорирован. Если задано больше одного payload используется только первый.

type Card

type Card struct {
	ImageID     string       `json:"image_id,omitempty"`
	Title       string       `json:"title,omitempty"`
	Description string       `json:"description,omitempty"`
	Button      *ImageButton `json:"button,omitempty"`

	Type   string `json:"type"`
	Header *struct {
		Text string `json:"text,omitempty"`
	} `json:"header,omitempty"`
	Items  []Image `json:"items,omitempty"`
	Footer *struct {
		Text   string       `json:"text,omitempty"`
		Button *ImageButton `json:"button,omitempty"`
	} `json:"footer,omitempty"`
}

Card структура для добавления в ответ картинок.

type Entities

type Entities map[string][]newrapper

Entities контейнер для передачи необработанных именованных сущностей.

func (Entities) DatesTimes

func (e Entities) DatesTimes() []NEDateTime

DatesTimes возвращает готовый к использованию массив именованных сущностей с датами и временем.

func (Entities) Locations

func (e Entities) Locations() []NELocation

Locations возвращает готовый к использованию массив именованных сущностей с топонимами.

func (Entities) Names

func (e Entities) Names() []NEName

Names возвращает готовый к использованию массив именованных сущностей с ФИО.

func (Entities) Numbers

func (e Entities) Numbers() []NumberWrapper

Numbers возвращает готовый к использованию массив именованных сущностей с числами.

type Entity

type Entity struct {
	Tokens struct {
		Start int `json:"start"`
		End   int `json:"end"`
	} `json:"tokens"`
	Type  string           `json:"type"`
	Value *json.RawMessage `json:"value"`
}

Entity структура прототипа именованной сущности в запросе.

type Handler

type Handler func(k Kit) *Response

Handler сигнатура функции, передаваемой методу Loop().

type Image

type Image struct {
	ImageID     string       `json:"image_id"`
	Title       string       `json:"title,omitempty"`
	Description string       `json:"description,omitempty"`
	Button      *ImageButton `json:"button,omitempty"`
}

Image структура картинки.

type ImageButton

type ImageButton struct {
	Title   string      `json:"title,omitempty"`
	URL     string      `json:"url,omitempty"`
	Payload interface{} `json:"payload,omitempty"`
}

ImageButton структура кнопки для добавления интерактивности картинке.

func NewImageButton

func NewImageButton(title, url string, payload ...interface{}) ImageButton

NewImageButton создает кнопку для добавления интерактивности картинке. Payload может быть проигнорирован. Если задано больше одного payload используется только первый.

type Kit

type Kit struct {
	Req  *Request
	Resp *Response
	// Ctx позволяет получить сигнал об истечении периода ожидания ответа.
	Ctx context.Context
	// contains filtered or unexported fields
}

Kit структура для передачи данных в главный цикл.

func (Kit) Init

func (k Kit) Init() (*Request, *Response)

Init получает входящий пакет и заготовку исходящего из данных запроса.

type List

type List struct {
	Images []Image
}

List хранилище картинок для создания списка.

func (*List) Add

func (l *List) Add(id, title, desc string, button ...ImageButton) *List

Add добавляет картинку в заготовку для списка. Кнопка может быть проигнорирована. Если задано больше одной кнопки используется только первая.

func (*List) AddImages

func (l *List) AddImages(images ...Image) *List

AddImages добавляет одну или несколько картинок в заготовку для списка.

type NEDateTime

type NEDateTime struct {
	Start, End        int
	Year              int  `json:"year,omitempty"`
	YearIsRelative    bool `json:"year_is_relative,omitempty"`
	Month             int  `json:"month,omitempty"`
	MonthIsRelative   bool `json:"month_is_relative,omitempty"`
	Day               int  `json:"day,omitempty"`
	DayIsRelative     bool `json:"day_is_relative,omitempty"`
	Hour              int  `json:"hour,omitempty"`
	HourIsRelative    bool `json:"hour_is_relative,omitempty"`
	Minute            int  `json:"minute,omitempty"`
	MinuterIsRelative bool `json:"minute_is_relative,omitempty"`
}

NEDateTime структура типа NEDataTimeType.

type NELocation

type NELocation struct {
	Start, End  int
	Country     string `json:"country,omitempty"`
	City        string `json:"city,omitempty"`
	Street      string `json:"street,omitempty"`
	HouseNumber string `json:"house_number,omitempty"`
	Airport     string `json:"airport,omitempty"`
}

NELocation структура типа NELocationType.

type NEName

type NEName struct {
	Start, End     int
	FirstName      string `json:"first_name,omitempty"`
	PatronymicName string `json:"patronymic_name,omitempty"`
	LastName       string `json:"last_name,omitempty"`
}

NEName структура типа NENameType.

type NENumber

type NENumber float32

NENumber структура типа NENumberType.

type NumberWrapper

type NumberWrapper struct {
	Start, End int
	Value      float32
}

NumberWrapper обертка для чисел из именованных сущностей.

type Options

type Options struct {
	AutoPong bool
	Timeout  time.Duration
	Debug    bool
}

Options структура с настройками.

type Phrase

type Phrase struct {
	Text string
	TTS  string
}

Phrase структура фразы.

func NewPhrase

func NewPhrase(text, tts string) Phrase

NewPhrase создает фразу с текстом и TTS.

type Request

type Request struct {
	Meta struct {
		Locale     string `json:"locale"`
		Timezone   string `json:"timezone"`
		ClientID   string `json:"client_id"`
		Interfaces struct {
			AccountLinking *struct{} `json:"account_linking"`
			Screen         *struct{} `json:"screen"`
		} `json:"interfaces"`
	} `json:"meta"`

	LinkingComplete *struct{} `json:"account_linking_complete_event,omitenpty"`

	Request struct {
		Command           string `json:"command"`
		OriginalUtterance string `json:"original_utterance"`
		Type              string `json:"type"`
		Markup            struct {
			DangerousContext *bool `json:"dangerous_context,omitempty"`
		} `json:"markup,omitempty"`
		Payload interface{} `json:"payload,omitempty"`
		NLU     struct {
			Tokens   []string `json:"tokens"`
			Entities []Entity `json:"entities,omitempty"`
		} `json:"nlu"`
	} `json:"request"`

	Session struct {
		New       bool   `json:"new"`
		MessageID int    `json:"message_id"`
		SessionID string `json:"session_id"`
		SkillID   string `json:"skill_id"`
		UserID    string `json:"user_id"`
	} `json:"session"`

	State struct {
		Session interface{} `json:"session,omitempty"`
	} `json:"state,omitempty"`

	Version string `json:"version"`
	Bearer  string
}

Request структура входящего сообщения.

func (*Request) AuthToken

func (req *Request) AuthToken() string

AuthToken токен, полученный при связке аккаунтов.

func (*Request) CanAccountLinking

func (req *Request) CanAccountLinking() bool

CanAccountLinking поддерживает ли устройство пользователя создание связки аккаунтов.

func (*Request) ClientID

func (req *Request) ClientID() string

ClientID идентификатор клиентского устройства или приложения. Не рекомендуется использовать.

func (*Request) Command

func (req *Request) Command() string

Command реплика пользователя, преобразованная Алисой. В частности, текст очищается от знаков препинания, а числительные преобразуются в числа.

func (*Request) DangerousContext

func (req *Request) DangerousContext() bool

DangerousContext флаг опасной реплики.

func (*Request) Entities

func (req *Request) Entities() (Entities, error)

Entities возвращает необработанные именованные сущности из запроса.

Example
package main

import (
	"fmt"
	"net/http"

	"github.com/azzzak/alice"
)

func main() {
	updates := alice.ListenForWebhook("/hook")
	go http.ListenAndServe(":3000", nil)

	updates.Loop(func(k alice.Kit) *alice.Response {
		req, resp := k.Init()

		entities, _ := req.Entities()
		for _, v := range entities.Names() {
			fmt.Printf("%+v\n", v)
		}
		for _, v := range entities.Locations() {
			fmt.Printf("%+v\n", v)
		}
		for _, v := range entities.DatesTimes() {
			fmt.Printf("%+v\n", v)
		}
		for _, v := range entities.Numbers() {
			fmt.Printf("%+v\n", v)
		}

		return resp.Text("ok")
	})
}
Output:

func (*Request) HasScreen

func (req *Request) HasScreen() bool

HasScreen имеет ли устройство пользователя экран.

func (*Request) IsLinkingComplete

func (req *Request) IsLinkingComplete() bool

IsLinkingComplete связка аккаунтов создана.

func (*Request) IsNewSession

func (req *Request) IsNewSession() bool

IsNewSession отправлена реплика в рамках нового разговора или уже начатого.

func (*Request) Locale

func (req *Request) Locale() string

Locale язык в формате POSIX.

func (*Request) MessageID

func (req *Request) MessageID() int

MessageID счетчик сообщений в рамках сессии.

func (*Request) OriginalUtterance

func (req *Request) OriginalUtterance() string

OriginalUtterance реплика пользователя без изменений.

func (*Request) Payload

func (req *Request) Payload() (map[string]interface{}, error)

Payload возвращает map[string]interface{} с данными, которые были переданы в Payload кнопки. Подходит для Payload, оформленного в виде json-объекта. Если Payload простая строка следует использовать метод PayloadString(). Если в запросе нет Payload возвращается ошибка.

Example
package main

import (
	"fmt"
	"net/http"

	"github.com/azzzak/alice"
)

func main() {
	updates := alice.ListenForWebhook("/hook")
	go http.ListenAndServe(":3000", nil)

	updates.Loop(func(k alice.Kit) *alice.Response {
		req, resp := k.Init()

		// payload вида {"msg":"ok","n":42}
		payload, err := req.Payload()
		if err == nil {
			fmt.Println(payload["msg"].(string))
			fmt.Println(payload["n"].(int))
		}

		return resp.Text("ok")
	})
}
Output:

func (*Request) PayloadString

func (req *Request) PayloadString() (string, error)

PayloadString возвращает строку, которая была передана в Payload кнопки. Для сложных объектов следует использовать метод Payload(). Если в запросе нет Payload возвращается ошибка.

Example
package main

import (
	"fmt"
	"net/http"

	"github.com/azzzak/alice"
)

func main() {
	updates := alice.ListenForWebhook("/hook")
	go http.ListenAndServe(":3000", nil)

	updates.Loop(func(k alice.Kit) *alice.Response {
		req, resp := k.Init()

		payload, err := req.PayloadString()
		if err == nil {
			fmt.Println(payload)
		}

		return resp.Text("ok")
	})
}
Output:

func (*Request) SessionID

func (req *Request) SessionID() string

SessionID идентификатор сессии.

func (*Request) SkillID

func (req *Request) SkillID() string

SkillID идентификатор навыка.

func (*Request) StateSession

func (req *Request) StateSession(key string) interface{}

State.Session Состояние сессии.

func (*Request) StateSessionAsJson

func (req *Request) StateSessionAsJson() (string, error)

State.Session Состояние сессии json строкой

func (*Request) Text

func (req *Request) Text() string

Text синоним метода OriginalUtterance().

func (*Request) Timezone

func (req *Request) Timezone() string

Timezone название часового пояса.

func (*Request) Tokens

func (req *Request) Tokens() []string

Tokens массив слов из реплики.

func (*Request) Type

func (req *Request) Type() string

Type тип запроса (реплика или нажатие кнопки).

func (*Request) UserID

func (req *Request) UserID() string

UserID идентификатор пользователя.

func (*Request) Ver

func (req *Request) Ver() string

Ver версия протокола.

type Response

type Response struct {
	Response *struct {
		Text       string   `json:"text"`
		TTS        string   `json:"tts,omitempty"`
		Card       *Card    `json:"card,omitempty"`
		Buttons    []Button `json:"buttons,omitempty"`
		EndSession bool     `json:"end_session"`
	} `json:"response,omitempty"`
	Text_       string   `json:"text"`
	TTS_        string   `json:"tts,omitempty"`
	Card_       *Card    `json:"card,omitempty"`
	Buttons_    []Button `json:"buttons,omitempty"`
	EndSession_ bool     `json:"end_session"`

	StartAccountLinking *struct{} `json:"start_account_linking,omitempty"`

	Session struct {
		MessageID int    `json:"message_id"`
		SessionID string `json:"session_id"`
		UserID    string `json:"user_id"`
	} `json:"session"`

	SessionState interface{} `json:"session_state,omitempty"`

	Version string `json:"version"`
}

Response структура исходящего сообщения.

func (*Response) AddSessionState

func (resp *Response) AddSessionState(key string, data interface{}) error

AddSessionState добавляет па

func (*Response) BigImage

func (resp *Response) BigImage(id, title, desc string, button ...ImageButton) *Response

BigImage добавляет к ответу одну большую картинку. Кнопка может быть проигнорирована. Если задано больше одной кнопки используется только первая. Требуемые размеры изображения: 1x — 388x172, 1.5x — 582x258, 2x — 776x344, 3x — 1164x516, 3.5x — 1358x602, 4x — 1552x688.

Example
package main

import (
	"net/http"

	"github.com/azzzak/alice"
)

func main() {
	updates := alice.ListenForWebhook("/hook")
	go http.ListenAndServe(":3000", nil)

	updates.Loop(func(k alice.Kit) *alice.Response {
		_, resp := k.Init()

		return resp.BigImage("111111/00000000000000000000", "image", "desc")
	})
}
Output:

Example (Button)
package main

import (
	"net/http"

	"github.com/azzzak/alice"
)

func main() {
	updates := alice.ListenForWebhook("/hook")
	go http.ListenAndServe(":3000", nil)

	updates.Loop(func(k alice.Kit) *alice.Response {
		_, resp := k.Init()

		b := alice.NewImageButton("кнопка", "https://yandex.ru")
		return resp.BigImage("111111/00000000000000000000", "image", "desc", b)
	})
}
Output:

func (*Response) Button

func (resp *Response) Button(title, url string, hide bool, payload ...interface{}) *Response

Button создает кнопку и добавляет ее в ответ. Payload может быть проигнорирован. Если задано больше одного payload используется только первый.

func (*Response) Buttons

func (resp *Response) Buttons(buttons ...Button) *Response

Buttons добавляет одну или несколько кнопок в ответ.

func (*Response) CustomSound

func (resp *Response) CustomSound(skill, sound string) *Response

CustomSound добавляет к TTS собственный звук.

func (*Response) Effect

func (resp *Response) Effect(effect string) *Response

Effect накладывает звуковой эффект на TTS.

func (*Response) EndSession

func (resp *Response) EndSession() *Response

EndSession флаг о закрытии сессии.

func (*Response) List

func (resp *Response) List(header, footer string, l List, button ...ImageButton) *Response

List добавляет к ответу список с картинками. Кнопка может быть проигнорирована. Если задано больше одной кнопки используется только первая.

Example
package main

import (
	"net/http"

	"github.com/azzzak/alice"
)

func main() {
	updates := alice.ListenForWebhook("/hook")
	go http.ListenAndServe(":3000", nil)

	updates.Loop(func(k alice.Kit) *alice.Response {
		_, resp := k.Init()

		var list alice.List
		list.Add("111111/00000000000000000000", "image1", "desc1")
		list.Add("222222/00000000000000000000", "image2", "desc2")
		list.Add("333333/00000000000000000000", "image3", "desc3")

		return resp.Text("список").List("список", "подвал", list)
	})
}
Output:

func (*Response) NoEffect

func (resp *Response) NoEffect() *Response

NoEffect отключает наложенный на TTS эффект.

func (*Response) Pause

func (resp *Response) Pause(n int) *Response

Pause добавляет паузу к TTS (знак "-").

func (*Response) Phrase

func (resp *Response) Phrase(p ...Phrase) *Response

Phrase добавляет к тексту и TTS ответа данные фразы.

func (*Response) RandomPhrase

func (resp *Response) RandomPhrase(p ...Phrase) *Response

RandomPhrase добавляет к тексту и TTS ответа данные случайной фразы из числа предложенных.

func (*Response) RandomText

func (resp *Response) RandomText(s ...string) *Response

RandomText добавляет к текстовому ответу случайную строку из числа предложенных.

func (*Response) ResetTTS

func (resp *Response) ResetTTS() *Response

ResetTTS обнуляет TTS.

func (*Response) ResetText

func (resp *Response) ResetText() *Response

ResetText обнуляет текстовый ответ.

func (*Response) S

func (resp *Response) S() *Response

S синоним метода Space().

func (*Response) Sound

func (resp *Response) Sound(sound string) *Response

Sound добавляет к TTS звук из библиотеки Алисы.

func (*Response) Space

func (resp *Response) Space() *Response

Space добавляет пробел к текстовому ответу.

func (*Response) StartAuthorization

func (resp *Response) StartAuthorization() *Response

StartAuthorization начать создание связки аккаунтов и показать пользователю карточку авторизации.

func (*Response) TTS

func (resp *Response) TTS(tts ...string) *Response

TTS добавляет строку к TTS. Если передано несколько строк, они будут разделены пробелом.

func (*Response) Text

func (resp *Response) Text(s ...string) *Response

Text добавляет строку к текстовому ответу. Если передано несколько строк, они будут разделены пробелом.

func (*Response) TextWithTTS

func (resp *Response) TextWithTTS(s, tts string) *Response

TextWithTTS добавляет строки к текстовому ответу и к TTS.

type Stream

type Stream <-chan Kit

Stream канал, передающий данные в основной цикл.

func ListenForWebhook

func ListenForWebhook(hook string, opts ...func(*Options)) Stream

ListenForWebhook регистрирует обработчик входящих пакетов.

Example
package main

import (
	"net/http"

	"github.com/azzzak/alice"
)

func main() {
	updates := alice.ListenForWebhook("/hook", alice.Debug(true))
	go http.ListenAndServe(":3000", nil)

	updates.Loop(func(k alice.Kit) *alice.Response {
		_, resp := k.Init()
		return resp.Text("ok")
	})
}
Output:

func (Stream) Loop

func (updates Stream) Loop(f Handler)

Loop отвечает за работу главного цикла.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL