Zenn
Open33

denoでいい感じにweb API requestをしたい

podhmopodhmo

(あとで冒頭の説明を書く)

📝思っていることのメモ

  • 初手の1ファイルのスクリプトをどこから書き始めるかを考えたい
  • 最終的にまともな型がつくような状態に遷移させたい
  • fetch()のwrapperがあれば十分でクラスとか不要なのでは?
  • はじめからライブラリを使うと統合に苦労するのでは?
podhmopodhmo

1st step (ChatGPT API)

class不要でfetch()のwrapperだけあれば良いのでは?という発想のもと
ChatGPTのAPIを元にコードを書いてみる

https://gist.github.com/podhmo/7b5415c81c102ddb861a9b7b5f0bf048

奮闘の履歴

https://gist.github.com/podhmo/33c1452b24105a4b2123ba068d082308

podhmopodhmo

不足していること

  • stream 対応 (SSE?)
  • request/responseの型をどうやって定義する?(JSONからtransform.toolsとか?)
  • testがない
  • ファイルで入出力を受けるならjsonschemaなども生成したい?
  • modelをコマンドラインオプションにしたい

ライブラリ的な話

  • pathに変数があるAPIへの対応はどうする? e.g. /usrs/{userId}
  • backoff対応はどうする?
  • trace部分はAPIを作る毎に書き下すの? (自動計装まわりでnode-fetchのpatchとかある?)
  • ブラウザ経由で呼び出すのは楽?
podhmopodhmo

2nd step (gemini API)

⚠️googleのweb APIだと認証周りが面倒な気がする。手書きしたくない

https://gist.github.com/podhmo/b404de3a3df5298186997d390a6b581a

🐾 key=<gemini api key> で十分だった。それなりに…機能は…していそう…。

podhmopodhmo
  • pathに変数がある場合は? -> plaecholderで指定して fetchの中でreplace
  • stream対応は? -> https://jsr.io/@lukeed/fetch-event-stream を使った
    -(cli parserのところでchoicesを使うときに補完が効かなくなる問題があった)

path変数の方はfetch()に余分なオプションが与えられるようになったのがキモい。他の方法があれば選択したい。

podhmopodhmo

あと、web ui側のようにrequest/responseを繰り返す所作をやってない。

podhmopodhmo

型を真面目に指定したい

  • responseの型は https://transform.tools/json-to-io-ts でどうにかなる
  • requestの型は documentなどをみて自前で書かないといけない
    • request/responseの型を定義してしまうならDocの型も要らなそう Record<path, url>
podhmopodhmo

tempreature とかを指定したいとnumberも指定したくなるのか。
typescriptはinteger型とか無いのだった。

podhmopodhmo

3rd step

bskyに投稿したい。

https://gist.github.com/podhmo/c020447997d59f2f28b26f0cda9ab242

結構悩ましい事が色々ある

  • どうせなので1ファイルで簡潔させたい
    • 名前の衝突は避けたい
    • namespaceを使うとdeno-lintに怒られるけれどnamespaceを使うことにする
  • request/responseがあやふやになる
  • パスワードがそのまま表示される(ライブラリ的なものの不備)

💭bsky固有の話としてそもそも文字数制限に引っかかる

podhmopodhmo

使用感を求めるタイミングになったら途端にどうでも良くなってきた感がある。

podhmopodhmo

4th step

gistへの投稿をしてみたい。存在しないファイルを存在しているかのようにして。
認証部分を相手にする必要がある?gh auth loginとかで手に入るから大丈夫。

podhmopodhmo

直接 web APIを叩くという方法もあるんじゃ?tokenだけ受け取る。

podhmopodhmo

requestするたびにwithTraceを取るのもめんどくさいのでjsrに上げたくなった。どうせ自分でfetchを呼ぶときには常に欲しくなるしmaskingもしたくなるし。

podhmopodhmo

6th step

一歩戻ってauth周りをgh cliみたいな形で作っていきたい。bsky用のクライアントをそのようなインターフェイスで作ってみる。

  • auth周りのサブコマンドを作る(login,logout,status,token,refresh)
  • passwordの入力
  • postでふつうにpost

https://gist.github.com/podhmo/ca18aa3f456dd1aba25faba2200eda44

podhmopodhmo

できたことは

  • auth login
  • auth status
  • auth token
  • auth refresh
  • post

気になるところはaccess tokenがrequiredとして載りそのままヘルプメッセージに載ってしまうこととauth tokenやauth statusでacess tokenを所持にしていない場合にauth loginを促すような仕組みを作るのがコードとして面倒ということ

あとpostの方ではfacetsを設定しないとテキストがリンクとして機能しないようだった。
とりあえず import { RichText } from "npm:@atproto/api@0.13.20"; でお茶を濁していた。

jsr:@std/dotenvはコメントにも対応していて便利だった。

podhmopodhmo

手抜きでやった結果型チェックが雑になっていた。

podhmopodhmo

スレッドの投稿はできたけれど内容の加工をどのように加えるかという案が思いつかない。

podhmopodhmo

backoffが必要ななにかがほしいかも?
テストを一切書いていない

podhmopodhmo

いっそのこと次回はatprotoへの依存を許して実装してみるか。

podhmopodhmo

8step OGPのデータをブラウザ上で取得したかった

CLI上ではふつうに deno run -A jsr:@podhmo/ogp/collect-ogp https://github.com/podhmo とかが動くがブラウザ上では上手くいかない。基本的にcors関連のあれこれで上手く動いてくれない。試したことは

  • 直接fetch()
  • ifarme
  • window.openでpopup

追記

bsky.appでどうやっているかが気になった。

bsky.appがどうやっているのかといえば素直に自前のweb APIにリクエストしているだけっぽい。cardyb.bsky.app

  1. ogp関連のデータを取得するweb API /v1/extract
  2. カード画像のデータを取得するweb API /v1/image

詳細

GET https://cardyb.bsky.app/v1/extract?url=https%3A%2F%2Fgithub.com%2Fpodhmo

{
  "error": "",
  "likely_type": "html",
  "url": "https://github.com/podhmo",
  "title": "podhmo - Overview",
  "description": "podhmo has 255 repositories available. Follow their code on GitHub.",
  "image": "https://cardyb.bsky.app/v1/image?url=https%3A%2F%2Favatars.githubusercontent.com%2Fu%2F80613%3Fv%3D4%3Fs%3D400"
}
GET https://cardyb.bsky.app/v1/image?url=https%3A%2F%2Favatars.githubusercontent.com%2Fu%2F80613%3Fv%3D4%3Fs%3D400
podhmopodhmo

(これはブラウザ上の話なのでdenoの話とは関係ないかも?)

podhmopodhmo
podhmopodhmo

まだ途中そう。。

  • tsx -> ts -> js変換の結果を保持したclient sideのjsの作り方が分からない
  • server sideだけの場合はhonoとかのほうが良いかも?
podhmopodhmo

一応文字列直書きのバージョンは03communicate.tsで完成している

podhmopodhmo

あと分かっていないこと

  • esm.sh経由でimportしているときにキャッシュが効いていないような気がする?
  • honoの中でscriptタグを挿入するのを試していない
ログインするとコメントできます