見出し画像

非エンジニアでも半自動で積み上げツイートをしたい 作り方2(実装編)

こんにちはfullです。
前回の準備編の方はいかがでしたでしょうか、この記事は
"非エンジニアでも半自動で積み上げツイートをしたい 作り方1(準備編)"
という記事の続きになっていますのでまだ読んでいない方は先にそちらを読むことをおすすめします。

Twitter developers 申請の審査に数日かかるので前回の記事を読んでから時間があいてしまっている方も多いかと思うので今回もやりたいことイメージから入っていきます。

やりたいことイメージ

画像1

こんな感じでLINEbotとのやり取りだけで毎日簡単に #今日の積み上げのツイートがしたいと言う内容でした

デモ動画もあります↓


今回やる作業

・スクリプトエディターを開こう
・ソースコードをコピーしよう
・LINEbotを作成しよう
・GASとLINEbotを連携させよう
・GASとTwitterを連携させよう
・google docsにある投稿文の雛形を読み込ませよう
・LINE userIDを挿入しよう
・トリガーの設定をしよう
・LINEからTwitterに投稿してみよう

今回やる作業はざっとこんな感じです!
一つず紹介していきます。

・スクリプトエディターを開こう

まずは準備編で作成したスプレッドシートからスクリプトエディターを開きましょう。

・ソースコードをコピーしよう

スクリプトエディターが開けたら、ここにGASコードを書いていきます。
今回は私が予めコードを書いておいたのでこちらをコピペしてください。

//LINEから投稿

//LINE Developersで取得したアクセストークンに置き換えてください
var CHANNEL_ACCESS_TOKEN = 'アクセストークン';


//LINEでのやり取り
function doPost(e) {
 var json = JSON.parse(e.postData.contents);
var event = json.events[0]
var replytoken= event.replyToken;
 if (typeof replytoken === 'undefined') {
   return;
 }
 //送られてきたメッセージを取得
 var user_message = json.events[0].message.text;
 var url = 'https://api.line.me/v2/bot/message/reply'; 
//if文で送られて来たメッセージにより行う処理や返信の内容を変える

 //"投稿"と送られてきた場合はinputとpostTweetを実行し投稿した文を伝える
 if(user_message==="投稿"){
   writeSheet () 
   postTweet()
   var sheet = SpreadsheetApp.getActiveSheet();
   var posted = sheet.getRange("B8").getValue();
 var replymsg=user_message+"完了!"+"\n"+"\n"+posted+"\nと投稿されました。" }
 //"君エラー起こしたよ"と送られてきた場合はそれを修正する関数errorを実行しその完了を伝える
 else if (user_message==="君エラー起こしたよ"){
    error ()
    var replymsg="ごめんなさい、投稿回数を過加算してしまったので−1しました。\n教えてくれてありがとう。" 
    
 }
 //それ以外は下書きと捉えセル"A8"に登録し、その実行を伝える。
 else{

   var replymsg=user_message+"\n"+"\n"+"と下書きしました"
   var sheet = SpreadsheetApp.getActiveSheet();
   sheet.getRange("A8").setValue(user_message);
 }

 //返信用メッセージを作成
 UrlFetchApp.fetch(url, {
   'headers': {
     'Content-Type': 'application/json; charset=UTF-8',
     'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
   },
   'method': 'post',
   'payload': JSON.stringify({
     'replyToken': replytoken,
     'messages': [{
       'type': 'text',
       'text':replymsg
     }],
   }),
 });
 return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}

//毎晩通知

function sendLine(postmsg) {
 var PUSH = "https://api.line.me/v2/bot/message/push";
   // リクエストヘッダ
   var headers = {
       "Content-Type" : "application/json; charset=UTF-8",
       "Authorization" : "Bearer " + CHANNEL_ACCESS_TOKEN
   };
   // メッセージ
 
   var postData = {
       "to" : "userID",//ここにこのbotを使いたいユーザーのuserIDを入力
       "messages" : [
           {
               "type" : "text",
               "text" : postmsg
           }
       ]
   };
   // POSTオプション作成
   var options = {
       "method" : "POST",
       "headers" : headers,
       "payload" : JSON.stringify(postData)
        //postDataをJSON 文字列に変換
   };
   return UrlFetchApp.fetch(PUSH, options);
         //PUSHがURL、optionsパラメータ
         
}


