Implementing feed of Facebook page in the website - facebook-graph-api

I have to implement the Facebook feed (our website page in Facebook) in the home page.
I tried with this plugin (https://developers.facebook.com/docs/plugins/like-box-for-pages), but I couldn't change the display style. Example, I don't want to display logo, page title and images in the feed.
Graph API + JSON + jQuery seems the way to get and customize the Facebook feed before adding website. Image is attached for how to display the feed.
I went through the API's page of Facebook. But, I need some direction to follow if anyone have already done this.
I am using the below to get the feed.
$(document).ready(function () {
$.ajax({
url: 'https://graph.facebook.com/1234/feed?access_token=cxcx&callback=?', //Replace with your own access token
dataType: 'json',
success: displayFacebookFeed,
error:alertError
});
});
It's working fine, but the message I am accessing has links, which comes as text.
var html="";
$.each(result.data, function (i, item) {
var body = item.message;
if (!body) {
body = item.description;
}
html += "<li>" + body + "</li>";
});
So for an example.
9 Sensational Traits of Highly Promotable Employees | Inc.com https://www.inc.com/jeff-haden/9-sensational-traits-of-highly-promotable-employees.html
In the above feed, I want this as link, but its coming as plain text.
Is there any suggestion?

How about the Activity Feed for your domain, using the Activity Feed plugin?
https://developers.facebook.com/docs/plugins/activity

Here is a solution I came up with for a project a while back. Definitely not plug+play since it is integrated with my javascript architecture but hopefully can get you started:
"use strict";
var Facebook = function(sb, options) {
options = options || {};
var language = options.language || "en_US";
var self = this;
var access_token = encodeURIComponent(YOUR ACCESS TOKEN);
var listenerQueue = [];
var loading = false;
var FACEBOOK;
var appId = YOUR APP ID;
if (window.FB) {
FACEBOOK = window.FB;
}
(function _load() {
if (!loading) {
loading = true;
window.fbAsyncInit = function() {
// init the FB JS SDK
FACEBOOK = window.FB;
FACEBOOK.init({
appId : appId,
status : true,
oauth : true,
cookie : true,
xfbml : true
});
sb.publish("facebook:initialized");
};
// Load the SDK asynchronously
(function(d, s, id){
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/" + language + "/all.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
}
})();
(function() {
sb.subscribe('facebook:initialized', function() {
listenForLogin();
if (listenerQueue.length) {
clearListenerQueue();
}
});
})();
function listenForLogin() {
FACEBOOK.Event.subscribe('auth.authResponseChange', function(response) {
if (response.status === 'connected') {
getLoggedInUserData();
} else {
}
});
}
function getLoggedInUserData() {
FACEBOOK.api('/me', function(response) {
sb.publish('facebook:loggedIn', response);
});
}
function clearListenerQueue() {
if (FACEBOOK) {
for (var i=0; i<listenerQueue.length; i++) {
listenerQueue[i].fn.apply(this, listenerQueue[i].args);
}
listenerQueue = [];
}
}
function sharePage(url, options) {
var opts = options || {};
if (FACEBOOK) {
FACEBOOK.ui(
{
method: 'feed',
name: opts.name || '',
caption: opts.caption || '',
description: opts.description || '',
link: url,
picture: opts.picture || ''
},
function(response) {
var success = (response && response.post_id);
sb.publish('facebook:shared', {response : response, success : success});
}
);
} else {
listenerQueue.push({fn : sharePage, args : [url, options]});
}
return self;
}
function getPosts(fbHandleOrId, options) {
options = options || {};
if (FACEBOOK) {
var limit = options.limit || '10';
var graphPOSTS = '/' + fbHandleOrId +'/posts/?date_format=U&access_token=' + access_token + "&limit=" + limit;
FACEBOOK.api(graphPOSTS, function(response) {
sb.publish('facebook:gotPosts', {response : response, handleUsed : fbHandleOrId});
});
} else {
listenerQueue.push({fn : getPosts, args : [fbHandleOrId, options]});
}
}
function getStatuses(fbHandleOrId, options) {
options = options || {};
if (FACEBOOK) {
var limit = options.limit || '10';
var graphStatuses = '/' + fbHandleOrId + "/feed/?access_token=" + access_token + "&limit=" + limit;
FACEBOOK.api(graphStatuses, function(response) {
sb.publish('facebook:gotStatuses', {response : response, handleUsed: fbHandleOrId});
});
} else {
listenerQueue.push({fn : getStatuses, args : [fbHandleOrId, options]});
}
}
function getNextPageOfPosts(nextPostsUrl, options) {
options = options || {};
if (FACEBOOK) {
FACEBOOK.api(nextPostsUrl, function(response) {
sb.publish('facebook:gotNextPosts', {response : response, handleUsed : fbHandleOrId});
});
} else {
listenerQueue.push({fn : getNextPageOfPosts, args : [nextPostsUrl, options]});
}
}
function getPublicUserInfo(fbHandleOrId, options) {
options = options || {};
var graphUSER = '/'+ fbHandleOrId +'/?fields=name,picture&callback=?';
if (FACEBOOK) {
FACEBOOK.api(graphUSER, function(response) {
var returnObj = {response : response, handleUsed : fbHandleOrId};
sb.publish('facebook:gotPublicUserInfo', returnObj);
});
} else {
listenerQueue.push({fn : getPublicUserInfo, args : [fbHandleOrId, options]});
}
}
function getLikes(pageHandle, options) {
options = options || {};
var graphLIKES = '/' + pageHandle + '/?fields=likes';
if (FACEBOOK) {
FACEBOOK.api(graphLIKES, function(response) {
var returnObj = {response : response, handleUsed: pageHandle};
sb.publish('facebook:gotLikes', returnObj);
});
} else {
listenerQueue.push({fn : getLikes, args : [pageHandle, options]});
}
}
function login() {
if (FACEBOOK) {
FACEBOOK.getLoginStatus(function(response) {
if (response.status !== "connected") {
// not logged in
FACEBOOK.login(function() {}, {scope : 'email'});
} else {
getLoggedInUserData();
}
});
} else {
listenerQueue.push({fn : login, args : []});
}
}
function getNextPageOfPosts(callback) {
callback = callback || function() {};
}
return {
getLikes : getLikes,
getPublicUserInfo : getPublicUserInfo,
getCurrentUser : getLoggedInUserData,
getNextPageOfPosts : getNextPageOfPosts,
getPosts : getPosts,
getStatuses : getStatuses,
sharePage : sharePage,
login : login
}
};

Facebook has now just added;
NOTE: With the release of Graph API v2.3, the Activity Feed plugin is deprecated and will stop working on June 23rd 2015.
The Activity feed displays the most interesting, recent activity taking place on your site, using actions (such as likes) by your friends and other people. https://developers.facebook.com/docs/plugins/activity

you can use the FB Javascript SDK
if i remember correctly this should work should users already have a facebook permission setup for your web site. or you don't mine asking them for basic authentication
FB.login(function(){
FB.api('/v2.0/page_group_address_or_id/feed', 'GET', '', function(feedContent){
// handle rendering the feed in what ever design you like
console.log(feedContent);
});
});
the only other way would be to use server side to get an oAuth access and use your own access token though php making a request to the GraphAPI server

Related

requirejs + django_select2

I'm building a wagtail / django app using requirejs as js assets combiner, for the site front end.
I'm using it because I've ever been in a kind of JS dependencies hell, where nothing works because of multiple versions of same libs loaded, from different django apps... (I don't even know if it is a good solution)
I've to tell that I'm not a JS expert, and I've none arround me :(
I'm using the good old templates to render the pages, not using angular, react, riot nor vue : I'm a pretty old school dev :)
I've already adapted some scripts to use require, but I'm stuck for now...
I've installed the django_select2 application, and I'm trying to adapt the django_select2.js asset.
I've loaded select2 through bower, and I've updaetd my config.js:
"shim": {
select2: {
deps: ["jquery"],
exports: "$.fn.select2"
}
},
paths: {
...
select2: "select2/dist/js/select2"
}
Then I'm trying to adapt the django_select2.js:
require(['jquery', 'select2'], function ($, select2) {
return (function ($) {
var init = function ($element, options) {
$element.select2(options);
};
var initHeavy = function ($element, options) {
var settings = $.extend({
ajax: {
data: function (params) {
var result = {
term: params.term,
page: params.page,
field_id: $element.data('field_id')
}
var dependentFields = $element.data('select2-dependent-fields')
if (dependentFields) {
dependentFields = dependentFields.trim().split(/\s+/)
$.each(dependentFields, function (i, dependentField) {
result[dependentField] = $('[name=' + dependentField + ']', $element.closest('form')).val()
})
}
return result
},
processResults: function (data, page) {
return {
results: data.results,
pagination: {
more: data.more
}
}
}
}
}, options);
$element.select2(settings);
};
$.fn.djangoSelect2 = function (options) {
var settings = $.extend({}, options);
$.each(this, function (i, element) {
var $element = $(element);
if ($element.hasClass('django-select2-heavy')) {
initHeavy($element, settings);
} else {
init($element, settings);
}
});
return this;
};
$(function () {
$('.django-select2').djangoSelect2();
});
}($));
});
I'm having a Mismatched anonymous define() when running my page in the browser...
I'me realy not a JS expert, I'm coding by trial and error... Could anyone help me with this ?
Thanks !
OK, I have an auto-response...
I've inherited the mixin:
class _Select2Mixin(Select2Mixin):
def _get_media(self):
"""
Construct Media as a dynamic property.
.. Note:: For more information visit
https://docs.djangoproject.com/en/1.8/topics/forms/media/#media-as-a-dynamic-property
"""
return forms.Media(js=('django_select2/django_select2.js', ),
css={'screen': (settings.SELECT2_CSS,)})
media = property(_get_media)
class _Select2MultipleWidget(_Select2Mixin, forms.SelectMultiple):
pass
Then I can use the widget:
class DocumentationSearchForm(forms.Form):
...
document_domains = forms.ModelMultipleChoiceField(required=False,
label=_('Document domains'),
queryset=NotImplemented,
widget=_Select2MultipleWidget)
I've set my config.js file for path:
requirejs.config({
paths: {
jquery: 'jquery/dist/jquery',
select2: "select2/dist/js"
},
shim: {
"select2/select2": {
deps: ["jquery"],
exports: "$.fn.select2"
}
}
});
Then I've overridden the django_select2.js file, to wrap the content in a require satement:
require(['jquery', 'select2/select2'], function ($) {
(function ($) {
var init = function ($element, options) {
$element.select2(options);
};
var initHeavy = function ($element, options) {
var settings = $.extend({
ajax: {
data: function (params) {
var result = {
term: params.term,
page: params.page,
field_id: $element.data('field_id')
}
var dependentFields = $element.data('select2-dependent-fields')
if (dependentFields) {
dependentFields = dependentFields.trim().split(/\s+/)
$.each(dependentFields, function (i, dependentField) {
result[dependentField] = $('[name=' + dependentField + ']', $element.closest('form')).val()
})
}
return result
},
processResults: function (data, page) {
return {
results: data.results,
pagination: {
more: data.more
}
}
}
}
}, options);
$element.select2(settings);
};
$.fn.djangoSelect2 = function (options) {
var settings = $.extend({}, options);
$.each(this, function (i, element) {
var $element = $(element);
if ($element.hasClass('django-select2-heavy')) {
initHeavy($element, settings);
} else {
init($element, settings);
}
});
return this;
};
$(function () {
$('.django-select2').djangoSelect2();
});
}($));
});
That's all, folks !

Using a query to search for a task_name, when function to find by id is already implemented

Okay so I'm trying to create a simple todo list, web api. I have the basic functions implemented and working properly but I'm trying to use a query to search by task_name as declared in my code, but no matter what I can't seem to get it functioning.
app.js
var express = require('express')
, routes = require('./routes')
, http = require('http')
, tasks = require('./routes/tasks')
, mongoose = require('mongoose');
// MongoDB Connection
mongoose.connect('mongodb://localhost/task_tracker');
var app = express();
app.configure(function(){
app.set('port', 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
app.configure('development', function(){
app.use(express.errorHandler());
});
app.get('/', routes.index);
app.get('/tasks', tasks.index);
app.get('/tasks/:id', tasks.show);
//app.get('/tasks/tasks?', tasks.search);
app.get('/tasks?', tasks.search);
app.post('/tasks', tasks.create);
app.put('/tasks', tasks.update);
app.del('/tasks', tasks.delete);
http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port 3000");
});
tasks.js
var Task = require('../models/task').Task;
/*
* Tasks Routes
*/
exports.index = function(req, res) {
Task.find({}, function(err, docs) {
if(!err) {
res.json(200, { tasks: docs });
} else {
res.json(500, { message: err });
}
});
}
exports.show = function(req, res) {
var id = req.params.id;
Task.findById(id, function(err, doc) {
if(!err && doc) {
res.json(200, doc);
} else if(err) {
res.json(500, { message: "Error loading task." + err});
} else {
res.json(404, { message: "Task not found."});
}
});
}
exports.create = function(req, res) {
var task_name = req.body.task_name; // Name of task.
var description = req.body.task_description; // Description of the task
//Task.findOne({ name: task_name }, function(err, doc) { // This line is case sensitive.
Task.findOne({ name: { $regex: new RegExp(task_name, "i") } }, function(err, doc) { // Using RegEx - search is case insensitive
if(!err && !doc) {
var newTask = new Task();
newTask.name = task_name;
newTask.description = description;
newTask.save(function(err) {
if(!err) {
res.json(201, {message: "Task created with name: " + newTask.name });
} else {
res.json(500, {message: "Could not create task. Error: " + err});
}
});
} else if(!err) {
// User is trying to create a task with a name that already exists.
res.json(403, {message: "Task with that name already exists, please update instead of create or create a new task with a different name."});
} else {
res.json(500, { message: err});
}
});
}
exports.update = function(req, res) {
var id = req.body.id;
var task_name = req.body.task_name;
var task_description = req.body.task_description;
Task.findById(id, function(err, doc) {
if(!err && doc) {
doc.name = task_name;
doc.description = task_description;
doc.save(function(err) {
if(!err) {
res.json(200, {message: "Task updated: " + task_name});
} else {
res.json(500, {message: "Could not update task. " + err});
}
});
} else if(!err) {
res.json(404, { message: "Could not find task."});
} else {
res.json(500, { message: "Could not update task." + err});
}
});
}
exports.delete = function(req, res) {
var id = req.body.id;
Task.findById(id, function(err, doc) {
if(!err && doc) {
doc.remove();
res.json(200, { message: "Task removed."});
} else if(!err) {
res.json(404, { message: "Could not find task."});
} else {
res.json(403, {message: "Could not delete task. " + err });
}
});
}
exports.search = function(req, res) {
var name = req.query.name;
Task.findByName(name, function(err, doc) {
if(!err && doc) {
res.json(200, doc);
} else if(err) {
res.json(500, { message: "Error loading task." + err});
} else {
res.json(404, { message: "Task not found."});
}
});
}
task.js model
var mongoose = require('mongoose')
, Schema = mongoose.Schema;
var taskSchema = new Schema({
name : { type: String, required: true, trim: true, index: { unique: true } }
, description : { type: String, required: true }
, date_created : { type: Date, required: true, default: Date.now }
});
var task = mongoose.model('task', taskSchema);
module.exports = {
Task: task
};
Basically i am just trying to use a similar function to that of my search by id function but i know i can't just use parameters and I can't figure out how to get the query working. Any help would be appreciated. If you can't tell I'm using Node.js, Express and Mongodb.
TL;DR: You need to merge tasks.index and tasks.search route, ie. like this:
tasks.index = function(req, res, next) {
if (req.query.name !== undefined) {
// pass on to next handler
return next();
}
// the rest of your tasks.index.
});
And adjust the Router setup like this:
app.get('/tasks', tasks.index);
app.get('/tasks', tasks.search);
Why? Query string is not part of the route. So '/tasks?' is just a regex for /tasks+1 character, but not for a query string - query string is not a part of the route match.
More specifically, you have in your routes this:
app.get('/', routes.index);
app.get('/tasks', tasks.index);
app.get('/tasks?', tasks.search);
That last, /tasks? route will not get registered like you seem to expect. The question mark isn't representing query string processing, it's a part of the route regex, and basically means that you'd catch anything that adds one character to /tasks route, ie /tasksa, /tasksb, /tasks7 etc.
So, 7 characters, first six of which are known, the last is different, query string not included.
You cannot parse query strings in the router, it's in the individual controllers, kind of like this:
tasks.search = function(req, res) {
if (req.query.name) {
// you have the name query
}
// etc.
}
Additional advice is, what is usually done on a REST API is have the global tasks.index, like you have there, and add two things on it: paging and filter/searching.
If you want just one result
Paging is page=3&limit=10 (3rd page, 10 items per page), and filtering/sorting/searching is what you want. And depending how you want it, that's how you expose it.
Ie. you might want to sort by name:
if (req.query.sort === 'name:desc') {
mongoCursor.sort = {name: -1};
}
Or something of a sort.
So you'd probably have a search, or maybe directly a name query parameter, like this:
GET /tasks?name=<search term>
And the name param is usually optional.
So your req would list all things, and if name query string is set, it would filter by name first.
Your query building process can then look like this:
tasks.index = function(req, res) {
var query = {};
if (req.query.name) {
query.name = req.query.name;
}
Tasks.find(query, ...);
In that case, you don't need helpers on the Task model.
I found this method also works.
/**
* Module dependencies.
*/
var express = require('express'),
cors = require('cors'),
routes = require('./routes'),
http = require('http'),
tasks = require('./routes/tasks'),
mongoose = require('mongoose'),
search = require('./routes/search');
var Task = require('./models/task').Task;
// MongoDB Connection
mongoose.connect('mongodb://localhost/task_tracker');
var app = express();
app.configure(function() {
app.set('port', 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.urlencoded());
app.use(express.json());
app.use(cors());
});
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
var corsOptions = {
origin: 'http://localhost:3000'
};
app.get('/', routes.index);
app.get('/tasks', tasks.index);
//app.get('/search', tasks.FindByQuery);
//app.get('/tasks/:task.:name?', task.FindByQuery);
app.get('/search', function(req, res, next) {
var query = req.query
//res.send(query['name']);
Task.findOne({name: query['name']}, function(err, doc) {
if(!err && doc) {
res.json(200, doc);
} else if(err) {
res.json(500, { message: "Error loading task." + err});
} else {
res.json(404, { message: "Task not found."});
}
});
//res.end(JSON.stringify(query));
});
app.get('/tasks/:id', tasks.show);
app.post('/tasks', tasks.create);
app.put('/tasks', tasks.update);
app.del('/tasks', tasks.delete);
http.createServer(app).listen(app.get('port'), function() {
console.log("Express server listening on port 3000");
});

How to define Handlebar.js templates in an external file

I am currently defining my Handlebars templates within the same HTML file in which they will be used.
Is it possible to define them as external templates, which can be called when the page is loaded?
For those that get here through Google search like I did, I finally found the perfect answer in this post, check it out :
http://berzniz.com/post/24743062344/handling-handlebarsjs-like-a-pro
Basically you need to implement a method, getTemplate :
Handlebars.getTemplate = function(name) {
if (Handlebars.templates === undefined || Handlebars.templates[name] === undefined) {
$.ajax({
url : 'templatesfolder/' + name + '.handlebars',
success : function(data) {
if (Handlebars.templates === undefined) {
Handlebars.templates = {};
}
Handlebars.templates[name] = Handlebars.compile(data);
},
async : false
});
}
return Handlebars.templates[name];
};
and then call your template with it :
var compiledTemplate = Handlebars.getTemplate('hello');
var html = compiledTemplate({ name : 'World' });
That way, if you precompiled the templates (great for production use) it will find it directly, otherwise it will fetch the template and compile it in the browser (that's how you work in development).
You can use AJX to load them.
Here's an example function which accepts a URL to a Handlebars template, and a callback function. The function loads the template, and calls the callback function with the compiled Handlebars template as a parameter:
function loadHandlebarsTemplate(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var raw = xhr.responseText;
var compiled = Handlebars.compile(raw);
callback(compiled);
}
};
xhr.send();
}
For example, assume you have a Handlebars template defined in a file named /templates/MyTemplate.html, such as:
<p>The current date is {{date}}</p>
You can then load that file, compile it and render it to the UI, like this:
var url = '/templates/MyTemplate.html';
loadHandlebarsTemplate(url, function(template) {
$('#container').html(template({date: new Date()}));
});
An even better solution, would be to pre-compile the templates which would speed up the time they take to load. More info on precompilation can be found here.
Edited solution from Jeremy Belolo for working more templates in directories, if i do not want to have all templates in templates directory.
Handlebars.getTemplate = function(name, dir) {
if (dir === undefined) //dir is optional
dir = "";
if (Handlebars.templates === undefined || Handlebars.templates[name] === undefined) {
$.ajax({
url : 'templates/' + dir+'/' + name, //Path, dir is optional
success : function(data) {
if (Handlebars.templates === undefined) {
Handlebars.templates = {};
}
if (Handlebars.templates[dir] === undefined) {
Handlebars.templates[dir] = {};
}
if (dir === undefined)
Handlebars.templates[name] = Handlebars.compile(data);
else
Handlebars.templates[dir][name] = Handlebars.compile(data);
},
async : false
});
}
if (dir === undefined)
return Handlebars.templates[name];
else
return Handlebars.templates[dir][name];
};
Using async: false; is far away from being the perfect solution. With jQuery in your toolbox, just make use of $.Deferred.
I came up with this solution:
;(function ($, Handlebars) {
'use strict';
var namespace = window,
pluginName = 'TemplateEngine';
var TemplateEngine = function TemplateEngine(options) {
if(!(this instanceof TemplateEngine)) {
return new TemplateEngine(options);
}
this.settings = $.extend({}, TemplateEngine.Defaults, options);
this._storage = {};
return this;
};
TemplateEngine.Defaults = {
templateDir: './tpl/',
templateExt: '.tpl'
};
TemplateEngine.prototype = {
constructor: TemplateEngine,
load: function(name, $deferred) {
var self = this;
$deferred = $deferred || $.Deferred();
if(self.isCached(name)) {
$deferred.resolve(self._storage[name]);
} else {
$.ajax(self.urlFor(name)).done(function(raw) {
self.store(name, raw);
self.load(name, $deferred);
});
}
return $deferred.promise();
},
fetch: function(name) {
var self = this;
$.ajax(self.urlFor(name)).done(function(raw) {
self.store(name, raw);
});
},
isCached: function(name) {
return !!this._storage[name];
},
store: function(name, raw) {
this._storage[name] = Handlebars.compile(raw);
},
urlFor: function(name) {
return (this.settings.templateDir + name + this.settings.templateExt);
}
};
window[pluginName] = TemplateEngine;
})(jQuery, Handlebars);

Select 30 random friends and send app requests

**HI i am trying to send app request to 30 random friends of the user. So i want to get user ids of 30 facebook friends parse it and feed the uids into
function sendRequestToRecipients() {
var user_ids = document.getElementsByName("user_ids")[0].value;
FB.ui({method: 'apprequests',
message: 'sample message',
to: 'id of friend1,id of friend2,id of friend 3,,,,,,,'
}, requestCallback);
}**
Below is the full sample code...
<script>
FB.init({
appId : 'appid',
frictionlessRequests: true,
});
we have to put ids of friend here.....
function sendRequestToRecipients() {
var user_ids = document.getElementsByName("user_ids")[0].value;
FB.ui({method: 'apprequests',
message: 'sample message',
to: 'id of friend,id of friend'
}, requestCallback);
}
function sendRequestViaMultiFriendSelector() {
FB.ui({method: 'apprequests',
message: 'sample message'
}, requestCallback);
}
function requestCallback(response) {
// Handle callback here
}
</script>
FB.api({ method: 'friends.get' }, function(result) {
var user_ids="" ;
var totalFriends = result.length;
var randNo = Math.floor(Math.random() * totalFriends);
var numFriends = result ? Math.min(30,totalFriends) : 0;
if (numFriends > 0) {
for (var i=0; i<numFriends; i++) {
user_ids+= (',' + result[randNo]);
randNo ++;
if(randNo >= totalFriends){
randNo = 0;
}
}
}
profilePicsDiv.innerHTML = user_ids;
alert(user_ids);
});
Refer my answer at Facebook App invitation request

Installing one application by another

I am trying to check with my application if one application is installed on specific fan page and if it is not installed I want to install it..
for some reason i am unable to get the page access tokens.
I am able to get the user access tokens and user id, but the page access token returns "Exception" "Unknown fields: access_token".
What is wrong here?
I am using this resources:
http://developers.facebook.com/docs/reference/api/page/#tabs
https://developers.facebook.com/docs/authentication/
<html>
<head>
</head>
<body>
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : '188474844587139',
status : true,
cookie : true,
xfbml : true,
oauth : true,
});
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
var uid = response.authResponse.userID;
var userAccessToken = response.authResponse.accessToken;
console.log("User Access Token: "+userAccessToken);
console.log("User ID: "+uid);
// get page access token
FB.api('https://graph.facebook.com/'+uid+'/accounts?access_token='+userAccessToken, function(response) {
console.log(response);
var pageAccessToken = 'Need to get from the response...';
// get information if user got this app
FB.api("https://graph.facebook.com/102561956524622/tabs/353470634682630?access_token="+pageAccessToken,
function(data) {
console.log(data);
});
// install the app
var params = {};
params['app_id'] = '353470634682630';
FB.api('https://graph.facebook.com/102561956524622/tabs'+pageAccessToken, 'post', params, function(response) {
if (!response || response.error) {
console.log("Error: "+response);
} else {
console.log("Ok: "+response);
}
});
});
} else if (response.status === 'not_authorized') {
console.log("the user is logged in to Facebook, but not connected to the app.");
} else {
console.log("the user isn't even logged in to Facebook.");
}
});
};
(function(d){
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
</script>
</body>
</html>
I managed to solve this issue if any one care this is the code
One of reasons it didn't work was because I used the full address "http://graph.facebook.com..." and as you can see in the code I am using the
FB.api function which is adding this address automatically.
Another reason is that I used the user access token to get information about the application instead of the page access token.
I was also having problem to install the application because I needed to send the page access token as well.
P.S: Don't forget that you need manage_pages permission.
<script>
window.fbAsyncInit = function() {
FB.init({
appId : '188474844587139',
status : true,
cookie : true,
xfbml : true,
oauth : true,
});
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
var uid = response.authResponse.userID;
console.log(response.authResponse);
var userAccessToken = response.authResponse.accessToken;
var pageId = '102561956524622';
var appId = '353470634682630';
console.log("User Access Token: "+userAccessToken);
console.log("User ID: "+uid);
// get page access token
FB.api('/'+pageId+'?fields=access_token='+userAccessToken, function(response) {
var pageAccessToken = response.access_token;
// get information if user got this app
FB.api('/'+pageId+'/tabs/'+appId+'?access_token='+pageAccessToken,
function(data) {
if (data.data.length < 1) {
console.log("Not installed, Installing...");
// install the app
var params = {};
params['app_id'] = appId;
FB.api('/'+pageId+'/tabs?access_token='+pageAccessToken, 'post', params, function(response) {
if (!response || response.error) {
console.log("Error Installing:");
console.log(response);
} else {
console.log("Installed :)");
console.log(response);
}
});
}
else {
console.log("Already installed.");
}
});
});
} else if (response.status === 'not_authorized') {
console.log("the user is logged in to Facebook, but not connected to the app.");
} else {
console.log("the user isn't even logged in to Facebook.");
}
});
};
(function(d){
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));