寄付金可視化を支える技術 — GitHub Actions で実現する政治の透明性

[チームみらい](https://team-mir.ai/)は、公式ページで受け取った寄付金の総額を毎時更新で公開しています。また、[ダッシュボード](https://lookerstudio.google.com/u/0/reporting/e4efc74f-051c-4815-87f1-e4b5e93a3a8c/page/p_lvnweavysd)では金額の推移も公開しています。これがどのような仕組みで動いているのかを解説します。この記事はチームみらいの技術的な取り組みを共有するものであり、寄付を呼びかけるものではありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38209/8bba340f-ba9c-42bf-bdd0-97d5781a0d79.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38209/f2b08277-e78d-4006-b80e-b62dd2ab08a0.png)

## Stripe APIからデータをとって可視化

チームみらいのWebサイトからの寄付はStripeを使ってオンラインで可能になっています。ここから情報をとって可視化するだけの簡単な仕事ですが、Stripe管理画面へのアクセス権を与えると誰から寄付があったかが見えてしまうのでアクセスできる人を信頼できる少数の人間に絞らざるをえません。なのでサポーターSlackにタスク依頼を出すことができませんでした。

もともと千葉県選挙区総支部長でエンジニアの小林しゅうへいさんが担当していたのですが、当然のように多忙なので誰かに任せられないかというアラートが上がり、僕が手伝うことにしました。サポーターSlackでのハッカソンに参加していた人は私がプロジェクト一覧にない寄付金の可視化を急にやり始めたのを覚えているかもしれませんね。

実装自体は簡単でChatGPT o3にStripeからのデータ取得をPythonで書いてといったら書いてくれました。後は実際のAPI Keyを入れて動作テストするだけ...

## 現実は思ったほどシンプルではない

あれ？なんか口座が2つあるな？

そう、2024年の都知事選の時に安野さんが作った個人の口座と、政党「チームみらい」結成の時に作られた政党の口座があるんですね。これは合算しないといけない？

さらに、実はStripeを経由しないで直接銀行振込をするケースもあるとのこと。これをどうしよう？

## 出力先は？

Google Spreadsheetに書いてLooker Studioで可視化したいと言う要件と、ウェブサイトで表示したいのでGET APIを作ってくれという要件の2つがあった。これって一つの方法で両方みたすのは無理なのでは？そもそも表示したいデータが異なるのでは？

## 最終的な構成

- (A): 銀行振り込みを記帳するGoogle Spreadsheet
- (B): 2つのStripe口座と(A)を読んで合算するGitHub Actions(毎時実行)
- (C): 日毎にまとめた時系列データをGoogle Spreadsheetに出力
  - これをLooker Studioで可視化
- (D): Webサイト向けに必要なデータをまとめた簡潔なJSONを生成、これをGistにアップロードする
  - WebサイトはGistのraw URLをGET APIとして使う

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38209/1ccd11c4-4cf6-4f84-93d7-ebc26da3b6c2.png)

ソースコードを含めたもっと細かい話は[こちら](https://github.com/team-mirai-volunteer/knowledge/blob/main/general/data_extraction_implementation_guide.md)

## Devinが大活躍

構成は複雑ですが「こういう形でやろう」と言う高抽象度の意思決定を人間がやれば、低抽象度の具体的実装は非同期AIエージェントのDevinがやってくれるので楽でした。たとえば「GET APIが必要なので何らかの形で実現してほしい」というリクエストに対して「Gistでいいのでは」と思いついたのは人間の僕で、それが技術的に実現可能かどうかを実際にプロトタイプを作って確認したのはDevinです。

特にDevinが非同期型のAIエージェントであることのメリットは、本業が他にあるエンジニアが能力を発揮するシチュエーションにうまくはまった感じがありますね。始業前にリクエストを投げて昼休みにできてるか確認する、そして追加の指示を出しておいて終業後に確認する、という感じでやっていました。

Webサイト側(フロントエンド)に関しては小林しゅうへいさんのタスクだったのですが、忙しそうだったので勝手にDevinにプロトタイプを作らせておくことにしました。「このGistを表示して」と言ってGistのURLと画面デザインの画像をDevinに渡すだけで大体うまくいきました。見栄えは画像だけやるのは難しそうだったです。Figmaもあったはずなのでそこから詳細データをDevinに渡せばもっと良い見栄えになったかもですが、僕がWebサイト担当ではないので何を参照したら良いか分からなかったのと、最終的にリリースするのは小林さんだったので「プロトタイプを作っておくので、使えそうだったら使って、ダメそうだったら捨てていいからね」というボールの渡し方をしました。

これはDevin動画の「最初と最後を人間がやって、中をDevinがやる」という活用パターンに合致しているますね。Devinを作ってるCognition社CEOのScott Wuが来日した時の安野さんとの対談動画で語られています。まだみていなければ、ぜひ。AIエージェントがある時代のエンジニアの働き方の参考になると思います。

<iframe width="560" height="400" src="https://www.youtube.com/embed/UzBLeOBm2_0?si=tAL5HJj0uaVUUIB5" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

<iframe width="560" height="400" src="https://www.youtube.com/embed/c3D0hNJA5xQ?si=29SP05Z48HGwUlCy" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

サポーターSlackでのOSS開発もDevinが活用されて、どんどんと盛り上がってきていますが、その話はまたの機会にしたいと思います。(書いたらここにリンクを書く)