OAUTH2を使ったDropboxへのアップロード

このチュートリアルでは、Dropboxへファイルをアップロードする方法をみていきます。このスクリプトは、アップロードとアクセストークンの保存を行います。


はじめに

  1. FlashAirにUploadフォルダを作成し、アップロードするファイルを設置します。
  2. アップロード機能を有効にするために、CONFIGファイルにUPLOAD=1を追加します。
  3. FlashAirでLuaを実行するを参考に、Luaスクリプト実行方法をCONFIGファイルに指定します。

アプリの登録

この作業は、インターネットに接続されたPC上で行います。

  1. Dropbox Developersを開きます。
  2. 画面右上の”Sign in”をクリックし、Dropboxアカウントにログインします。
  3. ログイン後、左ナビゲーションの”My apps”をクリックし、”Create apps”をクリックします。 アプリの登録
  4. APIの設定をすべて入力し、”Create app”をクリックしてください。 アプリの登録
    • 例: “Dropbox API”,”App folder”,”Lua Upload”
  5. appが作成できると、App keyとApp secretが取得できます。App secretは”Show”をクリックすると表示されます。これらの情報は取扱に注意し、他人と共有しないようにしてください。 アプリの登録
  6. 以下のリンクより”authorization code”を取得します。ウェブブラウザから以下のURLにアクセスします。client_idには取得したApp keyを入力してください。
      https://www.dropbox.com/oauth2/authorize?client_id=btbjfXxXxXxXxXx&response_type=code
    
  7. APIリクエストの承認画面が出るので、”許可”をクリックします。 アプリの登録
  8. APIリクエストが承認されました。取得した”authorization code”を控えておきます。 アプリの登録

さあはじめましょう

これで準備ができました。もし最後に実行するスクリプトで、再認証が求められたら、取得したコードの期限が切れている可能性がありますので、再度”authorization code”を取得します。

/DropboxUpload.lua
    --[[
    FlashAir Lua Dropbox example.

    This script uploads and files in a directory to dropbox, using oauth2.
    It will store the access token in dropbox_token.txt
    --]]
    local tokenfile		= "/dropbox_token.txt" 	-- Where to log output on the FA
    local folder 		= "/Upload" 		-- What folder to upload files from
    local app_key		= "btbjfXxXxXxXxXx"	-- Your Dropbox app's key
    local app_secret	= "4k79gXxXxXxXxXx"	-- Your Dropbox app's secret

    --NOTE: Remember to authorize your app!
    local auth_code 	= "XrfRXkfTNcXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxX" -- authorization code

次に、 fa.requestを使用して、アクセストークンを取得しましょう。

    --[[
    requestToken(app key, app secret, authorization code)
    requests the oath2 token, using fa.request().
    returns the token, or nil on a failure.
    --]]
    local function requestToken(key, secret, auth_code)
    	--Request a token
    	message = "grant_type=authorization_code&code="..auth_code.."&client_id="..key.."&client_secret="..secret
    	b, c, h = fa.request{
    		url = "https://api.dropboxapi.com/oauth2/token",
    		method = "POST",
    		headers = {["Content-Length"] = string.len(message),
    		["Content-Type"] = "application/x-www-form-urlencoded"},
    		body = message
    	}

    	--Decode the response body (json format)
    	response = cjson.decode(b)
    	access_token = response["access_token"]
    	if access_token ~= nil then
    		return access_token
    	else
    		error = response["error_description"]
    		print("Failed to get access token. Error: "..c..": "..error)
    		return nil
    	end
    end

取得したトークンを保存するために、2つの関数を用意ましょう。

Note: FlashAirをPCにマウントしてスクリプトを実行している場合、アクセストークンファイルを書き込めないことがあります。その場合は、一度FlashAir取り出して、もう一度実行してみてください。

    --[[
    These functions simply load or save the access token to/from a file (tokenfile).
    --]]
    local function saveToken(access_token)
    	local file = io.open(tokenfile, "w" )
    	file:write(access_token)
    	io.close(file)
    end
    local function loadToken()
    	local file = io.open(tokenfile, "r" )
    	access_token = nil
    	if file then
    		access_token = file:read( "*a" )
    	end
    	return access_token
    end

最後に、実際にファイルをアップロードする関数を書いてみましょう。ここでは、また fa.requestを使用して、PUTリクエストを実行します。

--[[
	uploadFile(folder, file name, access token)
	Attempts to upload a file to dropbox!
--]]
local function uploadFile(folder, file, access_token)
	file_path=folder .. "/" .. file
	--get the size of the file
	local filesize = lfs.attributes(file_path,"size")
	if filesize ~= nil then
		print("Uploading "..file_path.." size: "..filesize)
	else
		print("Failed to find "..file_path.."... something wen't wrong!")
		return
	end

	--Upload!
	b, c, h = fa.request{
		url = "https://content.dropboxapi.com/2/files/upload",
		method = "POST",
		headers = {["Authorization"] = "Bearer "..access_token,
		["Content-Length"] = filesize,
		["Content-Type"] = "application/octet-stream",
		["Dropbox-API-Arg"] = '{"path":"'..file_path..'","mode":{".tag":"overwrite"}}'},
		body = "<!--WLANSDFILE-->",
		bufsize = 1460*10,
		file=file_path
	}

	print(c)
	print(b)

end

これで全てがそろいました。さあ実行してみましょう!保存しているトークンの読み込みを行います。読み込みが失敗した場合、トークンをリクエスト、もしくはauthorization codeの入力を要求します。 そして、LuaFileSystemを使ってディレクトリ内をスキャンし、 FTPチュートリアル同様にアップロードします。

--Script starts

--Attempt to load a token from the file
token = loadToken()

--See if we loaded one, if not request one
if token == nil then
	--Request an access token
	print("No token found, attempting to request one...")
	token = requestToken(app_key, app_secret, auth_code)

	--Was it successful?
	if token == nil then
		print("Failed to request token, do you need to authorize?")
		print("Auth url: https://www.dropbox.com/oauth2/authorize?client_id="..app_key.."&response_type=code")
	else
		print("New token: "..token)
		saveToken(token)
	end

end

--Before continuing, make sure we have an access token
if token ~= nil then
	print("INIT, with token: "..token)
	-- For each file in folder...
	for file in lfs.dir(folder) do
		-- Get that file's attributes
		attr = lfs.attributes(folder .. "/" .. file)

		-- Don't worry about directories (yet)
		if attr.mode == "file" then
			--Attempt to upload the file!
			uploadFile(folder, file, token)
		end
	end
end

Dropboxにアクセスし、アプリフォルダをクリックします。

アプリの登録

作成したアプリ名をクリックします。

アプリの登録

アップロードしたファイルが表示されます。 アプリの登録


サンプルコード

リポジトリを見る(GitHub)

このサイトのサンプルコードはLGPLv2または二条項BSDライセンスで提供されています。