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