Yappli Tech Blog

株式会社ヤプリの開発メンバーによるブログです。最新の技術情報からチーム・働き方に関するテーマまで、日々の熱い想いを持って発信していきます。

ヤプリでChatGPTを活用したプッシュ通知作成支援ツールを作ってみた

みなさんどうもこんにちは、ヤプリでデータサイエンティストとして1ヶ月間インターンに参加させていただきました、高橋(@jorijorl)です。本記事ではインターン中に取り組んだ、ChatGPTを活用したプッシュ通知生成について紹介したいと思います。

サマリー

  • ChatGPTを使って「土井善晴の和食」というアプリのプッシュ通知作成を支援するツールを作成しました
  • 100%そのまま使える品質のものを生成することはできませんでしたが、使えるフレーズを複数生成でき、"支援"ができました

背景

インターンに参画した当初、以下のような状況にありました。

  • ノーコード総研を筆頭に、ヤプリ内でChatGPTの利活用について議論が起きていた。
  • アプリ担当者がプッシュ通知の文言を考える際に時間がかかっていた。

そこで、ヤプリ×ChatGPTの取っ掛かりとして「土井善晴の和食」というアプリのプッシュ通知生成に取り組むことにしました。

土井善晴の和食とは

季節に合わせた『旬』の食材を用いて、土井善晴のオリジナルレシピを、動画やテキストでお届けする公式アプリです。

doiwashoku.com

処理フロー

プッシュ通知生成のために、今回は2つのフローを作成しました。

Slackワークフローで作成したフォームへの回答を元にプッシュ通知の文言を生成

1つ目のフローは、Slackへの投稿をトリガーとし、OepnAIのAPIを使いプッシュ通知を生成し、その結果をSlackに投稿、さらにGoogle スプレッドシートに保存するフローです。具体的には以下の1〜3の手順を踏みます。

  1. ワークフローでフォームの回答を投稿 先ず、Slackワークフローで料理名や文体、季節などを入力し、入力内容を投稿します。
  2. Zapierで投稿内容をパースし、OpenAIへのAPIエンドポイントPOST1.の投稿内容をPythonでパースし、それを元に作成したペイロードをOpenAIへのAPIエンドポイントPOSTし、プッシュ通知の生成結果を取得します。
  3. 2.のZap内で生成結果をSlackに投稿し、Google スプレッドシートに保存します。

最終的に生成ID、生成結果、ボタンからなるメッセージがSlackbotから投稿されます。 この投稿のボタンを押下することで2つ目のフローが始まります。

押下されたボタンの要望を元にプッシュ通知の文言を生成

2つ目のフローは、Slackに投稿された生成結果に付属するボタンを押下することをトリガーとし、ボタンの要望に基づくプッシュ通知の文言を生成し、その結果をSlackに投稿、さらにGoogle スプレッドシートに保存するフローです。OpenAIへのAPIエンドポイントPOST以降は1つ目のフローと同じですが、その前が少し異なります。

ボタンには、「もっと長く」、「もっと短く」、「絵文字を多く」、「もう一度生成」の4種類を設定しており、いずれかを押下することでそれぞれの要望を満たすプロンプトがOpenAIのAPIエンドポイントにPOSTされます。

障壁と解決法

今回、一連の機能を作る上でぶつかった壁とその解決法を紹介します。

Zap内でのAPIエンドポイントへのPOST

OpenAIのAPIを利用する際、ペイロードの一部であるmessagesは[{"role": "hoge1", "content": "fuga1"}, {"role": "hoge2", "content": "fuga2"}]というフォーマットなのですが、これをZapierの変数参照機能で呼び出すことに苦戦しました。 というのも、1つ前のActionでPytonコードを実行し、ペイロードを作成する際に[{"role": "hoge1", "content": "fuga1"}, {"role": "hoge2", "content": "fuga2"}]というリストを返す場合、Zapierの変数参照で参照できるのはhoge1, hoge2fuga1, fuga2といった具合に分割された要素になってしまうからです。そこで、Pythonコードの返り値をリストではなく、json.dumps([{"role": "hoge1", "content": "fuga1"}, {"role": "hoge2", "content": "fuga2"}], ensure_ascii=False)と文字列にすることで期待通りの値を参照できるようにしました。

ZapierのAction当たりの実行時間の制限

1つのActionには制限時間があり、現在のプランではPythonコードの実行は30秒の時間制限がありました。APIエンドポイントからのレスポンスを待っている間に30秒経過し、TimeOut Errorが発生したため、Pythonでリクエストを送ることは諦め、ZapierのWebhook機能を使うことにしました。ただ、Webhookについても時間制限は存在するようで、今回の実装では実用に耐えましたが、トークン数の増加などに伴い、時間制限に引っかかるようであれば別の方法を模索する必要があります。

Slackの絵文字

Slackでは絵文字を特定のエイリアスに変換します。例えば、😂は:joy:となります。そのため、生成結果を参照する際にSlackに投稿したものを参照すると絵文字が表示されないという問題が発生しました。この問題によって、「Slackでボタンが押下された生成結果を参照し、Zapierで処理する」ということができませんでした。そこで、生成結果に加えて生成IDをSlackに投稿し、さらに、生成IDを付与して生成結果をGoogle スプレッドシートに登録することで、「ボタン押下」→「Slackから生成ID取得」→「生成IDを元にスプシから生成結果を取得」という流れで絵文字が正しく表示されている生成結果を取得できるようにしました。

成果

実際に「土井善晴の和食」というアプリのプッシュ通知作成を行なっている担当者の方に使っていただきました。 100%そのまま使える品質のものを生成することはできませんでしたが、複数生成した文言を組み合わせ、推敲することでプッシュ通知を作り上げることができ、「作成にかかる時間が減った!」、「自分では出てこないフレーズがあり重宝した」などの声をいただきました。

実際に完成したプッシュ通知が以下になります。

学んだこと

本インターンを通して、SlackのワークフローやZapierを使った簡単なアプリケーションの作り方を学ぶことができました。非エンジニアでも新しい技術を簡単に扱えるツールを素早く作成することで、社員の新しい技術に対する解像度を高めることができ、より良いアイデアの創出につながると感じました。

さらに、機能開発とユーザからのフィードバックをループすることの重要性と楽しさを学びました。今回のテーマで言うと、アプリ運用担当者がどこに課題を感じているか、作ったツールの満足なところと不満なところはどこかなどをヒアリングしながら開発を進めることができました。ユーザに価値を提供することができるエンジニアになるために、ユーザが抱えている顕在的・潜在的な課題を洗い出し、より良い方法で解決するということを今後も心がけていきたいです。