Feedly で要約した記事を見る仕組みを作る

背景

日々の情報収集には Feedly の News Reader を使用していてプランは Pro+ を契約しており、RSS feed のフォローだけでなく NewsLetter や Feedly AI など様々な方法を使って興味のありそうな情報を集めています。読みたい記事が増えた一方ですべてを読むのに時間がかかるという問題がありました。

これを解決してくれそうな方法として Feedly では Pro+ から使える Feedly AI が記事を要約してくれる機能 があります。記事を2,3文くらいでまとめてくれる便利機能なのですが、記事の要点を掴むには少し情報量が足りないと感じることがありました。また現時点では日本語の記事はサポートしていなさそうでした。他にも AI Actions とよばれる要約や翻訳依頼などインタラクティブな対話ができる機能が Beta であるのですが現在は Enterprise プランでしか使えないようです。

ただ記事の要約を見て記事の全体像を掴むというのは良いアプローチだなと思ったので、自作してみることにしました。

つくったもの

下記の図の仕組みを今回つくりました。いくつかのステップがありますが、すべてをゼロから用意したわけではなく既にある仕組みなどを使いつつ構築していきました。

大まかな流れとしては Feedly 上で任意の記事を Board に追加すると Zapier がそのイベントを拾います。そこで取得した記事のタイトルや本文、URL を Argo Events の Webhook 経由で Argo Workflows に渡します。Workflow で使用されるプログラムでは OpenAI API を使い記事の要約を取得して、それを Gmail の SMPT Server を使って Feedly NewsLetter に送ります。

Feedly NewsLetter に送ることによって Feedly 上で完結する仕組みを作ることができました。

各ステップの解説

ここからはさきほどの画像の各ステップの解説をします。

① 特定のプロジェクトへの記事追加をトリガー

事前調査で Feedly API があることは知っていたので、これを使った仕組みを最初は考えていました。しかし Feedly APIPricing に記載されているように、現在は Enterprise プランでしか使えないようです。幸いなことに Pro プランから Zapier が提供されていて、Trigger の1つの New Article in Board を使うことで記事のタイトル、内容、URL を取得して後続の処理に使えることが分かりました。

② 記事タイトル・内容・URL を元にリクエス

ステップ①で取得した記事情報は Code by Zapier Action を使って下記のようなコードで今回用意した Argo Events の Webhook Endpoint へとリクエストしました。 Zapier には Webhook app が提供されているのですが、Free plan の私は使えませんでした。

await fetch("[webhook endpoint]", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    article: {
      title: inputData.title,
      url: inputData.url,
      content: inputData.content
    },
  })
})

Code by Zapier によって任意のエンドポイントにリクエストを送ることができるようになったのですが、ここで1つ課題に直面しました。Free plan では Code の実行は1秒を超えるとタイムアウトエラーとなります。Webhook endpoint へのリクエストにはどうしても1秒以上かかるため毎回エラーになっていました。

この問題を解決するために Cloudflare Workers を使いました。Worker では Webhook へのリクエストを waituntil を使うように実装し、Worker に対するリクエストのレスポンスはすぐに返すようにしました。その結果 Code by Zapier の1秒問題を解決できました。この方法は以前 LINE Bot を使った時にも使った手だったのですぐに実装できました。詳しくは下記の記事をご覧ください。

hatappi.blog

③ Webhook endpoint にリクエス

Cloudflare Worker からリクエストする Webhook Endpoint は Argo Events の Webhook を使用しました。Argo Events は Kubernetes Cluster にインストールする必要があります。既に他の用途で使用している Kubernetes Cluster があったので、今回はこれを使用しました。Webhook の外への公開に関しても他の用途で使っていた Istio Ingress Gateway と Cloudflare を再利用して公開しました。

④ Workflow 作成

Argo Events にはデフォルトで Argo Workflow Trigger が提供されています。 argoproj.github.io

これを使用して下記のマニフェストのように先程の Webhook で受けた Body を Argo Workflows の Workflow で引数として使用します。

apiVersion: argoproj.io/v1alpha1
kind: Sensor
spec:
  ~~
  dependencies:
    - name: feedly
      eventSourceName: webhook
      eventName: feedly
  triggers:
    - template:
        name: workflow
        k8s:
          operation: create
          source:
            resource:
              apiVersion: argoproj.io/v1alpha1
              kind: Workflow
              metadata:
                generateName: feedly-
              spec:
                arguments:
                  parameters:
                  - name: title
                  - name: content
                  - name: url
                ~~~
          parameters:
            - src:
                dependencyName: feedly
                dataKey: body.article.title
              dest: spec.arguments.parameters.0.value
            - src:
                dependencyName: feedly
                dataKey: body.article.content
              dest: spec.arguments.parameters.1.value
            - src:
                dependencyName: feedly
                dataKey: body.article.url
              dest: spec.arguments.parameters.2.value

⑤ 記事内容の要約をリクエス

Workflow で使用されるプログラムでは最初のステップとして引数で受け取った記事のタイトル、内容、URL を使って翻訳するプロンプトを OpenAI API へ送ります。OpenAI API へのアクセスを良い感じにするのは下記の記事を書いた時に作った Cloudflare Worker を再利用しました。

hatappi.blog

Feedly の Newsletter にメール送信

Feedly の Pro+ プランでは NewsLetter をフォローできます。この機能ではユニークな Email アドレスが付与され、そこにメールを送ることで送った内容を他の記事と同じように Feedly で見ることができます。 この機能によって取得した Email アドレス宛に OpenAI API から取得した翻訳結果を Gmail の SMPT Server を使ってメールを送ります。

最後に

今回は Feedly 上で任意の記事を要約して閲覧する仕組みを作りました。この目的を達成するならここまで作らなくても Zapier に課金したり Cloudflare Workers だけで完結できたと思います。ただ僕は Argo 製品が好きで Argo Events は前から気になっていて使用する機会を探していたので今回使いました。せっかく使い始めたのでいろいろ遊んでみたいと思います。