こんにちは、タクトシステムRPAチームです。
弊社では社内の連絡用ツールにRocket.Chatというサービスを使用しています。自身で環境を構築する手間はありますが基本的に無料で使用することができ、社内および社外ユーザーのアカウントを自由に作成することで手軽に連絡を取り合うことができます。

Rocket.Chatの画面
このRocket.ChatにChatGPT API(OpenAI API)および画像生成API(DALL-E 2)を実装してみました。
Rocket.Chatとは
Rocket.Chatは独自に環境構築ができるオープンソースの通信プラットフォームです。
公式サイトの説明文を引用します。
Rocket.Chat is a customizable open-source communications platform for organizations with high data protection standards. It enables real-time conversations between colleagues, other companies, or your customers across web, desktop, or mobile devices.
(ChatGPTで翻訳)
Rocket.Chatは、高いデータ保護基準を持つ組織向けのカスタマイズ可能なオープンソースのコミュニケーションプラットフォームです。これにより、同僚、他の会社、またはお客様とのリアルタイムの会話をウェブ、デスクトップ、モバイルデバイスを通じて可能にします。
PC以外でもモバイルアプリ(iOS/Android)での実行が可能です。
Webhook統合
Rocket.Chatはカスタマイズすることが可能です。OpenAI APIの設定は管理機能のうち 統合(Integration) を使用します。

