作ったばかりの有料機能を、自分で破りに行った — 無料アカウントで叩いたら穴が3つ出た — 制作日誌 #21
「自分のAIキーを持ち込めるようにできないか」から始まった機能を、有料プランの特典として出した。実機で5つの穴を潰して満足しかけたが、無料のアカウントを1つ作って自分のサーバーを叩いてみたら、まだ3つ残っていた。
自作のタスク管理アプリには、AIに文章を渡して予定に変える機能がある。動かす費用はこちらが持っているので、使える回数に上限を置いている。
そこへ「自分で契約しているAIの鍵を持ち込めるようにすれば、上限を気にせず使えるのでは」という話が出た。月100円くらいでどうか、と。
結論から書くと、100円の単独プランは作らなかった。そして機能そのものは作って出した。さらに出したあとで、自分の作ったばかりの機能を自分で破りに行った。
まず値付けで分岐した
100円の箱を新しく作るか、既にある有料プランの特典として入れるか。調べてから決めた。
| 見たこと | 分かったこと |
|---|---|
| 同種のアプリで「鍵の持ち込み」に課金している例 | ゼロ。持ち込みは無料が標準で、有料の例は月8ドル〜・買い切り39ドル〜の機能の束だった |
| 審査の前例 | 「鍵を入れると機能が開く」形が却下された例がある(2024年・開発者向け掲示板 763884) |
| 100円は設定できるのか | できる。ただし手取りは約85円、消費税を納める立場なら約78円 |
3つ目は念のため調べた数字で、決め手は上2つだった。前例がゼロの値付けを、却下の前例がある形で出す理由がない。持ち込みは既にある有料プランの特典にした。特典は2つ、自分の鍵で動かした分は回数に数えないことと、AIの会社とモデルを選べること。
作ったもの
サーバー側に、会社ごとにバラバラだった呼び出しを1か所へまとめた窓口を新しく置いた。こちらが費用を持つ経路も、持ち込みの経路も、全部そこを通る。
鍵の扱いは1つだけ決めた。受け取ったらその場で使って捨てる。記録にも保管場所にも残さない。 端末側では鍵は端末の金庫にだけ置き、つながるかどうかの確認とモデルの一覧取得は、サーバーを通さず端末から各社へ直接叩く。こちらの手を経由しないので、そもそも見えない。
出す前に、変更前と変更後のサーバーを偽の外部につないで突き合わせ、こちらが費用を持つ経路6通りの応答が完全に一致することを確かめた。窓口を1か所に寄せる工事は、既に動いているものを壊しやすい。
もう1つ決めたのは、間違った鍵が来たときに黙ってこちらの鍵へ切り替えないことだ。切り替えれば利用者から見れば動き続けるし、その場は親切に見える。ただし「自分の鍵で動いている」と思っている人の裏で、こちらの費用が静かに増える。持ち込みの資格がなければ突き返し、値が壊れていれば壊れていると返す。動かないことが分かるほうが、動いているように見えることより安全だと判断した。
実機で5つ出た
書き上げてから端末で触った。5つ出た。
| 出たこと | 何が起きていたか |
|---|---|
| 既定のモデルが一番高い段になっていた | 一覧の名前に日付が付いていて名前の完全一致から外れ、「一覧の先頭」に落ちていた |
| 自分の鍵なのに「今月あと◯回」と出る | 上限なしの表示に切り替わっていなかった |
| 起動しても表示が変わらない | 起動時に鍵を読み込んでいなかった |
| 週次の棚卸しが回数を1つ食う | 持ち込みで動かしたのに、その日の枠が減っていた |
| 残高切れが「混雑しています」と出る | ある会社は残高切れを混雑と同じ番号で返してくる。鍵の問題として出すよう直した |
5つのうち上の4つは「見た目が合っていない」類で、1つ目だけは中身が違う。名前の完全一致で探して見つからなかったら一覧の先頭を選ぶ、という書き方をしていたせいで、一番高い段が既定になっていた。黙って高いほうを選ぶのは、費用を持ち込んだ人にとっては請求の話になる。名前の一部で探す順番を決める形に直した。
ここまで直して、正直なところ終わったつもりでいた。
終わらせずに、自分で破りに行った
有料の特典として出したということは、無料のまま使えてしまってはいけないということだ。画面で押せないようにするのは簡単だが、押せないことと、使えないことは違う。
無料のアカウントを1つ作って、アプリではなくサーバーを直接叩いた。AIを使う入口4経路、すべて「有料プランが要る」と突き返された。回数を記録する経路も、持ち込みの合図を付けて叩いても上限なしには化けなかった。
守り自体は効いていた。それでも、周りから3つ出た。
1つ目。 有料プランの案内画面に飛ぶと、見出しが別の機能の名前になっていた。鍵の行が、案内画面に渡す合図を間違えていた。機能としては軽いが、売り文句が違う機能を指しているのは案内として壊れている。
2つ目。 アプリの中の画面には、外から直接ひらく合言葉がある。それを使うと、無料のまま鍵の画面が開けた。サーバーは弾くので実際には動かないのだが、「回数に数えません」と書かれた画面で、使えない鍵を保存できてしまう。画面そのものに判定を入れて、無料なら案内へ差し替えた。
3つ目が一番危なかった。 有料かどうかを調べる関数が、まだ調べ終わっていない状態を有料として扱うようになっていた。守るつもりで書いた既定だ。画面を出すか隠すかの判断なら、それでいい。迷ったら見せておくほうが親切だから。
ところがその同じ判定を、鍵をサーバーへ送るかどうかにも使っていた。結果、起動した直後や通信が不安定なときに、無料の人の鍵が送られ、サーバーに突き返され、AIの機能がまるごと失敗する。守るための既定が、壊す側に回っていた。
調べ終わっていない時を有料とみなさない、別の判定を作った。使うのは鍵を送るかどうかと「上限なし」の表示の2か所だけ。画面の出し分けは今までどおりにした。守る側の既定と、渡す側の既定は逆を向く、というのがこの日の収穫だった。
売り文句に載っていなかった
ついでに気づいたことがある。持ち込みは有料プランの特典なのに、有料プランを売っている画面の説明文に一言も書いていなかった。買う理由として並べていないものを、買った人だけの特典にしていたことになる。13の言語ぶん、説明文に足した。
まだ確かめていないこと
- 3つ目の穴は、起きる条件を実機で再現できていない。直したのはコードの上だけで、症状が消えたことを目で見てはいない。
- 一連の確認はすべてAndroidの端末でやった。iPhoneの実機では未確認。しかも配信に使っている手順は、中身だけ差し替える配り方がiPhone側にしか届かない作りになっている。
- 3社のうち1社は、契約している鍵の残高が切れていて、返ってきた本文まで確かめられていない。
出したことと、確かめたことは違う。ここに書いておかないと、次に触るときの自分が「あれは見たはず」と勘違いする。
コメント (0)
まだコメントはありません。最初の一言を残しませんか?