Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(response): добавлена поддержка массива строк в тексте #249

Merged
merged 2 commits into from
Apr 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 49 additions & 4 deletions marusia/skill.go
Original file line number Diff line number Diff line change
Expand Up @@ -472,12 +472,18 @@ type AudioMeta struct {
// Response данные для ответа пользователю.
type Response struct {
// Текст, который следует показать и сказать пользователю. Максимум 1024
// символа. Не должен быть пустым. В тексте ответа можно указать переводы
// строк последовательностью «\n».
//
// TODO: поддержка массива строк.
// символа. В тексте ответа можно указать переводы
// строк последовательностью «\n». Используется, если вам не нужен
// массив строк.
Text string `json:"text"`

// Текст, который следует показать пользователю. Максимум 1024
// символа в элементе массива. Должен быть заполнен при пустом Text.
// В тексте ответа можно указать переводы строк последовательностью «\n».
// Используется, если вам нужен массив строк. Если в массиве более
// одного элемента, то сообщения разобьются на баблы.
TextArray []string `json:"text_array,omitempty"`

// Для того, чтобы передать SSML в ответе из внешнего скилла,
// необходимо передать "ssml".
TTSType string `json:"tts_type,omitempty"`
Expand Down Expand Up @@ -534,6 +540,22 @@ type Response struct {
UserStateUpdate json.RawMessage `json:"user_state_update,omitempty"`
}

// ArrayResponse данные для ответа пользователю с массивом строк.
// Является копией Response, но имеет отличия в поле Text.
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"`
}

// AddURL добавляет к ответу кнопку с ссылкой.
func (r *Response) AddURL(title string, url string) {
if r.Buttons == nil {
Expand Down Expand Up @@ -575,3 +597,26 @@ func SpeakerAudioVKID(id string) string {
func SpeakerAudio(name string) string {
return fmt.Sprintf(`<speaker audio=%s>`, strconv.Quote(name))
}

// ResponseWithTextArray возвращает измененную структуру Response
//
// Функция реализована для поддержки массива строк в тексте с учётом
// обратной совместимости, она изменяет итоговую структуру так, чтобы
// в `json:"text" оказался массив строк и пользователь получил
// несколько баблов с текстом. При условии, что поле Text
// оригинальной структуры не задано.
func (r *Response) ResponseWithTextArray() (ArrayResponse, error) {
return ArrayResponse{
Text: r.TextArray,
TTSType: r.TTSType,
SSML: r.SSML,
TTS: r.TTS,
Buttons: r.Buttons,
Push: r.Push,
EndSession: r.EndSession,
Card: r.Card,
AudioPlayer: r.AudioPlayer,
SessionState: r.SessionState,
UserStateUpdate: r.UserStateUpdate,
}, nil
}
55 changes: 41 additions & 14 deletions marusia/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ type response struct {
Version string `json:"version"` // Версия протокола.
}

// arrayResponse структура ответа серверу с массивом строк.
type arrayResponse struct {
Response ArrayResponse `json:"response"` // Данные для ответа.
Session responseSession `json:"session"` // Данные о сессии.
Version string `json:"version"` // Версия протокола.
}

// Webhook структура.
type Webhook struct {
event func(r Request) Response
Expand Down Expand Up @@ -73,7 +80,10 @@ func (wh *Webhook) HandleFunc(w http.ResponseWriter, r *http.Request) {
return
}

var req Request
var (
req Request
fullResponse any
)

err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
Expand All @@ -82,19 +92,36 @@ func (wh *Webhook) HandleFunc(w http.ResponseWriter, r *http.Request) {
}

resp := wh.event(req)

fullResponse := response{
Response: resp,
Session: responseSession{
SessionID: req.Session.SessionID,
MessageID: req.Session.MessageID,
UserID: req.Session.UserID,
SkillID: req.Session.SkillID,
New: req.Session.New,
User: req.Session.User,
Application: req.Session.Application,
},
Version: Version,
if resp.Text != "" {
fullResponse = response{
Response: resp,
Session: responseSession{
SessionID: req.Session.SessionID,
MessageID: req.Session.MessageID,
UserID: req.Session.UserID,
SkillID: req.Session.SkillID,
New: req.Session.New,
User: req.Session.User,
Application: req.Session.Application,
},
Version: Version,
}
} else {
SevereCloud marked this conversation as resolved.
Show resolved Hide resolved
newResp, _ := resp.ResponseWithTextArray()

fullResponse = arrayResponse{
Response: newResp,
Session: responseSession{
SessionID: req.Session.SessionID,
MessageID: req.Session.MessageID,
UserID: req.Session.UserID,
SkillID: req.Session.SkillID,
New: req.Session.New,
User: req.Session.User,
Application: req.Session.Application,
},
Version: Version,
}
}

if wh.debuging {
Expand Down