統合
Rocket.Chat supports webhooks to integrate tools and services you like into the platform. Webhooks are simple event notifications via HTTP POST. This way, any webhook application can post a message to a Rocket.Chat instance and much more.
(ChatGPTで翻訳)
Rocket.Chatは、好きなツールやサービスをプラットフォームに統合するためのWebhookをサポートしています。Webhookは、HTTP POSTを通じたシンプルなイベント通知です。これにより、任意のWebhookアプリケーションがRocket.Chatのインスタンスにメッセージを投稿したり、その他の操作を行ったりすることができます。
Webhookとは、ウェブアプリケーションから外部のアプリケーションに自動的に通知を送信する仕組みです。
Rocket.Chatの管理機能の統合でWebhookの設定をおこなうと、ユーザーのメッセージ送信がトリガーとなってChatGPT API(OpenAI API)が自動的に返信します。
ChatGPTの実装
さて、Rocket.ChatではWebhookでOpenAI APIの実装が可能ということはわかったのですが、そもそもノウハウがないため株式会社Omitさんのこちらのページを参考にしながら試行錯誤してみました。ありがとうございます!
TypeScriptなるスクリプトは正直不勉強だったのですがとりあえずやってみることに。しかし、ネットのコードあるあるですがそのままコピペしても動きません。いろいろ調べていくうちにどうやらコードではなくユーザー(Bot)をアプリの権限にしてあげないと動作しないことが判明。さらにTypeScriptを自社向けに最適化することでなんとか動作しました!
しかし、質問の答えは返ってくるけど、その先の会話は続かない…。どうもTypeScriptでRocket.Chatの会話履歴を取得するにはもうちょっと検証しなくてはいけないようです。
画像生成DALL-E 2の実装
会話は続きませんでしたがRocket.ChatでChatGPTを実装できたので、こんどは画像生成API(DALL-E 2)を実装してみました。OpenAI APIにはプロンプトをもとに画像生成ができる仕組みも存在します。
Rocket.Chatでアプリの権限にて作成した画像生成ユーザー(Bot)にリクエストを送ると、画像URLが返される設計にしました。返された画像URLをそのままサムネイルとして表示します。
設定は以下のとおりです。
イベントトリガー | メッセージが送信されました |
有効 | オン |
名前(オプション) | ImageGeneration |
Channel | all_public_channels, all_private_groups, all_direct_messages |
トリガーになる言葉 | @img (←半角スペースあり) |
URLs | (空白) |
ユーザーの偽装 | オフ |
投稿者 | img |
エイリアス(オプション) | Image Generation |
スクリプトが有効 | オン |
※ img というユーザーを作成しappのロール(権限)を設定しています。
TypeScriptは以下となります。
class Script { /** * @params {object} request */ userName; imgUserName; apiKey; imgOrder; constructor(){ this.userName = ""; this.imgUserName = "img"; this.apiKey = "<OPENAI_API_KEY>"; this.imgOrder = ""; } prepare_outgoing_request({ request }) { let d = new Date(); console.log("---- OpenAI Image Generation START ----- "+d.toString()); // ユーザー名 this.userName = request.data.user_name; // ユーザー入力 userInput = request.data.text; let match; // トリガーにマッチするかどうかの正規表現 let pat = new RegExp("^\@"+this.imgUserName+"\\s"); match = userInput.match(pat); // トリガーにマッチする場合 if (match) { console.log("---- OpenAI Image Generation MATCH ----- "+userInput); // リクエストURLの設定 request.url = "https://api.openai.com/v1/images/generations"; request.headers = { 'Authorization': 'Bearer '+this.apiKey, 'Content-Type': 'application/json' }; // 生成画像の命令 const regex1 = /^@img\s(.+?)(\s-n\s.+)*(\s-size\s.+)*$/; const matchResult1 = userInput.match(regex1); if (matchResult1) { imgOrder = matchResult1[1].trim(); console.log(imgOrder); }else{ return; } // 画像の個数 const regex2 = /-n\s([1-5])/; const matchResult2 = userInput.match(regex2); if (matchResult2) { imgNum = parseInt(matchResult2[1]); console.log(imgNum); } else { imgNum = 3; } // 画像のサイズ const regex3 = /-size\s(256|512|1024)/; let matchResult3 = userInput.match(regex3); if (matchResult3) { imgSize = matchResult3[1]; console.log(imgSize); } else { imgSize = "256"; } data = { "prompt": imgOrder, "n": imgNum, "size": imgSize+"x"+imgSize }; return { url: request.url, headers: request.headers, method: 'POST', data: data }; } } /** * @params {object} request, response */ process_outgoing_response({ request, response }) { // パースする const jsonResponse = response.content; // JSONデータをパースしてオブジェクトに変換 const responseObject = JSON.parse(jsonResponse); const dataArray = responseObject.data; const urlArray =[]; dataArray.forEach((item) => { urlArray.push({"image_url": item.url,"thumb_url": item.url}) }); return { content: { text: "@"+this.userName+" "+imgOrder, parseUrls: false, attachments: urlArray } }; } }
-
- APIの使用にはAPI keysの取得が必要です。
- img というユーザーにメンション(@img )を送るテイで生成したい画像のプロンプトを送信すると、画像URLが返信で届きます。
- 初期設定では生成される画像数は3つ、画像サイズは256×256にしています。送信するテキストにつづけて画像数 -n と画像サイズ -size を入力するパラメータ調整ができるようにしてあります。
@img (生成する送信プロンプト) -n 5 -size 512
※ -n に続けて数字を入れると画像数(1〜5個まで)、 -size に続けて画像サイズ(256/512/1024のいずれか)を指定できます。 - OpenAI APIでの画像生成はURL生成後1時間で画像が消去されます。
自前でChatGPTと画像生成AI環境を構築
ChatGPTを活用したプロダクトは巷に多くありますが、APIを活用することでRocketChatに自前で画像生成AI環境を構築することができました。次のステップとしてはRocket.Chat上でChatGPTと会話を続けることができるように改修したいところです。また、画像生成API(DALL-E 2)はプロンプトが日本語だとあまり思ったような生成ができません(2023年5月時点)。このあたりはBing Image Creatorの方が日本語に対応しているので使い勝手がいいという印象です。プロンプトをOpenAI API(またはその他翻訳API)で英語に翻訳、からの画像生成APIリクエストも可能ですが「やりすぎ」でしょうか? おそらくトークンが増加して課金額が大変なことになってしまいそうです。
- とはいえ、普段使用しているツールでChatGPTや画像生成ができるのはなかなか便利なものです。Rocket.ChatでのChatGPT環境構築にご興味があればお手伝いいたしますので、ぜひともお問い合わせください。