Хранение состояния

Возможность работает в тестовом режиме и активно развивается, поэтому протокол ее использования может меняться.

API Яндекс Диалогов позволяет сохранять данные внутри сессии навыка, а если пользователь авторизован на поверхности, где работает навык, — то и между сессиями.

Первоначальная настройка

Подключите возможность сохранять состояние:

  1. В консоли разработчика откройте страницу настроек навыка.
  2. В блоке Основные настройки найдите опцию Хранилище.
  3. Выберите Использовать хранилище данных в навыке.

Хранение состояния сессии

Чтобы сохранить данные внутри сессии, навык должен отправить свойство session_state в ответе. Записанное значение придет в следующем запросе в навык. Данные хранятся до конца сессии.

Сессия завершается, когда:

  • пользователь запрашивает выход из навыка;
  • навык явно завершает работу ("end_session": true);
  • от пользователя долго не поступает команд (тайм-аут зависит от поверхности, минимум несколько минут).

Максимальный размер JSON-объекта session_state — 1 КБ:

{
  "response": {
    "text": "Здравствуйте! Это мы, хороводоведы.",
    "tts": "Здравствуйте! Это мы, хоров+одо в+еды.",
    "end_session": false
  },
  "session_state": {
      "value": 10
  },
  "version": "1.0"
}

Состояние сессии перестанет храниться, если в ответе навыка не вернуть свойство session_state. Если для запроса состояние не меняется, но его нужно хранить, навыку следует вернуть тот же объект session_state, что пришел в запросе.

Пример запроса с сохраненным состоянием:

{
  "meta": {
    "locale": "ru-RU",
    "timezone": "Europe/Moscow",
    "client_id": "ru.yandex.searchplugin/5.80 (Samsung Galaxy; Android 4.4)",
    "interfaces": {
      "screen": { }
    }
  },
  "request": {
    "command": "привет",
    "original_utterance": "привет",
    "type": "SimpleUtterance",
    "markup": {
      "dangerous_context": true
    },
    "payload": {},
    "nlu": {
      "tokens": [
         "привет"
      ],
      "entities": [
      ]
    }
  },
  "session": {
    "new": true,
    "message_id": 4,
    "session_id": "2eac4854-fce721f3-b845abba-20d60",
    "skill_id": "3ad36498-f5rd-4079-a14b-788652932056",
    "user_id": "AC9WC3DF6FCE052E45A4566A48E6B7193774B84814CE49A922E163B8B29881DC",
    "application": {
      "application_id": "AC9WC3DF6FCE052E45A4566A48E6B7193774B84814CE49A922E163B8B29881DC"
    },
  },
  "state": {
    "session": {
      "value": 10
    }
  },
  "version": "1.0"
}

Хранение состояния между сессиями

Состояние навыка хранится только для пользователей, которые авторизовались с помощью Яндекс ID.

Чтобы сохранить данные о пользователе, навык должен отправить в ответе свойство user_state_update. Максимальный размер JSON-объекта — 1 КБ:

{
  "response": {
    "text": "Здравствуйте! Это мы, хороводоведы.",
    "tts": "Здравствуйте! Это мы, хоров+одо в+еды.",
    "end_session": false
  },
  "session": {
    "session_id": "2eac4854-fce721f3-b845abba-20d60",
    "message_id": 4,
    "user_id": "AC9WC3DF6FCE052E45A4566A48E6B7193774B84814CE49A922E163B8B29881DC",
    "application": {
      "application_id": "AC9WC3DF6FCE052E45A4566A48E6B7193774B84814CE49A922E163B8B29881DC"
    },
  },
  "user_state_update": {
      "value": 42
  },
  "version": "1.0"
}

Чтобы удалить поле, записанное в состояние пользователя, навык должен отправить это поле со значением null.

Сохраненное значение придет в следующем запросе в навык:

