Facebookへのアップロード
このチュートリアルでは、Facebookにファイルをアップロードしてみます。 本サイトでは、Facebookへアップロードする サンプルプログラムを公開していますので、ここでは、サンプルプログラムがどのように動作するかをみていきます。
Facebook.html
facebook.htmlは、FacebookのOAuthサービスへリダイレクトするためにjavascriptを使用します。これは、認証トークンを取得するために使用します。
fb_get_token.lua
fb_get_token.luaは、長期アクセストークン(60日間有効)を取得するために使用します。
まず、現在のアクセストークン(有効期限が1時間)が有効であることを確認するために、 fa.requestとcjsonを使用します。
local function hasValidToken(t)
local b, c, h = fa.request {
url = 'https://graph.facebook.com/debug_token?input_token='
..t.user_access_token..'&access_token='
..t.app_access_token,
headers = {Connection = 'close'}
}
if (c == 200) then
local cjson = require("cjson")
local res = cjson.decode(b)
cjson = nil
if (res.error ~= nil) then
t.message = res.error.message
else
t.long_term = res.data.issued_at
if (res.data.error ~= nil) then
t.message = res.data.error.message
else
t.message = res.data.message
end
end
return res.data.is_valid
else
t.message = b
return false
end
end
レスポンスコード(c)を確認し、200の場合、JSONレスポンスへデコードします。いずれかのステップで失敗した場合、有効なトークンが取得できず、showAuthorizationURL()が呼ばれ、新しいキーを取得するよう指示する文字が表示されます。
hasValidTokenが「true」を返した場合、長期アクセストークンを取得しにいきます。ここで、FacebookのOAuth APIを呼び出すために、 fa.requestを再び使用します。一時的なアクセストークンを渡すと、60日間有効なアクセストークンに更新され、表示されるはずです。
local function getLongtermToken(t)
local b, c, h = fa.request {
url = 'https://graph.facebook.com/oauth/access_token?grant_type=fb_exchange_token'
..'&client_id='..t.app_id
..'&client_secret='..t.app_secret
..'&fb_exchange_token='..t.user_access_token,
headers = {Connection = 'close'}
}
if (c == 200) then
local s, e = b:find("&")
local longtermToken = b:sub(1, s - 1)
local file = io.open( t.token_fullpath, "w" )
file:write( longtermToken )
io.close( file )
file = nil
s, e = longtermToken:find("=")
-- Store the returned token
t.user_access_token = longtermToken:sub(e+1, #longtermToken)
end
end
fb_token_handler.lua
このスクリプトは、fb_get_token.lua用の設定ファイル(facebook.cfg)を管理します。結果を含むテーブル(mod)を返します。
fb_auto_up.lua
最後に、このスクリプトは、Facebookにアップロードするためのスクリプトです。まず、無線LANが接続されるのを待ちます(waitWlanConnect())。そして、接続が確立されると、アップロードディレクトリ内の各フォルダをを探索し、1回に1ファイルをアップロードします。
各ファイルを選択するために、LuaFileSystemを利用します(autoUpload())。
--...
--For each directory...
for aDirectory in lfs.dir("/DCIM") do
local _dir_id = tonumber(aDirectory:sub(1, 3))
-- print("DIR:"..aDirectory, lfs.attributes("/DCIM/"..aDirectory, "modification"))
if (_dir_id ~= nil and _dir_id >= lastDirectory) then
--for each file in that directory...
for aFile in lfs.dir("/DCIM/"..aDirectory) do
--Process and upload!
--...
次に、フォルダをアップロードする前に、アルバムを作成するためにFacebookのGraph APIを使います。これは、基本的な fa.requestでリクエストを発行します。正しい場所にアップロードするために、レスポンス文字列をデコードし、アルバムIDを取得します。
local function createAlbum(_name, _message)
local req = {}
req["url"] = 'https://graph.facebook.com/v2.1/me/albums?access_token='..user_access_token
..'&name='..string.gsub (_name, " ", "+")
..'&message='..string.gsub (_message, " ", "+")
..'&privacy=%7B%22value%22%3A+%22SELF%22%7D'
req["method"] = 'POST'
req["headers"] = {Connection = "close"}
local b,c,h = fa.request(req)
if (c ~= 200) then
print(h, b)
return nil
end
req = nil
c, h = nil
local cjson = require("cjson")
local res = cjson.decode(b)
collectgarbage()
return res["id"]
end
最後に、POSTリクエストを発行するために、 fa.requestを使用して各ファイルのアップロードを行います。(uploadFile(filePath,_album_id))
local function uploadFile(filePath, _album_id)
local boundary = '--bnfDxpKY69NKk'
local headers = {}
local place_holder = '<!--WLANSDFILE-->'
headers['Connection'] = 'close'
headers['Content-Type'] = 'multipart/form-data; boundary="'..boundary..'"'
local body = '--'..boundary..'\r\n'
..'Content-Disposition: form-data; name="source"; filename="'
..filePath..'"\r\n'
..'Content-Type: image/jpeg\r\n\r\n'
..'<!--WLANSDFILE-->\r\n'
.. '--' .. boundary .. '--\r\n'
headers['Content-Length'] =
lfs.attributes(filePath, 'size')
+ string.len(body)
- string.len(place_holder)
local args = {}
args["url"] = 'https://graph.facebook.com/v2.1/'
.._album_id..'/photos?access_token='
..user_access_token
..'&message='..filePath
args["method"] = "POST"
args["headers"] = headers
args["body"] = body
args["file"] = filePath
args["bufsize"] = 1460*10
local b,c,h = fa.request(args)
b, h = nil
collectgarbage()
if (c ~= 200) then
print(h, b)
return nil
end
return c
end
アップロードには数分かかる場合があります。
サンプルコード
このサイトのサンプルコードは二条項BSDライセンスで提供されています。