Использовать API Facebook в веб-приложении Google Apps Script?
Я пытаюсь создать приложение Facebook, используя скрипт Google Apps в качестве веб-приложения, в качестве бэк-энда. Единственным API Facebook, который кажется применимым, является JavaScript SDK, но я даже не могу заставить его работать.
Текущая проблема заключается в том, что Facebook JS SDK использует идентификаторы Javascript, которые заканчиваются на: "__". Скрипт Google Apps запрещает имена, которые заканчиваются двойным подчеркиванием.
Если я использую измененную копию JS-файла Facebook без двойные подчеркивания в именах, я получаю эту ошибку:Refused to display [URL] in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'
любая идея, как получить газ, играющий хорошо с FB?
1 ответов
я понял, как использовать сценарий приложений UrlFetchApp.fetch
и Служба HTML для входа пользователя в приложение My Apps Script с Facebook. Я также могу опубликовать в Facebook с помощью скрипта приложений.
- вам не нужен Facebook Javascript SDK
Общие Сведения
есть 8 различных платформ Facebook:
платформа Facebook, которую я использую с помощью скрипта приложений, является платформой веб-сайта. Этот Веб-сайт не запускается встроенным в Facebook.
что вы не можете сделать: (насколько я знаю)
- существует разница между веб-сайтом, который взаимодействует с Facebook, и вкладкой страницы Facebook. В Facebook
Page Tab
работает встроенный в Facebook. Мой опыт заключается в том, что URL-адрес скрипта приложений вызывает проблемы с FacebookPage Tab
. URL-адрес для скрипта приложений имеет много вещей, добавленных в конец, который Facebook, похоже, удаляет. (Или что-то подобное) Я пробовал много различных вариантов продуктов Google с Facebook. Вы можете использовать сайт Google в качестве вкладки страницы Facebook, но если вы вставляете скрипт Google Apps внутри сайта, то есть внутри вкладки страницы Facebook, это приводит к Междоменной ошибке. Итак, единственный вариант, который я могу получить на работу, - это вариант веб-сайта.
своего рода работа, которую я использую для Проблемы вкладки страницы, заключается в использовании статического HTML Thunderpenny в качестве вкладки страницы Facebook, которая затем ссылается на скрипт моих приложений App, или приложение GAE. (В зависимости от того, нужен ли мне HTTP S или нет)
вы можете использовать сайт Google в качестве вкладки страницы, но Thunderpenny может создать приложение с HTML, Javascript и CSS, как обычно. О! И я попытался использовать Facebook Javascript SDK внутри Thunderpenny, и ничего не получил с этим. Кроме того, приложение Thunderpenny не имеет бэкэнда, сценарий приложений имеет бэкэнд (.GS code), где вы можете скрыть свое приложение Facebook Знак.
основные шаги:
- вызвать ссылку на Facebook oauth из вашего приложения.
- href="https://www.facebook.com/dialog/oauth?client_id=yourIDhereNoQuotes&redirect_uri=https://script.google.com/macros/s
- захват возвращенного токена Facebook из URL-адреса с помощью функции OnLoad
- вы не можете обработать URL перенаправления Facebook обратно в приложение с
doGet(e)
. Вот почему. Apps Script должен видеть вопросительный знак в URL-адресе для анализа URL-адреса. Facebook возвращает URL-адрес с другой конфигурацией. - запуск сценария при загрузке приложения для обработки токена Facebook .onload=function () {};
- на работает
.gs
функция для проверки маркера - использовать
UrlFetchApp.fetch
todebug
маркер - кэшировать статус входа в личный кэш
- кэш var = CacheService.getPrivateCache ();
- при необходимости проверьте статус входа в систему.
обратите внимание, что Facebook отслеживает состояние входа в приложение самостоятельно. Но ваше приложение может иметь статус входа в систему по-прежнему активен, когда токен Facebook истек. Так что тебе нужно это проверить.
Использовать Официальную Графику Facebook
скачать Facebook графики. Читать и Донта
создать кнопку входа в 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?&response_type=token&scope=publish_stream"><img src="https://FacebookGraphic.png" height="95%" width="95%"></a>
</div>
стиль кнопки входа в Facebook
#FbLog {
padding: 10px;
background-color: white;
margin-left:auto;
margin-right:auto;
cursor: pointer;
}
Окно OnLoad Код
вот такое окно.загрузите код на стороне клиента, который я использую для захвата токена Facebook. Это используется только для захвата маркера 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, но он не пройдет проверку в коде на стороне сервера.
это .gs
код для обработки входа в Facebook:
проверка кода GS токена Facebook
//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;
};
};
вам понадобится one time
маркер приложения, который не изменится, если вы не измените секрет приложения. Вы должны создать это с помощью one время выполнения фрагмента кода.
получите маркер доступа к приложению с помощью этого кода:
//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);
};
сообщение в Facebook GS код
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;
};
};
сообщение в 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_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>