15
12

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.

はじめに

この記事は5分でできるLINE Bot + AI応答をベースに、DALL-Eという生成AIに画像を作ってもらえるようにした記事です
プログラミング初心者でも5分で画像生成LINEBotが作れることを目指して手順を極力簡単にしました。
LINEBot自作のとっかかりとして活用してください!

前提

  • Googleアカウントを持っていること
  • LINE Developersにログインできること
  • LINE Messaging API についてある程度理解しておくと進めやすいです
  • openAIでアカウントを作成していること

手順

目次

  1. LINE Developersにログインし、設定を行い、トークンを発行します
  2. LINEBotのテンプレートをコピーし自分のGoogleフォルダに移します
  3. GoogleAppScriptのコードにトークンを書き込んで、デプロイをします
  4. デプロイすると発行されるURLをLINE Developersで設定します
  5. オウム返しBotが完成!
  6. openAIにログインし、API Keyを発行
  7. GoogleAppScriptにAPI Keyを書き込み、AIの設定を行う

という手順で、5分でできます!

LINE Developersにログインし、設定を行い、トークンを発行します

LINE DevelopersにLINEのアカウントでログインします

スクリーンショット 2022-05-15 0.33.40.png

適当な名前でプロバイダーを作成します
スクリーンショット 2022-05-15 0.33.59.png

スクリーンショット 2022-05-15 0.34.35.png

MessagingAPIでチャンネルを作成します
スクリーンショット 2022-05-15 0.34.48.png

チャンネルの必須項目を適当に埋めて作成します
スクリーンショット 2022-05-15 0.35.05.png

スクリーンショット 2022-05-15 0.35.58.png
スクリーンショット 2022-05-15 0.36.04.png

MessagingAPI設定から設定を行います
スクリーンショット 2022-05-15 0.43.00.png

設定するのは2つです
・応答メッセージをオフにする
・チャンネルアクセストークンを発行し、あとで使うのでコピーしておく
スクリーンショット 2022-05-15 0.43.58.png

LINEBotのテンプレートをコピーし自分のGoogleフォルダに移します

LINEBotのテンプレートを用意しているので
https://docs.google.com/spreadsheets/d/1fCp7YzMUH17geUutyaLW_kqOQS0r_fzCvqShQT_S77s/edit
を開いて、自分のフォルダにコピーします

スクリーンショット 2024-01-01 3.29.02.png

スクリーンショット 2024-01-01 3.29.48.png

GoogleAppScriptのコードにトークンを書き込んで、デプロイをします

これ以降は、コピーした自分のスプレッドシートで作業します
コピー元のスプレッドシートはもう利用しないので閉じてください

スプレッドシートを開き、拡張機能 > Apps Scriptを開きます
スクリーンショット 2022-05-14 19.57.22.png

さきほどの手順でコピーしたチャネルアクセストークンで、3行目の「LINE Developersから取得したチャネルアクセストークン(長期)で書き換えます」を上書きし、保存します
スクリーンショット 2024-01-01 3.31.58.png

画面右上の「デプロイ」から「新しいデプロイ」を選択します
スクリーンショット 2024-01-01 3.32.36.png

左の歯車のアイコンを押し、「ウェブアプリ」をクリックします
スクリーンショット 2022-05-14 19.59.07.png

以下のように設定して、デプロイを押します
「説明文」 => 適当に入力
「次のユーザーとして実行」 => 自分
「アクセスできるユーザー」 => 全員
スクリーンショット 2022-05-14 19.59.40.png

アクセスを承認をクリック
スクリーンショット 2022-05-14 20.00.23.png

アカウントを選択し
スクリーンショット 2024-01-01 3.45.56.png

Advanced(詳細)をクリックし、
ページへ移動
スクリーンショット 2024-01-01 3.49.49.png

Allow(許可)をクリック
スクリーンショット 2024-01-01 3.49.55.png

これでデプロイ完了です
次で使うのでURLをコピーしてください
スクリーンショット 2022-05-14 20.01.06.png

デプロイすると発行されるURLをLINE Developersで設定します

再びLINE Developersに戻ります

Webhook URLを編集し、先ほどのURLを設定します
スクリーンショット 2022-05-14 20.01.39.png
スクリーンショット 2022-05-14 20.01.46.png

検証を押して、成功と出たらOKです
スクリーンショット 2022-05-14 20.01.59.png

Webhookの利用をONにします
スクリーンショット 2022-05-17 18.05.40.png

LINE Developters に戻り、QRコードを読み込んでBotと友達になり、メッセージを送ってみるとそのまま返却してくれたら成功です!

スクリーンショット 2022-05-15 1.11.41.png

補足

ソースコードに変更を加えたら

ソースコードに変更を加えたら再度デプロイが必要です
スクリーンショット 2022-05-17 18.04.42.png

