Ameba Arduino: [RTL8195]讓Ameba在Facebook塗鴉牆發表文章

Facebook是線上社群網站,提供平台給一般使用者,使用者可以在上面溝通、分享、儲存影音、參與社團等等,並且提供Graph API供開發者開發應用程式在不同的平台上,包括iOS、Android、網頁應用程式、與Facebook Canvas。應用程式可以在使用者同意之下,使用使用者的資源與服務。

Graph API是基於HTTP protocol的API,在這篇文章裡將會使用Graph API讓Ameba在塗鴉牆上發表文章

材料準備

  • Ameba x 1

範例說明

  • 設定Facebook應用

為了讓Ameba可以存取Facebook,Facebook需要知道來存取的用戶是誰,以及是哪個應用程式的要求。所以我們需要先為我們的應用程式作一些設定。首先到這個網址 https://developers.facebook.com/apps
如果是第一次使用, 會出現成為開發人員的選項, 點選註冊

2

跳出一張選單填選工作職稱,以及同意Facebook的Policy,完成後點選Register。

2

成功後點選點選Done

2

如果之前沒有開發過任何Facebook應用程式, 會跳出底下選單讓你選。這邊我們選Website

2

點選右上方的 “Skip and Create App ID”

2

跳出一張表單,要填寫以下內容

  • Display Name: 這個名字會是你在後台管理時看到的名字,也是這個應用程式代表使用者在Facebook上做出任何行為時會看到的名字。這個範例裡我們填ameba
  • Contact Email: 如果你已經登入,這邊應該已經幫你填好了
  • Category: 根據你的應用填分類

填完之後點選 “Create App ID”

2

完成後會進入後台管理平台。畫面上方有個 APP ID,這個 APP ID用來識別你目前的Facebook應用程式,範例裡的APP ID是 “312698492463829”。 應用程式後端管理平台可以做一些額外的設定,像是OAuth、應用程式domain、上架流程等等

2

  • 取得Access Token

Facebook應用程式會代表使用者在Facebook操作,如果讓應用程式擁有所有的權限就太危險了,所以應用程式實際上需要一個access token。access token是一組很長的字串,在Graph API裡所使用的HTTP protocol常常需要攜帶這個access token,而Facebook紀錄了每一個access token所擁有的權限,代表的應用程式,以及時間限制。我們可以在Graph API Explorer管理我們的access token: https://developers.facebook.com/tools/explorer
這個後台管理介面好幾個部份,簡述如下:

2

  • 右上方有個Application的選單,第一次進來應該會選到 “Graph API Explorer”, 我們點開這個選單應該會看到裡面有 ameba的應用程式
  • Application的選單下方有個 “Get Token”的選單, 點選之後裡面有三種Token,這個範例裡我們只會用到 “user access token”,關於不同的access token的用途可以參考底下網址:
    https://developers.facebook.com/docs/facebook-login/access-tokens
  • 在 “Token Type”左邊則是Token的值,以字串表示
  • 下面那欄則是使用者想要下達的Graph API命令。由左至右分別是
    • HTTP Request type: 根據Graph API使用手冊填入想下達的HTTP Request type,常用的通常只有GET與POST
    • Graph API Version: Facebook會不同時改版Graph API,範例裡的版本是v2.8。在應用程式開發裡也可以不帶版號,Facebook預設會使用當下所允許的最舊版本
    • Request content: 這裡填Graph API裡需要帶的參數。Graph API Explorer會視情況幫你加上access token
  • 畫面中央則是一些debug訊息

現在我們來設定應用程式的access token,點選Application,選擇ameba

2

在 “Get Token” 的地方,點選 “Get User Access Token”

2

接著會跳出一個選單,這個選單是讓你勾選你的 ameba Facebook應用程式可以代表使用者作哪些行為。因為我們需要在塗鴉牆上寫東西,所以我們參考Graph API說明文件:

https://developers.facebook.com/docs/graph-api/reference/v2.8/group/feed

https://developers.facebook.com/docs/graph-api/reference/v2.8/user/feed

於是我們需要底下幾個permission:
publish_actions, user_managed_groups

2

接著可能會出現警告訊息,這是因為Facebook不希望使用者在不知情的情況下被應用程式拿來散佈與發表訊息,因此要求應用程式提供相關Policy供使用者確認,這一步我們先跳過,只有要將應用程式公開並嘗試通過Facebook審查才需要補上這部份。

2

接著會詢問你是否同意ameba Facebook應用程式將代替你發表文章,點選OK

2

接著詢問你是否同意ameba Facebook應用程式將代替你管理社團與粉絲團,點選OK

2

完成後跳回Graph API Explorer,現在access token的地方已有值

