├── .gitignore ├── example ├── .meteor │ ├── .gitignore │ ├── release │ ├── .finished-upgraders │ ├── packages │ ├── .id │ └── versions ├── packages │ └── percolate:intercom ├── example.css ├── example.html └── example.js ├── .npm └── package │ ├── .gitignore │ ├── README │ └── npm-shrinkwrap.json ├── check_hash └── check_hash.js ├── package.js ├── .versions ├── intercom_server.js ├── intercom_loader.js ├── intercom_client.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /example/.meteor/.gitignore: -------------------------------------------------------------------------------- 1 | local 2 | -------------------------------------------------------------------------------- /.npm/package/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /example/.meteor/release: -------------------------------------------------------------------------------- 1 | METEOR@0.9.3.1 2 | -------------------------------------------------------------------------------- /example/packages/percolate:intercom: -------------------------------------------------------------------------------- 1 | ../.. -------------------------------------------------------------------------------- /example/example.css: -------------------------------------------------------------------------------- 1 | /* CSS declarations go here */ 2 | -------------------------------------------------------------------------------- /example/.meteor/.finished-upgraders: -------------------------------------------------------------------------------- 1 | # This file contains information which helps Meteor properly upgrade your 2 | # app when you run 'meteor update'. You should check it into version control 3 | # with your project. 4 | 5 | notices-for-0.9.0 6 | notices-for-0.9.1 7 | -------------------------------------------------------------------------------- /example/.meteor/packages: -------------------------------------------------------------------------------- 1 | # Meteor packages used by this project, one per line. 2 | # 3 | # 'meteor add' and 'meteor remove' will edit this file for you, 4 | # but you can also edit it by hand. 5 | 6 | meteor-platform 7 | autopublish 8 | insecure 9 | percolate:intercom 10 | -------------------------------------------------------------------------------- /example/example.html: -------------------------------------------------------------------------------- 1 | 2 | example 3 | 4 | 5 | 6 |

Welcome to Meteor!

