2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【個人開発】ChatGPTをchatworkに連携。メッセージ自動返信ツールを作る

Posted at

制作物

image.png
画像のように、質問したら自動で回答してくれるメッセージツールを作ります。

技術スタック

  • chatGPT
  • chatwork
  • Google App Script

関係図

image.png

  1. webhookで自分宛メッセージが来たら、Google App Scriptに通知する。
  2. Google App Scriptは受け取ったデータを、chatGPTに送信
  3. chatGPTが回答を生成
  4. chatGPTからGoogle App Scriptへレスポンスを送信
  5. Google App ScriptからChatworkへ回答を送信

Open AI のAPIを使って文章を自動生成

APIキーを発行し、エンドポイントにPOSTメソッドでBearer認証をリクエストする。

APIキーの発行

https://platform.openai.com/account/api-keys
「Create new secret key」で発行される
image.png

useOpenAiApi.gs
function requestCompletion(_prompt) {
  //スクリプトプロパティに設定したOpenAIのAPIキーを取得
  const apiKey = ScriptProperties.getProperty('APIKEY');
  //文章生成AIのAPIのエンドポイントを設定
  const apiUrl = 'https://api.openai.com/v1/completions';
  //文章生成AIに投げるテキスト(プロンプト)を定義
  const prompt = _prompt;
  //OpenAIのAPIリクエストに必要なヘッダー情報を設定
  let headers = {
    'Authorization': 'Bearer ' + apiKey,
    'Content-type': 'application/json',
    'X-Slack-No-Retry': 1
  };
  //文章生成で利用するモデルやトークン上限、プロンプトをオプションに設定
  let options = {
    'muteHttpExceptions': true,
    'headers': headers,
    'method': 'POST',
    'payload': JSON.stringify({
      'model': 'text-davinci-003',
      'max_tokens': 1024,
      'temperature': 0.5,
      'prompt': prompt
    })
  };
  //OpenAIの文章生成(Completion)にAPIリクエストを送り、結果を変数に格納
  const response = JSON.parse(UrlFetchApp.fetch(apiUrl, options).getContentText());
  //OpenAIのAPIレスポンスをログ出力
  console.log(response.choices[0].text);
  return response.choices[0].text;
}

chatwork側の設定

①chatwork APIトークンの取得

https://www.chatwork.com/service/packages/chatwork/subpackages/api/token.php
image.png

②Google App Script と Chatworkの連携

Chatwork Clientというライブラリを使用
https://github.com/cw-shibuya/chatwork-client-gas
Google App Script スクリプト ID: 1nf253qsOnZ-RcdcFu1Y2v4pGwTuuDxN5EbuvKEZprBWg764tjwA5fLav
image.png

sendMessage.gs
function sendChatworkMessage(_message, _room_id) {
  //Chatwork API Tokenを定数として定義(自分のAPIトークンをセット)
  const token = '自分のAPIトークン';

  //メッセージを取得したいルームIDを定数として定義
  const room_id = _room_id;
  // ChatworkAPIクライアント作成
  const client = ChatWorkClient.factory({ token: token });
  //チャットワークAPIで投稿するメッセージを設定
  const message = _message;
  //ChatworkAPIクライアントからメッセージ投稿
  client.sendMessage({
    room_id: room_id,
    body: message
  });
}

③Webhookを設定して、自分宛メッセージを通知する

image.png

Webhookで取得したデータをもとに、回答メッセージを送信。
今回はroom_id bodyを使用する

フィールド名 タイプ 必須 説明
from_account_id 数値 メンション元のアカウントID
to_account_id 数値 メンション先のアカウントID
room_id 数値 メンションが発生したチャットルームID
message_id 文字列 メンションが発生したメッセージID
body 文字列 メンションメッセージ本文
send_time 数値 メッセージの送信時刻(エポック秒)
update_time 数値 メッセージの最終編集時刻(エポック秒)

doPost.gs (POSTメソッドで呼び出される)に以下を記述

doPost.gs
function doPost(e) {

  try {
    var json = JSON.parse(e.postData.contents);
    var msg_body = json.webhook_event.body;
    var send_time = json.webhook_event.send_time;
    var room_id = json.webhook_event.room_id;
    var from_account_id = json.webhook_event.from_account_id;
    var to_account_id = json.webhook_event.to_account_id;
    var message_id = json.webhook_event.message_id;

    writeSpreadSheet([msg_body, send_time, room_id, from_account_id, to_account_id, message_id]);

    // messageを渡す
    main(msg_body, room_id);

  } catch (error) {
    writeSpreadSheet([error]);
  }

}

完成!

最後に、requestCompletionメソッドとsendMessageメソッドをつなげれば
完成!!

main.gs
/**
 * @param message, room_id
 */

function main(message, room_id) {
  const createMsg = requestCompletion(message);
  sendChatworkMessage(createMsg, room_id);
}

アレンジ方法

chatGPTに送信するメッセージの先頭に、「カジュアルに答えて:」など追加すると、回答させるメッセージが変わります!

参考記事

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?