1時間でできるTwitterBOT作成
こんにちは。なんだかんだで投稿が3ケ月ぶりになってしまいました。
先日友達からこんなLINEが、、、
ってことで今回はめっちゃ優しく簡単にBOT作成やっていきたいと思います。
1.Google Apps Scriptプロジェクトの作成
今回もGoogle Apps Script(通称GAS)を使っていきます。
サーバー無しで簡単に動くからいいんですよコレ。
まずは下記にアクセスして
右上の「新しいプロジェクト」を押下して作成
そしたらこんな感じのものができたと思う
Google Apps Scriptはお分かりの通りGoogleが提供しているプログラミング言語です。ベースはJavaScriptです。
最新のECMAScriptも対応しています。ということはclassも使えるということですね。
とりあえずJavaScriptを実行してみたいと思います。
最初のは消してこれをコピペでもいいので記入してみてください。
function hello() {
const obj = "Hello World!!"
console.log(obj)
}
GASは関数毎に別々に実行することができます。
そうすると…
2.Twitter Developersに登録する。
※この操作はアカウントの2段階認証必須です。
電話番号を登録する必要があります。
そして本題、TwitterBOTを作っていきたいと思います。
まず、チャットボットとは
らしい。
とりあえず、Twitter上でメンションしてくれた人に「巻き込んでますよ」と返信してくれるBOTを作っていきたいと思います。
右上にあるDeveloper Portal に移動します。もしかしたらログイン必要かもしれません。
そしたら色々出てくると思う
とりあえずJapanで。
今回の目的はBOT作成なのでMaking a botにします。
その後プライバシーポリシーかなんか出てくると思うので
そのまま進みます。
私の場合は英語での利用申請が必要でした(˘・_・˘)Twitter~
もし聞かれたらDeepLなどつかって翻訳しながら書いていきましょう。
App nameはお好みでどうぞ
決めたらGet keysでアクセストークンを発行してもらいます。
そしたらこんな画面が出てきたと思います。
API KeyとAPI Key Secretをどこかにメモっておきましょう
(付箋アプリおすすめ)
とりあえずTwitterアプリの作成は完了しました!
少しコーヒーでも飲んで休憩しましょう。
私も3時間ぐらいぶっ通しでやってるので休んできます。
3. コードを書く
さて、それではGASに戻ります。
+マークからスクリプトを新規追加します。
名前はなんでもいいですが、今回は、「TwitterClient」にします。
TwitterClient.gs
/**
* belltreeSzkさんからお借りしました。ありがとうございます。
* GitHub: https://github.com/belltreeSzk/TwitterClient
* HomePage: https://belltree.life/
*/
/**
* Twitterの認証に関わる処理をまとめたクラス
* 認証、API実行など
*/
class TwitterClient {
/**
* コンストラクタ
*/
constructor(consumerKey, consumerSecret, clientName) {
this.consumerKey = consumerKey;
this.consumerSecret = consumerSecret;
this.scriptId = ScriptApp.getScriptId();
this.clientId = this.scriptId + clientName;
this.oauth = this._getOAuthService();
}
/**
* 認証開始
*/
authorize() {
if (this.oauth.hasAccess()) {
Logger.log('既に認証されています');
} else {
let authorizationUrl = this.oauth.authorize();
Logger.log('以下のURLからログインを行ってください');
Logger.log(authorizationUrl);
}
}
/**
* authorize() の後にTwitterでログインした際に実行される処理
* @return {TextOutput}
*/
authCallback(request) {
const isAuthorized = this.oauth.handleCallback(request);
const mimeType = ContentService.MimeType.JSON;
const result = {
message: isAuthorized ? '認証に成功しました。このタブは閉じてください。' : '認証に失敗しました。',
}
return ContentService.createTextOutput(JSON.stringify(result)).setMimeType(mimeType);
}
/**
* Twitterで作ったアプリに登録するための callbackUrl を取得する処理
* @return {string}
*/
getCallbackUrl() {
return OAuth1.getCallbackUrl(this.scriptId);
}
/**
* 認証を解除する
*/
reset() {
this.oauth.reset();
Logger.log('認証を解除しました');
}
/**
* POSTのAPIを実行する
*/
postRequest(apiUrl, paramsObject) {
if (this.oauth.hasAccess()) {
const response = this.oauth.fetch(apiUrl, {
'method': 'post',
'muteHttpExceptions': true,
'contentType': 'application/json',
'payload': JSON.stringify(paramsObject)
});
Logger.log('実行しました: POST ' + apiUrl);
const result = JSON.parse(response)
if (Object.keys(result).some((elem) => elem === 'errors')) console.error(result) //APIのエラー処理
return result
} else {
Logger.log('認証されていません');
throw Error('認証されていません');
}
}
/**
* GETのAPIを実行する
*/
getRequest(apiUrl, paramsObject) {
let paramsStr = '';
for (var key in paramsObject) {
// URLに日本語や記号を付けると上手く検索できないことがあるので#も変換する encodeURIComponent をする
paramsStr += key + '=' + encodeURIComponent(paramsObject[key]) + '&'
}
if (paramsStr !== '') {
// &が余計に付いているので削除しておく
paramsStr = paramsStr.slice(0, -1);
}
if (this.oauth.hasAccess()) {
let fetchUrl = ''
if (paramsStr == '') {
fetchUrl = apiUrl
} else {
fetchUrl = apiUrl + '?' + paramsStr
}
const response = this.oauth.fetch(fetchUrl);
Logger.log('実行しました: GET ' + fetchUrl);
const result = JSON.parse(response)
return result
} else {
Logger.log('認証されていません');
throw Error('認証されていません');
}
}
/**
* OAuthのインスタンスを作る
*/
_getOAuthService() {
return OAuth1.createService(this.clientId)
.setAccessTokenUrl('https://api.twitter.com/oauth/access_token')
.setRequestTokenUrl('https://api.twitter.com/oauth/request_token')
.setAuthorizationUrl('https://api.twitter.com/oauth/authorize')
.setConsumerKey(this.consumerKey)
.setConsumerSecret(this.consumerSecret)
.setCallbackFunction('authCallback')
.setPropertyStore(PropertiesService.getUserProperties());
}
}
/**
* TwitterClientクラスを外部スクリプトから呼び出すための関数
* @return {TwitterClient}
*/
function getInstance(consumerKey, consumerSecret, clientName = '') {
const client = new TwitterClient(consumerKey, consumerSecret, clientName);
clientList[client.oauth.serviceName_] = client
return client
}
const clientList = {}
/**
* TwitterClientクラスのインスタンスの一覧を取得
* @return {Array}
*/
function getClientList () {
return clientList
}
次にコード.gsに書き込んでいきます。
元の文は消して下のコードをコピペ。
コード.gs
'use strict';
//ここにキーとシークレットキーを入れる
const consumerKey = 'CONSUMER_KEY'
const consumerSecret = 'CONSUMER_SECRET'
const client = getInstance(consumerKey,consumerSecret)
/**
* ①Twitterで作ったアプリに登録するための callbackUrl を取得する
*/
function getCallbackUrl() {
Logger.log('以下のURLをTwitterアプリのCallbackURLに登録');
Logger.log(client.getCallbackUrl());
}
/**
* ②認証を実行する
*/
function authorize() {
client.authorize()
}
/**
* 認証をリセット
*/
function reset() {
client.reset()
}
/**
* authorizeでTwitterでの認証後に実行される処理
*/
function authCallback(request) {
return client.authCallback(request)
}
コード.gs
//ここにキーとシークレットキーを入れる
const consumerKey = 'CONSUMER_KEY'
const consumerSecret = 'CONSUMER_SECRET'
ここに先ほど控えたキーとシークレットキーを入れてください。
認証などはBelltreeさんのコードをお借りしました。
4. GASにライブラリを追加する
Twitter APIの認証はOAuthなのでGAS用のOAuthのライブラリを追加します。
ファイルを追加したときのようにライブラリと書いてある横の+を押します。
Oauth1のライブラリ スクリプトID ↓↓↓↓
1CXDCY5sqT9ph64fFwSzVtXnbjpSfWdRymafDrtIZ7Z_hwysTY7IIhi7s
検索します。
5. アプリにコールバックを設定する。
※TwitterClient.gsが一番上に配置するようにしてください‼
点々で変更できます。上から読み込まれるんですね
では、保存したのを確認して
コード.gsのgetCallbackUrlの関数を実行します。
おそらく「承認が必要です」と出ると思います。承認しちゃってください。
実行するとURLが出てくると思うのでコピーしておく。
行き来しちゃってすいません >︿<
このURLをTwitterアプリのコールバックに登録します。
下のほうにあるUser authentication settingsの
Set upをクリック
やる事
OAuth 1.0a をオンにする。
App permissionの項目でRead and Writeにする。
コールバックURLを入れる。
必須のWebsite URLはなんでもいい…
終わったらSaveを押す。
権限を変更しますか→Yes
6. OAuth認証する
authorizeを実行してTwitter APIの認証をします。
{"message":"認証に成功しました。このタブは閉じてください。"}
このメッセージが表示されたらOKです。
次章でツイートしてみます!!
7. APIでツイートしてみる
では、Twitter APIをつかってツイートしてみます。
やっとこの時が…ドドド
この関数を追加して実行してみてください。
コード.gs
function tweetTest() {
//お好きなメッセージ
const message = "Twitter APIからのツイート"
const params = {
text: message
}
const result = client.postRequest('https://api.twitter.com/2/tweets',params) //ツイートのエンドポイント: https://api.twitter.com/2/tweets
console.log(result)
}
ドキュメントはここ
8. ボットをつくる
後はもうGASでコーディングしていくだけです簡単ですね。
reply.gsというファイルを作ります。
reply.gs (コピペOK)
//自身のアカウント情報
const me = client.getRequest('https://api.twitter.com/2/users/me').data
/**
* メンションされたツイートに返信する(1分おきにトリガー実行)
*/
function lookUpMension() {
const params = {
max_results: 10,//ツイートを取得する数
}
const newestId = ScriptProperties.getProperty('newestTweetId')
if (newestId !== null) {
params['since_id'] = newestId
}
const result = client.getRequest(`https://api.twitter.com/2/users/${me.id}/mentions`, params)
console.log(result)
if (result.meta.result_count !== 0) {
ScriptProperties.setProperty('newestTweetId', result.meta.newest_id)
reply() //返信する関数
}
function reply() {
result.data.forEach(tweet => {
console.log(tweet)
const param = {
//パラメーター
text: '巻き込んでますよ。',
reply: { in_reply_to_tweet_id: tweet.id } //返信パラメータ
}
const result = client.postRequest('https://api.twitter.com/2/tweets', param) //データをポストする
console.log(result) //ログにresultを表示
})
}
}
function deleteScript() {
ScriptProperties.deleteProperty('newestTweetId')
}
lookUpMension関数を実行すると.....
できてるはずです
あとはいつでも返信できるように5分おきに実行できるようにしていきます。
右にある目覚まし時計アイコン → トリガーを追加
こんな感じの設定にしていきます。
やっと完成です
結構長くなってしまって最後のほう雑になってしまいましたが一応完成です。8000文字以上書いたぜ。過去最高かも
個人的にはもっとコードの解説とかしたかったのですが、、
もし何か質問などあればTwitterのDMで受け付けます。
https://twitter.com/wakiwakkii
この記事が参加している募集
この記事が気に入ったらサポートをしてみませんか?