在Google Apps Script Web应用中使用Facebook API? [英] Use the Facebook API in a Google Apps Script web app?

查看:230
本文介绍了在Google Apps Script Web应用中使用Facebook API?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Google Apps脚本作为Web应用程序创建一个Facebook应用程序作为后端。似乎适用的唯一的Facebook API是



下载Facebook图形。阅读Do's and Dont's



创建Facebook登录按钮



  div id =FbLog> 
< a href =https://www.facebook.com/dialog/oauth?client_id=YourClientID&redirect_uri=https://script.google.com/macros/s/YourAppsScript/exec?& height =95%width =95%>< / a>>< img src =https://FacebookGraphic.png
< / div>



设计Facebook登录按钮



  #FbLog {
padding:10px;
background-color:white;
margin-left:auto;
margin-right:auto;
cursor:pointer;
}



Window OnLoad代码



这是我用来捕获Facebook令牌的window.onload客户端代码。这只用于捕获Facebook令牌,而不是验证令牌。我的应用程序允许Facebook登录和定期登录。验证Facebook令牌是在另一个代码中完成的。

  window.onload = function(){
//控制台.log(this onload did run);

//从浏览器地址栏中获取URL
//根据情况,该URL可以附加多个不同的字符串。
// 1)使用Facebook登录。 2)有人想要购买一个项目3)有人想要输入一个项目出售。
// FB后登录的任何情况都是在后端启动的。
window.daURL = window.location;
window.urlStrng = daURL.toString();

//console.log(\"url:+ urlStrng);
//如果有一个FaceBook登录,url字符串中将有一个主题标签
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 {
//如果不是Facebook登录,请转到下一个选项
//如果URL字符串中有& L,那么项目列表信息正在被传递,因为有人点击了购买
window.whatToLoad = urlStrng.indexOf(& L);
console.log(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令牌,但是不会通过服务器端代码检查。



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



验证Facebook令牌GS代码



  //我把这个缓存行放在`.gs`文件的最上方。另一个代码
//可以放在更低的位置。

var cache = CacheService.getPrivateCache();

函数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);

//本部分用于验证(调试)通过Facebook实际登录的用户
//第一个FB令牌在用户登录后立即从URL传入,这个应用脚本加载。
//重要!重要!!!你必须逃避|字符与代码%7C

var AppAccssTkn ='YourAppID%7YourAppToken'; //这个永远不会改变,除非应用程序的秘密变化
var optnGetTkn = {method:get,muteHttpExceptions:true};
//这个Debugs在用户使用Facebook登录后,URL中返回的令牌。您应该验证该令牌是否真实。
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);
//这是FB用户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){
//这是如何确定某人是否登录。
cache.put('imin','9847594ujglfugfjogj',4000);
return arryFirstName;
};
};

您需要一个一次应用程序令牌除非您的App Secret更改,否则不会更改。您必须通过一次代码生成该代码。



使用以下代码获取您的App访问令牌:



  // Facebook App令牌永远不会改变,除非你去Facebook Developers Console,你
//更改App Secret。所以,不要继续请求一个新的应用程序令牌。只要得到一次,然后
//硬编码成后端的秘密功能。
//应用程序令牌可以用来修改你的应用程序,但你可以这样做'手动'
函数getOneTimeFB_AppToken(){
Logger.log(getOneTimeFB_AppToken ran);
//保持此信息秘密
//生成App访问令牌
var ysshAppID ='您的应用程序ID';
var ysshAppSecret ='你的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(从GET返回的对象+ getAppTkn)
var myAppTkn = getAppTkn.getContentText();
Logger.log(myAppTkn:+ myAppTkn);
};



发布到Facebook GS代码



 函数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);
};

函数fncPostSecurly_(arg1ToPost,arg2ToPost,arg3ToPost,argEtcToPost){
Logger.log(fncPostSecurly ran);

var sttsUpdate = argToPost +你的文本发布在这里+ argToPost;
var fromLogInTkn = cache.get('fbTkn');

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

//这是增加的安全性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;


//发布页面
var whatHappened = UrlFetchApp.fetch(PostToFB_URL,optnPostFB);
//从Facebook返回是一个对象。必须转换成字符串。
var strFrmFbObj = whatHappened.getContentText();
Logger.log(Post的返回值+ strFrmFbObj);

//当Facebook成功发布帖子时,返回对象将以id值的形式传回。

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

if(rtrnVerify!= -1){
return true;
} else {
return false;
};
};



发布到Facebook前端Javascript代码



 < 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_Descripti on')。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(无法保存数据);
}
else if(rtrnInput ===NotLogged){
alert(您尚未登录!);
mainStart('SignInBody','SignIn');
}
else if(rtrnInput ===noItemForPic){
alert(您需要保存项目以附加图片);
}
else {
alert(您的数据已保存!);
//显示刚刚保存在上传图片按钮旁边的列表
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')值;

};
};

