docs: Alexa TTS文書を30番に一本化しアーカイブ索引を追加
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# マスタードキュメント - Alexa TTS API 編
|
||||
|
||||
> **最終更新**: 2026-03-03
|
||||
> **最終更新**: 2026-03-04
|
||||
> **対象システム**: windmill.keinafarm.net(ワークスペース: admins)
|
||||
> **目的**: このドキュメントだけで Alexa TTS API の全容を把握し、作業を継続できること
|
||||
|
||||
@@ -44,10 +44,11 @@ Windmill ワークフロー
|
||||
|
||||
### 現在の状態
|
||||
|
||||
**✅ 完全動作中(2026-03-03 解決済み)**
|
||||
**✅ 完全動作中(2026-03-04 時点)**
|
||||
|
||||
- ローカルPCからもサーバーのDockerコンテナからも、日本語テキストの読み上げが動作する
|
||||
- 解決の鍵: `sequenceJson` 内の日本語文字を `\uXXXX` 形式にエスケープして送信する
|
||||
- 補足: `u/admin/alexa_speak` を API 更新した直後、Windmill UI の入力欄が即時更新されない場合がある(後述の運用回避策を適用)
|
||||
|
||||
---
|
||||
|
||||
@@ -506,6 +507,22 @@ curl -X POST \
|
||||
"https://windmill.keinafarm.net/api/w/admins/jobs/run_wait_result/p/u/admin/alexa_speak"
|
||||
```
|
||||
|
||||
### API反映後にUI入力欄が変わらない場合(2026-03-04 追記)
|
||||
|
||||
`u/admin/alexa_speak` を `create-script` で更新後、API上の `schema` は更新済みでも、Input フォームが旧表示のまま残ることがある。
|
||||
|
||||
対応手順:
|
||||
|
||||
1. APIで最新状態を確認する
|
||||
2. `hash` 更新と `schema.properties.device` の以下2項目を確認する
|
||||
- `format = "dynselect-device"`
|
||||
- `originalType = "DynSelect_device"`
|
||||
3. Windmill UI を `Ctrl + Shift + R` でハードリロードする
|
||||
4. 反映されない場合は `Edit -> Deploy` を1回実行する
|
||||
5. Input フォームで `Device` がドロップダウン表示になったことを確認する
|
||||
|
||||
実運用上は「API反映成功」と「UIフォーム反映成功」を別チェックとして扱う。
|
||||
|
||||
---
|
||||
|
||||
## 11. 既知の問題・落とし穴
|
||||
@@ -546,9 +563,11 @@ curl -X POST \
|
||||
|
||||
| ファイル | 説明 |
|
||||
|---------|------|
|
||||
| `docs/alexa-api/10_Alexa TTS API 実装記録 (2026-03-02).md` | Claude Code による実装記録(Triliumからコピー) |
|
||||
| `docs/alexa-api/11_色々やってダメだった.txt` | ChatGPT との試行錯誤チャットログ |
|
||||
| `docs/alexa-api/12_ローカルで試したこと.md` | 日本語TTS問題の調査記録(解決過程) |
|
||||
| `docs/archive/alexa-tts/10_Alexa TTS API 実装記録 (2026-03-02).md` | Claude Code による実装記録(アーカイブ) |
|
||||
| `docs/archive/alexa-tts/11_色々やってダメだった.txt` | ChatGPT との試行錯誤チャットログ(アーカイブ) |
|
||||
| `docs/archive/alexa-tts/12_ローカルで試したこと.md` | 日本語TTS問題の調査記録(アーカイブ) |
|
||||
| `docs/archive/alexa-tts/21_引き継ぎ_alexa_speak_API反映後にUIドロップダウンが変わらない件.md` | API反映後のUI未反映事象の切り分けと回避策(アーカイブ) |
|
||||
| `docs/archive/alexa-tts/README.md` | Alexa TTS 関連の中間資料アーカイブ索引 |
|
||||
| `docs/30_マスタードキュメント_Alexa_TTS_API編.md` | 本ドキュメント |
|
||||
|
||||
---
|
||||
@@ -602,3 +621,4 @@ var rawSequenceJson = JSON.stringify(sequenceObj).replace(
|
||||
| 2026-03-03 | `\uXXXX` エスケープで日本語TTS完全解決。server.js・test_tts.js に反映 |
|
||||
| 2026-03-03 | 本マスタードキュメント作成 |
|
||||
| 2026-03-03 | findDevice 検索ロジック、キャッシュ仕様、起動初期化、auth4.js 詳細、Dockerfile 仕様を追記 |
|
||||
| 2026-03-04 | `u/admin/alexa_speak` の API 反映後にUIドロップダウンが即時反映されない事象と標準対応(`Edit -> Deploy`)を統合。中間資料のアーカイブ索引を追加 |
|
||||
|
||||
148
docs/archive/alexa-tts/10_Alexa TTS API 実装記録 (2026-03-02).md
Normal file
148
docs/archive/alexa-tts/10_Alexa TTS API 実装記録 (2026-03-02).md
Normal file
@@ -0,0 +1,148 @@
|
||||
Alexa TTS API マスタードキュメント
|
||||
|
||||
最終更新: 2026-03-03 状態: サーバーからの日本語TTS未解決(調査中)
|
||||
------------
|
||||
2026/03/03 10:24 akira記録
|
||||
akiraが下記の変更をしましたので、内容を読んでください。
|
||||
|
||||
1) 構成とサーバーへのファイル受け渡し方法を変更しました
|
||||
/home/claude/windmill_workflow
|
||||
に、https://gitea.keinafarm.net/akira/windmill_workflow.gitをcloneしました
|
||||
これにより、
|
||||
C:\Users\akira\Develop\windmill_workflow
|
||||
とのやり取りはgiteaを使って出来るようになります。
|
||||
|
||||
2) docker compose up -dで、「 Docker 内部の IP アドレスが変わり、Traefik のルーティングが古い IP を参照したまま 502/504 エラーになる」のは、原因があるはずです。(他のコンテナで、問題になっていないので)
|
||||
調査して、Traefik 再起動が不必要になるようにしたいです
|
||||
|
||||
|
||||
|
||||
------------
|
||||
|
||||
概要
|
||||
Windmill から家中の Echo デバイスに任意のテキストを読み上げさせる API サーバー。Node.js + Express で実装し、Docker コンテナとして Windmill サーバー上で稼働する。
|
||||
|
||||
⚠ 現在の問題: ローカル PC からは日本語TTS動作確認済み。しかしサーバー(keinafarm.net)のコンテナからリクエストすると日本語文字が Amazon 側で除去されて発話されない。原因は Amazon の IP ベースフィルタリング(海外IPからは日本語 textToSpeak を無視する模様)。調査継続中。
|
||||
|
||||
ファイル構成
|
||||
ファイル 場所 役割 備考
|
||||
server.js alexa-api/(リポジトリ) Express API サーバー本体 本番コード。変更したらビルド・再デプロイが必要
|
||||
Dockerfile alexa-api/(リポジトリ) Docker イメージ定義 node:20-alpine ベース。server.js と package*.json をコピー
|
||||
docker-compose.yml alexa-api/(リポジトリ) コンテナ起動設定 windmill_windmill-internal ネットワーク接続。外部ポート非公開
|
||||
package.json / package-lock.json alexa-api/(リポジトリ) npm 依存関係 本番: express のみ。devDeps に alexa-remote2(不使用)
|
||||
.env.example alexa-api/(リポジトリ) 環境変数テンプレート ALEXA_COOKIE=xxx の形式
|
||||
.env alexa-api/(リポジトリ、.gitignore 対象) 実際の Cookie 保管 Git にコミットしない。ローカル作業後に scp でサーバーへ転送
|
||||
auth4.js alexa-api/(リポジトリ) Amazon 認証・Cookie 取得スクリプト ローカルのみで実行(Windows PC)
|
||||
auth.js / auth2.js / auth3.js alexa-api/(リポジトリ) auth4.js の旧バージョン 参考用。実際は auth4.js を使う
|
||||
test_tts.js alexa-api/(リポジトリ) ローカルテスト用スクリプト 直接 alexa.amazon.co.jp を叩いて動作確認
|
||||
サーバー上のファイル場所: /home/claude/alexa-api/(git リポジトリとは別にコピーして管理)
|
||||
|
||||
サーバーへのデプロイ手順
|
||||
server.js や Dockerfile、package.json を変更した場合は以下の手順でサーバーに反映する。
|
||||
|
||||
Step 1: ローカルでファイルを編集
|
||||
リポジトリ(c:\Users\akira\Develop\windmill_workflow\alexa-api\)でファイルを編集する。
|
||||
|
||||
Step 2: scp でサーバーに転送
|
||||
変更したファイルをサーバーに scp で転送する:
|
||||
|
||||
# server.js を変更した場合 scp alexa-api/server.js keinafarm-claude:/home/claude/alexa-api/server.js # Dockerfile や package.json を変更した場合 scp alexa-api/Dockerfile keinafarm-claude:/home/claude/alexa-api/Dockerfile scp alexa-api/package.json keinafarm-claude:/home/claude/alexa-api/package.json scp alexa-api/package-lock.json keinafarm-claude:/home/claude/alexa-api/package-lock.json # .env を更新した場合(Cookie 更新時など) scp alexa-api/.env keinafarm-claude:/home/claude/alexa-api/.env
|
||||
|
||||
Step 3: サーバーでビルドして再起動
|
||||
⚠ 重要: docker compose restart はイメージをリビルドしない。server.js 等を変更した場合は必ず build + up -d を実行すること。
|
||||
|
||||
# SSH でサーバーに接続してビルド+起動 ssh keinafarm-claude cd /home/claude/alexa-api # イメージをビルド(server.js 等の変更を反映) sudo docker compose build # コンテナを再作成して起動 sudo docker compose up -d # Traefik を再起動(コンテナ再作成後は必須) sudo docker restart traefik
|
||||
|
||||
Step 4: 動作確認
|
||||
# ヘルスチェック(Windmill ワーカーコンテナ内から) curl http://alexa_api:3500/health # ログ確認 sudo docker logs alexa_api -f # デバイス一覧確認 curl http://alexa_api:3500/devices
|
||||
|
||||
Cookie だけ更新する場合(server.js 変更なし)
|
||||
# .env をサーバーに転送 scp alexa-api/.env keinafarm-claude:/home/claude/alexa-api/.env # コンテナを再起動(restart で OK → イメージのリビルド不要) ssh keinafarm-claude 'sudo docker compose -f /home/claude/alexa-api/docker-compose.yml restart' # ※ Traefik の再起動は不要(コンテナ再作成しないため)
|
||||
|
||||
Traefik 再起動が必要な理由
|
||||
docker compose up -d はコンテナを「再作成」する(docker compose restart は既存コンテナを再起動するだけ)。コンテナが再作成されると Docker 内部の IP アドレスが変わり、Traefik のルーティングが古い IP を参照したまま 502/504 エラーになる。
|
||||
|
||||
対処: sudo docker restart traefik で Traefik に新しい IP を再検出させる。
|
||||
|
||||
この問題は Traefik の設定で watch: true にすれば自動解消できるが、現状はコンテナ再作成のたびに手動で Traefik を再起動する運用としている。
|
||||
|
||||
docker-compose.yml の内容
|
||||
services: alexa-api: build: . container_name: alexa_api restart: unless-stopped env_file: - .env environment: - PORT=3500 networks: - windmill_windmill-internal # 外部には公開しない(Windmill ワーカーから内部ネットワーク経由でのみアクセス) # デバッグ時は以下のコメントを外す: # ports: # - "127.0.0.1:3500:3500" networks: windmill_windmill-internal: external: true
|
||||
|
||||
認証方法(auth4.js)
|
||||
Amazon Japan OpenID フローを自前で実装。ローカル PC(Windows)でのみ実行する:
|
||||
|
||||
# ローカルPC の alexa-api ディレクトリで実行 cd alexa-api AMAZON_EMAIL="メールアドレス" AMAZON_PASSWORD="パスワード" node auth4.js
|
||||
|
||||
成功すると alexa-api/.env が生成または更新される。
|
||||
|
||||
ログインフローの概要:
|
||||
|
||||
GET https://www.amazon.co.jp/ap/signin?openid.assoc_handle=amzn_dp_project_dee_jp
|
||||
hidden フィールド(anti-csrftoken-a2z, appActionToken, workflowState 等)を抽出
|
||||
POST でメール/パスワードを送信
|
||||
alexa.amazon.co.jp/api/apps/v1/token へのリダイレクトをたどる
|
||||
取得した Cookie(at-acbjp, sess-at-acbjp, sst-acbjp, session-token 等)を .env に保存
|
||||
TTS の仕組み(server.js)
|
||||
alexa-remote2 は使わない直接 API 実装。Endpoints:
|
||||
|
||||
POST /speak — { device: "デバイス名 or serial", text: "しゃべる内容" }
|
||||
GET /devices — デバイス一覧
|
||||
GET /health — ヘルスチェック
|
||||
内部の API 呼び出し順序:
|
||||
|
||||
GET /api/language → Set-Cookie: csrf=XXXXX を取得(毎リクエストごと)
|
||||
GET /api/bootstrap → customerId を取得(キャッシュ: 永続)(A1AE8HXD8IJ61L)
|
||||
GET /api/devices-v2/device → デバイス一覧(5分キャッシュ)
|
||||
POST /api/behaviors/preview にシーケンス JSON を送信
|
||||
POST /api/behaviors/preview のボディ構造:
|
||||
|
||||
{ behaviorId: "PREVIEW", sequenceJson: JSON.stringify({ "@type": "com.amazon.alexa.behaviors.model.Sequence", startNode: { "@type": "com.amazon.alexa.behaviors.model.OpaquePayloadOperationNode", type: "Alexa.Speak", operationPayload: { deviceType: "...", deviceSerialNumber: "...", customerId: "A1AE8HXD8IJ61L", locale: "ja-JP", // ← 重要(下記参照) textToSpeak: "発話内容" } } }), status: "ENABLED" }
|
||||
|
||||
ヘッダーに csrf: XXXXX と Cookie に csrf=XXXXX の両方が必要。Content-Length は Buffer.byteLength で計算(マルチバイト文字対応)。
|
||||
|
||||
⚠ locale パラメータについて(重要・未解決)
|
||||
locale 値 ローカル PC から サーバー(keinafarm.net)から
|
||||
""(空文字) ✅ 日本語・英語・漢字全て発話 ❌ 英語TTSになり日本語部分が発話されない
|
||||
"ja-JP" ❌ 一瞬音が出るだけ(失敗) ❌ 日本語文字が Amazon 側で除去され英字のみ発話
|
||||
現在 server.js では locale: "ja-JP" に設定している。
|
||||
|
||||
仮説: Amazon が海外IP(keinafarm.net = 非日本IP)からのリクエストを IP ベースでフィルタリングし、textToSpeak の日本語文字を除去している。Alexa.TextCommand は同じ問題がない(異なる API パス)。
|
||||
|
||||
確認済み事実: alexa_api の server.js ログには日本語テキストが正しく届いている。除去は Amazon サーバー側で発生。
|
||||
|
||||
次の調査候補:
|
||||
|
||||
SSML の <lang xml:lang="ja-JP"> タグで強制的に日本語 TTS を指定できるか
|
||||
Alexa.TextCommand で「次を読み上げて:{text}」形式が使えるか
|
||||
ローカルブリッジ方式(ユーザーのローカル PC で小さなプロキシサーバーを動かし、クラウドサーバーからローカル経由で alexa.amazon.co.jp を叩く)
|
||||
デバイス一覧(Echo デバイスのみ)
|
||||
名前 deviceType serialNumber
|
||||
プレハブ A4ZXE0RM7LQ7A G0922H085165007R
|
||||
リビングエコー1 ASQZWP4GPYUT7 G8M2DB08522600RL
|
||||
リビングエコー2 ASQZWP4GPYUT7 G8M2DB08522503WF
|
||||
オフィスの右エコー A4ZXE0RM7LQ7A G0922H08525302K5
|
||||
オフィスの左エコー A4ZXE0RM7LQ7A G0922H08525302J9
|
||||
寝室のエコー ASQZWP4GPYUT7 G8M2HN08534302XH
|
||||
Windmill スクリプト(u/admin/alexa_speak)
|
||||
export async function main(device: string, text: string) { const res = await fetch("http://alexa_api:3500/speak", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ device, text }), }); if (!res.ok) throw new Error("alexa-api error " + res.status); return res.json(); }
|
||||
|
||||
device はデバイス名(日本語)またはシリアル番号で指定可能。Windmill ワーカーから http://alexa_api:3500 でアクセス(windmill_windmill-internal ネットワーク経由)。
|
||||
|
||||
Cookie の更新手順
|
||||
Cookie は数日〜数週間で期限切れ。切れたら:
|
||||
|
||||
# 1. ローカル PC で Cookie を取得 cd alexa-api AMAZON_EMAIL="メールアドレス" AMAZON_PASSWORD="パスワード" node auth4.js # → alexa-api/.env が更新される # 2. サーバーに .env を転送 scp alexa-api/.env keinafarm-claude:/home/claude/alexa-api/.env # 3. コンテナを再起動(restart で OK、リビルド不要) ssh keinafarm-claude 'sudo docker compose -f /home/claude/alexa-api/docker-compose.yml restart' # ※ Traefik 再起動は不要(コンテナ再作成なし)
|
||||
|
||||
既知の問題・落とし穴
|
||||
docker compose restart ≠ リビルド: server.js を変更しても restart ではコンテナ内のコードは古いまま。build + up -d が必要。
|
||||
コンテナ再作成後は Traefik 再起動必須: up -d でコンテナ再作成すると Docker 内部 IP が変わり Traefik が 502/504 を返す。sudo docker restart traefik で解消。
|
||||
alexa-remote2 は使えない: 取得した Cookie 文字列を受け付けない(内部で再認証しようとして失敗)。直接 API 実装が必要。
|
||||
CSRF トークンは Cookie と ヘッダーの両方に必要: csrf ヘッダーだけ、または Cookie だけでは認証失敗。
|
||||
operationPayload に customerId 必須: ないと 400 エラー。
|
||||
レート制限: 短時間に連続リクエストすると HTTP 429 または 200 で音が出ない。通常の通知用途では問題なし。
|
||||
git push がブロックされる: Gitea の pre-receive フック(remote: Gitea: User permission denied for writing)で push が失敗する。根本原因は未調査。ファイル転送は scp で行っている。
|
||||
firstRunCompleted: false はデバイス設定の未完了フラグ: TTS には直接影響しない(root cause ではなかった)。
|
||||
サーバー上の運用コマンド一覧
|
||||
# コンテナ状態確認 sudo docker ps | grep alexa # リアルタイムログ確認 sudo docker logs alexa_api -f # コンテナ停止 sudo docker compose -f /home/claude/alexa-api/docker-compose.yml stop # ビルド+起動(コード変更後) cd /home/claude/alexa-api sudo docker compose build sudo docker compose up -d sudo docker restart traefik # Cookie 更新時(再起動のみ) sudo docker compose -f /home/claude/alexa-api/docker-compose.yml restart
|
||||
|
||||
2129
docs/archive/alexa-tts/11_色々やってダメだった.txt
Normal file
2129
docs/archive/alexa-tts/11_色々やってダメだった.txt
Normal file
File diff suppressed because it is too large
Load Diff
163
docs/archive/alexa-tts/12_ローカルで試したこと.md
Normal file
163
docs/archive/alexa-tts/12_ローカルで試したこと.md
Normal file
@@ -0,0 +1,163 @@
|
||||
# Alexa 日本語 TTS 問題 試行記録
|
||||
|
||||
最終更新: 2026-03-03
|
||||
担当: akira + AI (Antigravity)
|
||||
|
||||
---
|
||||
|
||||
## 現在の問題
|
||||
|
||||
`/api/behaviors/preview` + `Alexa.Speak` を使って日本語テキストを TTSで発話させようとしているが、
|
||||
**日本語Unicode文字だけが Amazon 側でフィルタリングされ、発話されない。**
|
||||
ASCII文字(英語)は正常に発話される。
|
||||
|
||||
---
|
||||
|
||||
## 環境
|
||||
|
||||
- テスト用スクリプト: `alexa-api/test_tts.js`(ローカルPCから直接 alexa.amazon.co.jp を叩く)
|
||||
- 本番: `alexa-api/server.js`(VPS上のDockerコンテナ)
|
||||
- テストデバイス: オフィスの右エコー (serial: G0922H08525302K5, type: A4ZXE0RM7LQ7A)
|
||||
- Alexaアプリでデバイス言語設定: **日本語** に設定済み(確認済み)
|
||||
- VPS IP: 162.43.33.56(大阪・Xserver Inc. = 日本国内 ✅ )
|
||||
|
||||
---
|
||||
|
||||
## 試行ログ(時系列)
|
||||
|
||||
### 【サーバー側での試行】(ChatGPT との会話ログより、2026-03-02〜03)
|
||||
|
||||
#### ❌ `speakType: 'ssml'` を `operationPayload` に追加
|
||||
```json
|
||||
"type": "Alexa.Speak",
|
||||
"operationPayload": { ..., "speakType": "ssml" }
|
||||
```
|
||||
→ 変化なし。`Alexa.Speak` はSSML非対応のため無効。
|
||||
|
||||
#### ❌ `type: 'Alexa.SpeakSsml'` に変更 + `textToSpeak` にSSMLなし
|
||||
```json
|
||||
"type": "Alexa.SpeakSsml",
|
||||
"operationPayload": { ..., "textToSpeak": text }
|
||||
```
|
||||
→ 英語も含めて完全無音(LEDも反応なし)。
|
||||
|
||||
#### ❌ `Alexa.SpeakSsml` + `textToSpeak: '<speak>'+text+'</speak>'`
|
||||
→ 英語も無音。`Alexa.SpeakSsml` は `textToSpeak` ではなく別キーを要求する模様。
|
||||
|
||||
#### ❌ `Alexa.SpeakSsml` + `ssml: ssml`(キー名を変更)
|
||||
→ 英語も発話せず。
|
||||
|
||||
**ChatGPTの最終見解:** `/api/behaviors/preview` では `Alexa.SpeakSsml` は動作しない(APIの癖)。`Alexa.Speak` に戻すしかない。
|
||||
|
||||
---
|
||||
|
||||
### 【ローカルPCでの試行】(2026-03-03 午前)
|
||||
|
||||
#### ❌ `locale: 'ja-JP'` + 日本語テキスト(test_tts.js デフォルト)
|
||||
```js
|
||||
locale: 'ja-JP',
|
||||
textToSpeak: 'テストです。聞こえますか'
|
||||
```
|
||||
→ 「エ」だけ発話(最初の「テ」の母音のみ)。
|
||||
|
||||
#### ✅ `locale: ''` + ASCII: `'hello'`
|
||||
→ 「ハロー」と正常発話。英語は問題なし。
|
||||
|
||||
#### ❌ `locale: ''` + 日本語: `'テストです。聞こえますか'`
|
||||
→ 「エ」のみ。デバイス言語が英語設定ならこの動作になるが、日本語設定確認済みのため別原因。
|
||||
|
||||
#### ❌ `locale: 'ja-JP'` + 日本語: `'テストです。これは日本語のテストです'`
|
||||
→ 「えんえ」のような音のみ(断片的な音)。
|
||||
|
||||
#### ❌ `locale: 'ja-JP'` + ひらがな: `'あいうえお'`
|
||||
→ 無音(LEDは点滅 = 通知は届いている)。
|
||||
|
||||
#### 🔍 `locale: 'ja-JP'` + 混在: `'あいうえおThis is Testあいうえお'`
|
||||
→ 「ディスイズテスタ」のみ発話。
|
||||
**重要: 日本語部分は無音、ASCII部分のみ日本語アクセントで読まれる。**
|
||||
→ Amazon側で日本語Unicodeを除去している証拠。
|
||||
|
||||
#### ❌ `locale: 'ja-JP'` + Unicodeエスケープ: `'\u3053\u308c\u306f\u30c6\u30b9\u30c8\u3067\u3059'`
|
||||
→ 無音。ファイルエンコード問題ではない(Unicodeエスケープ = `これはテストです` と同一)。
|
||||
**→ 文字コードの問題ではないことが確定。**
|
||||
|
||||
#### ❌ `type: 'AlexaAnnouncement'` + locale:`'ja-JP'` + content[].speak構造
|
||||
```json
|
||||
"type": "AlexaAnnouncement",
|
||||
"operationPayload": {
|
||||
"content": [{ "locale": "ja-JP", "speak": { "type": "text", "value": "日本語のテストです" } }],
|
||||
"target": { "devices": [...] }
|
||||
}
|
||||
```
|
||||
→ 「えんえせんと」("AlexaAnnouncement" を日本語発音で読んだもの)。
|
||||
コンテンツではなくノード型名が読まれた → このノードタイプは別用途。
|
||||
|
||||
---
|
||||
|
||||
## 確定した事実
|
||||
|
||||
| 事実 | 根拠 |
|
||||
|------|------|
|
||||
| 通知自体は届いている | LEDが点滅する |
|
||||
| 英語ASCIIは正常発話 | "hello" → 「ハロー」、"This is Test" → 「ディスイズテスタ」 |
|
||||
| 日本語Unicodeのみ除去される | 混在テキストで確認。Unicodeエスケープでも同じ |
|
||||
| デバイス言語設定は日本語 | Alexaアプリで確認済み |
|
||||
| サーバーIPは日本(大阪) | ipinfo.io で確認: Xserver Inc., JP |
|
||||
| 文字コードは問題なし | Unicodeエスケープテストで確定 |
|
||||
| `Alexa.SpeakSsml` 系は全て失敗 | 英語含め無音 |
|
||||
| `AlexaAnnouncement` は別用途 | ノード型名が読まれた |
|
||||
|
||||
---
|
||||
|
||||
## 仮説(現在)
|
||||
|
||||
Amazon の `/api/behaviors/preview` エンドポイントが、
|
||||
何らかの理由で `textToSpeak` 内の日本語Unicodeを除去している。
|
||||
|
||||
考えられる原因:
|
||||
1. **セッション/Cookie が古くなりJapanese TTS権限が変わった**(Cookie の再生成で解消する可能性)
|
||||
2. **Amazonが API の挙動を変更した**(非公開APIのためいつでも変更しうる)
|
||||
3. **別のAPIエンドポイントが必要**(未探索のルートがある可能性)
|
||||
|
||||
---
|
||||
|
||||
## 試行ログ続き(2026-03-03 午後)
|
||||
|
||||
#### Cookie 新規取得(auth4.js 再実行)
|
||||
→ 変化なし。Cookie は原因ではなかった。
|
||||
|
||||
#### ❌ `AlexaAnnouncement` ノードタイプ
|
||||
→ 「えんえせんと」("AlexaAnnouncement" を日本語で読んだ)。コンテンツではなくノード名が読まれた。別用途のノード。
|
||||
|
||||
#### ✅ **解決!** `sequenceJson` の non-ASCII を `\uXXXX` エスケープに変換
|
||||
|
||||
```javascript
|
||||
var rawSequenceJson = JSON.stringify(sequenceObj).replace(
|
||||
/[\u0080-\uffff]/g,
|
||||
function(c) { return '\\u' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4); }
|
||||
);
|
||||
```
|
||||
|
||||
→ 「これは日本語のテストです」が完璧に発話された!
|
||||
|
||||
---
|
||||
|
||||
## ✅ 解決済み(2026-03-03)
|
||||
|
||||
**根本原因**: `sequenceJson` 内の日本語文字を raw UTF-8 のまま Amazon に送ると、Amazon 側のパーサーがそれをフィルタリングして無視する。
|
||||
|
||||
**解決策**: `JSON.stringify(sequenceObj)` 後に non-ASCII 文字(`\u0080` 以上)を `\uXXXX` 形式のJSONエスケープシーケンスに変換してから `sequenceJson` として送る。
|
||||
|
||||
**修正箇所**: `alexa-api/server.js` と `alexa-api/test_tts.js`
|
||||
|
||||
**確定したパラメータ**:
|
||||
- `type: 'Alexa.Speak'`
|
||||
- `locale: 'ja-JP'`
|
||||
- `textToSpeak: <日本語テキスト>`
|
||||
- `sequenceJson` は non-ASCII を `\uXXXX` エスケープして送る
|
||||
|
||||
---
|
||||
|
||||
## 参考
|
||||
|
||||
- 実装記録: `docs/alexa-api/10_Alexa TTS API 実装記録 (2026-03-02).md`
|
||||
@@ -0,0 +1,105 @@
|
||||
# 引き継ぎ - `u/admin/alexa_speak` API反映後にUIドロップダウンが変わらない件
|
||||
|
||||
> **作成日**: 2026-03-04
|
||||
> **対象**: `windmill.keinafarm.net` / workspace `admins`
|
||||
> **対象スクリプト**: `u/admin/alexa_speak`
|
||||
> **目的**: 別端末から同じ事象に遭遇しても、原因切り分けと復旧をすぐ実施できるようにする
|
||||
|
||||
---
|
||||
|
||||
## 1. 事象の概要
|
||||
|
||||
`u/admin/alexa_speak` を Windmill API(`create-script`)で更新した直後、
|
||||
|
||||
- Scriptタブ上のコードは更新済み
|
||||
- `schema` 上も `device` が `dynselect-device`
|
||||
- しかし Inputフォームは `Device` がテキスト入力のまま(ドロップダウンにならない)
|
||||
|
||||
という状態になった。
|
||||
|
||||
---
|
||||
|
||||
## 2. 当日の時系列(要点)
|
||||
|
||||
1. 既存スクリプトを取得し、ローカル `scripts/alexa_speak.ts`(Dynamic Select実装あり)をAPIで反映
|
||||
2. サーバー再取得で `content` 一致を確認(更新自体は成功)
|
||||
3. UIを開くと `Device` が入力欄のままで、ドロップダウン化されていない
|
||||
4. `schema.device` を `format: dynselect-device`, `originalType: DynSelect_device` に更新して再反映
|
||||
5. それでも UI は直ちには変わらず
|
||||
6. Windmill UIで `Edit` に入り、`Deploy` を1回実施
|
||||
7. 直後にドロップダウン表示へ反映
|
||||
|
||||
---
|
||||
|
||||
## 3. 確認できた事実
|
||||
|
||||
- API反映は成功している(hash更新)
|
||||
- 中間: `a6010687183a199d`
|
||||
- 最終: `318d78f45a084e32`
|
||||
- 最終状態では以下がAPIで確認済み
|
||||
- `schema.properties.device.format = "dynselect-device"`
|
||||
- `schema.properties.device.originalType = "DynSelect_device"`
|
||||
- UI反映は API反映だけでは即時にならず、`Edit -> Deploy` 後に反映された
|
||||
|
||||
---
|
||||
|
||||
## 4. 想定される原因
|
||||
|
||||
Windmill CE 側で、API経由更新時にフォームUIメタ情報(入力ウィジェット解決)の再計算または再適用が即時反映されないケースがある。
|
||||
|
||||
実務上は「API更新後にUIで1回Deploy」が回避策として有効。
|
||||
|
||||
---
|
||||
|
||||
## 5. 再現時の標準対応手順(Runbook)
|
||||
|
||||
### 5.1 APIでスクリプト更新
|
||||
|
||||
```bash
|
||||
cd /home/akira/develop/windmill_workflow
|
||||
./wm-api.sh get-script u/admin/alexa_speak > /tmp/remote_alexa_speak.json
|
||||
# parent_hash を含む payload を作成して create-script
|
||||
./wm-api.sh create-script /tmp/alexa_speak_push.json
|
||||
```
|
||||
|
||||
### 5.2 APIで反映確認
|
||||
|
||||
```bash
|
||||
./wm-api.sh get-script u/admin/alexa_speak
|
||||
```
|
||||
|
||||
確認ポイント:
|
||||
|
||||
- `hash` が更新されている
|
||||
- `content` が想定コードになっている
|
||||
- `schema.properties.device.format` が `dynselect-device`
|
||||
- `schema.properties.device.originalType` が `DynSelect_device`
|
||||
|
||||
### 5.3 UI反映されない場合
|
||||
|
||||
1. `u/admin/alexa_speak` を最新リビジョンで開く
|
||||
2. ハードリロード(`Ctrl + Shift + R`)
|
||||
3. 変化がなければ `Edit -> Deploy` を1回実施
|
||||
4. Inputフォームの `Device` がドロップダウン化されたことを確認
|
||||
|
||||
---
|
||||
|
||||
## 6. 補足(今回の最終状態)
|
||||
|
||||
- スクリプト: `u/admin/alexa_speak`
|
||||
- 期待UI:
|
||||
- `Device`: ドロップダウン(dynselect)
|
||||
- `Text`: テキスト入力
|
||||
- 前提:
|
||||
- `alexa_api` コンテナが稼働
|
||||
- `http://alexa_api:3500/devices` が取得可能
|
||||
|
||||
---
|
||||
|
||||
## 7. 引き継ぎメモ
|
||||
|
||||
- 「API反映成功」と「UIフォーム反映成功」は同時とは限らない
|
||||
- 引き継ぎ時は、必ず以下をセットで確認する
|
||||
1. APIレスポンスの `hash` と `schema`
|
||||
2. UI表示(必要なら `Edit -> Deploy`)
|
||||
|
||||
24
docs/archive/alexa-tts/README.md
Normal file
24
docs/archive/alexa-tts/README.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# Alexa TTS API 関連アーカイブ
|
||||
|
||||
最終統合ドキュメントは以下:
|
||||
|
||||
- `docs/30_マスタードキュメント_Alexa_TTS_API編.md`
|
||||
|
||||
途中経過・検証メモ(本アーカイブ内コピー):
|
||||
|
||||
- `docs/archive/alexa-tts/10_Alexa TTS API 実装記録 (2026-03-02).md`
|
||||
- `docs/archive/alexa-tts/11_色々やってダメだった.txt`
|
||||
- `docs/archive/alexa-tts/12_ローカルで試したこと.md`
|
||||
- `docs/archive/alexa-tts/21_引き継ぎ_alexa_speak_API反映後にUIドロップダウンが変わらない件.md`
|
||||
|
||||
原本の参照先:
|
||||
|
||||
- `docs/alexa-api/10_Alexa TTS API 実装記録 (2026-03-02).md`
|
||||
- `docs/alexa-api/11_色々やってダメだった.txt`
|
||||
- `docs/alexa-api/12_ローカルで試したこと.md`
|
||||
- `docs/flow-manage/11_引き継ぎ_alexa_speak_API反映後にUIドロップダウンが変わらない件.md`
|
||||
|
||||
補足:
|
||||
|
||||
- `docs/flow-manage/10_マスタードキュメント_Windmillフロー管理_API一本化編.md` は
|
||||
Alexa TTS 単体ではなく、Windmill API運用全体の親ドキュメントとして維持する。
|
||||
Reference in New Issue
Block a user