デプロイ > デプロイを管理 > 新バージョンを選択してデプロイ(URLは変更されないので、LINEDevelopersで操作は不要です)
スクリーンショット 2022-05-17 18.04.52.png

AIの設定

API Keyを発行

openAIのアカウントを作成します

まだ登録しない人は、 https://openai.com/ にアクセスし、
右上の「Menu」から「Sing Up」をクリックしてアカウントを作成しましょう

新しくアカウントを作成する場合、クレジットカードの設定を行わないとAPIの利用ができないようになっています(2023/5/20現在)
設定をしておきましょう

スクリーンショット 2023-05-20 17.42.30.png

openAIにログインします

https://platform.openai.com/overview
スクリーンショット 2023-05-20 17.13.28.png

API Keys をクリック

スクリーンショット 2024-01-01 3.52.29.png

API keyを作成

スクリーンショット 2023-05-20 17.18.54.png

スクリーンショット 2023-05-20 17.20.14.png

API Keyが発行されるのでコピーして控えておきましょう
スクリーンショット 2023-05-20 17.21.11.png

GASのコードを編集

赤枠を編集します

スクリーンショット 2024-01-01 3.54.03.png

// AI設定
const openAIApiKey = "openAIから取得したAPIキーで書き換えます";

messages の中身を忘れずに更新してデプロイしましょう
スクリーンショット 2024-01-01 3.55.15.png

設定お疲れ様でした!これで完成です!動作を確認してみましょう

スクリーンショット 2024-01-01 3.40.32.png

コードの解説


//ポストで送られてくるので、ポストデータ取得
function doPost(e) {

  // ① ========================================
  // 動作確認用のログ出力
  // log_to_sheet("A", "doPost")

  // ② ========================================
  // LINEBotから送られてきたデータを、プログラムで利用しやすいようにJSON形式に変換する
  json = JSON.parse(e.postData.contents);

  // ③ ========================================
  //返信するためのトークン取得
  replyToken= json.events[0].replyToken;
  if (typeof replyToken === 'undefined') {
    return;
  }

  // ④ ========================================
  // 返信するメッセージを作成
  // オウム返しができるようになったら、message = test_message()をコメントアウトし、messages = getAIImageAnswer(json.events[0].message.text)をコメントイン
  messages = test_message()
  // messages = getAIImageAnswer(json.events[0].message.text)

  // ⑤ ========================================
  // line-bot-sdk-gas のライブラリを利用しています ( https://github.com/kobanyan/line-bot-sdk-gas )
  const linebotClient = new LineBotSDK.Client({ channelAccessToken: CHANNEL_ACCESS_TOKEN });

  // メッセージを返信
  try{
    linebotClient.replyMessage(replyToken, messages);
  }catch(e){
    // うまく動作しない場合は、エラーが発生していないか確認してみましょう
    // log_to_sheet("A", e)
  }


  // ⑥ ========================================
  return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}

// 動作確認用のオウム返しのメッセージを作成する関数
function test_message() {
  //送られたLINEメッセージを取得
  var user_message = json.events[0].message.text;  

  //送られたメッセージをそのままオウム返し
  var reply_messages = [user_message];
 
  // メッセージを返信
  var messages = reply_messages.map(function (v) {
    return {'type': 'text', 'text': v};    
  });

  return messages
}

function getAIImageAnswer(text){
  // LINEBotに送られてきた文言でDALL-Eに画像の作成を依頼する。
  // textをそのままで画像を作るのではなく、画像生成に関する指示を足すと特徴的なLINEBotになります。
  // LINEBotから画像を送信するには画像のURLが必要なので、imageURLとして受け取る
  var imageURL = generateImageURL(text)
  // リプライメッセージを組み立てる
  messages = [
    {'type':'text', 'text': '画像ができました!'},
    {'type':'image', 'originalContentUrl': imageURL, 'previewImageUrl': imageURL}
  ]
  return messages
}

// DALL·E APIを呼び出し、出力結果の画像のURLを取得する関数
// 他にもいろいろパラメーターを設定することができるので、カスタマイズするには公式ドキュメントを読みましょう
// https://platform.openai.com/docs/api-reference/images
function generateImageURL(text) {
  // リクエストを送信するためのオプションを設定する
  var options = {
    "method": "post",
    "headers": {
      "Content-Type": "application/json",
      "Authorization": "Bearer " + openAIApiKey
    },
    "payload": JSON.stringify({
      "prompt": text,
      "size": "256x256",
      "response_format": "url"
    })
  };
  // リクエストを送信する
  var response = UrlFetchApp.fetch(DALLE_API, options);
  var data = JSON.parse(response.getContentText());
  // 画像のURLを取得する
  return data.data[0].url;
}