7 | 8 | {{> hello}} 9 | 10 | 11 | 15 | -------------------------------------------------------------------------------- /example/.meteor/.id: -------------------------------------------------------------------------------- 1 | # This file contains a token that is unique to your project. 2 | # Check it into your repository along with the rest of this directory. 3 | # It can be used for purposes such as: 4 | # - ensuring you don't accidentally deploy one app on top of another 5 | # - providing package authors with aggregated statistics 6 | 7 | 7eeob6115931q28tpbj 8 | -------------------------------------------------------------------------------- /.npm/package/README: -------------------------------------------------------------------------------- 1 | This directory and the files immediately inside it are automatically generated 2 | when you change this package's NPM dependencies. Commit the files in this 3 | directory (npm-shrinkwrap.json, .gitignore, and this README) to source control 4 | so that others run the same versions of sub-dependencies. 5 | 6 | You should NOT check in the node_modules directory that Meteor automatically 7 | creates; if you are using git, the .gitignore file tells git to ignore it. 8 | -------------------------------------------------------------------------------- /check_hash/check_hash.js: -------------------------------------------------------------------------------- 1 | var crypto = require('crypto'); 2 | 3 | var userId = process.argv.pop(); 4 | var secretKey = process.argv.pop(); 5 | 6 | if (! secretKey || ! userId) { 7 | return console.log("USAGE: node check_hash.js SECRET USER_ID"); 8 | } 9 | 10 | console.log(secretKey, userId) 11 | 12 | var hash = crypto.createHmac('sha256', secretKey) 13 | .update(userId.toString()).digest('hex'); 14 | 15 | 16 | console.log('The intercom hash for userId ' + userId + ' is ' + hash); -------------------------------------------------------------------------------- /example/example.js: -------------------------------------------------------------------------------- 1 | if (Meteor.isClient) { 2 | // counter starts at 0 3 | Session.setDefault("counter", 0); 4 | 5 | Template.hello.helpers({ 6 | counter: function () { 7 | return Session.get("counter"); 8 | } 9 | }); 10 | 11 | Template.hello.events({ 12 | 'click button': function () { 13 | // increment the counter when button is clicked 14 | Session.set("counter", Session.get("counter") + 1); 15 | } 16 | }); 17 | } 18 | 19 | if (Meteor.isServer) { 20 | Meteor.startup(function () { 21 | // code to run on server at startup 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'verso:intercom', 3 | summary: "Intercom.io basic integration (uses 'widget' snippet)", 4 | version: '1.5.0', 5 | git: 'https://github.com/versolearning/meteor-intercom.git' 6 | }); 7 | 8 | Npm.depends({ 'intercom-client': '2.8.3' }); 9 | 10 | Package.onUse(function(api) { 11 | if (api.versionsFrom) 12 | api.versionsFrom('1.3'); 13 | 14 | api.use(['underscore', 'accounts-base', 'ecmascript']); 15 | api.use(['session', 'tracker'], 'client'); 16 | 17 | api.add_files('intercom_server.js', 'server'); 18 | api.add_files(['intercom_loader.js', 'intercom_client.js'], 'client'); 19 | 20 | api.export('IntercomSettings'); 21 | api.export('IntercomHash', 'server'); 22 | api.export('IntercomClient', 'server'); 23 | }); 24 | -------------------------------------------------------------------------------- /.versions: -------------------------------------------------------------------------------- 1 | accounts-base@1.2.4 2 | allow-deny@1.0.2 3 | babel-compiler@6.5.2 4 | babel-runtime@0.1.6 5 | base64@1.0.6 6 | binary-heap@1.0.6 7 | blaze@2.1.5 8 | blaze-tools@1.0.6 9 | boilerplate-generator@1.0.6 10 | callback-hook@1.0.6 11 | check@1.1.2 12 | ddp@1.2.3 13 | ddp-client@1.2.3 14 | ddp-common@1.2.3 15 | ddp-rate-limiter@1.0.2 16 | ddp-server@1.2.4 17 | deps@1.0.10 18 | diff-sequence@1.0.3 19 | ecmascript@0.4.1 20 | ecmascript-runtime@0.2.8 21 | ejson@1.0.9 22 | geojson-utils@1.0.6 23 | html-tools@1.0.7 24 | htmljs@1.0.7 25 | id-map@1.0.5 26 | jquery@1.11.6 27 | localstorage@1.0.7 28 | logging@1.0.10 29 | meteor@1.1.12 30 | minimongo@1.0.12 31 | modules@0.5.1 32 | modules-runtime@0.6.1 33 | mongo@1.1.5 34 | mongo-id@1.0.2 35 | npm-mongo@1.4.41 36 | observe-sequence@1.0.9 37 | ordered-dict@1.0.5 38 | promise@0.6.5 39 | random@1.0.7 40 | rate-limit@1.0.2 41 | reactive-dict@1.1.5 42 | reactive-var@1.0.7 43 | retry@1.0.5 44 | routepolicy@1.0.8 45 | service-configuration@1.0.7 46 | session@1.1.3 47 | spacebars@1.0.9 48 | spacebars-compiler@1.0.9 49 | tracker@1.0.11 50 | ui@1.0.9 51 | underscore@1.0.6 52 | verso:intercom@1.5.0 53 | webapp@1.2.6 54 | webapp-hashing@1.0.7 55 | -------------------------------------------------------------------------------- /example/.meteor/versions: -------------------------------------------------------------------------------- 1 | accounts-base@1.1.1 2 | application-configuration@1.0.2 3 | autopublish@1.0.0 4 | autoupdate@1.1.1 5 | base64@1.0.0 6 | binary-heap@1.0.0 7 | blaze-tools@1.0.0 8 | blaze@2.0.1 9 | boilerplate-generator@1.0.0 10 | callback-hook@1.0.0 11 | check@1.0.1 12 | ctl-helper@1.0.3 13 | ctl@1.0.1 14 | ddp@1.0.9 15 | deps@1.0.4 16 | ejson@1.0.3 17 | fastclick@1.0.0 18 | follower-livedata@1.0.1 19 | geojson-utils@1.0.0 20 | html-tools@1.0.1 21 | htmljs@1.0.1 22 | http@1.0.6 23 | id-map@1.0.0 24 | insecure@1.0.0 25 | jquery@1.0.0 26 | json@1.0.0 27 | livedata@1.0.10 28 | localstorage@1.0.0 29 | logging@1.0.3 30 | meteor-platform@1.1.1 31 | meteor@1.1.1 32 | minifiers@1.1.0 33 | minimongo@1.0.3 34 | mobile-status-bar@1.0.0 35 | mongo@1.0.6 36 | observe-sequence@1.0.2 37 | ordered-dict@1.0.0 38 | percolate:intercom@1.1.1 39 | random@1.0.0 40 | reactive-dict@1.0.3 41 | reactive-var@1.0.2 42 | reload@1.1.0 43 | retry@1.0.0 44 | routepolicy@1.0.1 45 | service-configuration@1.0.1 46 | session@1.0.2 47 | spacebars-compiler@1.0.2 48 | spacebars@1.0.2 49 | templating@1.0.7 50 | tracker@1.0.2 51 | ui@1.0.3 52 | underscore@1.0.0 53 | url@1.0.0 54 | webapp-hashing@1.0.0 55 | webapp@1.1.2 56 | -------------------------------------------------------------------------------- /intercom_server.js: -------------------------------------------------------------------------------- 1 | // Generate an intercomHash for secure mode as outlined at 2 | // https://segment.io/docs/integrations/intercom/#secure-mode 3 | var crypto = Npm.require('crypto'); 4 | var Intercom = Npm.require('intercom-client'); 5 | 6 | IntercomClient = function IntercomClient() { 7 | //support for Personal Access token: 8 | const pat = Meteor._get(Meteor, 'settings', 'intercom', 'personalAccessToken'); 9 | 10 | //api 11 | const id = Meteor._get(Meteor, 'settings', 'public', 'intercom', 'id'); 12 | const apikey = Meteor._get(Meteor, 'settings', 'intercom', 'apikey'); 13 | 14 | //priority 15 | if (pat) { 16 | return new Intercom.Client({ token: pat }); 17 | } 18 | 19 | if (id && apikey) { 20 | return new Intercom.Client(id, apikey); 21 | } 22 | 23 | return console.warn(` 24 | You must set Meteor.settings.intercom.personalAccessToken 25 | or add Meteor.settings.public.intercom.id 26 | and Meteor.settings.intercom.apikey to use IntercomClient 27 | `); 28 | }; 29 | 30 | // returns undefined if there is no secret 31 | IntercomHash = function(userId) { 32 | var secret = Meteor.settings && 33 | Meteor.settings.intercom && Meteor.settings.intercom.secret; 34 | 35 | if (secret) { 36 | return crypto.createHmac('sha256', new Buffer(secret, 'utf8')) 37 | .update(userId).digest('hex'); 38 | } 39 | }; 40 | 41 | Meteor.publish('currentUserIntercomHash', function() { 42 | if (this.userId) { 43 | var intercomHash = IntercomHash(this.userId); 44 | 45 | if (intercomHash) 46 | this.added("users", this.userId, {intercomHash: intercomHash}); 47 | } 48 | this.ready(); 49 | }); 50 | -------------------------------------------------------------------------------- /intercom_loader.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function() { 2 | // If the app id is set, we should use the new url for the widget otherwise 3 | // fall back to the old url but apparantly in-app messaging will no longer 4 | // work 5 | var widgetUrl; 6 | var minimumUserInfo = IntercomSettings.minimumUserInfo(); 7 | var appId = minimumUserInfo && minimumUserInfo.app_id; 8 | 9 | if (appId) 10 | widgetUrl = 'https://widget.intercom.io/widget/' + appId; 11 | else 12 | widgetUrl = 'https://static.intercomcdn.com/intercom.v1.js'; 13 | 14 | // ------ The snippet below is almost identical to the official one however 15 | // ------ we substitute in widgetUrl instead of a statically defined one. 16 | // ------ In addition, it has been found that the window.onload event is unreliable 17 | // ------ in some browsers (specifically on mobile), where it may never fire. 18 | // ------ We have replaced waiting on window.onload with simply executing the script loader. 19 | // ------ As we are inside of Meteor.startup, this should be ok. 20 | 21 | (function(){ 22 | var w=window; 23 | var ic=w.Intercom; 24 | if (typeof ic==="function") { 25 | ic('reattach_activator'); 26 | ic('update',intercomSettings); 27 | } else { 28 | var d=document; 29 | var i=function(){ 30 | i.c(arguments)}; 31 | i.q=[]; 32 | i.c=function(args) { 33 | i.q.push(args) 34 | }; 35 | w.Intercom=i; 36 | function l() { 37 | var s=d.createElement('script'); 38 | s.type='text/javascript'; 39 | s.async=true; 40 | s.src=widgetUrl; 41 | var x=d.getElementsByTagName('script')[0]; 42 | x.parentNode.insertBefore(s,x); 43 | } 44 | l(); 45 | } 46 | })(); 47 | // ------ 48 | }); 49 | -------------------------------------------------------------------------------- /intercom_client.js: -------------------------------------------------------------------------------- 1 | // We *must* have the intercom id set otherwise the intercom loader script throws 2 | // exceptions. Warn people about this. 3 | Meteor.startup(function() { 4 | if (! Meteor._get(Meteor, 'settings', 'public', 'intercom', 'id')) { 5 | console.warn("You must set Meteor.settings.public.intercom.id to use percolate:intercom"); 6 | } 7 | }); 8 | 9 | Meteor.subscribe('currentUserIntercomHash'); 10 | 11 | var minimumUserInfo = function(user) { 12 | var info = { 13 | app_id: Meteor._get(Meteor, 'settings', 'public', 'intercom', 'id') 14 | }; 15 | 16 | if (user) 17 | _.extend(info, { 18 | user_id: user._id, 19 | created_at: Math.round(user.createdAt/1000), 20 | user_hash: user.intercomHash 21 | }); 22 | 23 | return info; 24 | }; 25 | 26 | IntercomSettings = { 27 | // if you want to manually call it 28 | minimumUserInfo: minimumUserInfo 29 | }; 30 | 31 | var booted = false; 32 | 33 | // send data to intercom 34 | Meteor.startup(function() { 35 | Tracker.autorun(function() { 36 | var user = Meteor.user(); 37 | 38 | var info = IntercomSettings.minimumUserInfo(user); 39 | var ready; 40 | 41 | if (!user) { 42 | if (Meteor._get(Meteor, 'settings', 'public', 'intercom', 'allowAnonymous') === true) { 43 | if (IntercomSettings.anonymousInfo) { 44 | ready = IntercomSettings.anonymousInfo(info); 45 | if (ready === false) 46 | return; 47 | } 48 | } else { 49 | // console.log('shutdown') 50 | booted = false; 51 | return Intercom('shutdown'); 52 | } 53 | } else { 54 | if (IntercomSettings.userInfo) { 55 | ready = IntercomSettings.userInfo(user, info); 56 | if (ready === false) 57 | return; 58 | } 59 | } 60 | 61 | if (info) { 62 | var type = booted ? 'update' : 'boot'; 63 | 64 | // console.log(type, info) 65 | Intercom(type, info); 66 | booted = true; 67 | } 68 | }); 69 | }); 70 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Meteor Intercom 2 | 3 | A package to use [Intercom.io](http://intercom.io) easily with Meteor. 4 | 5 | NOTE: Package updates are released under `verso:intercom` as it replaces `percolate:intercom`. 6 | 7 | ## Installation 8 | 9 | Intercom can be installed with Meteor's package manager: 10 | 11 | ``` sh 12 | $ meteor add verso:intercom 13 | ``` 14 | 15 | ## API 16 | 17 | Ensure you have `Meteor.settings.intercom.secret` and `Meteor.settings.public.intercom.id` defined to the values provided to you by Intercom. *API Keys are being deprecated*. You can define the `Meteor.settings.intercom.personalAccessToken` if you intend to use Intercom on the server side, otherwise you can still define `Meteor.settings.intercom.apikey`. 18 | 19 | Some Intercom subscription packages allow for anonymous users. To enable the use of anonymous users, set `Meteor.settings.public.intercom.allowAnonymous` to `true`. 20 | 21 | By default, the package will send up the user's id, creation date, and hash (if defined, see below). To send custom data, set: 22 | 23 | ```js 24 | IntercomSettings.userInfo = function(user, info) { 25 | // add properties to the info object, for instance: 26 | if (user.services.google) { 27 | info.email = user.services.google.email; 28 | info['name'] = user.services.google.given_name + ' ' + user.services.google.family_name; 29 | } 30 | } 31 | ``` 32 | 33 | `email` and `name` are preset fields provided by Intercom. You may add any additional custom user attribute. 34 | 35 | If you need to wait on a user subscription for e.g. the hash to come down, you can return `false` in your `userInfo` function to tell the package to wait. 36 | 37 | ```js 38 | IntercomSettings.userInfo = function (user, info) { 39 | if (!user.intercomHash) { 40 | return false; // the hash isn't loaded to the users collection yet. come back later. 41 | } 42 | // ... 43 | } 44 | ``` 45 | 46 | If you want to add fields sent to intercom for an anonymous user, you can add them through in the `anonymousInfo` function. 47 | 48 | ```js 49 | IntercomSettings.anonymousInfo = function ( info ) { 50 | // check all router subscriptions have loaded 51 | if (!Router.current() || !Router.current().ready()) 52 | return false; 53 | 54 | info.anonymous = true; 55 | return; 56 | }; 57 | ``` 58 | 59 | On the server, you can also interact with the Intercom API via the official [intercom-node client](https://github.com/intercom/intercom-node). 60 | ```js 61 | const client = IntercomClient(); 62 | 63 | // Create an event for a user 64 | client.events.create({ 65 | event_name: 'Test event', 66 | created_at: Math.floor(new Date().getTime() / 1000), 67 | user_id: '' 68 | }, function (d) { 69 | console.log(d); 70 | }); 71 | ``` 72 | 73 | ## Notes 74 | 75 | This package will automatically subscribe the current user to the `currentUserIntercomHash` publication which will add an `intercomHash` property to your user documents enabling the use of intercom's secure mode. 76 | 77 | ## Other References 78 | 79 | Integrating intercom.io into a meteor app. 80 | https://meteoruniversity.org/integrating-intercom-io-into-a-meteor-app/ 81 | 82 | ## License 83 | 84 | MIT. (c) Percolate Studio 85 | 86 | Meteor Intercom was developed as part of the [Verso](http://versoapp.com) project. 87 | -------------------------------------------------------------------------------- /.npm/package/npm-shrinkwrap.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "ansi-regex": { 4 | "version": "2.0.0", 5 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", 6 | "from": "ansi-regex@>=2.0.0 <3.0.0" 7 | }, 8 | "ansi-styles": { 9 | "version": "2.2.1", 10 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", 11 | "from": "ansi-styles@>=2.2.1 <3.0.0" 12 | }, 13 | "asn1": { 14 | "version": "0.2.3", 15 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", 16 | "from": "asn1@>=0.2.3 <0.3.0" 17 | }, 18 | "assert-plus": { 19 | "version": "0.2.0", 20 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", 21 | "from": "assert-plus@>=0.2.0 <0.3.0" 22 | }, 23 | "async": { 24 | "version": "0.9.2", 25 | "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", 26 | "from": "async@>=0.9.0 <0.10.0" 27 | }, 28 | "aws-sign2": { 29 | "version": "0.6.0", 30 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", 31 | "from": "aws-sign2@>=0.6.0 <0.7.0" 32 | }, 33 | "aws4": { 34 | "version": "1.5.0", 35 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.5.0.tgz", 36 | "from": "aws4@>=1.2.1 <2.0.0" 37 | }, 38 | "bcrypt-pbkdf": { 39 | "version": "1.0.0", 40 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.0.tgz", 41 | "from": "bcrypt-pbkdf@>=1.0.0 <2.0.0" 42 | }, 43 | "bl": { 44 | "version": "1.1.2", 45 | "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz", 46 | "from": "bl@>=1.1.2 <1.2.0" 47 | }, 48 | "bluebird": { 49 | "version": "3.4.6", 50 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.6.tgz", 51 | "from": "bluebird@>=3.3.4 <4.0.0" 52 | }, 53 | "boom": { 54 | "version": "2.10.1", 55 | "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", 56 | "from": "boom@>=2.0.0 <3.0.0" 57 | }, 58 | "caseless": { 59 | "version": "0.11.0", 60 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", 61 | "from": "caseless@>=0.11.0 <0.12.0" 62 | }, 63 | "chalk": { 64 | "version": "1.1.3", 65 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", 66 | "from": "chalk@>=1.1.1 <2.0.0" 67 | }, 68 | "combined-stream": { 69 | "version": "0.0.7", 70 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", 71 | "from": "combined-stream@>=0.0.4 <0.1.0" 72 | }, 73 | "commander": { 74 | "version": "2.9.0", 75 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", 76 | "from": "commander@>=2.9.0 <3.0.0" 77 | }, 78 | "core-util-is": { 79 | "version": "1.0.2", 80 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 81 | "from": "core-util-is@>=1.0.0 <1.1.0" 82 | }, 83 | "cryptiles": { 84 | "version": "2.0.5", 85 | "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", 86 | "from": "cryptiles@>=2.0.0 <3.0.0" 87 | }, 88 | "dashdash": { 89 | "version": "1.14.0", 90 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.0.tgz", 91 | "from": "dashdash@>=1.12.0 <2.0.0", 92 | "dependencies": { 93 | "assert-plus": { 94 | "version": "1.0.0", 95 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 96 | "from": "assert-plus@>=1.0.0 <2.0.0" 97 | } 98 | } 99 | }, 100 | "delayed-stream": { 101 | "version": "0.0.5", 102 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz", 103 | "from": "delayed-stream@0.0.5" 104 | }, 105 | "ecc-jsbn": { 106 | "version": "0.1.1", 107 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", 108 | "from": "ecc-jsbn@>=0.1.1 <0.2.0" 109 | }, 110 | "escape-string-regexp": { 111 | "version": "1.0.5", 112 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 113 | "from": "escape-string-regexp@>=1.0.2 <2.0.0" 114 | }, 115 | "extend": { 116 | "version": "3.0.0", 117 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz", 118 | "from": "extend@>=3.0.0 <3.1.0" 119 | }, 120 | "extsprintf": { 121 | "version": "1.0.2", 122 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", 123 | "from": "extsprintf@1.0.2" 124 | }, 125 | "forever-agent": { 126 | "version": "0.6.1", 127 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 128 | "from": "forever-agent@>=0.6.1 <0.7.0" 129 | }, 130 | "form-data": { 131 | "version": "0.2.0", 132 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz", 133 | "from": "form-data@>=0.2.0 <0.3.0" 134 | }, 135 | "generate-function": { 136 | "version": "2.0.0", 137 | "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", 138 | "from": "generate-function@>=2.0.0 <3.0.0" 139 | }, 140 | "generate-object-property": { 141 | "version": "1.2.0", 142 | "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", 143 | "from": "generate-object-property@>=1.1.0 <2.0.0" 144 | }, 145 | "getpass": { 146 | "version": "0.1.6", 147 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz", 148 | "from": "getpass@>=0.1.1 <0.2.0", 149 | "dependencies": { 150 | "assert-plus": { 151 | "version": "1.0.0", 152 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 153 | "from": "assert-plus@>=1.0.0 <2.0.0" 154 | } 155 | } 156 | }, 157 | "graceful-readlink": { 158 | "version": "1.0.1", 159 | "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", 160 | "from": "graceful-readlink@>=1.0.0" 161 | }, 162 | "har-validator": { 163 | "version": "2.0.6", 164 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", 165 | "from": "har-validator@>=2.0.6 <2.1.0" 166 | }, 167 | "has-ansi": { 168 | "version": "2.0.0", 169 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", 170 | "from": "has-ansi@>=2.0.0 <3.0.0" 171 | }, 172 | "hawk": { 173 | "version": "3.1.3", 174 | "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", 175 | "from": "hawk@>=3.1.3 <3.2.0" 176 | }, 177 | "hoek": { 178 | "version": "2.16.3", 179 | "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", 180 | "from": "hoek@>=2.0.0 <3.0.0" 181 | }, 182 | "http-signature": { 183 | "version": "1.1.1", 184 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", 185 | "from": "http-signature@>=1.1.0 <1.2.0" 186 | }, 187 | "inherits": { 188 | "version": "2.0.3", 189 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 190 | "from": "inherits@>=2.0.1 <2.1.0" 191 | }, 192 | "intercom-client": { 193 | "version": "2.8.3", 194 | "resolved": "https://registry.npmjs.org/intercom-client/-/intercom-client-2.8.3.tgz", 195 | "from": "intercom-client@2.8.3" 196 | }, 197 | "is-my-json-valid": { 198 | "version": "2.15.0", 199 | "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz", 200 | "from": "is-my-json-valid@>=2.12.4 <3.0.0" 201 | }, 202 | "is-property": { 203 | "version": "1.0.2", 204 | "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", 205 | "from": "is-property@>=1.0.0 <2.0.0" 206 | }, 207 | "is-typedarray": { 208 | "version": "1.0.0", 209 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 210 | "from": "is-typedarray@>=1.0.0 <1.1.0" 211 | }, 212 | "isarray": { 213 | "version": "1.0.0", 214 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 215 | "from": "isarray@>=1.0.0 <1.1.0" 216 | }, 217 | "isstream": { 218 | "version": "0.1.2", 219 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 220 | "from": "isstream@>=0.1.2 <0.2.0" 221 | }, 222 | "jodid25519": { 223 | "version": "1.0.2", 224 | "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz", 225 | "from": "jodid25519@>=1.0.0 <2.0.0" 226 | }, 227 | "jsbn": { 228 | "version": "0.1.0", 229 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.0.tgz", 230 | "from": "jsbn@>=0.1.0 <0.2.0" 231 | }, 232 | "json-schema": { 233 | "version": "0.2.3", 234 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 235 | "from": "json-schema@0.2.3" 236 | }, 237 | "json-stringify-safe": { 238 | "version": "5.0.1", 239 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 240 | "from": "json-stringify-safe@>=5.0.1 <5.1.0" 241 | }, 242 | "jsonpointer": { 243 | "version": "4.0.0", 244 | "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.0.tgz", 245 | "from": "jsonpointer@>=4.0.0 <5.0.0" 246 | }, 247 | "jsprim": { 248 | "version": "1.3.1", 249 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.3.1.tgz", 250 | "from": "jsprim@>=1.2.2 <2.0.0" 251 | }, 252 | "lodash": { 253 | "version": "4.16.4", 254 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.16.4.tgz", 255 | "from": "lodash@>=4.14.0 <5.0.0" 256 | }, 257 | "mime": { 258 | "version": "1.3.4", 259 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", 260 | "from": "mime@>=1.3.4 <1.4.0" 261 | }, 262 | "mime-db": { 263 | "version": "1.12.0", 264 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz", 265 | "from": "mime-db@>=1.12.0 <1.13.0" 266 | }, 267 | "mime-types": { 268 | "version": "2.0.14", 269 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz", 270 | "from": "mime-types@>=2.0.3 <2.1.0" 271 | }, 272 | "node-uuid": { 273 | "version": "1.4.7", 274 | "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz", 275 | "from": "node-uuid@>=1.4.7 <1.5.0" 276 | }, 277 | "oauth-sign": { 278 | "version": "0.8.2", 279 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", 280 | "from": "oauth-sign@>=0.8.1 <0.9.0" 281 | }, 282 | "pinkie": { 283 | "version": "2.0.4", 284 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", 285 | "from": "pinkie@>=2.0.0 <3.0.0" 286 | }, 287 | "pinkie-promise": { 288 | "version": "2.0.1", 289 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", 290 | "from": "pinkie-promise@>=2.0.0 <3.0.0" 291 | }, 292 | "process-nextick-args": { 293 | "version": "1.0.7", 294 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", 295 | "from": "process-nextick-args@>=1.0.6 <1.1.0" 296 | }, 297 | "qs": { 298 | "version": "6.2.1", 299 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.1.tgz", 300 | "from": "qs@>=6.2.0 <6.3.0" 301 | }, 302 | "readable-stream": { 303 | "version": "2.0.6", 304 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", 305 | "from": "readable-stream@>=2.0.5 <2.1.0" 306 | }, 307 | "request": { 308 | "version": "2.74.0", 309 | "resolved": "https://registry.npmjs.org/request/-/request-2.74.0.tgz", 310 | "from": "request@>=2.74.0 <2.75.0", 311 | "dependencies": { 312 | "async": { 313 | "version": "2.1.1", 314 | "resolved": "https://registry.npmjs.org/async/-/async-2.1.1.tgz", 315 | "from": "async@>=2.0.1 <3.0.0" 316 | }, 317 | "combined-stream": { 318 | "version": "1.0.5", 319 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", 320 | "from": "combined-stream@>=1.0.5 <1.1.0" 321 | }, 322 | "delayed-stream": { 323 | "version": "1.0.0", 324 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 325 | "from": "delayed-stream@>=1.0.0 <1.1.0" 326 | }, 327 | "form-data": { 328 | "version": "1.0.1", 329 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.1.tgz", 330 | "from": "form-data@>=1.0.0-rc4 <1.1.0" 331 | }, 332 | "mime-db": { 333 | "version": "1.24.0", 334 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.24.0.tgz", 335 | "from": "mime-db@>=1.24.0 <1.25.0" 336 | }, 337 | "mime-types": { 338 | "version": "2.1.12", 339 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.12.tgz", 340 | "from": "mime-types@>=2.1.7 <2.2.0" 341 | } 342 | } 343 | }, 344 | "sntp": { 345 | "version": "1.0.9", 346 | "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", 347 | "from": "sntp@>=1.0.0 <2.0.0" 348 | }, 349 | "sshpk": { 350 | "version": "1.10.1", 351 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.10.1.tgz", 352 | "from": "sshpk@>=1.7.0 <2.0.0", 353 | "dependencies": { 354 | "assert-plus": { 355 | "version": "1.0.0", 356 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 357 | "from": "assert-plus@>=1.0.0 <2.0.0" 358 | } 359 | } 360 | }, 361 | "string_decoder": { 362 | "version": "0.10.31", 363 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", 364 | "from": "string_decoder@>=0.10.0 <0.11.0" 365 | }, 366 | "stringstream": { 367 | "version": "0.0.5", 368 | "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", 369 | "from": "stringstream@>=0.0.4 <0.1.0" 370 | }, 371 | "strip-ansi": { 372 | "version": "3.0.1", 373 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 374 | "from": "strip-ansi@>=3.0.0 <4.0.0" 375 | }, 376 | "supports-color": { 377 | "version": "2.0.0", 378 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", 379 | "from": "supports-color@>=2.0.0 <3.0.0" 380 | }, 381 | "tough-cookie": { 382 | "version": "2.3.1", 383 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.1.tgz", 384 | "from": "tough-cookie@>=2.3.0 <2.4.0" 385 | }, 386 | "tunnel-agent": { 387 | "version": "0.4.3", 388 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", 389 | "from": "tunnel-agent@>=0.4.1 <0.5.0" 390 | }, 391 | "tweetnacl": { 392 | "version": "0.14.3", 393 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.3.tgz", 394 | "from": "tweetnacl@>=0.14.0 <0.15.0" 395 | }, 396 | "unirest": { 397 | "version": "0.5.1", 398 | "resolved": "https://registry.npmjs.org/unirest/-/unirest-0.5.1.tgz", 399 | "from": "unirest@>=0.5.1 <0.6.0" 400 | }, 401 | "util-deprecate": { 402 | "version": "1.0.2", 403 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 404 | "from": "util-deprecate@>=1.0.1 <1.1.0" 405 | }, 406 | "verror": { 407 | "version": "1.3.6", 408 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", 409 | "from": "verror@1.3.6" 410 | }, 411 | "xtend": { 412 | "version": "4.0.1", 413 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", 414 | "from": "xtend@>=4.0.0 <5.0.0" 415 | } 416 | } 417 | } 418 | --------------------------------------------------------------------------------