window.postFbFail = function(){
alert(无法发布到Facebook!再次尝试登录);
unsignFB();
};

window.savedToFB = function(pstFbStat){
if(pstFbStat === false){
alert(你没有登录到Facebook!
unsignFB();
google.script.run.withFailureHandler(onFailure)
.signOutFB();
} else {
alert(您的项目已发布到Facebook!);
};
};

< / script>


I'm trying to create a Facebook app using a Google Apps Script as web app, as the back-end. The only Facebook API that seems applicable is the Javascript SDK, but I can't even get that one to work.
The current problem I'm having is that the Facebook JS SDK uses Javascript identifiers that end with: "__". Google Apps Script restricts names that end in double underscores.

If I use a modified copy of Facebook's JS file without double underscores in names, I get this error:
Refused to display [URL] in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'

Any idea how to get GAS playing nicely with FB?

解决方案

I've figured out how to use Apps Script UrlFetchApp.fetch and the HTML Service to log a user in to my Apps Script App with Facebook. I can also post to Facebook with Apps Script.

  • You don't need the Facebook Javascript SDK

General Overview

There are 8 different Facebook Platforms:

The Facebook Platform that I'm using with Apps Script is the Website platform. The Website does not run embedded in Facebook.

What you can't do: (As far as I know)

  • There is a difference between a Website that interacts with Facebook, and a Facebook Page Tab. A Facebook Page Tab runs embedded in Facebook. My experience is, that the Apps Script URL causes problems with a Facebook Page Tab. The URL for Apps Script has lots of stuff appended to the end that Facebook seems to strip out. (Or something like that) I've tried many different variations of Google products with Facebook. You can use a Google Site as a Facebook Page Tab, but if you embed a Google Apps Script inside a Site, that is then inside a Facebook Page Tab, it causes a Cross Domain error. So, the only option I can get to work is the Website option.

A sort of work around that I use for the Page Tab problem, is to use Thunderpenny Static HTML as a Facebook Page Tab, that then links to either my Apps Script App, or a GAE App. (Depending upon whether I need HTTP S or not)

You could use a Google Site as the Page Tab, but Thunderpenny can design an app with HTML, Javascript and CSS as you normally would. OH! And I've tried using the Facebook Javascript SDK inside of Thunderpenny, and got nowhere with that. Besides, the Thunderpenny app doesn't have a backend, Apps Script does have a backend (.gs code) where you can hide your Facebook App Token.

The basics steps are:

  • Trigger a link to Facebook oauth from your App.
  • href="https://www.facebook.com/dialog/oauth?client_id=yourIDhereNoQuotes&redirect_uri=https://script.google.com/macros/s
  • Capture the returned Facebook token from the URL with an OnLoad function
  • You can NOT process the Facebook redirect URL back to your application with doGet(e). Here's why. Apps Script needs to see a question mark in the URL in order to parse the URL. Facebook returns a URL with a different configuration.
  • Run a script when your app loads to process the Facebook Token
  • window.onload=function(){};
  • The onload function runs a .gs function to verify the token
  • Use UrlFetchApp.fetch to debug the token
  • Cache the login status in private cache
  • var cache = CacheService.getPrivateCache();
  • Check log in status when needed.

Note that Facebook keeps track of your app login status independently. But your app could have a logged in status of still active when the Facebook token has expired. So you need a way to check that.

Use Official Facebook Graphics

Brand Resources - Facebook

Download Facebook graphics. Read Do's and Dont's

Create a Facebook Login Button

<div id="FbLog">
    <a href="https://www.facebook.com/dialog/oauth?client_id=YourClientID&redirect_uri=https://script.google.com/macros/s/YourAppsScript/exec?&response_type=token&scope=publish_stream"><img src="https://FacebookGraphic.png" height="95%" width="95%"></a>
</div>

Style the Facebook Login Button

#FbLog {
    padding: 10px;
    background-color: white;
    margin-left:auto;
    margin-right:auto;
    cursor: pointer;
}

Window OnLoad Code

Here is the window.onload client side code that I use to capture the Facebook token. This is only used to capture the Facebook token, not to validate the token. My app allows both Facebook login, and a regular login. Validation of the Facebook token is done in another code.

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');
     };
  };
};

Note that even though the Facebook login is triggered in the front end, the validation happens in .gs code. Someone could inject a false Facebook token, but it's not going to pass inspection in the server side code.

This is the .gs code to process the Facebook Login:

Validation of Facebook Token GS Code

//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;
  };
};

You need a one time App token that won't change unless you App Secret changes. You must generate that with a one time run piece of code.

Get Your App Access Token with this code:

//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);
};

Post to Facebook GS Code

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;
    };
 };

Post to Facebook Front End Javascript Code

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

这篇关于在Google Apps Script Web应用中使用Facebook API?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