// 処理の確認用にログを出力する関数
function log_to_sheet(column, text) {
  if(logSheet.getRange(column + "1").getValue() == ""){
    lastRow = 0
  } else if(logSheet.getRange(column + "2").getValue() == ""){
    lastRow = 1
  } else {
    var lastRow = logSheet.getRange(column + "1").getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow();
    // 無限に増えるので1000以上書き込んだらリセット
    console.log("lastRow", lastRow)
    if(lastRow >= 1000){
      logSheet.getRange(column + "1:" + column + "10").clearContent()
      lastRow = 0
    }
  }
  var putRange = column + String(lastRow + 1)
  logSheet.getRange(putRange).setValue(text);
}

① log_to_sheet("A", "doPost")

GASでLINEBotを作る際につまづきやすいところとして、エラーが起きたときに何が起きてるのかわからない!というのがあります。
それを解消するために、スプレッドシートに「log」というシートを用意し、今どこまで処理が進んでいるのか?というのを調べるために、log_to_sheetという関数を用意しました。

log_to_sheet("出力する列", 出力する内容)

という内容で呼び出すと利用でき、

log_to_sheet("A", "doPost")

だと、シート「log」のA列の一番上の空いているセルに"doPost"と書き込むことができます。
これを出力していると、LINEBotが動かない時に、そもそもLINEBotからGASに処理が飛んできているのか?という判定に使え、doPostという文言が出力されていないと、「LINEDevelopersに貼り付けたWebhookURLが間違っていないか?」と効率よく検証をすることができます。

② json = JSON.parse(e.postData.contents);

LINE 公式のMessaging APIから画像を拝借しました。
messaging-api-architecture.f40bffbb.png

この記事では、この画像の右側のYOUR SYSTEMの部分をGASで作っていますスクリーンショット 2023-01-02 2.22.13.png
 LINEから文字が入力された際、「入力された文字」は "e.postData.contents" という変数の中に入っています。
そのほかに、リプライトークンと呼ばれる「特定の相手に返信をするための合言葉」も入っていて、それらをプログラム上で扱いやすいように、JSONと呼ばれるデータ形式に変換します。

③ 返信するためのトークン取得

リプライトークンと呼ばれる「特定の相手に返信をするための合言葉」は、先ほど変換したjsonのデータから以下のように取り出せます。

replyToken= json.events[0].replyToken;

もし何らかのアクシデントでリプライトークンが入手できなかった場合は、その後の処理が無駄になるので、ここで処理を中断させます

  if (typeof replyToken === 'undefined') {
    return;
  }

④ 返信するメッセージを作成

返信するメッセージは以下の形式にする必要があります

[{'type':'text', 'text':'メッセージ'}]

参考:テキストメッセージの公式リファレンス
スタンプなど他の形式で送りたい場合は、公式リファレンスで調べてみてください

送られてきたメッセージをそのままオウム返しにするtest_messageという関数を用意しているので

messages = test_message()

と書けば、変数messagesに送られてきたメッセージがそのまま詰められた返信メッセージのデータが挿入されます。自分用のプログラムを書く時にも返信する内容を以下のようにしてあげればOKです。

[{'type':'text', 'text':'メッセージ'}]

⑤ line-bot-sdk-gas のライブラリを利用してクライアントを生成

前回の記事(5分でつくるLINEBot)から大きく変えた点です。
LINE Messaging API を Google Apps Script で利用するためのライブラリ作りましたの記事で紹介されているライブラリをスプレッドシートに組み込んでいます。

このライブラリを使うことで、返信をするためのコードがグッと少なくなります

ライブラリなし
UrlFetchApp.fetch('https://api.line.me/v2/bot/message/reply', {
  'headers': {
    'Content-Type': 'application/json; charset=UTF-8',
    'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
  },
  'method': 'post',
  'payload': JSON.stringify({
    'replyToken': replyToken,
    'messages': messages,
  }),
});
ライブラリあり
const linebotClient = new LineBotSDK.Client({ channelAccessToken: CHANNEL_ACCESS_TOKEN });
linebotClient.replyMessage(replyToken, messages);

そもそもライブラリとは?

GASでは、作ったプログラムを他の人が利用できるようにする機能があり、先ほどの記事で紹介されていたライブラリを組み込んで、このスプレッドシートでも利用できるようにしています。
このline-bot-sdk-gasというライブラリは、Node.jsで利用できる「SDK」(ソフトウェア開発キット)と同じようなことがGASでも出来るように作られているため、Messaging API公式リファレンスのNode.js用のサンプルコードを参考に開発を進めることができます
スクリーンショット 2023-01-02 2.55.16.png

実際に使える関数の詳しい内容はこちらから確認してください。

⑥ 関数の終了をLINEBotに伝える

LINEBotに処理が終わったことを伝えます。ここは特に変更が必要になることはないと思います。

return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);

おわり

以上、簡単にLINEBotを作るやり方の紹介でした!

15
12
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
15
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?