在這篇教學中,會一步步說明如何製造一隻轉噗機器人。以下是你會需要的工具:
- 一隻 Plurk 帳號,用來轉噗的
- 一個 Google Drive 帳號,用來寄存機器人
- 電腦,你會需要修改一些程式碼(如果你要挑戰用手機應該也是可以)
怪異生物在人類文明的生活隨筆
在這篇教學中,會一步步說明如何製造一隻轉噗機器人。以下是你會需要的工具:
上一篇把後端寫到一半,是因為我覺得切前後端兩部分寫會太不平衡,加上我想睡覺了(主因)。現在,就來把這項功能正式完工吧!在這一篇文章我打算扯去 Ajax,所以說不定還會有第三部分,但目前我是寫上和下篇啦~
在完成後端部分,我們只需要將兩個串起來就可以了。doGet 函數會接收 GET 請求,並將參數放到 parameter 中。我們依序處理驗證與轉送後可以得出這樣的 Code:
function doGet(e) {
var result;
var isHuman = verify(e.parameter['token']);
if (isHuman[0]) {
var sendToLine = forward(e.parameter['message']);
if (sendToLine[0]) {
result = {
success: true
};
} else {
result = {
success: false,
error: 'LINE-Notify Failed: ' + sendToLine[1]
}
}
} else {
result = {
success: false,
error: 'reCaptcha Failed: ' + isHuman[1]
};
}
return ContentService.createTextOutput(JSON.stringify(result));
}
然後就可以發布為服務了,我們會獲得一個網址。(我很懶得重拍,所以直接抓別文章的 XD)
而在前端部分,我們需要做到的事有:
載入 reCaptcha 的部分,我們需要把 token 存起來,用於後續發送時使用。
<script src="https://www.google.com/recaptcha/api.js?render={你的 reCaptcha 認證金鑰}"></script>
<script>
let token
grecaptcha.ready(function() {
grecaptcha.execute('<你的 reCaptcha 認證金鑰>', {action: 'LIME'}).then(function(t) {
token = t
})
})
</script>
(action 部分是我後來才發現的東西,但因為感覺沒差,就不回頭修改了)
Ajax 的部分,我們將運用 mini-xhr。網址是方才取得的,而欄位則是上篇所規畫好的,這邊接受 message 和一個 callback,便於後來使用。
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/miniXhr.js"></script>
<script>
function sendToServer (message, token, callback) {
miniXhr('https://........../exec?token=' / 你的 Apps Script 網址 / + token + '&message' + message, {}
).then(callback)
}
</script>
完成後,我們開始處理能看見的部分(?),最基本就是一個輸入框(Input Text 或 Textarea)和一個按鈕,而我還會另外做一個顯示狀態的窗格。
<input type="text" id="message">
<button type="button" onclick="submit()">送出</button>
<div id="result"></div>
在上面我們對按鈕加入一個 Click 事件,指向 submit 函數。接下來就開始撰寫 submit 函數,message 就是單純讀取欄位,callback 則是將回傳狀態寫回狀態資訊窗格中。
<script>
function submit () {
let message = document.getElementById('message').value
sendToServer(message, token, data => {
data = JSON.parse(data)
if (data.success) {
document.getElementById('result').innerHTML = '成功'
} else {
document.getElementById('result').innerHTML = '失敗:' + data.error
}
})
}
</script>
這樣就大功告成了,其餘美化的部分就交給各位了。(#)
這篇文章有許多處還滿隨便的,因為就是在一個很隨便的心情下寫的,如果想認真學習 JavaScript 的請…別模仿過度。
另外如果想可以一次多發,可以執行 grecaptcha.execute 處來重新獲得 token(token 只能用一次)。
到底為什麼這個網站會充斥著 LINE Notify 嗎?我還真希望是業配,但可惜不是。在滿久以前我做了一個 LINE 我自己的小接口,最近莫名其妙被挖出來了,發現好像有人會感興趣。那位挖出來的捧油把它變成一個匿名提問箱,好像是不錯的主題?
這個小專案其實滿簡單,就是轉發請求到 LINE Notify 的 API 上,基於安全理由,不太可能讓使用者直接騷擾(?)LINE Notify,畢竟應該沒人想看到滿滿的垃圾訊息吧。
那麼要做的事情就很明顯了:
這邊驗證將使用 reCaptcha,首先先新增一個網站,進入 reCaptcha 首頁後右上方會有 Admin Console,如果沒有建立過就會自動跳轉,但已有建立過則需要按下新增。
在網域中填入靜態網頁存放的地方,如果是使用 GitHub Pages 可填入 github.io 或 <你的帳號>.github.io 等等。
完成後就會得到兩組鑰匙,先存放到其他地方。
接著到 Google Drive,新增一個 Google Apps Script。(如果不知道該怎麼新增請參考這篇文章)我們將會有兩個主要邏輯:驗證與轉送。
驗證部分,參考 reCaptcha Reference,我們可以知道要呼叫 siteverify,傳遞 Secret 和 Response 兩個參數,其中 Secret 是上一步的密鑰,Response 是使用者傳送的驗證代碼。
接著他會回傳一份 JSON,其中我們只需要 success 就夠了,但如果出問題,提供錯誤訊息或許也不錯。
製作 HTTP 請求的部分,我們可以應用 Google Apps Script 的 UrlFetchApp 服務。
綜合上述,參考 UrlFetchApp 後可以寫出這樣的 Code:
function verify(response) {
var secret = '' / 請放入你的 reCaptcha 認證金鑰 /;
var recaptcha = UrlFetchApp.fetch('https://www.google.com/recaptcha/api/siteverify', {
method: 'POST',
payload: 'secret=' + secret + '&response=' + response
}).getContentText();
var digested = JSON.parse(recaptcha);
if (digested['success']) {
return [true];
} else {
return [false, digested['error-codes']];
}
}
這樣只要傳入使用者的 Response,就可以獲得包含結果與錯誤的陣列。接著進行轉送,參考 LINE Notify 文件可以知道會需要 Token,進入個人頁面並發行個人權杖,並將權杖紀錄。
接著按照文件,我們需要的是傳送 Message(如果有想增加其他功能可自行類推),需要的是組成一個請求,Header 包含權杖,並傳遞 message 參數。而伺服器會透過 HTTP 狀態表明結果。結合以上,可以寫出這樣的 Code:
function forward(message) {
var token = '' / 放入你的 LINE Notify 權杖 /;
var notify = UrlFetchApp.fetch('https://notify-api.line.me/api/notify', {
'method': 'post',
'headers': {
'Authorization': 'Bearer '+ token
},
'payload': 'message=' + message
});
switch(notify.getResponseCode()) {
case 200:
return [true];
case 400:
return [false, 'Unauthorized'];
case 401:
return [false, 'Invalid Accesstoken'];
case 500:
return [false, 'Server Side Error'];
default:
return [false, 'Unexcepted Failed'];
}
}
如此一來,後端兩個主要邏輯就完成了,下一篇我們將把兩個邏輯組合,並製作前端。
下篇:https://limaois.me/archives/51
前幾天就有考慮把它拓展成訂閱式的,今天目標告一段落,就回來動工。 很快地建立另一個 App,包含 storeToken、getTokens、send 以及處理請求的 doGet。
本記在這:https://limaois.me/archives/55
研究了一下 LINE-Notify,首先會要求提供 Callback URL,接著將使用者導引到
https://notify-bot.line.me/oauth/authorize
?response_type=code
&client_id=your_client_id
&redirecturi=yourcallback_url
&scope=notify
&state=a_hash
其中 your_redirect_url 要與 Callback URL 一致,your_client_id 則登錄後會取得,state 用於防止 CSRF(跨站偽造請求),不過想不太到要怎麼驗證,所以姑且略過之。
當使用者進到這個網址會出現選擇聊天室的介面,選擇後會再把使用者導引到
http(s)://your_redirect_url
?code=user’s_code
?state=a_hash
得到 user’s_code 後,再發送 POST 請求到
並附帶
grant_type=authorization_code
redirect_uri=your_callback_url
client_id=your_client_id
client_secret=your_client_secret
code=user’s_code
便會回傳 access_token,然後依照上篇處理即可。
最近 Packt 的每日免費書回來了,便想用 LINE Notify 做一個自動通知當日免費書的工具,而為了一個小工具去 Heroku 之類的開專案又似乎有點小題大作,另外是我的額度也不夠讓我這樣隨便花了,所以就把目標轉移到功能較為簡單的 Google App Script。
由於規模不大,將在這篇文一次講完(可能會有點長)。Google App Script 的這部分,參考文件是這份。首先開啟 Google Drive,新增一個 Google Apps Script,如果你沒用過需要到商店連結應用程式。
(對我是複製貼上別篇文章的。)
因為這次只有一個 Function,就用他預設的名稱,接著取得網頁資料,並且取出書本標題和介紹。
第二行讀取網頁,第三行將 HTML 中 > 後、 < 前的空白移除以方便操作,然後第四行透過切離 title"><h2> 後到 </h2> 的文字取得標題,再取得標題後的第一個 <div> 內容作為介紹。如果想看看取的甚麼內容,可以加入 Logger.log(title) 和 Logger.log(info),就可以在檢視中的紀錄看到了。
取得完畢後,必須發送到 LINE Notify,參考的文件是這份。進入個人頁面並發行個人權杖,並將權杖紀錄。
接著回到 Google App Script,對 LINE Notify 的 API 發送請求,注意必須使用 POST,並加入名為 Authorization 的 Header,內容是 Bearer <Token>。
這樣就完成啦!你可以執行看看,應該會在 LINE 收到今日的書。接著設定每日上午八點發作,進入編輯中的現有專案的啟動程序。
如此一來他便應該要在早上八點到九點這個時間通知新的書,本篇到此結束。
外傳:https://limaois.me/archives/54
終於來到最終章,最麻煩的地方已經過了,現在只需要把前端介面弄好就可以使用了。如果你懶,你可以選擇用 Google 表單接收,只需要將試算表關聯並調整程式碼即可,或者你可以參考這篇文,利用 HTML 等等的來創造自己的表單。
<< 上一篇請點我 <<
因為新版的 Google Sites 無法使用 HTML,我們需要使用舊版的 Google Sites。左上角建立新的傳統網站。(我不確定是否因為我關閉追蹤,應該有中文版。)
設定完後建立。
調整一下網站,插入 HTML BOX。
form 的標籤會告訴瀏覽器這是一個表單,method 告訴瀏覽器應該用什麼方式送出這個表單,action 則告訴瀏覽器該送到哪(留空會送給自己),我們寫的程式該使用 GET,並送到那個應用程式的網址。標籤內部會有多個表單元件,例如 textarea 表示這是一個多行的文字輸入區塊,row 和 col 分別代表行數和寬度,button 表示一個按鈕,沒有設定類別則會視為送出。
<form method="GET" action="{script url}">
<label>發文內容:</label><br />
<textarea row="8" col="80" name="content">
</textarea><br />
<button>送出</button>
</form>
儲存後大概長這樣,這是正常的,重整後會正常顯示,推測應該是編輯器會把 form 消去。
試著發個文……成功了!接著回到 Facebook 應用程式,將應用程式發佈,就可以開放給所有人了,如果沒發佈應用程式,所有文章只有你可見。進入你的應用程式,從應用程式審查那邊切換。
這樣就完成了,可喜可賀!
上篇我們完成了事前準備,這篇要來實作發文系統,之所以先做系統而不先介面是因為介面製作要配合系統規劃,既然沒有先規劃,也沒要協作開發,那麼先做系統應該會是比較好的選擇。
<< 上一篇請點我 <<
本文章程式碼可在此查看:https://github.com/flyinglimao/ganomy
我們需要一份試算表,用於儲存資料,以及一份 Google Apps Script,試算表大致上應該長這樣:
紀錄文章內容可以避免發文失敗時文章無法取回,發文時間可以方便找到文章,文章 ID則有其他利用價值,例如刪文系統等。(這系列文章應該不會講到刪文系統,也許番外篇?)將當前網址紀錄後即可關閉。完成後建立 Google Apps Script,用於接受輸入。
doGet 函數接收 GET 請求,POST 請求則使用 doPost, 因為發文系統不太需要避免資料竄改竊取,使用 GET 是可以的,下面例子使用 GET,使用 POST 只需要將函數名稱改成 doPost 即可。
從剛剛的試算表可以知道要接收的資料就是發文內容,然後時間戳可以用 JavaScript 的 Date() 產生。
如果想使用其他格式,請參考 JavaScript Date 物件 。接著我們使用 SpreadsheetApp 存取剛剛的試算表,讀取工作表1。
再來取得目前資料最後一行並加一取得輸入目標,然後依序填入資料。
完成這部份後就可以對 Facebook 發送發文請求了,這裡用到的是 External APIs。還記得上篇測試時的作法嗎?對 Graph API 發送 feed 請求,在 message 中放入內文。對 Graph API 發送的路徑是:
https://graph.facebook.com/v2.8/me/feed?access_token={token}。
因為 Facebook 的回傳是 JSON,因此使用 JSON.parse 直接解讀成物件。再將文章 ID 寫入試算表即可。完成後透過 ContentService 對請求端回傳 Ok,輸入完後儲存。
試著 debug 吧!建立另一個腳本,並以 debug 命名並模擬請求,按下蟲蟲啟動,會需要授權。
成功了!這樣發文系統就大致完成了。我們要取得這個程式碼的網址,因此必須先發佈這個應用程式成 Web 應用程式,記得將允許的使用者。
將這網址紀錄,下篇會使用到。
>> 下一篇請點我 >>
話說之前有段時間,匿名發文粉絲專頁如雨後春筍般冒出,現在好像過飽和了…(?),不過我覺得匿名粉專是個不錯的練習題材,因為他可以練習紀錄資料、API 調用、前端網頁,如果想要還可以製作管理介面等。
這系列文章會建立一個即時的,也就是無審核(審核版的可能使用番外篇釋出),系列次序大概是:
匿名發文的流程是:發文者訪問發文介面→發文介面紀錄資料→發文系統讀取資料→發文系統調用發文 API 發文。所以我們要製作的就是發文介面和系統,發文介面可以簡單的使用 Google Form 達成,也可以使用自己的介面,而系統就需要自己寫了。
我們會需要用到的工具包含:
參考文件則有:
當然不用先把這兩個文件食用完畢,不過如果哪天這系列的程式碼無法使用請參考文件修改。首先開啟 Google Drive,新增一個 Google Apps Script,如果你沒用過需要到商店連結應用程式。
Google Apps Script 是 Google 自己的一個平台,應該可以這麼說,使用 JavaScript。這邊先擱置,下一篇再來開始使用。接著我們要準備的是 Facebook 粉絲專頁,建立粉專就跳過了(相信這對大家並不構成問題)。建立應用程式則需要到 Facebook for Developers,我相信建立也沒什麼問題。
完成後我們需要建立粉絲專頁的 Token,從工具中的圖形 API 測試工具可以生成。
使用剛剛建立的應用程式取得粉絲專頁的權杖(我習慣叫 Token,通常網路上的資源也都是稱 Token),同時要求 publish_page。中間可能會跳出授權請求,同意即可。
接著可以試著使用對 /feed 發送 POST 請求,並新增 message 欄位,填入測試訊息,他會回傳一個帶有文章 ID 的 JSON。你可以使用 https://www.facebook.com/{id} 來看看效果。例如下面這個例子就是:
測試能用後(如果不能請確定應用程式有 publish_page 的權限,如果有但不行……我也不知道),我們需要把這個暫時 Token 轉換成長久 Token,以前可以永久,現在好像比較麻煩。打開存取權杖工具後延長,將此 Token 紀錄。
這樣事前準備就大致完成了。
>> 下一篇請點我 >>