2

我們先利用Graph API Explorer測試一下是否可以發文, 我們在HTTP request的幾個欄位填寫如下:

  • HTTP REQ Type: 點選並改成POST
  • HTTP REQ content: 填寫 “me/feed?message=HelloWorld” 其中message後面的值是要發表的內容,以URI編碼

完成後按下Submit後,下方debug資訊會出現該篇文章的id

2

文章的id可以拿做一些操作,像是修改文章、按讚、留言等等,這些可以在Graph API文件裡找到相關資訊。

我們回到Facebook,會發現自己的塗鴉牆上,ameba Facebook應用程式已經代替自己發表了文章,並且該篇文章自己名字底下有 “ameba” 的字串

2

剛剛執行的動作其實是送HTTP protocol的資訊,並且可以用openssl來模擬,如果你有安裝openssl的話,請執行:

openssl s_client -connect graph.facebook.com:443

會進入interactive mode,接著輸入底下內容(中間請勿打錯字修改刪除,這些行為都會被當成控制字元送出)。其中access_token=後面的值是你的access token。最後的message=我們改成HelloWorldV2。最後面記得輸入空白行結束HTTP命令

POST 
/v2.8/me/feed?access_token=EAAEcZAcqQqtUBAAN0YbAemjZCwvmknqjocENiPwUX92TR7Q54jiKrtyEOR8p2EgfR1RQz3uWeDmEQt9oNYOMaRBqGci55CD9chdXcCQXu1jwXPvLpvPZAMeZBVxWZA94sCEZBVN93ZADDe6XkaJpDxJlvdTF0zATFMZD&message=HelloWorldV2
Host: graph.facebook.com

成功的話應該會收到底下訊息

HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Pragma: no-cache
Cache-Control: private, no-cache, no-store, must-revalidate
facebook-api-version: v2.8
Expires: Sat, 01 Jan 2000 00:00:00 GMT
Content-Type: text/javascript; charset=UTF-8
x-fb-trace-id: AWAKUnVL1yX
x-fb-rev: 2757773
Vary: Accept-Encoding
X-FB-Debug: 7SqJtuZjt0RZzpAGiknOhcUs0qbDG0Q4WNep592ssnzoc0xRM7IGhsrGy/B38uvGt36vky8rgcfVTD8zuLQ7NA==
Date: Mon, 26 Dec 2016 11:42:36 GMT
Connection: close
Content-Length: 40

{"id":"103964610106403_103999236769607"}closed

塗鴉牆上也多了一篇文章

2

如果想在message帶空格或是中文,可以參考一些http url encoder將中文改成URL的值 http://meyerweb.com/eric/tools/dencoder/
這部份留給讀者自行嘗試

  • 檢視token的內容與展延token

我們在前小節裡取得的access token其實有時間限制,我們可以使用 Access Token Debugger 來檢查何時到期
https://developers.facebook.com/tools/debug/accesstoken/

可以看到這個access token的資訊,包括是哪個應用程式所使用、權限、到期時間(以UNIX epoch時間表示)。通常預設Graph API Explorer給的access token是short-lived token,時間在兩個小時內就到期。Access token還有另一種long-lived token,時間為兩個月到期,並且每次使用token就可以展延為兩個月。在Access Token Debugger下方就有Extend Access Token的選項,我們點選它

2

下方會出現新的Token,這個long-lived token的值與short-lived token的值不同,我們點選右下方的 Debug看這個 long-lived token的內容

2

會看到它的時間已經展延成兩個月

2

最後補上幾點說明:

1. 根據Graph API文件,每次使用token,Facebook會在不固定的時間重置long-lived token 為2個月,所以只要應用程式一直有在使用,就不用擔心過期的問題
https://developers.facebook.com/docs/facebook-login/access-tokens/expiration-and-extension
但如果一直都沒使用並且token到期,就得重新執行索取token的動作,新的token的值不會與舊的相同
2. 我們可以不經由Graph API explorer取得short-lived token或long-lived token。細節可以參考Graph API文件 https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow

  • 在社團或粉絲團塗鴉牆發表文章

這部份其實跟在自己塗鴨牆發表文章很像,只是我們需要社團的group id。進入社團頁面之後,可以在網址列上看到社團的group id,以底下的例子來說是 “1210426395661463”

2

如果社團或粉絲團曾經修改過名稱,可以藉由一些網站來幫忙找group id:

http://lookup-id.com/

http://wallflux.com/facebook_id/

接著我們使用 Graph API Explorer填入以下的值

  • HTTP REQ type: 一樣是 POST
  • HTTP REQ content: “1210426395661463/feed?message=HelloGroup”
    前面那串數字是group id,後面的message我們改成HelloGroup

