From 40f5df5b9b57cf971468f5c1fb38fcf8c119da39 Mon Sep 17 00:00:00 2001 From: Mikhail Nevskiy <139659391+trudenboy@users.noreply.github.com> Date: Wed, 6 May 2026 20:43:39 +0300 Subject: [PATCH 1/4] docs(plugins): add Yandex Alice plugin page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a documentation page for the Yandex Alice plugin, which exposes Music Assistant playback to Alice via a Yandex Dialogs custom skill ("aliceSkill" / «Навык») — the voice-skill side of the integration, extracted from the Yandex Smart Home plugin into its own provider so voice-only and device-bridge users can configure independently. Covers v1.1.0: - Free-form Russian voice playback («Алиса, попроси ...»): search-and-play, transport, queue, multi-room, now-playing, voice- first disambiguation, Russian NLU (verb stripping, inflection-aware player matching). - Automatic skill creation via OAuth Device Flow at ya.ru/device + the undocumented Yandex Dialogs developer-console API. Self-resuming state machine: same button doubles as 'Confirm and continue' / 'Resume' / 'Re-create' / 'Retry' depending on persisted state, so HTTP / proxy timeouts can't strand the flow. - Cached x_token reuse: long-lived token from first Device Flow is reused on subsequent rename / re-create within token lifetime (months). Silently dropped on 401. - Rename action: PATCH draft + re-deploy via cached x_token, with drift detection LABEL when MA-side Skill name differs from last_known_name in artifacts. - Manual setup remains the supported fallback when the undocumented Yandex Dialogs API breaks. Page follows the style of the Yandex Smart Home page (CAUTION / WARNING / NOTE callouts, voice commands table, settings list, known issues / notes) and cross-links between the two. Sidebar entry added to astro.config.mjs under Plugins. Related links: - Provider source: https://github.com/trudenboy/ma-provider-yandex-alice - Provider release v1.1.0: https://github.com/trudenboy/ma-provider-yandex-alice/releases/tag/v1.1.0 - Full plugin documentation (RU/EN): https://trudenboy.github.io/ma-provider-yandex-alice/ - Sibling plugin (Smart Home device bridge): https://github.com/trudenboy/ma-provider-yandex-smarthome Co-Authored-By: Claude Opus 4.7 (1M context) --- astro.config.mjs | 1 + src/content/docs/plugins/yandex-alice.md | 148 +++++++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 src/content/docs/plugins/yandex-alice.md diff --git a/astro.config.mjs b/astro.config.mjs index 2792a8191..7bf07d2bf 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -269,6 +269,7 @@ export default defineConfig({ { label: 'Spotify Connect Plugin', slug: 'plugins/spotify-connect' }, { label: 'Subsonic Scrobbler', slug: 'plugins/subsonic_scrobble' }, { label: 'VBAN Receiver', slug: 'plugins/vban-receiver' }, + { label: 'Yandex Alice Plugin', slug: 'plugins/yandex-alice' }, ], }, { diff --git a/src/content/docs/plugins/yandex-alice.md b/src/content/docs/plugins/yandex-alice.md new file mode 100644 index 000000000..c6846071a --- /dev/null +++ b/src/content/docs/plugins/yandex-alice.md @@ -0,0 +1,148 @@ +--- +title: "Yandex Alice Plugin" +description: Features and Notes for the Yandex Alice Plugin +--- + +# Yandex Alice + +Music Assistant can expose its players to [Yandex Alice](https://alice.yandex.ru/) as a [Yandex Dialogs](https://dialogs.yandex.ru/developer) custom skill ("aliceSkill" / *«Навык»*), so users can control playback by voice using free-form Russian phrases. + +Activation phrase is **«Алиса, попроси \ …»** — Yandex transcribes the rest of the phrase and POSTs it to a webhook on Music Assistant. The plugin parses the phrase server-side (Russian NLU: verb stripping, inflection-aware player matching, ordinal disambiguation), resolves the addressed player and the requested media, and dispatches the parsed intent to MA playback actions. + +This is the **voice-skill side** of the Yandex integration, extracted from [Yandex Smart Home Plugin](/plugins/yandex-smarthome) into its own plugin so users who only want voice control don't have to deal with the Smart Home device-bridge configuration, and vice versa. + +> [!CAUTION] +> This is an unofficial implementation and is not affiliated with or endorsed by Yandex. + +> [!WARNING] +> Music Assistant must be reachable on a **public HTTPS URL** — Yandex POSTs voice phrases to your MA server directly. There is no cloud relay for Dialogs custom skills. + +> [!NOTE] +> Full plugin documentation (RU/EN): **[trudenboy.github.io/ma-provider-yandex-alice](https://trudenboy.github.io/ma-provider-yandex-alice/)** +> +> For Smart Home device-bridge integration (volume, on/off, playlists as input sources via the Smart Home API) see [Yandex Smart Home Plugin](/plugins/yandex-smarthome). The two plugins can run side by side on the same MA instance. + + +## Features + +- Free-form Russian voice playback: search-and-play artists / albums / tracks / playlists / genres, control transport (pause / next / previous / seek), control queue (shuffle / repeat / add-to-queue), control multi-room (transfer / play-on-other-player / list speakers), and ask now-playing +- **Automatic skill creation** — one click in the config form runs OAuth Device Flow at `ya.ru/device`, then drives the Yandex Dialogs API end-to-end (CSRF → create app → upload logo → update draft → request deploy). Skill ID is filled in automatically. No manual setup in the Yandex.Dialogs console required +- **Self-resuming flow** — the same auto-create button doubles as «Confirm and continue» / «Resume» / «Re-create» / «Retry» depending on persisted state. Partial failures resume from the last completed step on the next click +- **Rename action** — sync the current `Skill name` to Yandex (PATCH draft + re-deploy) using the cached x_token. Drift detection LABEL appears when MA-side name differs from what's in Yandex +- **Russian NLU** — handles inflected forms (*кухню* → kitchen, *спальни* → bedroom), case-insensitive partial matches, fuzzy player-name resolution +- **Voice-first disambiguation** — when a player name is ambiguous, the skill replies *«первая, вторая или третья?»* and resolves the user's spoken ordinal answer + +### Supported voice commands + +After «Алиса, попроси \ …»: + +| Voice command | Action | +|---|---| +| `включи Metallica` | search → first artist → start artist radio | +| `включи Metallica на кухне` | same, but on the player named *"Кухня"* | +| `включи песню Yesterday` | track search → first match → play that track | +| `включи альбом Black Album` | album search → first match → play that album | +| `включи группу Beatles` | artist radio explicitly | +| `включи плейлист утренний джаз` | playlist search → first match → play that playlist | +| `включи мою волну` | yandex_music personal radio (`user:onyourwave`) | +| `включи жанр джаз` / `включи радио рок` | genre rotor → fall back to artist radio | +| `что играет` | now-playing announcement | +| `поставь на паузу` / `продолжи` / `стоп` | pause / resume / stop | +| `следующий трек` / `предыдущий` | skip ±1 | +| `громче` / `тише` | volume ±10 | +| `громкость 50` | absolute volume | +| `выключи звук` / `включи звук` | mute / unmute | +| `перемешай` / `выключи перемешивание` | shuffle on/off | +| `повтор песни` / `повтор очереди` / `повторяй` / `выключи повтор` | repeat one / all / off | +| `перемотай вперёд на минуту` / `назад на 30 секунд` / `к началу` | seek | +| `добавь Iron Maiden` | search → enqueue at end of queue | +| `переведи на спальню` / `продолжи в спальне` | transfer queue to another player | +| `включи на кухне` / `что играет на кухне` | address a different player without transfer | +| `список колонок` | enumerate exposed players | +| `забудь колонку` | clear "preferred player" memory | + +Player names are matched against MA's `player.name` (case-insensitive, with Russian inflections normalised — *«Кухня»* matches *«на кухне»*). Generic words like *колонка* / *плеер* / *проигрыватель* / *динамик* fall through to the previously-used player in the same conversation, or to the only exposed player. + +Verbs the parser understands (Yandex's voice-to-text returns various forms, all are accepted): `включи / включите / включай / включайте / включить`, `поставь / поставьте / поставить`, `запусти / запустите / запустить`, `сыграй / сыграйте / сыграть`, `играй / играйте`, `послушай / послушайте / послушать`. The optional trailing `на ` suffix is stripped before kind classification, so word order is fixed to ` [на ]`. + +Search prioritisation when no marker is given (`включи X`): **artist > album > track > playlist** with `radio_mode=True` — picking the artist matches the typical "play X music" intent and starts continuous playback. If you specifically want a playlist, say `плейлист X`; for an album, `альбом X`; for a single track, `песню X`. + +## Configuration + +### Automatic skill creation + +The config form's **Create skill** button registers the skill in Yandex Dialogs for you — no copy-paste into the developer console required. The flow is **self-resuming across clicks**: each click advances the state machine by one external-IO step, so HTTP / proxy timeouts can't strand the flow. Stages and what each click does: + +1. **First click — Create skill.** The plugin calls Yandex Passport's OAuth Device Flow. The form re-renders with a `user_code` (e.g. `ABCD-1234`) and a verification URL. Open `ya.ru/device` in your browser, enter the code, confirm. +2. **Second click — Confirm and continue.** The plugin polls the Device Flow once with a short window. If you've confirmed the code, it captures the `x_token`, refreshes Passport cookies, and runs the OAuth-free `aliceSkill` pipeline end-to-end (`fetch_csrf → create_app → upload_logo → update_draft → request_deploy`). On success **Skill ID** is filled in automatically. +3. If the underlying user_code expires or the pipeline fails partway (e.g. duplicate skill name), the button label flips to **Retry** and the LABEL above shows what went wrong. Fix the cause (change the skill name, retry) and click again — the pipeline resumes from the last completed step rather than starting from scratch. + +The **Cancel** button appears next to **Create skill** while a Device Flow session is pending or after a failure. It drops the in-flight session and resets artifacts; the cached `x_token` is preserved so the next Create click can skip Passport login. + +> [!NOTE] +> Yandex's deploy is asynchronous — for `aliceSkill` skills it usually takes 5-15 minutes under typical moderation queue conditions. The skill is unusable on Alice until the dev console shows *«На воздухе»* / `onAir: true`. The success message links the user to the skill's dev-console page so you can check on-air status at your convenience. + +### Cached x_token reuse + +The Yandex Passport `x_token` from the first successful Device Flow is cached in encrypted config. Subsequent `Re-create` and `Rename` clicks reuse it (no Passport re-login) within the token's lifetime — it's long-lived (months) and silently dropped on any 401 from Yandex. + +### Rename action + +Once a skill exists, a **Rename skill in Yandex** button appears in the form (visible only when both Skill ID and cached `x_token` are present). Click it to apply the current `Skill name` value to the existing skill in Yandex Dialogs (`PATCH /draft/update` + `request_deploy`). Uses the cached `x_token` — no re-authentication required. + +A drift-detection LABEL appears above the button when the MA-side `Skill name` differs from `last_known_name` in the persisted artifacts (i.e. you changed the name in MA but haven't synced it yet). Click **Rename** to push the change. + +> [!TIP] +> The `Skill name` is what users say to invoke the skill: *«Алиса, попроси \ …»*. Pick at least two words, globally unique across all Yandex skills (Yandex enforces both). Russian names work best for voice recognition: `Музыкальный Ассистент`, `Домашняя Музыка`, `Мой Плеер`, etc. + +### Manual setup (fallback) + +If the automatic skill creation breaks (Yandex changes their undocumented dev-console API), you can still set up the skill by hand: + +1. Create a custom dialog skill at . +2. Set its **Backend URL** to `/api/yandex_dialogs/webhook/` (the form pre-fills `` for you). +3. Save and request publication; wait for moderation to finish. +4. Copy the **Skill ID** (the UUID in the dev console URL) into the plugin's config form by hand. **Enable dialog skill** on. Save. + +### Settings + +- **Instance name** — internal display name for this plugin instance. +- **External base URL** — public HTTPS URL where Yandex can reach your MA webserver (e.g. `https://ma.example.com`). Leave empty to use MA's global Base URL setting. Required for auto-create. +- **Enable dialog skill** — turn this on once the skill is created (auto or manual) and the credentials below are populated. +- **Skill name** — display name pushed to Yandex Dialogs on auto-create / rename. Min 2, max 64 characters. +- **Skill ID** — UUID of the skill. Populated automatically after a successful auto-create, or paste manually if you set up the skill yourself. +- **Skill OAuth token** — optional; used for future state-callback push features (stored encrypted). +- **Webhook URL secret** — random secret embedded in the webhook URL. Pre-filled with a fresh value on first open; click 'Save' to commit. Stable across action clicks once generated. +- **Voice-controllable players** — multi-select of MA players the skill is allowed to control. Leave empty to expose all players. +- **Voice-addressable playlists** — optional curated list of playlists the user can ask for by name. Leave empty for full library search. + +## Multi-room + +Players are addressed by their MA name with Russian inflection support: + +- *«Алиса, попроси \ включи джаз на кухне»* — start playback on the player named *«Кухня»* +- *«… что играет на кухне»* — ask now-playing on a specific player +- *«… переведи на спальню»* — transfer the active queue to another player +- *«… продолжи в спальне»* — same, but with explicit "continue" semantics + +Aliases set in the *Home with Alice* app **do not** propagate into the dialog skill payload — Yandex only forwards the raw phrase. To use a custom voice name, rename the player in MA itself. + +## Disambiguation + +When a phrase matches multiple players (e.g. you have *«Кухня»* and *«Кухня small»*), the skill responds *«первая, вторая или третья?»* and waits for the user's spoken ordinal. The conversation state survives across requests via Yandex's session/state envelopes — there is no in-process cache. The skill recognises a wide range of ordinal forms (`первая` / `первый` / `первое` / `первое из`, `вторая`, `третий`, …, both feminine and masculine, both nominative and genitive). + +## Security notes + +- The webhook URL embeds a **random URL-safe 24-byte secret** (`/api/yandex_dialogs/webhook/`); knowing the secret requires access to the skill's Backend URL field in the Yandex Dialogs dev console. The secret is stable across action clicks (regeneration only happens on first form open if the field is empty). +- The handler also checks `body.session.skill_id` against the configured skill ID before processing — a payload from a different skill returns `401`. +- The plugin uses MA's standard logging redaction; the secret is only logged as the last 4 characters of the path on startup. +- The cached `x_token` is stored in MA's encrypted config (SECURE_STRING entry) and is never logged in plaintext. +- If you publish MA via a reverse proxy, expose only the prefix `/api/yandex_dialogs/webhook/`. Block `/` to keep the rest of the MA API/UI off the public internet. + +## Known Issues / Notes + +- Direct mode requires a publicly reachable HTTPS endpoint for the MA webserver (port forwarding, reverse proxy or similar). There is no cloud-relay alternative for Dialogs custom skills. +- Automatic skill creation uses an **undocumented** Yandex Dialogs developer-console API. If Yandex changes the contract, manual setup at remains the supported fallback. +- After `request_deploy` Yandex moderation takes 5-15 minutes for `aliceSkill` skills. The dev-console link in the success message lets you check on-air status. +- This plugin uses `mode(input_source)` capability indirectly: free-form voice phrases are parsed server-side, so the Yandex Smart Home `play_media` limit does not apply here. For ordinal-only playlist triggering via the Smart Home API see [Yandex Smart Home Plugin](/plugins/yandex-smarthome). +- The skill name displayed to users is what they say to invoke it (*«Алиса, попроси \ …»*) — Yandex enforces minimum 2 words and global uniqueness across all skills. From f1c939f5519f67edd4a32aba357761b9651abe6c Mon Sep 17 00:00:00 2001 From: Mikhail Nevskiy <139659391+trudenboy@users.noreply.github.com> Date: Thu, 7 May 2026 18:07:11 +0300 Subject: [PATCH 2/4] docs(yandex-alice): trim page down to plugin-page house style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aligns the page with the airplay-receiver / plex-connect template and addresses the review feedback from #623 (Yandex Smart Home docs PR): drop the voice-commands table, the deep-dive on the auto-create state machine + cached x_token + rename / drift / manual fallback, the explicit Settings list, and the standalone Multi-room / Disambiguation / Security sections — they were rephrasing details already covered in Features or in the source-repo guide. All Russian phrases translated or rephrased in English. Net change: 149 → 41 lines. The page now hands users off to the source-repo full setup guide for step-by-step configuration. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/content/docs/plugins/yandex-alice.md | 141 +++-------------------- 1 file changed, 17 insertions(+), 124 deletions(-) diff --git a/src/content/docs/plugins/yandex-alice.md b/src/content/docs/plugins/yandex-alice.md index c6846071a..28d2a4ef2 100644 --- a/src/content/docs/plugins/yandex-alice.md +++ b/src/content/docs/plugins/yandex-alice.md @@ -5,144 +5,37 @@ description: Features and Notes for the Yandex Alice Plugin # Yandex Alice -Music Assistant can expose its players to [Yandex Alice](https://alice.yandex.ru/) as a [Yandex Dialogs](https://dialogs.yandex.ru/developer) custom skill ("aliceSkill" / *«Навык»*), so users can control playback by voice using free-form Russian phrases. - -Activation phrase is **«Алиса, попроси \ …»** — Yandex transcribes the rest of the phrase and POSTs it to a webhook on Music Assistant. The plugin parses the phrase server-side (Russian NLU: verb stripping, inflection-aware player matching, ordinal disambiguation), resolves the addressed player and the requested media, and dispatches the parsed intent to MA playback actions. - -This is the **voice-skill side** of the Yandex integration, extracted from [Yandex Smart Home Plugin](/plugins/yandex-smarthome) into its own plugin so users who only want voice control don't have to deal with the Smart Home device-bridge configuration, and vice versa. +Music Assistant has the ability to be controlled by voice through [Yandex Alice](https://alice.yandex.ru/), Yandex's Russian-language voice assistant, by registering a custom skill in [Yandex Dialogs](https://dialogs.yandex.ru/developer). Users speak free-form Russian phrases like "Alice, ask <skill name> to play jazz" and Music Assistant resolves the player and the requested media server-side. > [!CAUTION] -> This is an unofficial implementation and is not affiliated with or endorsed by Yandex. +> This is an unofficial integration and is not affiliated with or endorsed by Yandex. > [!WARNING] -> Music Assistant must be reachable on a **public HTTPS URL** — Yandex POSTs voice phrases to your MA server directly. There is no cloud relay for Dialogs custom skills. +> Music Assistant must be reachable on a **public HTTPS URL** — Yandex sends voice phrases directly to your MA server. There is no cloud relay for Dialogs custom skills. > [!NOTE] -> Full plugin documentation (RU/EN): **[trudenboy.github.io/ma-provider-yandex-alice](https://trudenboy.github.io/ma-provider-yandex-alice/)** -> -> For Smart Home device-bridge integration (volume, on/off, playlists as input sources via the Smart Home API) see [Yandex Smart Home Plugin](/plugins/yandex-smarthome). The two plugins can run side by side on the same MA instance. - +> This is the voice-control side of the Yandex integration. For device-bridge integration (volume, on/off, playlists exposed as input sources) see the [Yandex Smart Home Plugin](/plugins/yandex-smarthome). The two plugins can run side by side on the same MA instance. ## Features -- Free-form Russian voice playback: search-and-play artists / albums / tracks / playlists / genres, control transport (pause / next / previous / seek), control queue (shuffle / repeat / add-to-queue), control multi-room (transfer / play-on-other-player / list speakers), and ask now-playing -- **Automatic skill creation** — one click in the config form runs OAuth Device Flow at `ya.ru/device`, then drives the Yandex Dialogs API end-to-end (CSRF → create app → upload logo → update draft → request deploy). Skill ID is filled in automatically. No manual setup in the Yandex.Dialogs console required -- **Self-resuming flow** — the same auto-create button doubles as «Confirm and continue» / «Resume» / «Re-create» / «Retry» depending on persisted state. Partial failures resume from the last completed step on the next click -- **Rename action** — sync the current `Skill name` to Yandex (PATCH draft + re-deploy) using the cached x_token. Drift detection LABEL appears when MA-side name differs from what's in Yandex -- **Russian NLU** — handles inflected forms (*кухню* → kitchen, *спальни* → bedroom), case-insensitive partial matches, fuzzy player-name resolution -- **Voice-first disambiguation** — when a player name is ambiguous, the skill replies *«первая, вторая или третья?»* and resolves the user's spoken ordinal answer - -### Supported voice commands - -After «Алиса, попроси \ …»: - -| Voice command | Action | -|---|---| -| `включи Metallica` | search → first artist → start artist radio | -| `включи Metallica на кухне` | same, but on the player named *"Кухня"* | -| `включи песню Yesterday` | track search → first match → play that track | -| `включи альбом Black Album` | album search → first match → play that album | -| `включи группу Beatles` | artist radio explicitly | -| `включи плейлист утренний джаз` | playlist search → first match → play that playlist | -| `включи мою волну` | yandex_music personal radio (`user:onyourwave`) | -| `включи жанр джаз` / `включи радио рок` | genre rotor → fall back to artist radio | -| `что играет` | now-playing announcement | -| `поставь на паузу` / `продолжи` / `стоп` | pause / resume / stop | -| `следующий трек` / `предыдущий` | skip ±1 | -| `громче` / `тише` | volume ±10 | -| `громкость 50` | absolute volume | -| `выключи звук` / `включи звук` | mute / unmute | -| `перемешай` / `выключи перемешивание` | shuffle on/off | -| `повтор песни` / `повтор очереди` / `повторяй` / `выключи повтор` | repeat one / all / off | -| `перемотай вперёд на минуту` / `назад на 30 секунд` / `к началу` | seek | -| `добавь Iron Maiden` | search → enqueue at end of queue | -| `переведи на спальню` / `продолжи в спальне` | transfer queue to another player | -| `включи на кухне` / `что играет на кухне` | address a different player without transfer | -| `список колонок` | enumerate exposed players | -| `забудь колонку` | clear "preferred player" memory | - -Player names are matched against MA's `player.name` (case-insensitive, with Russian inflections normalised — *«Кухня»* matches *«на кухне»*). Generic words like *колонка* / *плеер* / *проигрыватель* / *динамик* fall through to the previously-used player in the same conversation, or to the only exposed player. - -Verbs the parser understands (Yandex's voice-to-text returns various forms, all are accepted): `включи / включите / включай / включайте / включить`, `поставь / поставьте / поставить`, `запусти / запустите / запустить`, `сыграй / сыграйте / сыграть`, `играй / играйте`, `послушай / послушайте / послушать`. The optional trailing `на ` suffix is stripped before kind classification, so word order is fixed to ` [на ]`. - -Search prioritisation when no marker is given (`включи X`): **artist > album > track > playlist** with `radio_mode=True` — picking the artist matches the typical "play X music" intent and starts continuous playback. If you specifically want a playlist, say `плейлист X`; for an album, `альбом X`; for a single track, `песню X`. +- Free-form Russian voice playback: search and play artists, albums, tracks, playlists and genres +- Transport and queue control: pause / resume / next / previous / seek, shuffle, repeat, add to queue, what's playing +- Multi-room: address a specific player by name, transfer the queue to another player, list players +- Voice-first disambiguation when a player name is ambiguous (the skill asks "first, second, or third?") +- Russian NLU handles morphologically inflected forms and fuzzy player-name matching +- One-click skill registration in the config form via Yandex Passport sign-in (no manual setup in the Yandex Dialogs developer console required) ## Configuration -### Automatic skill creation - -The config form's **Create skill** button registers the skill in Yandex Dialogs for you — no copy-paste into the developer console required. The flow is **self-resuming across clicks**: each click advances the state machine by one external-IO step, so HTTP / proxy timeouts can't strand the flow. Stages and what each click does: - -1. **First click — Create skill.** The plugin calls Yandex Passport's OAuth Device Flow. The form re-renders with a `user_code` (e.g. `ABCD-1234`) and a verification URL. Open `ya.ru/device` in your browser, enter the code, confirm. -2. **Second click — Confirm and continue.** The plugin polls the Device Flow once with a short window. If you've confirmed the code, it captures the `x_token`, refreshes Passport cookies, and runs the OAuth-free `aliceSkill` pipeline end-to-end (`fetch_csrf → create_app → upload_logo → update_draft → request_deploy`). On success **Skill ID** is filled in automatically. -3. If the underlying user_code expires or the pipeline fails partway (e.g. duplicate skill name), the button label flips to **Retry** and the LABEL above shows what went wrong. Fix the cause (change the skill name, retry) and click again — the pipeline resumes from the last completed step rather than starting from scratch. - -The **Cancel** button appears next to **Create skill** while a Device Flow session is pending or after a failure. It drops the in-flight session and resets artifacts; the cached `x_token` is preserved so the next Create click can skip Passport login. - -> [!NOTE] -> Yandex's deploy is asynchronous — for `aliceSkill` skills it usually takes 5-15 minutes under typical moderation queue conditions. The skill is unusable on Alice until the dev console shows *«На воздухе»* / `onAir: true`. The success message links the user to the skill's dev-console page so you can check on-air status at your convenience. - -### Cached x_token reuse - -The Yandex Passport `x_token` from the first successful Device Flow is cached in encrypted config. Subsequent `Re-create` and `Rename` clicks reuse it (no Passport re-login) within the token's lifetime — it's long-lived (months) and silently dropped on any 401 from Yandex. - -### Rename action - -Once a skill exists, a **Rename skill in Yandex** button appears in the form (visible only when both Skill ID and cached `x_token` are present). Click it to apply the current `Skill name` value to the existing skill in Yandex Dialogs (`PATCH /draft/update` + `request_deploy`). Uses the cached `x_token` — no re-authentication required. - -A drift-detection LABEL appears above the button when the MA-side `Skill name` differs from `last_known_name` in the persisted artifacts (i.e. you changed the name in MA but haven't synced it yet). Click **Rename** to push the change. - -> [!TIP] -> The `Skill name` is what users say to invoke the skill: *«Алиса, попроси \ …»*. Pick at least two words, globally unique across all Yandex skills (Yandex enforces both). Russian names work best for voice recognition: `Музыкальный Ассистент`, `Домашняя Музыка`, `Мой Плеер`, etc. - -### Manual setup (fallback) - -If the automatic skill creation breaks (Yandex changes their undocumented dev-console API), you can still set up the skill by hand: - -1. Create a custom dialog skill at . -2. Set its **Backend URL** to `/api/yandex_dialogs/webhook/` (the form pre-fills `` for you). -3. Save and request publication; wait for moderation to finish. -4. Copy the **Skill ID** (the UUID in the dev console URL) into the plugin's config form by hand. **Enable dialog skill** on. Save. - -### Settings - -- **Instance name** — internal display name for this plugin instance. -- **External base URL** — public HTTPS URL where Yandex can reach your MA webserver (e.g. `https://ma.example.com`). Leave empty to use MA's global Base URL setting. Required for auto-create. -- **Enable dialog skill** — turn this on once the skill is created (auto or manual) and the credentials below are populated. -- **Skill name** — display name pushed to Yandex Dialogs on auto-create / rename. Min 2, max 64 characters. -- **Skill ID** — UUID of the skill. Populated automatically after a successful auto-create, or paste manually if you set up the skill yourself. -- **Skill OAuth token** — optional; used for future state-callback push features (stored encrypted). -- **Webhook URL secret** — random secret embedded in the webhook URL. Pre-filled with a fresh value on first open; click 'Save' to commit. Stable across action clicks once generated. -- **Voice-controllable players** — multi-select of MA players the skill is allowed to control. Leave empty to expose all players. -- **Voice-addressable playlists** — optional curated list of playlists the user can ask for by name. Leave empty for full library search. - -## Multi-room - -Players are addressed by their MA name with Russian inflection support: - -- *«Алиса, попроси \ включи джаз на кухне»* — start playback on the player named *«Кухня»* -- *«… что играет на кухне»* — ask now-playing on a specific player -- *«… переведи на спальню»* — transfer the active queue to another player -- *«… продолжи в спальне»* — same, but with explicit "continue" semantics - -Aliases set in the *Home with Alice* app **do not** propagate into the dialog skill payload — Yandex only forwards the raw phrase. To use a custom voice name, rename the player in MA itself. - -## Disambiguation - -When a phrase matches multiple players (e.g. you have *«Кухня»* and *«Кухня small»*), the skill responds *«первая, вторая или третья?»* and waits for the user's spoken ordinal. The conversation state survives across requests via Yandex's session/state envelopes — there is no in-process cache. The skill recognises a wide range of ordinal forms (`первая` / `первый` / `первое` / `первое из`, `вторая`, `третий`, …, both feminine and masculine, both nominative and genitive). +The plugin is added by navigating to MA Settings then selecting Plugins and clicking on ADD A PLUGIN. -## Security notes +The settings form walks through three steps: sign in to Yandex with the Passport device-code flow, create the skill in Yandex Dialogs (one click — the plugin handles registration and deployment), and select the players you want voice control to reach. After Yandex moderation completes (typically 5-15 minutes) the skill is on the air. -- The webhook URL embeds a **random URL-safe 24-byte secret** (`/api/yandex_dialogs/webhook/`); knowing the secret requires access to the skill's Backend URL field in the Yandex Dialogs dev console. The secret is stable across action clicks (regeneration only happens on first form open if the field is empty). -- The handler also checks `body.session.skill_id` against the configured skill ID before processing — a payload from a different skill returns `401`. -- The plugin uses MA's standard logging redaction; the secret is only logged as the last 4 characters of the path on startup. -- The cached `x_token` is stored in MA's encrypted config (SECURE_STRING entry) and is never logged in plaintext. -- If you publish MA via a reverse proxy, expose only the prefix `/api/yandex_dialogs/webhook/`. Block `/` to keep the rest of the MA API/UI off the public internet. +Full step-by-step setup, troubleshooting and FAQ: **[trudenboy.github.io/ma-provider-yandex-alice](https://trudenboy.github.io/ma-provider-yandex-alice/)**. ## Known Issues / Notes -- Direct mode requires a publicly reachable HTTPS endpoint for the MA webserver (port forwarding, reverse proxy or similar). There is no cloud-relay alternative for Dialogs custom skills. -- Automatic skill creation uses an **undocumented** Yandex Dialogs developer-console API. If Yandex changes the contract, manual setup at remains the supported fallback. -- After `request_deploy` Yandex moderation takes 5-15 minutes for `aliceSkill` skills. The dev-console link in the success message lets you check on-air status. -- This plugin uses `mode(input_source)` capability indirectly: free-form voice phrases are parsed server-side, so the Yandex Smart Home `play_media` limit does not apply here. For ordinal-only playlist triggering via the Smart Home API see [Yandex Smart Home Plugin](/plugins/yandex-smarthome). -- The skill name displayed to users is what they say to invoke it (*«Алиса, попроси \ …»*) — Yandex enforces minimum 2 words and global uniqueness across all skills. +- Yandex Dialogs custom skills require a publicly reachable HTTPS endpoint for the MA webserver. Reverse proxy, port forwarding or similar is needed; a private LAN address will not work. +- After the skill is created, Yandex moderation takes 5-15 minutes before voice commands actually reach Alice. The plugin shows live moderation status in the settings form. +- Player aliases set in the *Home with Alice* app are not forwarded to the skill — players are addressed by their Music Assistant name. Rename the player in MA if you want a different voice name. +- The skill is registered against your Yandex account; only one Yandex account per MA instance. From e7ac3ef25d1ac85cc8eaf75c0616683bb93b87c8 Mon Sep 17 00:00:00 2001 From: Mikhail Nevskiy <139659391+trudenboy@users.noreply.github.com> Date: Thu, 7 May 2026 18:13:36 +0300 Subject: [PATCH 3/4] docs(yandex-alice): drop the Yandex Smart Home cross-link callout Co-Authored-By: Claude Opus 4.7 (1M context) --- src/content/docs/plugins/yandex-alice.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/content/docs/plugins/yandex-alice.md b/src/content/docs/plugins/yandex-alice.md index 28d2a4ef2..d210a7fa4 100644 --- a/src/content/docs/plugins/yandex-alice.md +++ b/src/content/docs/plugins/yandex-alice.md @@ -13,9 +13,6 @@ Music Assistant has the ability to be controlled by voice through [Yandex Alice] > [!WARNING] > Music Assistant must be reachable on a **public HTTPS URL** — Yandex sends voice phrases directly to your MA server. There is no cloud relay for Dialogs custom skills. -> [!NOTE] -> This is the voice-control side of the Yandex integration. For device-bridge integration (volume, on/off, playlists exposed as input sources) see the [Yandex Smart Home Plugin](/plugins/yandex-smarthome). The two plugins can run side by side on the same MA instance. - ## Features - Free-form Russian voice playback: search and play artists, albums, tracks, playlists and genres From badb8b1f44f28299f9f4c2e0dd97b6fe566e2aea Mon Sep 17 00:00:00 2001 From: Mikhail Nevskiy <139659391+trudenboy@users.noreply.github.com> Date: Thu, 7 May 2026 18:14:55 +0300 Subject: [PATCH 4/4] docs(yandex-alice): drop Russian / Russian-language mentions Co-Authored-By: Claude Opus 4.7 (1M context) --- src/content/docs/plugins/yandex-alice.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/docs/plugins/yandex-alice.md b/src/content/docs/plugins/yandex-alice.md index d210a7fa4..0e84b8a1d 100644 --- a/src/content/docs/plugins/yandex-alice.md +++ b/src/content/docs/plugins/yandex-alice.md @@ -5,7 +5,7 @@ description: Features and Notes for the Yandex Alice Plugin # Yandex Alice -Music Assistant has the ability to be controlled by voice through [Yandex Alice](https://alice.yandex.ru/), Yandex's Russian-language voice assistant, by registering a custom skill in [Yandex Dialogs](https://dialogs.yandex.ru/developer). Users speak free-form Russian phrases like "Alice, ask <skill name> to play jazz" and Music Assistant resolves the player and the requested media server-side. +Music Assistant has the ability to be controlled by voice through [Yandex Alice](https://alice.yandex.ru/) by registering a custom skill in [Yandex Dialogs](https://dialogs.yandex.ru/developer). Users speak free-form phrases like "Alice, ask <skill name> to play jazz" and Music Assistant resolves the player and the requested media server-side. > [!CAUTION] > This is an unofficial integration and is not affiliated with or endorsed by Yandex. @@ -15,11 +15,11 @@ Music Assistant has the ability to be controlled by voice through [Yandex Alice] ## Features -- Free-form Russian voice playback: search and play artists, albums, tracks, playlists and genres +- Free-form voice playback: search and play artists, albums, tracks, playlists and genres - Transport and queue control: pause / resume / next / previous / seek, shuffle, repeat, add to queue, what's playing - Multi-room: address a specific player by name, transfer the queue to another player, list players - Voice-first disambiguation when a player name is ambiguous (the skill asks "first, second, or third?") -- Russian NLU handles morphologically inflected forms and fuzzy player-name matching +- Morphologically aware natural language understanding with fuzzy player-name matching - One-click skill registration in the config form via Yandex Passport sign-in (no manual setup in the Yandex Dialogs developer console required) ## Configuration