見出し画像

Chat-GPTとGASを使って名刺管理を自動化する(後編)

それでは前回の続きから。
前半までの、GoogleスプレッドシートとAppSheetの設定はこちらの記事をご覧ください。

GASの設定

いよいよプログラムを書いていきます。
大きく二つの処理をそれぞれ関数としてまとめて、それらを実行する大枠の関数を一つ作ります。こんなイメージです。

では、まず名詞を文字起こしする準備をしていきます。

文字起こしの準備

文字起こしも行程があります。

  1. 「AppSheet」から保存された名刺のファイル名を取得する

  2. そのファイルを取得する

  3. そのファイルをコピーして文字起こし

  4. コピーファイルを削除して、起こしたテキストだけ返す

こんな感じになります。

名刺は前編で紹介した「AppSheet」から登録されますが、その情報はスプレッドシートから見るとこのようになっています。

名刺のファイルパスを取得する

AppSheetでファイルを保存するとこんな感じでスプレッドシートに記録されます。

親ファイル名/キー値.カラム名.採番.拡張子

この内ファイル名は"/"より後ろの部分全てになります。
のでこれを取得します。

GASを開く

スプレッドシートの「拡張機能」→「App Script」をクリック


function getFileName(text){
  const num=text.indexOf("/")
  const fileName=text.substring(num+1)
  return fileName
}


これをスプレッドシートのG列全てに入れていきます。

ファイルを取得して文字起こし

G列で取得するファイル名をもとに、Googleドライブ上のファイルを取得します。
まず、GASでDriveにアクセスするために、DriveAPIの利用にチェックを入れます。

コードを書く

function ocr(name){
    const folderID = "親フォルダのID"
    const folder = DriveApp.getFolderById(folderID)
    const resource = {
      title: "OCR_TEST" 
    };
    const option = {
      "ocr": true,// OCR設定で有効にするため、trueを設定
      "ocrLanguage": "ja",// OCRを行う言語を英語で設定
    }

    const files=folder.getFiles()
    let fileId=""
    let text=""
    while(files.hasNext()){
      const file=files.next()
      const fileName=file.getName()
      if(fileName==name){
        fileId=file.getId()
        console.log(fileId)
        const copy=Drive.Files.copy(resource,fileId,option)
        text = DocumentApp.openById(copy.id).getBody().getText();
        console.log(text)
        Drive.Files.remove(image.id)
        return text
      }
    }

これで名刺情報をテキストで取得できました。
続いてメインのChat-GPTに必要箇所の抽出をさせます。

Chat-GPTでの処理

大きくはこんな流れです。

  1. Chat-GPTでアカウントを作成する

  2. API Keyを取得する

  3. Keyを使ってテキスト抽出する

1および2はこのあたりの記事を参考にして設定して見てください。

ではAPI Keyを取得した前提でコードを書いていきます。

Chat-GPTでテキスト抽出

function chatgpt(question){
    //スクリプトプロパティに設定したOpenAIのAPIキーを取得
    const apiKey = "Chat-GPTのAPI Key";
    //ChatGPTのAPIのエンドポイントを設定
    const apiUrl = 'https://api.openai.com/v1/chat/completions';
    //ChatGPTに投げるメッセージを定義(ユーザーロールの投稿文のみ)
    const messages = [{'role': 'user', 'content': question}];
    //OpenAIのAPIリクエストに必要なヘッダー情報を設定
    const headers = {
      'Authorization':'Bearer '+ apiKey,
      'Content-type': 'application/json',
      'X-Slack-No-Retry': 1
    };
    //ChatGPTモデルやトークン上限、プロンプトをオプションに設定
    const options = {
      'muteHttpExceptions' : true,
      'headers': headers, 
      'method': 'POST',
      'payload': JSON.stringify({
        'model': 'gpt-3.5-turbo',
        'max_tokens' : 250,
        'temperature' : 0.9,
        'messages': messages})
    };
    //OpenAIのChatGPTにAPIリクエストを送り、結果を変数に格納
    const response = JSON.parse(UrlFetchApp.fetch(apiUrl, options).getContentText());
    console.log(response)
    const res=response.choices[0].message.content
    //ChatGPTのAPIレスポンスをログ出力
    console.log(res);
    return res;
  }

これでテキストのトリミングも終わりました。最後にこれらを実行する大枠の関数を作ります。

function exe(){
  const ss=SpreadsheetApp.getActive()
  const sh=ss.getSheetByName("名刺情報")
  const lastRow=sh.getLastRow()
  const range=sh.getRange(2,1,lastRow-1,11).getValues()
  let num=0
  range.forEach((row,index)=>{
    if(row[6]!=="" && row[7]=="" && num<3){
      const text=ocr(row[20])
      sh.getRange(index+2,8).setValue(text)
      const question="以下のテキストから会社名、氏名、メールアドレスを抽出し{company,name,email}のjsonで出力してください"+text
      const response=chatgpt(question)
      try{
        const res=JSON.parse(response)
        const company=res.company
        const fullName=res.name
        const email=res.email
        const setdata=[[company,fullName,email]]
        console.log(setdata)
        sh.getRange(index+2,9,1,3).setValues(setdata)
        num+=1
      }catch{
      }
    }
  })

1分間に最大3回しかPOSTできないので、無理矢理numに代入してカウントしてます。

これで全工程が終了しました。
ぜひチャレンジしてみてください。

この記事が気に入ったらサポートをしてみませんか?