Aikの技術日記

技術的な進捗とか成果とかを細々と投稿するブログです。時々雑記も。

esa.ioにてAPI経由で記事を取得するやり方まとめてみた

はじめに

お久しぶりです、筆者です。
すっかり久々の投稿ですね…以前投稿したのが10か月以上前となってしまいました。

最近はプログラミングよりもYoutuber活動や、お絵描き投稿を頻繁にやってましたが…。
公には見せない、自分用のWebアプリもちょこちょこ開発しておりました。

そんな中、筆者が個人で使用させていただいている『esa.io』にて、投稿記事をAPIで取得したいと思い。
色々調査し、API取得方法やどんなデータが取得できるかといった役立ちそうな情報が纏まったので。
本記事では、自分への備忘録がわりにこれらをまとめていければと。

※「esa.ioってなんだ?」と言う方は、手前味噌ではありますが以前サービス概要をまとめましたので良ければ参照に: aik0aaat.hatenadiary.jp

それではいきましょう。

esa.ioが公開してるAPIについて

まずはesa.ioが公開しているAPIの基礎情報から。
執筆当時(2023/02/09)では、「esa API v1」と言う名称で公開されています。 docs.esa.io

APIに関する情報は全て↑記事に載ってるので、分からなくなったらここを見れば全部載ってます。
(その分めちゃくちゃ長い記事ですが…)

クライアントライブラリも提供されてますが、執筆当時ではRubyのみ提供されてます。
他言語で使いたい場合は、自前でAPIを叩かなければなりません。

なお、APIには利用制限が設けられてます。
デフォルトでは「ユーザ毎、15分間75リクエスト」が上限となっており、これ以上のリクエストは弾かれてしまいます。
個人利用ではこの上限は突破しないでしょうが、もし突破したい際は公式へ問い合わせれば緩和してくれるとのこと。

認証&認可について

前提として、esa.ioは「各チームごとに」記事が作られていくサービスであるため…。
記事を取得したい場合は対象記事が所属する「チーム」を指定しなければなりません。

もちろんesa.io上にある全てのチームにアクセスできるわけもなく…。
esa.ioAPIでは全てのリクエストにチームを指定する必要があり、更にそのチームにアクセス可能な「アクセストークン」が必要とされます。

このアクセストークンの取得方法ですが、下記2種類の方法があります:

  • ユーザーの管理画面から発行
  • OAuth認可フローで取得

この記事では発行が簡単な「ユーザーの管理画面から発行」する方法を紹介します。
なおアクセストークンは「ユーザーごと」に発行されるもので、チーム全体を跨いだものではありません。
適切に管理されてれば、アクセストークンからどのユーザーがAPIリクエストしたかが分かる形式ですね。

※本当はスクショして解説をと思いましたが、有料サービスなので手順だけ記載しておきます…。

  1. 自チームのesa.ioの左メニューバー>「Settings」をクリック
  2. メンバー一覧・管理のタブ>自身のアカウントをクリック
  3. 左サイドバー>「Applications」をクリック
  4. 「Personal access tokens」の右横「Generate new token」をクリック
  5. トークン作成画面に遷移するので、「トークン名」と「スコープ」を指定し作成
    • トークン名: esa.io設定画面上で表示されるだけのもの、API使用時には使わない(わかりやすい名前だといいかも)
    • スコープ: 「Read」(読み取り)と「Write」(書き込み)から選択可能
      • 単にデータを取得したいだけならReadのみ、とりあえず全部のAPIを使えるようにしたいならどちらにもチェック
      • ※記事削除APIもあるため、事故が怖い場合はReadのみチェックが吉
  6. 発行後、APIで使用するアクセストークンが表示
    • 画面を更新すると参照できなくなるので、忘れずにメモを

なお、発行したアクセストークンはApplications画面で見ることができますし、
後からトークン名やスコープを変えることができます。
スコープを後から変えれるのは嬉しいポイントですね…。

APIトークンの使い方についてですが、リクエストヘッダにAuthorizationとして追加するか:

Authorization: Bearer 1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef

パラメータ内部に埋め込むことで使用できます。

api.esa.io/v1/teams/[チーム名]/[エンドポイント]?access_token=1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef

※チーム名は「自チームのesa.ioURL」のドメインから、.esa.ioを抜いた部分です:
https://[チーム名].esa.io/

記事取得APIについて

前置きが長くなりましたが、ここから本題の記事取得APIについて見ていきましょう。

  • エンドポイント: https://api.esa.io/v1/teams/[チーム名]/posts
  • メソッド: GET
  • 指定可能なクエリパラメータ:
    • q: 記事の検索文字列(後述)
    • include: 取得したい追加情報↓を設定できる、カンマ区切りで複数指定可(stargazers,comments)
      • comments: 記事コメント
      • comments, comments.stargazers: 記事コメント、コメントに対するStar情報
      • stargazers: 記事自体についてるStar情報
    • sort: ソート方式を指定可能、指定可能な値↓
      • updated: 記事の更新日時(デフォルト値)
      • created: 記事の作成日時
      • number: 記事番号
      • stars: 記事へのStarの数
      • watches: 記事へのWatchの数
      • comments: 記事へのコメントの数
      • best_match: 検索文字列と一致したスコアが高い順(esaの記事検索のデフォルト並び順)
    • order: ソート順を指定可能、指定可能な値↓
      • desc: 降順(デフォルト値)
      • asc: 昇順
  • レスポンス
    • posts[配列]: 取得した記事データ(プロパティが多いので後述)
    • total_count[整数値]: 取得した記事データ総数
    • ページングに必要な情報(後述)

※公式Docsはこちら: docs.esa.io

