Facebook graph api 在谷歌应用程序脚本web应用程序中使用Facebook API?

Facebook graph api 在谷歌应用程序脚本web应用程序中使用Facebook API?,facebook-graph-api,google-apps-script,facebook-apps,Facebook Graph Api,Google Apps Script,Facebook Apps,我正在尝试创建一个Facebook应用程序,使用Google应用程序脚本作为web应用程序,作为后端。唯一适用的Facebook API似乎是,但我甚至无法让它工作。 我目前遇到的问题是,Facebook JS SDK使用的Javascript标识符以“\uuuu”结尾。以双下划线结尾的Google应用程序脚本名称 如果我使用Facebook的JS文件的修改副本,但名称中没有双下划线,我会得到以下错误: 拒绝在框架中显示[URL],因为它将“X-frame-Options”设置为“SAMEORI

我正在尝试创建一个Facebook应用程序,使用Google应用程序脚本作为web应用程序,作为后端。唯一适用的Facebook API似乎是,但我甚至无法让它工作。
我目前遇到的问题是,Facebook JS SDK使用的Javascript标识符以“\uuuu”结尾。以双下划线结尾的Google应用程序脚本名称

如果我使用Facebook的JS文件的修改副本,但名称中没有双下划线,我会得到以下错误:
拒绝在框架中显示[URL],因为它将“X-frame-Options”设置为“SAMEORIGIN”


你知道如何让GAS在FB上玩得很好吗?

我已经知道如何使用Apps脚本
UrlFetchApp.fetch
和HTML服务让用户在Facebook上登录到我的Apps脚本应用程序。我也可以通过应用程序脚本发布到Facebook

  • 您不需要Facebook Javascript SDK
概述 有8种不同的Facebook平台:

我在应用程序脚本中使用的Facebook平台是网站平台。该网站没有嵌入Facebook运行

你不能做的事:(据我所知)

  • 与Facebook互动的网站与Facebook页面标签之间存在差异。Facebook的
    页面选项卡
    嵌入在Facebook中运行。我的经验是,应用程序脚本URL会导致Facebook页面选项卡出现问题。“应用程序URL”脚本的结尾添加了很多内容,Facebook似乎将这些内容去掉了。(或者类似的)我在Facebook上尝试了许多不同的谷歌产品。您可以将Google站点用作Facebook页面选项卡,但如果将Google应用程序脚本嵌入到站点中,然后嵌入到Facebook页面选项卡中,则会导致跨域错误。所以,我唯一能去工作的选择就是网站
