ウ○娘のスクショからファン数取得→スプシに入力をGASで自動化

最近やってるソシャゲ、ウ○娘でサークル(=ギルド)というものがあり、各メンバーの貢献具合を可視化したい。ファン数の推移をスプシに記録するのが手っ取り早いが30人分のデータを手打ちするのは骨が折れる。
そこで今ちょいちょい勉強してるGASを用いて、Google Driveにスクショをアップロードするだけでスプシにファン数を自動入力してくれるようにしてみた

概要

今回行いたい処理は以下のような流れ

  1. Googleドライブに読み取り用フォルダを用意し、そこにスクショをアップする
  2. 指定フォルダ中の画像ファイルからOCR用のドキュメントファイルを生成する
  3. OCRで文字を読み取る
  4. スプレッドシートにスクショ画像をドライブにアップロードした日時、画像ファイル名、読み取った文字列を入力する
コードの手順
  1. ドライブ内対象フォルダにある画像ファイルからファイル名を取得する
  2. 取得したファイル名と画像と一緒にOCRオプションを使ってOCR用のドキュメントファイルを生成する
  3. OCR用のファイルからテキストデータを取り出し、配列に入れる
  4. 1~3を画像ファイルの数だけ繰り返す
  5. スプレッドシートに配列を移す
  6. 生成したドキュメントファイルをゴミ箱へ移す
試作コード

Drive APIを有効にしておかないと動作しないので注意

 function faninput() {
   function faninput() {
  var picFolderId = "スクショ画像を入れたフォルダのID";
  var folder = DriveApp.getFoldersByName('スクショ画像を入れたフォルダ名').next();
  var images = folder.getFilesByType('image/png');
  
  var sheet = SpreadsheetApp.getActiveSheet();
  
  var titleAndText = [];
  
  while(images.hasNext()){
    var image = images.next();
    var docName = image.getName().split("\.")[0];
    var createDateRaw = image.getDateCreated();
    var createDate = Utilities.formatDate(createDateRaw,"JST","YYYY/MM/dd HH:mm");
    
    var Request_body = {
      title: docName, 
      mimeType: 'image/jpeg'
    }
    Drive.Files.insert(Request_body, image, { ocr: true });
    
    var newFile = DriveApp.getFilesByName(docName).next();
    folder.addFile(newFile);
    DriveApp.getRootFolder().removeFile(newFile);
    
    var docs = folder.getFilesByType('application/vnd.google-apps.document');
    var file = docs.next();
    var docId = file.getId();
    var doc = DocumentApp.openById(docId);
  
    var text1 = doc.getBody().getText().split('数 ')[1];
    var text2 = doc.getBody().getText().split('数 ')[2];
    var text3 = doc.getBody().getText().split('数 ')[3];
    
    var numtext1 = text1.split("人")[0];
    var numtext2 = text2.split("人")[0];
    var numtext3 = text3.split("人")[0];
    
    titleAndText.push([createDate, docName, numtext1, numtext2, numtext3]);
    DriveApp.getFolderById(picFolderId).removeFile(file);
    DriveApp.getFilesByType('application/vnd.google-apps.document').next().setTrashed(true);
  }
  
  sheet.getRange(2, 1, titleAndText.length, titleAndText[0].length).setValues(titleAndText);
 
  var range = sheet.getRange(2, 1, sheet.getLastRow() - 1, sheet.getLastColumn());
  
  range.sort({column:1, descending: false});
  
}
コードの解説

前提としてGoogleドライブのフォルダに以下のようなスクショ画像を保存しておく

f:id:locodolinfo:20210504200622p:plain
サンプル画像で一部伏せているのはブログ公開時のプライバシー保護のためであり、ドライブに保存する際特別画像処理は必要ない

赤丸で囲った3人のファン数 "156,278,997" "155,749,508" "152,118,656"という3つの文字列を取得し、スプレッドシートに入力している

ゲーム内で役職順にソートすれば月を通してメンバーの掲載順を固定化してスクショ撮れる
上から順に3人分が載ったスクショをそれぞれ別のフォルダに保存しておく(フォルダ1にはAさんBさんCさんが写ったスクショ、フォルダ2にはDさんEさんFさんが写ったスクショといった感じ)

あとは上記スクリプトをコピペして10個用意し、取得する対象フォルダのIDと44、46行目のgetRange()で取得するセル範囲を変更してあげれば同じシートに30人分出力できる

部分ごとに処理を解説していく

①指定フォルダからスクショ画像ファイルからファイル名を取り出す

var picFolderId = "スクショ画像を入れたフォルダのID";
var folder = DriveApp.getFoldersByName('スクショ画像を入れたフォルダ名').next();
var images = folder.getFilesByType('image/png');

自分のスクショはpng画像なのでimage/pngを指定している

②取り出した画像とファイル名と一緒にOCRオプションを利用してOCR用のドキュメントファイルを作成する

var Request_body = {
title: docName,
mimeType: 'image/jpeg'
}
Drive.Files.insert(Request_body, image, { ocr: true });

var newFile = DriveApp.getFilesByName(docName).next();
folder.addFile(newFile);
DriveApp.getRootFolder().removeFile(newFile);

③テキストを取り出し、splitメソッドで分割することでファン数の数値部分だけ取り出してスプシに移行するため配列に入れておく


var docs = folder.getFilesByType('application/vnd.google-apps.document');
var file = docs.next();
var docId = file.getId();
var doc = DocumentApp.openById(docId);

var text1 = doc.getBody().getText().split('数 ')[1];
var text2 = doc.getBody().getText().split('数 ')[2];
var text3 = doc.getBody().getText().split('数 ')[3];

var numtext1 = text1.split("人")[0];
var numtext2 = text2.split("人")[0];
var numtext3 = text3.split("人")[0];

titleAndText.push([createDate, docName, numtext1, numtext2, numtext3]);


実際にLogger.log()でnumtext1、numtext2、numtext3を出力するとこのようになる

f:id:locodolinfo:20210504225553p:plain
サンプル画像の赤丸で囲んだ部分からファン数の数字だけを取り出せている
スプレッドシートにスクショをドライブにアップした日、ファイル名、ファン数を入力する

sheet.getRange(2, 1, titleAndText.length, titleAndText[0].length).setValues(titleAndText);

var range = sheet.getRange(2, 1, sheet.getLastRow() - 1, sheet.getLastColumn());

range.sort({column:1, descending: false});

1行目はヘッダに用いるのでgetRange()の範囲指定を2行A列目を開始セルにしている

実行結果

f:id:locodolinfo:20210504230714p:plain

あとはスプレッドシート上で処理すればいい 時限トリガー設定して週1くらいでスクリプト自動実行すれば楽に管理できそう

実際に運用してみて

コード書ききった後にGASのドキュメント作成制限250/日に引っかかるかもしれないことに気がついたがもうめんどくさいのでアカウント2つ用意して画像フォルダとスプシを共有アイテムにすることで解決した。