LoginSignup
3
4

More than 5 years have passed since last update.

「ふぁぼった人に○○します!」の代替をGoogleAppsScriptで作った

Last updated at Posted at 2017-07-24

ことのはじまり

  • TwitterAPIには「いいね!」した人をリストする機能が無い。
  • favstarとかもあるけど鍵付きの人は認識できないっぽいし一部有料。
  • むしろ「いいね!」でなくていい。欲しい人のTwitterアカウントが認識できればいい
  • 後で集計しやすい形が良い。.csvとか.xlsxとか.jsonとかとか…
  • Googleフォームなららくちん! ……でもTwitterID書いて投稿だったら簡単に偽装できる。
  • お、コレ行けるんじゃね?→[GAS] Google Apps Script でTwitter複数アカウントを使い分ける
  • GoogleAppsScriptならGoogleスプレッドシートに書きだせる!

というわけで作成した時にハマリ所をいくつかピックアップ。
詳しい使い方とかはココで紹介しませんので、各自でQiitってください。
「ええい御託は良い、はやくコードを写さんか!」って人はこちら

ハマり所とテクニック

コールバック

--- コード.gs ---
OAuth1.getCallbackUrl = function(scriptId) {
  return Utilities.formatString(
    'https://script.google.com/macros/s/%s/exec', scriptId);
}

