cat posts/%e3%80%90%e6%9c%97%e5%a0%b1%e3%80%91%e3%83%af%e3%82%a4%e3%81%ae%e5%9c%a8%e5%ba%ab%e7%ae%a1%e7%90%86%e3%82%a2%e3%83%97%e3%83%aa%e3%80%81%e5%a3%b0%e3%81%a7%e6%93%8d%e4%bd%9c%e3%81%a7%e3%81%8d%e3%82%8b.md

【朗報】ワイの在庫管理アプリ、声で操作できるようになる

1 風吹けば名無し 2026/09/23(水) 21:04:11 ID:St0kU9ru
ワイの在庫管理アプリ、ついに声で払い出しできるようになったわ
「アレクサ、ストクルを開いて」→「マウス」で在庫が1個減る

2 風吹けば名無し 2026/09/23(水) 21:05:02 ID:Kx7mQp2a
>>1 スマホでポチればええやん

3 風吹けば名無し 2026/09/23(水) 21:05:48 ID:St0kU9ru
>>2 棚の前で両手に段ボール持っとるときにスマホ出せんのや
声なら手ぶらでいける

4 風吹けば名無し 2026/09/23(水) 21:06:19 ID:Rn4bV8ce
で、インテントいくつ作ったんや

5 風吹けば名無し 2026/09/23(水) 21:07:03 ID:St0kU9ru
DecrementStockIntent 1個だけや。サンプル発話も {ItemName} だけ

6 風吹けば名無し 2026/09/23(水) 21:07:41 ID:Rn4bV8ce
>>5 雑すぎて草 「〜を払い出して」とか入れんのか

7 風吹けば名無し 2026/09/23(水) 21:09:12 ID:St0kU9ru
>>6 入れてもええけど品名は DB 側でどんどん増えるからな
発話パターンをモデルに焼き込むと品名を足すたびに再ビルドになる
スロット1個で受けて照合はアプリ側でやるほうが現実的やった

{
  "name": "DecrementStockIntent",
  "slots": [{ "name": "ItemName", "type": "ITEM_NAME" }],
  "samples": ["{ItemName}"]
}

8 風吹けば名無し 2026/09/23(水) 21:10:04 ID:Zq9wT3fh
照合てどうやっとるんや

9 風吹けば名無し 2026/09/23(水) 21:11:30 ID:St0kU9ru
最初は完全一致にしてたら「見つかりませんでした」の連発や
「ボールペン」て言うたのにひらがなで返ってくることがあってな

const normalize = (s) =>
  s.toLowerCase()
   .replace(/\s+/g, '')
   .replace(/[ぁ-ん]/g, (c) => String.fromCharCode(c.charCodeAt(0) + 0x60));

items.find((item) => normalize(item.name) === norm) ||
items.find((item) => normalize(item.name).includes(norm));

10 風吹けば名無し 2026/09/23(水) 21:12:18 ID:Zq9wT3fh
>>9 ひらがな→カタカナを文字コード +0x60 でやるの力技すぎるやろ

11 風吹けば名無し 2026/09/23(水) 21:13:02 ID:St0kU9ru
>>10 動いたからヨシ! 部分一致も入れて「ボールペン黒」でも拾えるようにした

12 風吹けば名無し 2026/09/23(水) 21:14:55 ID:St0kU9ru
でも本番はここからやった
Lambda やめて自前のコンテナにエンドポイント移したら Alexa から一切届かんくなった

13 風吹けば名無し 2026/09/23(水) 21:15:20 ID:Ld2sY6jn
502か?

14 風吹けば名無し 2026/09/23(水) 21:16:08 ID:St0kU9ru
>>13 WAFや。ModSecurity が Alexa の POST を丸ごと弾いとった

location /alexa {
    modsecurity off;
    proxy_pass         http://demo-inventory-alexa:3002;
    proxy_read_timeout 10s;
}

15 風吹けば名無し 2026/09/23(水) 21:16:44 ID:Ld2sY6jn
>>14 WAF切るとか正気か

16 風吹けば名無し 2026/09/23(水) 21:18:31 ID:St0kU9ru
>>15 サイト全体やないで、/alexa ロケーションだけや
ここに来るのは Amazon からの署名付きリクエストだけやからな
疎通確認で 400 が返ってきたら正常、っていうのも最初わからんくて30分溶かした

$ curl -sI -X POST https://inventory.example.com/alexa
HTTP/2 400          # ← これで正常(署名が無いので Alexa 側が400を返す)

17 風吹けば名無し 2026/09/23(水) 21:19:50 ID:Vb5hN1qw
ほかに踏んだ地雷ある?

18 風吹けば名無し 2026/09/23(水) 21:21:12 ID:St0kU9ru
Lambda 時代、Node.js 24 で動かしたら Runtime.CallbackHandlerDeprecated で即死や
22.x に落としたら直った。なんでや

19 風吹けば名無し 2026/09/23(水) 21:22:03 ID:Vb5hN1qw
最新にしとけばええってもんやないんやな

20 風吹けば名無し 2026/09/23(水) 21:23:40 ID:St0kU9ru
せやで
今は棚の前で品名を言うだけで在庫が減る
はたから見たら棚に話しかけとるヤバいやつや