handling google and facebook bots

By: Ryan Wong at

This is how you handle the google bot and facebook bot.

Inside of where you load middleware

1
2
var useragent = require('express-useragent');
app.use(useragent.express());

Inside your main.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
'use strict';

var url = require('url');
var path = require('path')
var childProcess = require('child_process')
var phantomjs = require('phantomjs')
var binPath = phantomjs.path;
var botService = path.join(__dirname, '../botservice.js');
var config = require('../config/environment');

function fullUrl(req) {
return req.protocol + "://" + (config.ip || 'localhost') + ":" + config.port + req.originalUrl;
}

module.exports = function(app){
app.route('/*').get(function(req, res) {
if(req.useragent && req.useragent.isBot){
var childArgs = [botService, fullUrl(req), "--load-images=false"];
childProcess.execFile(binPath, childArgs, function(err, stdout, stderr) {
if(!err) {
res.send(stdout);
}
});
} else {
res.sendfile(app.get('appPath') + '/index.html');
}
});
};

botservice.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
var page = require('webpage').create(),
system = require('system'),
url, apiURL;

if (system.args.length === 1) {
console.log('No URL Found');
phantom.exit();
}

url = system.args[1];


var resourceWait = 300,
maxRenderWait = 8000,
count = 0,
forcedRenderTimeout,
renderTimeout;

page.onResourceRequested = function (req, controller) {
count += 1;
clearTimeout(renderTimeout);
};

page.onResourceReceived = function (res) {
if (!res.stage || res.stage === 'end') {
count -= 1;
if (count === 0) {
renderTimeout = setTimeout(doRender, resourceWait);
}
}
};

function doRender() {
console.log(page.content);
setTimeout(function(){
phantom.exit();
}, 0);
};

page.open(url, function (status) {
if (status !== "success") {
console.log("Unable to access network");
phantom.exit(-1);
} else {
forcedRenderTimeout = setTimeout(function () {
doRender();
}, maxRenderWait);
}
});

In angular, this is how you can reset the metadata

entry.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
angular.module('app').service('PageTitle', function() {
var title,
defaultTitle;
title = defaultTitle = 'Some title';
return {
title: function() {return title; },
setTitle: function(newTitle) { title = newTitle + " - " + defaultTitle }
};
})

.service('MetaInformation', [function() {
var metaDescription,
ogDescription,
defaultMetaDescription,
metaKeywords,
ogImage,
defaultImage,
ogTitle,
defaultTitle;

metaDescription = ogDescription = defaultMetaDescription = 'default meta data description.';
metaKeywords = ' education, information';
ogImage = defaultImage = 'http://company.com/logo.png';
ogTitle = defaultTitle = 'network of tomorrow';
return {
metaDescription: function() { return metaDescription; },
metaKeywords: function() { return metaKeywords; },
ogImage: function() {return ogImage; },
ogTitle: function() {return ogTitle; },
ogDescription: function() {return ogDescription; },
url: function() {return document.location.href},
reset: function() {
metaDescription = defaultMetaDescription;
ogImage = defaultImage;
ogTitle = defaultTitle;
ogDescription = defaultMetaDescription;
},
setMetaDescription: function(newMetaDescription) {
metaDescription = newMetaDescription;
},
setOgImage: function(newOgImage) {
ogImage = newOgImage;
},
setOgTitle: function(newOgTitle) {
ogTitle = newOgTitle + " - " + defaultTitle;
},
setOgDescription: function(newOgDescription) {
ogDescription = newOgDescription;
metaDescription = newOgDescription;
},
appendMetaKeywords: function(newKeywords) {
for (var key in newKeywords) {
if (metaKeywords === '') {
metaKeywords += newKeywords[key].name;
} else {
metaKeywords += ', ' + newKeywords[key].name;
}
}
}
};
}]);


angular.module('app').run(function ($rootScope, $location, Auth, PageTitle, MetaInformation) {
$rootScope.PageTitle = PageTitle;
$rootScope.MetaInformation = MetaInformation;
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
$rootScope.MetaInformation.reset();
});
});

inside of a controller, you do the following

1
2
 $rootScope.PageTitle.setTitle('Something');
$rootScope.MetaInformation.setOgTitle('Something');