//積み上げツイートを促すメッセージを送る関数をトリガーで毎晩走らせる
function everynight_mag (){
 var sheet = SpreadsheetApp.getActiveSheet();
 var posted = sheet.getRange("B8").getValue();
 var postmsg = "こんばんは\n#今日の積み上げはもう既に投稿しましたか?\n\n前回の#今日の積み上げはこちらです。\n-------------------------\n"+posted
 sendline(postmsg)
}


//スプシにデータ入力
//これは投稿の際に使う処理
function writeSheet (){
 const sheet = SpreadsheetApp.getActiveSheet();
 //スプシの積み上げ日数を記録するセル"A2"の値を取得
 var A2 = sheet.getRange("A2").getValue();
 //取得した値に+1をして"A2"に再び格納
 sheet.getRange("A2").setValue(A2+1);
 //下書きとしてセル"A8"に記録していた文章を取得し"earnedmsg"と名付ける
 var earnedmsg = sheet.getRange("A8").getValue();
 //"earnedmsg"を\n(改行)区切りで分解
 var ary = earnedmsg.split("\n"); 


//分解した"earnedmsg"をそれぞれ別のセルに記録
 sheet.getRange("B2").setValue(ary[0]); //配列変数aryの1番目に格納されている値をセルB2(積み上げ1)に入力
 sheet.getRange("C2").setValue(ary[1]); //配列変数aryの2番目に格納されている値をセルC2(積み上げ2)に入力
 sheet.getRange("D2").setValue(ary[2]); //配列変数aryの3番目に格納されている値をセルD2(積み上げ3)に入力
 sheet.getRange("E2").setValue(ary[3]); //配列変数aryの4番目に格納されている値をセルE2(#タグ1)に入力
 sheet.getRange("F2").setValue(ary[4]); //配列変数aryの4番目に格納されている値をセルF2(#タグ2)に入力
 sheet.getRange("G2").setValue(ary[5]); //配列変数aryの4番目に格納されている値をセルG2(コメント)に入力

}


//投稿失敗したときの処理
//↓文字数オーバーなどで投稿に失敗すると積み上げ日数だけが無駄に加算されてしまうのでそれを修正する関数
function error (){
 const sheet = SpreadsheetApp.getActiveSheet();
 var A2 = sheet.getRange("A2").getValue();
 sheet.getRange("A2").setValue(A2-1);
}


//-----------------twitter--------------------------------

//認証用インスタンスの生成
var twitter = TwitterWebService.getInstance(
'API Key',//API Keyをここにいれる
'API secret keyをここにいれる'//API secret keyをここにいれる
);
//アプリを連携認証する
function authorize() {
 twitter.authorize();
}

//認証を解除する
function reset() {
 twitter.reset();
}

//認証後のコールバック
function authCallback(request) {
 return twitter.authCallback(request);
}

//投稿文の作成し、それをツイートする
function postTweet() {
 
 //投稿文作成------------------------------------
  //予め投稿文の雛形をGoogleDocsで作成しておき、そこからテキストを取得する
 const DOC_URL ="DocsのURLを挿入"
 const doc = DocumentApp.openByUrl(DOC_URL);
 const docText = doc.getBody().getText();

 //スプシに記録してある投稿回数や"積み上げ1~3"、タグ1~2、コメントを取得
  const sheet = SpreadsheetApp.getActiveSheet();
  const lastRow = sheet.getLastRow();;
  var A2 = sheet.getRange("A2").getValue();
  var B2 = sheet.getRange("B2").getValue();
  var C2 = sheet.getRange("C2").getValue();
  var D2 = sheet.getRange("D2").getValue();
  var E2 = sheet.getRange("E2").getValue();
  var F2 = sheet.getRange("F2").getValue();
  var G2 = sheet.getRange("G2").getValue();
  //テキストの形で取得した投稿文の雛形に取得した投稿回数"積み上げ1~3"、タグ1~2、コメントを当てはめてpostcontentと名付ける
  var postcontent = docText
     .replace('{〇〇}',A2)
     .replace('{積み上げ1}',B2)
     .replace('{積み上げ2}',C2)
     .replace('{積み上げ3}',D2)
     .replace('{タグ1}',E2)
     .replace('{タグ2}',F2)
     .replace('{コメント}',G2);
  //--------------------------------------------------

 //postcontentをtwitterに投稿
 var service  = twitter.getService();
 var endPointUrl = 'https://api.twitter.com/1.1/statuses/update.json';
 
 var response = service.fetch(endPointUrl, {
   method: 'post',
   payload: {
     status: postcontent //本当はここに投稿したい文をいれる!
   }
 });
 //投稿した文、すなわちpostcontentをスプシのセル"B8"に登録しておく
 sheet.getRange("B8").setValue(postcontent); 
}

//-----------------------------------------------------------------------


//お好みでリッチメニューを追加して完成!!!

スクリプトエディタにコピペしたらCommand+Sで保存です。
するとプロジェクトネームを聞かれるので"TW積み上げbot"とでも名付けて起きましょう。

ちなみにGASとはGoogle Apps Scriptの略で内容はjavascriptというプログラミング言語とほぼ同じです。

LINEbotを作成しよう

次はGASで動かすLINEbotを作っていきます。
https://developers.line.biz/ja/
LINE Developers↑にアクセスして"Messaging API"をクリック→"さあ始めよう"をクリックといった具合にすすめるとLINEbotを作成する画面までたどり着くことができます。
チャンネル名などの情報を入力して完成です。


・GASとLINEbotを連携させよう

次に先程作ったLINEbotをGASと連携させて見ましょう。
まず、チャンネルアクセストークンを入手します。
LINEbotの管理画面でMessagingAPI設定を選択し一番下までスクロールするとチャンネルアクセストークンを発行できるのでそれをコピーしておきます。

アクセストークン

つぎにスクリプトエディターに戻り先程コピーしておいたチャンネルアクセストークンを4行目の"アクセストークン"の文字の場所に挿入します。

スクリーンショット 2020-11-11 17.27.25

//LINE Developersで取得したアクセストークンに置き換えてください
var CHANNEL_ACCESS_TOKEN = 'ridTNoBqI0PzKIFYg9RYyokO1n15wXEjhWctaZjKUyaGfFoBG5QU3Q7R9HqqlrKVRO3UqP/6sCTZWT7ewe9QvqxaBAXQafwik5TmEnW0BuipteBtzzu/7EQ08A3uCI1m55racGdRz3QujV8w8IxumwdB04t89/1O/w1cDnyilFU=';
こんな感じになっていればOKです。
この時"アクセストークン"というように"で文字を囲ってあったようにアクセストークンも"ridTNoBqI0PzKIFYg"とダブルクォーテーションで囲ってください。

そしたらCommand+Sで保存し、公開→実行可能APIとして導入をクリックします。

スクリーンショット 2020-11-11 17.34.11

すると下記の画像のようなポップアップが現れるので
Project version→New
Execute version→Me
Who has access to the app→Anyone, even anonymous
といったように設定します。
画像と同じ設定になっていれば大丈夫なので更新をクリックします。


GAS公開

すると↓のようになるのでCurrent web app URLをコピーしておきます。

スクリーンショット 2020-11-11 17.42.22

次に再びLINEbotの管理画面を開き、Webhook URLの欄に先程のURLを挿入します。
更新→検証とクリックし、成功と出ればGASとLINEbotの連携は成功です。

スクリーンショット 2020-11-11 17.45.24

ついでなのでこのタイミングで応答メッセージとあいさつメッセージも無効にしておきましょう。

スクリーンショット 2020-11-11 17.52.31

このようになっていればOKです。

・GASとTwitterを連携させよう

ここの部分はかなりややこしいので前回と同じく分かりやすく解説している記事を見つけてきたのでこちらを参考に進めてください。

