上传到Facebook

本教程说明如何上传到Facebook。我们已经发布了示例 Facebook 脚本 ,所以我们不再重新编写,只介绍脚本如何工作。

Facebook.html

Facebook.html 使用javascript将用户导向Facebook Oauth服务。这样只是为了获取认证令牌。

fb_get_token.lua

该脚本用于获取“长期”的认证令牌(持续时间为60天,否则只有一个小时)。

首先使用 fa.request 和cjson来确认当前认证令牌(1小时版本)仍然有效。

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”,我们继续请求长期令牌。这里我们再次使用fa.request调用Facebook的OAuth API。我们将App的令牌和临时访问令牌进行传递,这样就应当返回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

F最后该脚本向Facebook上传。首先脚本等待WiFi连接(waitWlanConnect()),连接成功后,遍历上传目录下每个文件夹,并逐个上传文件。

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!
--...

N之后在上传文件夹之前,脚本使用Facebook的图形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

最后,每个文件都通过使用fa.request 发起POST请求来上传(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 2-Clause 许可证

返回顶部