├── index.js
├── .idea
├── encodings.xml
├── misc.xml
├── vcs.xml
├── modules.xml
└── botkit-middleware-fbuser.iml
├── package.json
├── README.md
└── src
└── botkit-middleware-fbuser.js
/index.js:
--------------------------------------------------------------------------------
1 | module.exports = require('./src/botkit-middleware-fbuser');
2 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/botkit-middleware-fbuser.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "botkit-middleware-fbuser",
3 | "version": "1.0.0",
4 | "description": "Adds a Facebook user_profile object to a Botkit message",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "dependencies": {
10 | "fb": "^1.1.1",
11 | "lodash": "^4.17.4",
12 | "moment": "^2.20.1"
13 | },
14 | "keywords": [
15 | "botkit",
16 | "facebook"
17 | ],
18 | "author": "Nathan Zylbersztejn",
19 | "license": "MIT"
20 | }
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Botkit Middleware to populate Facebook Messenger user info to a Botkit message
2 | ## Installation
3 | Add github repo url to package.json
4 |
5 | Example:
6 | ```js
7 |
8 | var fbuser = require('botkit-middleware-fbuser')({
9 | accessToken:'',
10 | fields: ['first_name', 'last_name', 'locale', 'profile_pic','timezone','gender','is_payment_enabled'],
11 | logLevel:'error',
12 | expire: 24 * 60 * 60 * 1000, // refresh profile info every 24 hours
13 | storage: ''
14 | });
15 |
16 |
17 | controller.middleware.receive.use(fbuser.receive)
18 | ```
19 | A message object will have an additional field `user_profile` with the fields requested to Facebook API.
20 |
21 | ##Author
22 |
23 | **Nathan Zylbersztejn**
24 |
25 | Github: [@znat](https://github.com/znat)
26 |
--------------------------------------------------------------------------------
/src/botkit-middleware-fbuser.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | const FB = require('fb');
3 | const moment = require('moment')
4 | const logLevels = ["debug", "info", "warn", "error"];
5 |
6 | module.exports = function (options) {
7 | if (!options || !options.storage || !options.accessToken || !options.fields || !options.expire){
8 | throw new Error("You must supply an options object storage, accessToken, and fields");
9 | }
10 | function logConsole(logLevel,msg){
11 | if (logLevels.indexOf(logLevel) >= logLevels.indexOf(options.logLevel)){
12 | console.log(msg);
13 | }
14 | }
15 |
16 | FB.setAccessToken(options.accessToken);
17 |
18 | function fetchFacebookProfile(message, cb){
19 | FB.api(message.user, { fields: options.fields}, function (fb_user) {
20 | if (!fb_user) {
21 | logConsole('error', 'ERROR - No user found for facebook id:' + message.user);
22 | return cb(new Error('User not found'));
23 | }
24 |
25 | else if (fb_user.error) {
26 | logConsole('error', 'ERROR - facebook error:' + message.user);
27 | return cb(fb_user.error)
28 | }
29 | return cb(null, fb_user)
30 | });
31 | }
32 |
33 | const middleware = {};
34 | middleware.receive = function (bot, message, next) {
35 | options.storage.users.get(message.user, function(err, user_data) {
36 |
37 | function finalize(usr) {
38 | message.user_profile = usr;
39 | next();
40 | }
41 |
42 | if (!user_data){
43 | logConsole('debug', 'No user found in storage. Fetching from Facebook API...')
44 | fetchFacebookProfile(message, (err,fb_user)=>{
45 | if (err)
46 | next(err);
47 | else{
48 | fb_user.id = message.user;
49 | options.storage.users.save(fb_user, function (err) {
50 | if (err)
51 | next(err);
52 | else
53 | finalize(fb_user);
54 | });
55 | }
56 | })
57 | }else if (!user_data.timestamp || (user_data && options.expire && moment.now() - options.expire > user_data.timestamp) ){
58 | fetchFacebookProfile(message, (err,fb_user)=>{
59 | if (err)
60 | next(err);
61 | else{
62 | user_data.gender = fb_user.gender;
63 | user_data.first_name = fb_user.first_name;
64 | user_data.last_name = fb_user.last_name;
65 | user_data.profile_pic = fb_user.profile_pic;
66 | user_data.locale = fb_user.locale;
67 | user_data.timezone = fb_user.timezone;
68 | user_data.gender = fb_user.gender;
69 | user_data.timestamp = moment.now()
70 | user_data.is_payment_enabled = fb_user.is_payment_enabled;
71 | user_data.last_ad_referral = fb_user.last_ad_referral;
72 | options.storage.users.save(user_data, function (err) {
73 | logConsole('debug','Facebook profile refreshed:'+JSON.stringify(user_data))
74 | if (err)
75 | next(err);
76 | else
77 | finalize(user_data);
78 | });
79 | }
80 | })
81 | }
82 | else{
83 | logConsole('debug','Found user_profile in storage:'+JSON.stringify(user_data))
84 | finalize(user_data);
85 | }
86 | });
87 | };
88 |
89 | return middleware;
90 | };
--------------------------------------------------------------------------------