レスポンスやリクエストの形式からお察しの通り、執筆当時(2023/02/09)では「1つの記事のIDを指定してそれだけを取得」するAPIはなさそうです。
目的の記事だけ取得したいなら、記事の検索文字列を工夫する必要があるかと。

また、指定可能なクエリパラメータを全て指定なしにすると「全ての記事」が「更新日時の降順」で取得できます。

いくつか後述としたところがあるので、1つずつ見ていきましょう。

記事データについて

クエリパラメータincludeに何も指定せず取得可能なプロパティは下記となります:
※種類が多いので、独自にカテゴライズしてみました

  • 基本情報
    • url[文字列(URL)]: 記事へのURL
    • name[文字列]: 記事名
    • category[文字列]: 記事のフォルダパス
    • full_name[文字列]: 記事の全名、category/name=full_nameとなる
    • number[整数値]: 記事ID(記事のURLに載ってるやつ:https://[チーム名].esa.io/posts/[記事ID]
    • tags[文字列配列]: 記事に紐づくタグ
  • 記事内容
    • body_md[文字列]: 記事内容(Markdown形式)
    • body_html[文字列]: 記事内容(HTML形式)
    • tasks_count[整数値]: 記事内部のタスク数
    • done_tasks_count[整数値]: 記事内部の完了したタスク数
  • 作成、更新情報
    • message[文字列]: 最新の更新時ChangeLog内容
    • revision_number[整数値]: 最新のバージョン数
    • created_at[文字列(日時)]: 記事作成日、日付の書式はYYYY-MM-DDThh:mm:ss+09:00
    • updated_at[文字列(日時)]: 記事更新日、日付の書式はYYYY-MM-DDThh:mm:ss+09:00
    • created_by[Object]: 記事作成者情報
      • myself[bool値]: APIトークン発行者と取得者が同じ=true、異なる=false
      • name[文字列]: 記事作成者名(名前)
      • icon[文字列(URL)]: 記事作成者のアイコンURLパス
    • updated_by[Object]: 記事更新者情報、Objectの中身は↑と同じ
  • 他ユーザーからのリアクション情報
    • comments_count[整数値]: コメント数
    • star[bool値]: APIトークン発行者がその記事をStarしてるかどうか
    • stargazers_count[整数値]: スター数
    • watch[bool値]: APIトークン発行者がその記事をWatchしてるかどうか
    • watchers_count[整数値]: Watchしているユーザーの数
  • その他
    • wip[bool値]: 記事が下書き状態=true、異なる=false
    • sharing_urls[文字列(URL)]: 外部公開用のURL、外部公開してない記事の場合nullとなる
    • kind[文字列]: 記事種別、stockflowが入る

一目見て「わぁお」となるくらい色んなデータが取得できます…なんて太っ腹。
個人使用だと主に使うのは「記事内容」や「基本情報」くらいでしょうが、
チームで活用している&各メンバーのesa.ioの活用具合を見たいなら「他ユーザーからのリアクション情報」は参考になりそうですね。

ひとまず、これだけデータが出てるならやりたい事は何でもできる気がします。

記事の検索文字列について

クエリパラメータqに設定可能な記事の検索文字列についてですが、
esa.ioページのヘッダー>検索フォーム欄に使える書式と全く同一です。

例えばこんな感じのものが使えます:

  • full_name:[検索したい文字列]: 検索文字列に一致する記事カテゴリ+タイトル(記事内容は参照しない)
  • #[検索したいタグ] or tag:[検索したいタグ]: 検索タグが紐づいた記事
  • watched:true: 自分がWatchしている記事
  • sharing:true: 外部公開している記事

カンマ区切りで複数条件を指定可能ですし、否定検索も可能みたいですね。
他にもさまざまな条件が使えるので、詳しくは公式記事を参照に: docs.esa.io

ページングについて

検索結果に該当する記事が多い場合、1回のリクエストでは全てを取得できない時があります。
(特にパラメータなしで指定すると、全部の記事が取得できますしね…)
そんな時に備え、記事取得APIは「ページング」に対応してくれてます。

記事取得APIには記事情報の他に、下記のプロパティも返却され:

  • prev_page[整数値 or null]: 前のページ数
  • next_page[整数値 or null]: 次のページ数

next_pagenullでない場合、そのリクエストでは全ての記事を取得できなかったと言うことを示します。
なので全部取得したい場合は、next_pageの値をクエリパラメータにpage=[next_pageの値]としてリクエスト->レスポンスのnext_pagenullになるまで繰り返せば、全ての記事データを取得可能です。

なお、1ページにどれだけの記事を取得できるかもレスポンスに記載されてます。

  • per_page[整数値]: 1ページあたりに含まれる記事数(デフォルトは20)
  • max_per_page[整数値]: 1ページあたりに含められる最大記事数

クエリパラメータにper_page=50とすれば一気に50記事取得が可能です。
ただし、per_pagemax_per_page以上の数は指定できないのでご注意を。

また、現在のページはレスポンス内容page(整数値)の値を見ればOKです。
(初回リクエストなら、絶対に1が入ってます)
「条件に一致する記事を200件くらい取りたい」のであれば、per_page=100としpage=2となるまで取得すれば目的は達成できるかと。

おわりに

今回はesa.ioAPIの基礎情報と、記事を取得するAPIについてまとめてみました。

記事取得APIについては、想像以上に様々なデータを取れて驚きました…。
ドキュメント管理ツールは世に沢山ありますが、APIでのいじりやすさ的にはかなり上位に来る気がします。
(まぁドキュメント管理ツールに対して、APIで色々するユースケースは稀でしょうけど…)

また、esa.ioには記事取得APIの他にもさまざまなAPIが提供されています。 docs.esa.io

コメントの投稿やスター、Watchの付与までAPIで出来るみたいなので…気になった方は是非見てみてください。

それでは〜