我解决页面标签问题的一种方法是使用Thunderpenny静态HTML作为Facebook页面标签,然后链接到我的应用程序脚本应用程序或GAE应用程序。(取决于我是否需要HTTPS

你可以使用谷歌网站作为页面标签,但Thunderpenny可以像平常一样用HTML、Javascript和CSS设计一个应用程序。哦我曾尝试在Thunderpenny中使用Facebook Javascript SDK,但没有成功。此外,Thunderpenny应用程序没有后端,应用程序脚本有一个后端(.gs代码),您可以在其中隐藏您的Facebook应用程序令牌

基本步骤包括:
  • 从应用程序中触发到Facebook oauth的链接
  • href=”https://www.facebook.com/dialog/oauth?client_id=yourIDhereNoQuotes&redirect_uri=https://script.google.com/macros/s
  • 使用OnLoad函数从URL捕获返回的Facebook令牌
  • 您无法使用
    doGet(e)
    将Facebook重定向URL处理回您的应用程序。原因如下。应用程序脚本需要在URL中看到问号才能解析URL。Facebook返回具有不同配置的URL
  • 在应用程序加载时运行脚本以处理Facebook令牌
  • window.onload=function(){}
  • onload
    函数运行
    .gs
    函数来验证令牌
  • 使用
    UrlFetchApp.fetch
    调试令牌
  • 在专用缓存中缓存登录状态
  • var cache=CacheService.getPrivateCache()
  • 需要时检查登录状态
请注意,Facebook会独立跟踪你的应用程序登录状态。但是,当Facebook令牌过期时,你的应用程序的登录状态可能为“仍处于活动状态”。因此,你需要一种方法来检查这一点

使用官方Facebook图形

下载Facebook图形。阅读“做”和“不做”

创建Facebook登录按钮 窗口加载代码 这是我用来捕获Facebook令牌的window.onload客户端代码。这只用于捕获Facebook令牌,而不是验证令牌。我的应用程序允许Facebook登录和常规登录。Facebook令牌的验证在另一个代码中完成

window.onload=function(){
  //console.log("This onload did run");

  //get the URL out of the browsers address bar
  //the URL can have multiple different strings attached depending upon the situation.
  //1)Sign in with Facebook. 2) Someone wanting to buy an item 3) Someone wanting to input an item for sale.
  //Any situation other than the FB log in is initiated in the back end.
  window.daURL = window.location;
  window.urlStrng = daURL.toString();

  //console.log("url: " + urlStrng);
  //If there was a FaceBook login, there will be a hashtag in the url string
  window.hashPos = urlStrng.indexOf("#");
  if (window.hashPos > 0) {
    mainStart('InputBlock', 'InputForm');
    window.urlEnd = urlStrng.split("#", 2);
    window.urlTkn = urlEnd[1].split("&", 2);
    window.fbAcsTkn = urlTkn[0].split("=", 2);
    window.finalTkn = fbAcsTkn[1];

    window.scndExpire = urlStrng.substring(urlStrng.indexOf("_in=")+4, urlStrng.length);
    console.log("scndExpire: " + scndExpire);

    google.script.run.withFailureHandler(onFailure)
    .withSuccessHandler(showFBsuccess)
    .processFB_LogIn(window.finalTkn, scndExpire)
  }
  else {
    //If it's not a Facebook log in, go to next two choices
    //If the URL string has &L in it, then item listing info is being passed because someone clicked 'Buy'
    window.whatToLoad = urlStrng.indexOf("&L");
    console.log("Second option of onload ran");
    if (window.whatToLoad > 0) {
      google.script.run.withFailureHandler(onFailure)
        .withSuccessHandler(injectBuyForm)
        .include('MutualCmit');
     } else {
     google.script.run.withFailureHandler(onFailure)
       .withSuccessHandler(injectSignInForm)
       .include('SignIn');
     };
  };
};
请注意,即使Facebook登录是在前端触发的,验证也会在
.gs
代码中进行。有人可能会注入一个虚假的Facebook令牌,但它不会在服务器端代码中通过检查

这是处理Facebook登录的
.gs
代码:

Facebook令牌GS代码的验证 您需要一个
one-time
App令牌,除非您的App Secret发生更改,否则该令牌不会更改。您必须使用一段一次性运行的代码生成该令牌

使用以下代码获取您的应用程序访问令牌: 发布到Facebook GS代码 发布到Facebook前端Javascript代码

window.WriteInput=函数(whereToPost){
window.strngCtgry=document.getElementById('id\u Category')。值;
window.strngMaker=document.getElementById('id\u Maker')。值;
window.strngAskingPrice=document.getElementById('id\u AskingPrice')。值;
window.strngType=document.getElementById('id\u ShrtDesc')。值;
window.strngFunction=document.getElementById('id_Function')。值;
window.strngCosmetic=document.getElementById('id_-Cosmetic')。值;
window.strngDescription=document.getElementById('id_Description')。值;
window.strngUserID=document.getElementById('pubID_Holder').textContent;
window.addrIP=document.getElementById('IP_Holder').textContent;
如果(whereToPost==='fb'){
console.log(“fncPostToFB run”+strngDescription);
if(strngDescription==“”| | strnggaskingprice==“”){alert(“缺少输入”);返回false;};
google.script.run.withFailureHandler(postFbFail)
.withSuccessHandler(savedToFB)
.fncPostItemFB(strngCtgry、strngMaker、strngGaskingPrice、strngType、strngDescription、strngFunction、strngCosmetic、addrIP);
}否则{
google.script.run.withFailureHandler(onFailure)
.withSuccessHandler(sa
#FbLog {
    padding: 10px;
    background-color: white;
    margin-left:auto;
    margin-right:auto;
    cursor: pointer;
}
window.onload=function(){
  //console.log("This onload did run");

  //get the URL out of the browsers address bar
  //the URL can have multiple different strings attached depending upon the situation.
  //1)Sign in with Facebook. 2) Someone wanting to buy an item 3) Someone wanting to input an item for sale.
  //Any situation other than the FB log in is initiated in the back end.
  window.daURL = window.location;
  window.urlStrng = daURL.toString();

  //console.log("url: " + urlStrng);
  //If there was a FaceBook login, there will be a hashtag in the url string
  window.hashPos = urlStrng.indexOf("#");
  if (window.hashPos > 0) {
    mainStart('InputBlock', 'InputForm');
    window.urlEnd = urlStrng.split("#", 2);
    window.urlTkn = urlEnd[1].split("&", 2);
    window.fbAcsTkn = urlTkn[0].split("=", 2);
    window.finalTkn = fbAcsTkn[1];

    window.scndExpire = urlStrng.substring(urlStrng.indexOf("_in=")+4, urlStrng.length);
    console.log("scndExpire: " + scndExpire);

    google.script.run.withFailureHandler(onFailure)
    .withSuccessHandler(showFBsuccess)
    .processFB_LogIn(window.finalTkn, scndExpire)
  }
  else {
    //If it's not a Facebook log in, go to next two choices
    //If the URL string has &L in it, then item listing info is being passed because someone clicked 'Buy'
    window.whatToLoad = urlStrng.indexOf("&L");
    console.log("Second option of onload ran");
    if (window.whatToLoad > 0) {
      google.script.run.withFailureHandler(onFailure)
        .withSuccessHandler(injectBuyForm)
        .include('MutualCmit');
     } else {
     google.script.run.withFailureHandler(onFailure)
       .withSuccessHandler(injectSignInForm)
       .include('SignIn');
     };
  };
};
//I put this cache line at the very top of the `.gs` file. The other code
// can be put somewhere lower.

var cache = CacheService.getPrivateCache();

function processFB_LogIn(argFB_Tkn, expTime) {
    cache.put('fbTkn', argFB_Tkn, 4000);
    cache.put('fbExpr', expTime, 4000);

    var meFBtkn = cache.get('fbTkn');

    Logger.log("FaceBook Token: " + meFBtkn);

     //This section is for verifying (debug) the user actually signed in through Facebook
    //The first FB token is passed in from the URL right after the user signs in, and when this apps Script loads.
    //IMPORTANT!!!    IMPORTANT!!!   You MUST escape the | character with code %7C

    var AppAccssTkn = 'YourAppID%7YourAppToken'; //This never changes unless app secret changes
    var optnGetTkn = {"method" : "get", "muteHttpExceptions" : true};
      //This 'Debugs' the token returned in the URL after the user signed in with Facebook.  You "should" verify that the token is real.
      var rsltDebug = UrlFetchApp.fetch("https://graph.facebook.com/debug_token?input_token="  + meFBtkn  + "&access_token=" + AppAccssTkn, optnGetTkn);
      var debugTxt = rsltDebug.getContentText();
      Logger.log("debugTxt: " + debugTxt);

      var jsonObj = JSON.parse(debugTxt);
      Logger.log("jsonObj: " + jsonObj);
      //This is the FB user ID
      var useIdTxt = jsonObj.data.user_id;
      cache.put('pubIDcache', useIdTxt, 4000);

      var tknValid = jsonObj.data.is_valid;

      Logger.log("reslt of the debug: " + useIdTxt);
      Logger.log("tknValid: " + tknValid);

      var getFbUseName = UrlFetchApp.fetch("https://graph.facebook.com/" + useIdTxt + "/?fields=first_name&access_token=" + AppAccssTkn, optnGetTkn);

      var objUseName = JSON.parse(getFbUseName);
      var arryFirstName = objUseName.first_name;
      Logger.log("user name: " + arryFirstName);

      cache.put('fbFrstName', arryFirstName, 4000);

   if (tknValid === false) {
     return 'notValid';
   }
   else if (arryFirstName != null) {
     //This is how it's determined if someone is logged in or not.
     cache.put('imin', '9847594ujglfugfjogj', 4000);
     return arryFirstName;
  };
};
//A Facebook App Token never changes unless you go to the Facebook Developers Console, and you
//change the App Secret.  So, do NOT keep requesting a new App Token.  Just get it once, then
//hard code it into a backend secret function.
// The App Token can be used to modify your App, but you can just do that 'Manually'
function getOneTimeFB_AppToken() {
  Logger.log("getOneTimeFB_AppToken ran");
  //keep this info secret
  //Generate an App Access Token
  var ysshAppID = 'Your App ID';
  var ysshAppSecret = 'Your App Secret';
  var optnAppTkn = {"method" : "get"};
  var getAppTknURL = "https://graph.facebook.com/oauth/access_token?client_id=" + ysshAppID + "&client_secret=" + ysshAppSecret + "&grant_type=client_credentials"
  var getAppTkn = UrlFetchApp.fetch(getAppTknURL, optnAppTkn);
  Logger.log("Object returned from GET: " + getAppTkn)
  var myAppTkn = getAppTkn.getContentText();
  Logger.log("myAppTkn: " + myAppTkn);
};
function fncPostItemFB(arg1ToPost, arg2ToPost, arg3ToPost, argEtcToPost) {
  var fbCacheTkn = cache.get('fbTkn');
  Logger.log("fbCacheTkn: " + fbCacheTkn);

  if (fbCacheTkn === null) {
    return false;
  };
  Logger.log("fncPostItemFB ran: " + fbCacheTkn);
  return fncPostSecurly_(arg1ToPost, arg2ToPost, arg3ToPost, argEtcToPost);
};

function fncPostSecurly_(arg1ToPost, arg2ToPost, arg3ToPost, argEtcToPost) {
  Logger.log("fncPostSecurly ran");

  var sttsUpdate = argToPost + "your text to post here" + argToPost;
  var fromLogInTkn = cache.get('fbTkn');

  Logger.log("cache FB token: " + fromLogInTkn);

  //This is added security https://developers.facebook.com/docs/graph-api/securing-requests/
  var appsecret_sig = Utilities.computeHmacSha256Signature(fromLogInTkn, "YourAppSecret");
  var optnPostFB = {"method" : "post"};  //
  var PostToFB_URL = "https://graph.facebook.com/FacebookPageOrGroupID/feed?message=" + sttsUpdate + "&access_token=" 
    + fromLogInTkn; // + "&appsecret_proof=" + appsecret_sig;


    //Make a post to the Page
    var whatHappened = UrlFetchApp.fetch(PostToFB_URL, optnPostFB );
    //The return from facebook is an object.  Has to be converted to a string.
    var strFrmFbObj = whatHappened.getContentText();
    Logger.log("Return value of Post: " + strFrmFbObj);

    //When a post is successfully made to Facebook, a return object is passed back with an id value.

    var rtrnVerify = strFrmFbObj.indexOf('{\"id\":\"');
    Logger.log("rtrnVerify: " + rtrnVerify);

    if (rtrnVerify != -1) {
      return true;
    } else {
      return false;
    };
 };
<script>
window.WriteInput = function(whereToPost) {

    window.strngCtgry = document.getElementById('id_Category').value;
    window.strngMaker = document.getElementById('id_Maker').value;
    window.strngAskingPrice = document.getElementById('id_AskingPrice').value;
    window.strngType = document.getElementById('id_ShrtDesc').value;
    window.strngFunction = document.getElementById('id_Function').value;
    window.strngCosmetic = document.getElementById('id_Cosmetic').value;  
    window.strngDescription = document.getElementById('id_Description').value;
    window.strngUserID = document.getElementById('pubID_Holder').textContent;
    window.addrIP = document.getElementById('IP_Holder').textContent;

  if (whereToPost === 'fb') {
    console.log("fncPostToFB ran" + strngDescription);
    if (strngDescription === "" || strngAskingPrice === "") {alert("Missing Input"); return false;};
    google.script.run.withFailureHandler(postFbFail)
    .withSuccessHandler(savedToFB)
    .fncPostItemFB(strngCtgry, strngMaker, strngAskingPrice, strngType, strngDescription, strngFunction, strngCosmetic, addrIP);
  } else {
    google.script.run.withFailureHandler(onFailure)
      .withSuccessHandler(savedLst)
      .fncSaveItem(strngCtgry, strngMaker, strngAskingPrice, strngType, strngDescription, strngFunction, strngCosmetic, addrIP);
      };
    };

window.savedLst = function(rtrnInput) {
   if (rtrnInput === false) {
     alert("Failed to Save Data");
   }
   else if (rtrnInput === "NotLogged") {
     alert("You are not logged in!");
     mainStart('SignInBody', 'SignIn');
   }
   else if (rtrnInput === "noItemForPic") {
     alert("You Need to Save an Item to attach the Picture to");
   }
   else {
  alert("Your Data Was Saved!");
  //Show the listing that was just saved next to the upload Pics button
  document.getElementById('listToPic').innerHTML = document.getElementById('id_ShrtDesc').value +
    ", " + document.getElementById('id_Description').value +
    ", - Made By: " + document.getElementById('id_Maker').value +
    ", Price: $" + document.getElementById('id_AskingPrice').value;

    };
};

window.postFbFail = function() {
  alert("Failed to Post to Facebook!  Try Signing In Again.");
  unsignFB();
};

window.savedToFB = function(pstFbStat) {
  if (pstFbStat === false) {
    alert("You are Not Signed in to Facebook!");
    unsignFB();
    google.script.run.withFailureHandler(onFailure)
      .signOutFB();
  } else {
    alert("Your Item was Posted to Facebook!");
  };
};

</script>