// getServiceを上書き、スクリプトIDを手動設定に変更
twitter.getService = function() {
    
    .setScriptId(PropertiesService.getScriptProperties().getProperty("OPENED_SCRIPT_ID"))

function doGet(e) {
    if (e && e.parameter.oauth_verifier)
    


--- プロジェクトのプロパティ ---
OPENED_SCRIPT_ID        : ********************************************************

一番悩んだところ。
デフォルトのプロパティではhttps://script.google.com/macros/s/スクリプトID/usercallbackに飛ぶのだが、このページに飛べるのはGoogleの認証ができる人のみ。
既に公開しているhttps://script.google.com/macros/s/スクリプトID/execにはGoogleの認証無しで見れるので、こっちに飛ばしてパラメータでコールバック前か後かを判断する。

認証前のページ

--- Oath.html ---
<a target="_top" href=<?=auth_url?>Twitterで認証</a>

クリックで飛ばす仕組み。
というのも、GAS上で表示するページは自動遷移ができない らしい。
metaタグやJavaScriptは書いても無効化されてしまう。セキュリティの関係上であろうし、コレは仕方ない。
(自動で別ページへ飛んで勝手にアヤシイサイトに入会させられて○○万円振り込め。 なんてよくある手口ですからね…)

スクリプトのプロパティ

--- コード.gs ---
var twitter = TwitterWebService.getInstance(
  PropertiesService.getScriptProperties().getProperty("TWITTER_CONSUMER_KEY"),
  PropertiesService.getScriptProperties().getProperty("TWITTER_CONSUMER_SECRET")
);

コード内でグローバル変数的なもの、マジックナンバーのようなものを格納できるGASの機能。
setPropertyもある。
QiitaやGitHubにコードを投稿した時にAWSのキーを消し忘れて大変なことに… って事が無くなる効果もある。
これからも積極的に使っていきたくなる機能。(グローバル変数の乱立には注意)

良い設定方法の記事無かったので書きました ↓
GoogleAppsScript スクリプトのプロパティの超簡単な使い方

HTMLの作成

--- コード.gs ---
var html_template = HtmlService.createTemplateFromFile('Comp');
html_template.name=user_info[3];
return html_template.evaluate();

--- Comp.html ---
  <body>
    <br /><?=name?>さんの受付が完了しました。</center>
  </body>

HtmlService.createTemplateFromFile(拡張子なしファイル名)で生成したテンプレートファイルに値を突っ込むだけでHTMLから参照できる。
最後にテンプレートをevaluate()して、出てきたオブジェクトをreturnで返してあげればページがユーザーに表示される仕組み。
プログラムでゴニョゴニョしてできた値を簡単にHTMLとして表示できる。

実装

以下のライブラリを追加。
* TwitterWebService: MFE2ytR_vQqYfZ9VodecRE0qO0XQ_ydfb
* OAuth1: 1CXDCY5sqT9ph64fFwSzVtXnbjpSfWdRymafDrtIZ7Z_hwysTY7IIhi7s

コード.gs

'use strict';

// OAuth1認証用インスタンス
var twitter = TwitterWebService.getInstance(
  PropertiesService.getScriptProperties().getProperty("TWITTER_CONSUMER_KEY"),
  PropertiesService.getScriptProperties().getProperty("TWITTER_CONSUMER_SECRET")
);

// コールバック先をexecに変更
// デフォルトのusercallbackだとGoogleでの認証が必要になってしまう。
OAuth1.getCallbackUrl = function(scriptId) {
  return Utilities.formatString(
    'https://script.google.com/macros/s/%s/exec', scriptId);
}

// getServiceを上書き、スクリプトIDを手動設定に変更
twitter.getService = function() {
  return OAuth1.createService('Twitter')
    .setAccessTokenUrl('https://api.twitter.com/oauth/access_token')
    .setRequestTokenUrl('https://api.twitter.com/oauth/request_token')
    .setAuthorizationUrl('https://api.twitter.com/oauth/authorize')
    .setConsumerKey(twitter.consumer_key)
    .setConsumerSecret(twitter.consumer_secret)
    .setCallbackFunction('exec')
    .setPropertyStore(PropertiesService.getUserProperties())
    .setScriptId(PropertiesService.getScriptProperties().getProperty("OPENED_SCRIPT_ID"))
}

// 認証時にURLを返すように変更
twitter.authorize = function() {
  var service = this.getService();
  if (service.hasAccess()) {
    Logger.log('Already authorized');
  } else {
    var authorizationUrl = service.authorize();
    return authorizationUrl;
  }
}

// 認証をリセット
function reset() {
  twitter.reset();
}

// 認証を行う
function authorize() {
  return twitter.authorize();
}

// スプレッドシートに追記
function addSpreadSheet(value){
  var id = PropertiesService.getScriptProperties().getProperty("SPREADSHEET_ID");
  var spreadSheet = SpreadsheetApp.openById(id);
  // 既に受付済の人は追記せずに帰る
  var idlst = spreadSheet.getSheetValues(2,3,spreadSheet.getSheetByName('data').getMaxRows(),1);
  for(var idv in idlst){
    if(idlst[idv][0]==value[2]){
      return;
    }
  }
  spreadSheet.getSheetByName('data').appendRow(value);
}

// ユーザ情報を取得
function getUserInfo() {
  var service  = twitter.getService();
  var response = service.fetch('https://api.twitter.com/1.1/account/verify_credentials.json');
  var response_list = JSON.parse(response)

  return [
    Date(),
    response_list["id_str"],
    '@'+response_list["screen_name"],
    response_list["name"],
  ]
}

function doGet(e) {
//test_code  
//    Comp.htmlをテストするときに此方を使う
//    var html_template = HtmlService.createTemplateFromFile('Comp');
//    html_template.name="テスト";
//    return html_template.evaluate();
//test_code
  // 初回、コールバック共に此方の関数を使う。
  // OAuthのパラメタ有無で認証前か後を判断する
  if (e && e.parameter.oauth_verifier){
    twitter.authCallback(e);
    var user_info = getUserInfo();
    addSpreadSheet(user_info);
    var html_template = HtmlService.createTemplateFromFile('Comp');
    html_template.name=user_info[3]; //name
    return html_template.evaluate();
  }else{
    reset();
    var html_template = HtmlService.createTemplateFromFile('Oath');
    html_template.auth_url=authorize();
    return html_template.evaluate();
  }
}

Oath.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <title>「ふぁぼった人に○○します!」の代替をGoogleAppsScriptで作った</title>
  </head>
  <body><center>
    <a target="_top" href=<?=auth_url?>Twitterで認証</a>
  </center></body>
</html>

Comp.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <title>認証完了</title>
  </head>
  <body>
    <br /><?=name?>さんの受付が完了しました。</center>
  </body>
</html>

プロジェクトのプロパティ -> スクリプトのプロパティ

TWITTER_CONSUMER_SECRET : **************************************************
TWITTER_CONSUMER_KEY    : *************************
SPREADSHEET_ID          : ********************************************
OPENED_SCRIPT_ID        : ********************************************************
  • TWITTER_CONSUMER_SECRETTWITTER_CONSUMER_KEY の二つはTwitterのアプリキー
  • SPREADSHEET_IDは書き込み先スプレッドシートID
  • OPENED_SCRIPT_IDは、アプリを公開した時のID(一度Webに公開してキーをコピってから再公開)
3
4
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
3
4