接著按下Submit,成功的話一樣會在Debug資訊欄出現該篇文章的id

2

回到社團頁面,會看到ameba已代替使用者成功發表文章

2

範例一:使用Ameba在塗鴉牆上發表文章

要讓Ameba在Facebook塗鴉牆發表文章,做的事情與前面使用openssl模擬發文的行為類似,只需經由SSL傳送HTTP protocol的內容即可。
在這個範例裡我們每分鐘發表一篇文章,因為Facebook會審查我們是否發表同樣的文章內容,所以我們用字串陣列來改變每次發表的內容。在Arduino IDE上打開範例 “File” -> “Examples” -> “AmebaWiFi” -> “Facebook” -> “facebook_feed_publish”

填上你欲連上的WiFi AP資訊

2

填上你所使用的access token

2

設定塗鴉牆的對象,如果是自己的塗鴉牆則使用 “me”,如果是社團或粉絲團則使用並填上group id

2

編譯並上傳至Ameba執行,等待一會兒可以看到Ameba在代表使用者發表文章

2

範例一:程式碼說明

  • 變數說明

字串 server內容為Facebook Graph API的server位置

char server[] = "graph.facebook.com";    // facebook graph api service

字串 access_token裡面放的是short-lived token或long-lived token。如果是short-lived token要注意token是否過期,一般來說short-lived token的期限大約在2小時

char access_token[] = "EAAEcZAcqQqtUBAAN0YbAemjZCwvmknqjocENiPwUX92TR7Q54jiKrtyEOR8p2EgfR1RQz3uWeDmEQt9oNYOMaRBqGci55CD9chdXcCQXu1jwXPvLpvPZAMeZBVxWZA94sCEZBVN93ZADDe6XkaJpDxJlvdTF0zATFMZD";

範例裡我們會使用到SSL,所以宣告WiFiSSLClient的變數

WiFiSSLClient client;

字串陣列message_list裡面放的是我們想發佈的訊息,以URI的方式encode。網路上有很多URI encode的工具可以幫忙轉換特殊符號與特殊文字

#define MESSAGE_LIST_SIZE 5
int message_index = 0;
char *message_list[MESSAGE_LIST_SIZE] = {
……
  • 程式流程

程式流程圖如下
2
比較需要注意的是當我們用WiFiSSLClient送HTTP POST訊息給Graph API之後,需要確認server端回應的訊息,如果沒有成功發佈訊息至圖鴉牆,那麼server會回一些簡易的錯誤資訊供你參考

範例二:使用Ameba發佈PM2.5訊息至塗鴉牆上

這個範例裡我們會使用Plantower的PMS3003/PMS5003模組,這個模組可以偵測空氣中的細微粒子,並給出PM2.5指數,有關Plantower的使用可以參考網站上之前的文章。

範例裡我們結合PM2.5,讓Ameba發佈偵測到的PM2.5訊息。當PM2.5的值變化超過10,或是已經一小時沒有發佈訊息,那麼Ameba就會發佈目前的PM2.5數值與注意事項至塗鴉牆

我們打開範例“File” -> “Examples” -> “AmebaWiFi” -> “Facebook” -> “facebook_pm25_notifier”

填上你欲連上的WiFi AP資訊:

2

填上你所使用的access token

2

設定塗鴉牆的對象,如果是自己的塗鴉牆則使用 “me”,如果是社團或粉絲團則使用並填上group id

2

選擇欲發佈訊息的語言,預設是英文,可以選擇繁體中文

2

設定完成後,將PMS3003或PMS5003接上Ameba:

2
然後將程式碼編譯並上傳至Ameba,執行結果如下,可以看到Ameba每隔一段時間就更新PM2.5數據,並提供戶外活動建議

2

範例二:程式碼說明

這個範例與前一個範例 “facebook_feed_publish” 類似,除了PM2.5的部份

PM2.5的部份,我們使用類別PMS3003來幫忙取得PMS3003/PMS5003的PM2.5數值。所使用的是pin 0與pin 1的uart功能

PMS3003 pms(0, 1);

然後呼叫get_pm25_aircondition()取得PM2.5的值, 裡面調用 get_pm2p5_air() 取得PM2.5數值

int pm25 = pms.get_pm2p5_air();

並且使用moving average來避免數值突然不穩定的情況, 公式如下:

PM2.5avg = PM2.5avg * 0.9 + PM2.5now * 0.1

在 get_pm25_level()裡面,根據底下的PM2.5分類方式與建議做分類

http://taqm.epa.gov.tw/taqm/en/fpmi.aspx

http://taqm.epa.gov.tw/taqm/tw/fpmi.aspx

整理程式流程如下:
2