StripeのDevRel活動を効率化するための個人開発: API Changelogの通知アプリ開発
この記事では、StripeのDevRel(Developer Advocate)が自身の日本での業務について説明しています。日本で一人だけで情報収集や記録・分析・報告を行うため、手作業を減らすためにGASやCLIコマンドの自動化を取り入れています。また、StripeはDevOpsなどの取り組みも盛んで、毎週アップデートが行われるため、最新情報を把握するための通知機能が欲しいとのことです。API変更ログをRSSフィードで取得し、取得したデータをSlackなどに送信します。また、Cloudflare KVを使用して通知を管理し、不要なデータは半年後に削除する仕組みを導入しています。さらに、要約や変更のユースケースを説明することができるAIの導入を検討しています。
目次
この記事は「DevRel Advent Calendar 2023」13日目の記事です。
コードでルーティンワークを減らしたい
StripeでDevRel (厳密にはDeveloper Advocate)をやっています。日本には自分一人ですし、もちろん日本語を扱えるのも自分一人のため、情報収集や記録・分析・報告などが定期的にスタックしそうになります。そのため、GASやちょっとしたCLIコマンドなどを作って、自動化または半自動化できるものは手でやらないようにしています。
APIの変更をPullではなくPushで見たい
StripeはDevOpsなどの取り組みも非常に盛んで、ほぼ毎週何かしらのリリースが行われています。ということは、毎週リリースされたアップデートを把握する必要があるのですが、社内のリリースメールだけでなくSlackなどにpushしてくれるものが欲しいなと思いました。
RSSフィードを読んで最新情報を取得する
まずStripeのAPI変更ログを配信するRSSフィードからデータを取得します。
import { parseFeed } from "htmlparser2";
export const loadRSSFeed = async (url: string) => {
const response = await fetch('https://stripe.com/docs/changelog/api/feed.xml')
if (!response.ok) {
return []
}
const htmlString = await response.text()
const feed = parseFeed(htmlString)
if (!feed) {
return []
}
return feed.items
}
Slackなどに通知メッセージを送る
取得したデータをSlackやDiscordなどのInbound Webhook APIに送ります。これで通知の基本部分は用意できました。
public async notifyAPIChangeLog(feed: FeedItem): Promise<void> {
if (!feed.id || !feed.title || !feed.description) return
await fetch(this.WEBHOOK_URL, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
content: [
`**${feed.title}のAPIアップデート情報**`,
feed.description,
feed.link
].filter(Boolean).join('\n')
})
})
}
Cloudflare KVで最新のアップデートだけを通知する仕組みを作る
実際に運用していくには、「このフィードアイテムは、もう通知済みか否か」を判定する仕組みが必要です。今回はCloudflare Workersを利用していたので、Workers KVでデータを管理しました。
フィードアイテムのIDやURLをキーに保存し、もしデータが存在するならスキップする処理にしています。
public async notifyAPIChangeLog(feed: FeedItem): Promise<void> {
if (!feed.id || !feed.title || !feed.description) return
const itemId = feed.id
const storeItem = await this.KV.get(itemId)
const date = new Date(feed.title);
const time = date.getTime()
if (isNaN(time)) return
if (storeItem) {
const expireTargetDate = new Date()
// 半年より前なら消す
if (calcMonthDiff(date, expireTargetDate) > -6) {
return
}
// Expireデータを削除する(1から半年ぐらい?)
await this.KV.delete(itemId)
return
}
// Save item to the KV
await this.KV.put(itemId, summary || "No summary data.")
await fetch(this.WEBHOOK_URL, {
method: "POST",
また、保存するだけではデータが増える一方なので、半年を目処に削除する仕組みもつけています。
今後について
ただフィードの内容をPushするだけでも助かってはいます。が、できるなら「要はどんな変更で、どんなユースケースがある?」みたいなところまで要約してくれると嬉しいなと思っています。この辺りはOpenAI / Workers AIなどを使えそうな気がしますので、年末〜来年の宿題かなと思います。