{
  "meta": {
    "locale": "ru-RU",
    "timezone": "Europe/Moscow",
    "client_id": "ru.yandex.searchplugin/5.80 (Samsung Galaxy; Android 4.4)",
    "interfaces": {
      "screen": { }
    }
  },
  "request": {
    "command": "привет",
    "original_utterance": "привет",
    "type": "SimpleUtterance",
    "markup": {
      "dangerous_context": true
    },
    "payload": {},
    "nlu": {
      "tokens": [
         "привет"
      ],
      "entities": [
      ]
    }
  },
  "session": {
    "new": true,
    "message_id": 4,
    "session_id": "2eac4854-fce721f3-b845abba-20d60",
    "skill_id": "3ad36498-f5rd-4079-a14b-788652932056",
    "user_id": "AC9WC3DF6FCE052E45A4566A48E6B7193774B84814CE49A922E163B8B29881DC",
    "application": {
      "application_id": "AC9WC3DF6FCE052E45A4566A48E6B7193774B84814CE49A922E163B8B29881DC"
    },
    "user": {
      "user_id": "8D7196B4A8AA15CFF3B7B3046738C03F234A7E638FFE33B23F2350BBD940B644"
    }
  },
  "state": {
    "user": {
      "value": 42
    }
  },
  "version": "1.0"
}

Хранение состояния для экземпляра приложения

Экземпляр приложения — это конкретное приложение (например, Браузер, приложение Яндекс, Навигатор) или устройство. Разрез хранения равносилен session.application.application_id для навыка.

Состояние для экземпляра приложения сохраняет взаимодействие с пользователем для одной поверхности,не распространяя его на другие поверхности пользователя.

Если поверхность Алисы не поддерживает авторизацию или пользователь не авторизован на поверхности, хранение в разрезе экземпляра приложения — единственный способ сохранить контекст между сессиями.

Чтобы сохранить состояние навыка для экземпляра приложения, навык должен отправить свойство application_state в ответе:

{
  "response": {
    "text": "Здравствуйте! Это мы, хороводоведы.",
    "tts": "Здравствуйте! Это мы, хоров+одо в+еды.",
    "end_session": false
  },
  "application_state": {
      "value": 37
  },
  "version": "1.0"
}

Сохраненное состояние придет в следующем запросе в навык:

{
  "meta": {
    "locale": "ru-RU",
    "timezone": "Europe/Moscow",
    "client_id": "ru.yandex.searchplugin/5.80 (Samsung Galaxy; Android 4.4)",
    "interfaces": {
      "screen": { }
    }
  },
  "request": {
    "command": "привет",
    "original_utterance": "привет",
    "type": "SimpleUtterance",
    "markup": {
      "dangerous_context": true
    },
    "payload": {},
    "nlu": {
      "tokens": [
         "привет"
      ],
      "entities": [
      ]
    }
  },
  "session": {
    "new": true,
    "message_id": 4,
    "session_id": "2eac4854-fce721f3-b845abba-20d60",
    "skill_id": "3ad36498-f5rd-4079-a14b-788652932056",
    "user_id": "AC9WC3DF6FCE052E45A4566A48E6B7193774B84814CE49A922E163B8B29881DC",
    "application": {
      "application_id": "AC9WC3DF6FCE052E45A4566A48E6B7193774B84814CE49A922E163B8B29881DC"
    },
    "user": {
      "user_id": "8D7196B4A8AA15CFF3B7B3046738C03F234A7E638FFE33B23F2350BBD940B644"
    }
  },
  "state": {
    "application": {
      "value": 37
    }
  },
  "version": "1.0"
}

Состояние для экземпляра приложения продолжает храниться, если в ответе навыка не вернуть application_state. Если для запроса состояние навыка для экземпляра приложения не изменяется, то можно не присылать application_state в ответе или отправить его со значением null.

Чтобы очистить сохраненное состояние приложения, навык может отправить это поле со значением {} — пустым словарем.

Полезные видео

Разработка прототипа голосового приложения

Часто задаваемые вопросы

Как сохранить историю общения с пользователем?

В настройках включите опцию Использовать хранилище данных в навыке, чтобы сохранять историю авторизованных пользователей. Историю неавторизованных сохраняйте на своем сервере: на Диалогах это пока невозможно.

Можно ли сохранять состояние навыка между сессиями?

Да, если пользователь авторизован на устройстве, а в настройках навыка включена опция Использовать хранилище данных в навыке. Для неавторизованных пользователей Диалоги сохраняют историю только внутри сессии.