やはりTwitter developperの部分が一番の山場です。
Twitter developperのサイトもUIがリニューアルしてしまっているのでかなり分かりにくいと思います。
もしわからなければ、ご気軽にnote、Twitter↓にて質問してください。
                                       https://twitter.com/21831141df
おそらく文字のやり取りで教えるのは難しいのでテレカンでおしえますw

・google docsにある投稿文の雛形を読み込ませよう

Twitterとの連携が完了したので次はTwitterに投稿する投稿文の雛形をGASに読み込ませていきましょう。
準備編で作成したgoogle docsのドキュメントを開いてURLをコピーします。

スクリーンショット 2020-11-11 18.24.51

そのURLをスクリプトエディタの162行目の"DocsのURLを挿入"の部分にこれまでと同じ方法で挿入して再びアクセストークンの際と同じようにバージョンをNewにして公開してください。

//投稿文作成------------------------------------
  //予め投稿文の雛形をGoogleDocsで作成しておき、そこからテキストを取得する
const DOC_URL ="https://docs.google.com/document/d/1K7hWeUs/edit"
const doc = DocumentApp.openByUrl(DOC_URL);
const docText = doc.getBody().getText();
こんな感じになっていればOKです。

・LINE userIDを挿入しよう

今回作成しているLINEbotは完全に個人での利用を目的としています。
万が一自分以外のユーザー友達追加されてしまい勝手にTwitterを動かされてしまうといけないのでLINE userIDを使って自分以外のLINEアカウントには一切反応しないように設定します。

70行目の"userID"の部分にこれまでと同じやりかたで準備編で取得しておいたLINE userIDを挿入しましょう。

 var postData = {
       "to" : "16e48dhf11",//ここにこのbotを使いたいユーザーのuserIDを入力
       "messages" : [
          
こんな感じになっていればOKなので再びversionをnewにして公開しましょう。

・トリガーの設定をしよう

ここまででほぼすべての機能の実装が完了しましたが、積み上げ投稿を習慣化するために指定の時間に積み上げ投稿を促すメッセージを送信する機能を実装しましょう。

everynight_msgと言う関数名で積み上げ投稿を促すメッセージを送信する機能は書いておいたのでトリガーという機能をつかって一日に1回指定の時間に走らせます。

スクリーンショット 2020-11-12 1.42.57

画像の"関数を選択"のタブの3つ左の時計のようなマークをクリックして、トリガーを設定する画面に飛びます。

スクリーンショット 2020-11-14 23.39.55

トリガーを追加するをクリックして↑の画像のように設定してください。
時間に関してはお好きな時間帯を選んでもらって結構です。

・LINEからTwitterに投稿してみよう

これですべての設定が完了です。
もうLINEbotから積み上げツイートが出来るようになっているのでLINEbotの管理画面のURLからbotを追加して、試しに以下の文をコピペで送って見ましょう。

今日の積み上げbot作成
筋トレ1時間
読書2時間
初めてのGAS
積み上げたのしい
これはテストです。

下書きが完了しましたと返ってきたら"投稿"と送信するとTwitterに積み上げ投稿が投稿されます。

Twitterでの投稿を確認したらスプレッドシートの方もしっかりとデータがキープされているか確認しましょう。
回数の項目が1になっていると思うのですが先程のツイートはテストなので積み上げ日数にカウントしたくないです、なのでこんどはbotに向かってエラーを修正する指示を送ってみましょう。

"君エラー起こしたよ"と送信してみてください。botから返事が返ってきたらスプレッドシートを確認しましょう、回数の項目が-1されて0になっていたらOK、取り敢えずこれで完成です!!


制作終了!!お疲れさまでした。

お疲れさまでした、これにてTW積み上げbotの作成は終了です!!
慣れてない方には少し難しかったと思いますが少しでも楽しんでいただけていたら光栄です!!

また、このbotの詳しい使い方について說明する短い記事とこの記事を通してGASに興味を持ってくれた方向けに今回使ったコードについて詳しく解説する記事を書こうと考えています。

記事にいいねが集まればできるだけ早く記事を書こうと思うので少しでもこの記事が気にいっていただけたら、ぜひいいねをおねがいします!



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