[Facebook][ASP.NET] 透過 signed_request 變數取得應用程式於粉絲專頁中的資訊(是否已按讚、傳遞參數)

Standard

這東西應該很久了,但最近有這個需求就做一下筆記囉。

我們在製作 Facebook 粉絲專頁的頁籤應用程式時,會有傳遞參數的需求,但若用一般方式丟參數進去,會發現接不到 :/

https://www.facebook.com/{page_id}?sk=app_{app_id}&key=value

這樣是不行的…

stackoverflow 找了一下,原來要透過 app_data 這個參數丟,並透過 signed_request 去解析。

是這樣丟的:

https://www.facebook.com/{page_id}?sk=app_{app_id}&app_data={"key1":"value1","key2":"value2"}

那至於 signed_request 怎麼解呢?
PHP SDK 有很方便的 $facebook->getSignedRequest() 方法,至於 ASP.NET 若要手刻的方式比較麻煩些(微軟那套 C# SDK 應該也是有方法,但它改版速度太快了,怕寫法一下就失效,所以這邊以不透過 SDK 的方式示範囉):

關鍵的 code 在這(C#):(出處 stackoverflow

string payload = Request.Form["signed_request"].Split('.')[1];
var encoding = new UTF8Encoding();
var decodedJson = payload.Replace("=", string.Empty).Replace('-', '+').Replace('_', '/');
var base64JsonArray = Convert.FromBase64String(decodedJson.PadRight(decodedJson.Length + (4 - decodedJson.Length % 4) % 4, '='));
var json = encoding.GetString(base64JsonArray);
var o = JObject.Parse(json);

解出 app_data 的值之後就可以做事啦,建議可以塞入 json 的字串,例如:

app_data={"key1":"value1","key2":"value2"}

這樣就可以傳遞多個參數了~

其實 signed_request 還有一些資訊可以幫助我們在做頁籤應用程式時使用,
例如:不用透過 Facebook Connect 就判斷使用者是否已經按讚(Like),或是判斷此頁籤應用程式是否被安裝到其他的粉絲專頁中了。
(安裝的方法很簡單:https://www.facebook.com/dialog/pagetab?app_id={APP_ID}&next=http://www.facebook.com)

這邊就不多說,直接參考下面的程式碼吧。

完整的 code 在這邊,記得還要將 JSON.NET 加入參考喔!

using System;
using System.Text;
using Newtonsoft.Json.Linq;

public partial class index : System.Web.UI.Page
{
    public string JSONString = "";
    public string output = "";
    public bool liked = false;
    public string pageid = "";
    public JObject app_data;

    protected void Page_Load(object sender, EventArgs e)
    {
        if (string.IsNullOrEmpty(Request.Form["signed_request"]))
        {
            Response.Write("<p>現在不是內嵌在粉絲專頁內喔</p>");
        }

        try
        {
            string payload = Request.Form["signed_request"].Split('.')[1];
            var encoding = new UTF8Encoding();
            var decodedJson = payload.Replace("=", string.Empty).Replace('-', '+').Replace('_', '/');
            var base64JsonArray = Convert.FromBase64String(decodedJson.PadRight(decodedJson.Length + (4 - decodedJson.Length % 4) % 4, '='));
            var json = encoding.GetString(base64JsonArray);
            var o = JObject.Parse(json);

            JSONString = "Decoded: <br />" + json;

            // 是否已經按讚
            liked = (bool)o.SelectToken("page.liked");
            // 粉絲專頁 ID
            pageid = (string)o.SelectToken("page.id");
            // 傳遞變數使用 app_data
            if (o.SelectToken("app_data") != null)
            {
                app_data = JObject.Parse((string)o.SelectToken("app_data"));
            }
        }
        catch (Exception ex)
        {
            output += "解析錯誤: " + ex.Message;
            Response.Write(output);
        }

        Response.Write("<p>" + JSONString + "</p>");

        string liketxt = (liked) ? "哈囉,你已經按讚,謝謝你" : "賞我個讚吧!";
        Response.Write("<p>" + liketxt + "</p>");

        Response.Write("<p>本專頁的 ID 為:" + pageid + "</p>");

        // 接收放在 app_data 中的 test 參數
        Label1.Text = (app_data != null && app_data.SelectToken("test") != null && !string.IsNullOrEmpty((string)app_data.SelectToken("test"))) ? app_data.SelectToken("test").ToString() : String.Empty;
    }
}

參考資料:

2 thoughts on “[Facebook][ASP.NET] 透過 signed_request 變數取得應用程式於粉絲專頁中的資訊(是否已按讚、傳遞參數)

  1. 羽落

    不好意思,請問一下,
    有辦法不要經過內嵌的app就得知使用者是否有加入粉絲團嗎?

    我有一個web使用Facebook登入,但Facebook一直不讓我通過取得使用者的user_likes,
    找到 signed_request的方法後,研究了好幾天,

    看了大大您的作法後才發現,這個方式似乎是Facebook呼叫內嵌網頁時才發出的Request…

    不知道大大有沒有其他妙招Orz

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *