intercom / intercom-node Goto Github PK
View Code? Open in Web Editor NEWNode.js bindings for the Intercom API
Home Page: https://developers.intercom.com
License: Other
Node.js bindings for the Intercom API
Home Page: https://developers.intercom.com
License: Other
Hi,
I'm creating leads through a form on my site using this library. In addition to email and IP Address, I'm passing along the User Agent string pulled directly from the request headers. Unfortunately, this information isn't showing up in the lead's profile.
Here's my code:
intercomClient.contacts
.create({
email: userEmail,
last_seen_ip: userIpAddress,
user_agent_data: request.headers['user-agent']
})
.then(() => {
return reply();
})
.catch((err) => {
return reply(Boom.badImplementation(err));
});
Here's the string coming from the headers:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36
And here's what I'm seeing in Intercom:
I thought it might be a format issue, but I tried the data in the CURL Example, but no luck.
Thanks!
It seems like the published version and what's noted in the PR above differ.
After creating and admin or user initiated conversation it would be great to reply to it.
After creating the admin or user initiated conversation if you try to reply to it providing the conversation id, it's not working.
The id of the conversation does not match the id that I can see in the messages inbox... so it looks like the conversation id is not provided...!
body.errors [{"code":"not_found","message":"Resource Not Found"}]
I found that I can pass id: 'last'
and it works but it's more an hack...! (Library code enabling that and doc for last reply)
I did not find a list of possible values to use for the template property nor a route which would allow me to query this.
My use case is, that I want to send an email with a certain style/template applied. From the intercom web app these 4 should be possible (plain, company, personal, announcement). Applying any of these strings as a param resulted in the same email sent.
The provided template is used for the email.
It always uses the personal template
//Require Intercom
var Intercom = require('intercom-client');
var client = new Intercom.Client({ token: token });
// Admin initiated messages:
// Sending an email to a User
var message = {
message_type: "email",
subject: "Hey",
body: "Simple email from intercom",
template: "company",
from: {
type: "user",
user_id: "582b18f6c370b6344a52b076"
},
to: {
type: "user",
user_id: "5825c98f1be52a4141905907"
}
}
client.messages.create(message).then(function (data) {
console.log('data: ', data.body)
})
data: { type: 'user_message',
id: '59464454',
created_at: 1479224902,
body: 'Simple email from intercom',
message_type: 'inapp' }
new Intercom.Client({
apiKey: 'apiKey',
appId: 'appId'
}
is generally less error-prone and more readable than
new Intercom.Client('app_id', 'api_key');
Not super critical, but easier to change while there are not too many users.
Please use the following template to submit your issue. Following this template will allow us to quickly investigate and help you with your issue. Please be aware that issues which do not conform to this template may be closed.
For feature requests please contact us at [email protected]
var Intercom = require('intercom-client')
Uncaught Error: Cannot find module "fs"
at webpackMissingModule (form_data.js:7)
at Object.<anonymous> (form_data.js:7)
at Object.<anonymous> (form_data.js:353)
at __webpack_require__ (bootstrap 68e893c…:585)
at fn (bootstrap 68e893c…:109)
at Object.<anonymous> (index.js:15)
at Object.<anonymous> (index.js:1091)
at __webpack_require__ (bootstrap 68e893c…:585)
at fn (bootstrap 68e893c…:109)
./~/unirest/index.js
./~/mime/mime.js
./~/mime/types.json
/~/unirest/~/form-data/lib/form_data.js
./~/unirest/~/mime-db/db.json
./~/tough-cookie/package.json
./~/request/lib/har.js...
Found two uses
Invalid use that responded with an empty response instead of something like "Error: 'message_type' must be 'email' or 'inapp'"
var Intercom = require('intercom-client')
var client = new Intercom.Client('foo', 'bar').usePromises()
var message = {
message_type: 'message', // this is an invalid type
body: 'Hi this is a admin initiated message',
from: {
type: 'admin',
id: '123'
},
to: {
type: 'user',
id: '123'
}
}
client.messages.create(message).then(console.log)
// => no response
Resource not found responds with an empty response instead of something like "Error: user not found"
var Intercom = require('intercom-client')
var client = new Intercom.Client('foo', 'bar').usePromises()
var message = {
message_type: 'inapp',
body: 'Hi this is a admin initiated message',
from: {
type: 'admin',
id: '123'
},
to: {
type: 'user',
id: '123' // not a real user
}
}
client.messages.create(message).then(console.log)
// => no response
I can understand if you'd prefer to fail silently for the second issue (though it would be nice if there was a setting to make it throw an error) but I def think the first one should have an error - required key having an invalid value
When you call user.list() it suggests that it only returns the first n items (along with a pages object to show how many other pages there are). As far as I can see though there is no way to get any other page from the api other than the first. Is there any way to list all users or get the users on the next n pages?
Are you still maintain this repo? 4 PR and failing tests are not fixed
Hi there, would this be difficult to do? I could create a PR if you want?
One of the problems when using the unofficial node lib (not the lib's fault) is the strict api rate limit. There's a limit of ~500 user updates per minute which is very low if you want to bulk update users.
Does this lib handles this limitation in any way?
is it possible to grab an auto message id, then make another call with the message id and a user id to send the message?
currently sending messages looses all the formatting.
My app's company_id type is Number, and I want to find user list in specific company(ex: company_id: 100).
I call to the listUsers API, but get the error.
I expect can do it using company_id, but intercom-node module doesn't implement it.
Intercom developer ref: List company users
Unhandled rejection Error
companies.listUsers({id: '100'}).then(r => {
console.log(r);
});
or
companies.find({id: '100'}).then(r => {
console.log(r);
});
Unhandled rejection Error: {"statusCode":404,"body":{"type":"error.list","request_id":"apr7l9f98ocvgbpv7dq0","errors":[{"code":"not_found","message":"Company Not Found"}]},"headers":{"cache-control":"no-cache","content-type":"application/json; charset=utf-8","date":"Thu, 26 Jan 2017 08:35:47 GMT","server":"nginx",
"set-cookie":["_mkra_ctxt=9de3915db548df5a585796b1497cab2a--404; path=/; max-age=5; HttpOnly; secure"],"status":"404 Not Found","strict-transport-security":"max-age=31557600; includeSubDomains; preload","vary":"Accept-Encoding",
"x-content-type-options":"nosniff","x-frame-options":"SAMEORIGIN","x-intercom-version":"7b241962ebd2722082d2c21c7c8dae7de99ff8e2","x-request-id":"apr7l9f98ocvgbpv7dq0","x-runtime":"0.054100","x-xss-protection":"1; mode=block","transfer-encoding":"chunked","connection":"Close"},
"request":{"uri":{"protocol":"https:","slashes":true,"auth":null,"host":"api.intercom.io","port":443,"hostname":"api.intercom.io","hash":null,"search":null,"query":null,"pathname":"/companies/279","path":"/companies/279","href":"https://api.intercom.io/companies/279"},
"method":"get","headers":{"Content-Type":"application/json","Accept":"application/json","User-Agent":"intercom-node-client/2.0.0","authorization":"Basic ZEc5ck9qUmtNak0xWVRVMFh6WmtZMkZmTkdWak5WODVNR0pqWHpnNVpUTmpOV0U0TVRrME9Ub3hPakE9Og==","content-length":0}}}
If you have a plan that find data using company_id, I can make P/R.
maybe
listUsers(params, f) {
if (params.company_id !== undefined) {
return this.client.get(`/companies`, {company_id: params.company_id, type: 'user'}, f);
} else (
return this.client.get(`/companies/${params.id}/users`, {}, f);
}
}
Thank you.
There's currently no way to update the company via this api client
This isn't a bug - more a suggested deprecation.
You're currently using arity detection to decide on the behavior for callbacks. This is consistently considered bad practice in JS. I did bring it up in the PR where it was introduced (#18 (comment)) but received no response.
This is particularly problematic in Node, where this is considered standard/idiomatic:
intercom.users.list(error => {
if (error)
log.warn('blah', [error]);
});
Executing the code above would result in unexpected behavior. It could be resolved by adding an unused second parameter to the function, but most linters consider this an error:
I'd suggest deprecating this behavior and then removing it in a future v3.
Method events.create
throws exception with response/error data as an object.
Method events.create
throws stringified request as a new error message.
Happen here:
https://github.com/intercom/intercom-node/blob/master/lib/client.js#L58
It would be helpful to have a function like this:
var client = new Intercom.Client({secretKey: MY_SECRET});
var userHash = client.userHash(userId);
// or
var userHash = Intercom.Util.generateUserHash({secretKey: MY_SECRET, userId: userId});
I know it just does this:
var crypto = require('crypto');
var userHash = crypto.createHmac('sha256', MY_SECRET).update(userId.toString()).digest('hex');
but it would be helpful to not learn that.
This request comes from enabling secure mode: https://docs.intercom.io/configuring-Intercom/enable-secure-mode.
I'm a bit confused if you prefer snake or camel casing.
Thanks.
Please use the following template to submit your issue. Following this template will allow us to quickly investigate and help you with your issue. Please be aware that issues which do not conform to this template may be closed.
For feature requests please contact us at [email protected]
Not able to use with browserify and backbone.js .. Following error comes
XMLHttpRequest cannot load https://api.intercom.io/users. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access. The response had HTTP status code 406.
The main reason I am submitting this is because the method actually succeeds in creating the contact, but throws an error in the application.
Instead of me having to write an empty callback create(userData, function (r) {})
to avoid the error.
I would prefer being able to simply leave it off create(userData)
Create users in bulk
Returns an error list containing an error of type: media_type_not_acceptable
error.list
Client:
'use strict';
var IntercomAPI = require( 'intercom-client' );
module.exports = new IntercomAPI.Client( {
appId : process.env.INTERCOM_APP_ID,
appApiKey : process.env.INTERCOM_APP_ID_KEY
} )
.usePromises();
Request:
var client = require( './client.js' );
module.exports = function( members ) {
var users = [];
for ( var key in members ) {
members.hasOwnProperty( key ) && users.push( {
create : members[ key ]
} );
}
return client.users.bulk( users )
.then( function( response ) {
console.info( '[intercom] [INFO] [Users: Add response]',
JSON.stringify( response )
);
} );
}
Result of the error list:
{
"errors": [
{
"code": "media_type_not_acceptable",
"message": "The Accept header should send a media type of application/json"
}
],
"type": "error.list"
}
I want to set some custom attributes on some existing users. Looking at the doc here updating a user is supported
https://doc.intercom.io/api/#create-or-update-user
The api doesn't have an update call but but does have the create/post. What are best practices for updating. Is it to call create again on the user?
My plan was to
Find user
Update the custom attributes object
update user (call create on existing user object with updated custom attributes?)
Hello intercom, is it normal that babel-eslint is not in devDependencies ?
According to the lib's docs Callbacks section:
This client library supports two kinds of callbacks:
// Option #1
client.users.list(function (d) {
// d is the response from the server
});
// Option #2
client.users.list(function (err, d) {
// err is an error response object, or null
// d is a successful response object, or null
});
How does Intercom know which style you want ? It checks the amount of arguments in your callback function and sends you each time a different one accordingly.
This is very confusing and non standard:
Documentation states I can use the token alone:
var client = new Intercom.Client({ token: 'my_token' });
But I still needed to pass the AppId:
var client = new Intercom.Client({ appId: 'my_appId', token: 'my_token' });
As far as I can tell, the scroll API isn't implemented?
Are there plans to implement this? I'm having to paginate through all users and I'm hitting the page limit.
Hi,
Is there any reason that events could not be sent using a user_id
?
Since email
are not a unique key, it could be confusing to send an event if two emails are the same.
Moreover, I don't understand this doc section:
// Note: events will work when identified by 'email'.
// Create a event
client.events.create({
event_name: 'Foo',
created_at: 1439826340,
user_id: 'bar'
}, function (d) {
console.log(d);
});
Do you mean it will only work with the email
field?
Thanks.
When making an invalid call, throw an error or call callback with error
Silence
Currently users.list() does not allow any arguments other than the callback function. How can I tell it to give me page 2, etc. ?
Calling intercom.users.find({ user_id: userId })
returns events in body.events
in the same way as it does for body.custom_attributes
.
No events are in the response anywhere I can see them.
There is no client.users.update method--only client.users.create. The readme incorrectly lists the former, whereas one must actually use the latter, which has UPSERT behavior, to update OR create the user.
the require module should be intercom-client
not intercom-node
i have a segment like the following code snippet which finds a user by their email and sends an intercom message using the api. the issue is sometimes i get an error like the following.
{"statusCode":400,"body":{"type":"error.list","request_id":"almvmvb7hnr3hjonq670","errors":[{"code":"conflict","message":"Multiple existing users match this email address [email protected] - must be more specific using user_id"}]}
I'm pretty sure this is because this email exists twice in intercom, since we were, for a while, using the same intercom app for both our dev and prod ios apps.
so my first question is in this case it possible to return a list of users , maybe using listBy
instead of just throwing an error when this case happens?
client.users.find({ email: req.user.email })
.then(function (r) {
var message = {
message_type: 'inapp',
subject: subject,
body: msg,
template: 'plain',
from: {
type: 'admin',
id: process.env.INTERCOM_FROM_ACCOUNT,
},
to: {
type: 'user',
user_id: r.body.user_id,
},
};
return client.messages.create(message);
}).then(function (r) {
return res.status(200).json({ success: true, message: helper.strings.MessageSent });
}).catch(function (e) {
helper.logging.logError(e, req);
res.status(500).json({ success: false, message: helper.strings.AnErrorHappened });
});
secondly, this might be more an iOS question, but I dont even see a way to get the user id from the API to pass it to the server.
Anyways, any suggestions are appreciated.
I see that there exist user_hash method, but i don't now, in which request i should put it(hash). For example, if i am trying to create user with user hash, calculated using your method(user_id as argument), response is:
errors: [ { "code": "bad_request', message: 'bad \"user_hash\" parameter"} ]
My request payload:
{
"user_id": "12345677",
"email": "[email protected]",
"user_hash": "calculatedHash"
}
Hi , I was getting below error when i was calling messages.create method .
Can any one explore this
"body": { "type": "error.list", "request_id": "alnvbrgmmvv77ttsm17g", "errors": [ { "code": "not_found", "message": "Resource Not Found" } ] },
Important: Would be great if this can be fixed ASAP.
We are about to start loosing data here in the next 12 hours.
This might be an issue with the API and this client using deprecated functionality?
Can create user with "signed_up_at" value.
Receive error message saying bad 'remote_created_at' parameter
.
const Intercom = require('intercom-client');
const INTERCOM_APP_ID = "xxxxxx";
const INTERCOM_API_KEY = "*******************";
var client = new Intercom.Client(INTERCOM_APP_ID, INTERCOM_API_KEY);
client.users.create({
"signed_up_at": "2016-11-24T02:51:26.363097+00:00",
"user_id": "12345675c235883a4f0c877a32fc9dd8"
}, function (resp) {
console.log(resp.status);
console.log(JSON.stringify(resp.body, null, 4));
});
{
"type": "error.list",
"request_id": null,
"errors": [
{
"code": "bad_request",
"message": "bad 'remote_created_at' parameter"
}
]
}
Is there a pure web JavaScript version of the library that is Promised-based?
If it not, could you kindly make available a version that is - I figure it is just a compile step away.
According to the documentation, API Keys are being deprecated in favor of Personnal Access Token. How do I use those with this client lib?
Thanks!
Please make a note that 'Leads' are actually contacts, and not users... it's hard to find the distinction in the documentation.
Cheers
I've encountered a strange error when using the library to send messages. I'll do my best to describe the issue, but my use case is quite particular.
I am using node's cluster module and the Intercom message is being sent via a child process and is also wrapped inside a try/catch block to ensure no uncaught errors cause the child process to crash. The Intercom message was the last call in the async chain, but it appears that it was never able to successfully call its callback as this internal node error appears in the logs:
nodejs: ../src/util-inl.h:196: TypeName* node::Unwrap(v8::Local<v8::Object>) [with TypeName = node::crypto::SecureContext]: Assertion `(object->InternalFieldCount()) > (0)' failed.
Logging the exit code and signal of the forked process (via the master process' on.("exit", ...)
event) shows that it exits with code null
and signal SIGABRT
.
Removing the Intercom message method stops the internal node error from appearing, the final callback is called, and the process exits with no errors. For now, I have replaced the library with a simple HTTP request via the request library and everything works correctly.
For reference, this was running on Ubuntu 14.04, Docker 1.10.2, Node v4.3.0.
I apologize if any of this is vague. Please ask for whatever details you may in order to look into this and I'll be happy to clarify.
I would recommend copying Stripe's approach to supporting Promises rather than the current usePromises()
approach. Typically, you would just have it return a promise unless there's a callback passed in. You also can use Bluebird's nodeify function or just a separate node module to handle this for you- https://www.npmjs.com/package/nodeify- and just stick to Promises in the core- wouldn't recommend anything different tbh.
It's also acceptable to just expose Promises and let the developer using the module nodeify it / wrap it if they prefer callbacks, imo (same with callbacks, just that Promises are the way things are headed towards).
Thoughts? @bobjflong
I am trying to get users from Intercom .
code:
var client = new Intercom.Client(appId,apiKey);
client.users.create({ email: '[email protected]' }, function (response) {
console.log(response);
});
I am using api key and Id which have Read & Write access.
But we are getting back https status 401
{"type":"error.list","request_id":"aacda07a-b315-4a58-a800-046efb118dbb","errors":[{"code":"token_not_found","message":"Unauthorized
"}]}].
Please help.:)
Thanks
Currently the only way to get the actual error message, code etc. is to parse error.message
In my case I first check to see if a user with a given email exists - If not I create them as a lead. Checking if a user exists throws a 404, so I need to JSON.parse(err.message)
to see if its just a 404, or some other error.
It would be nice if I could just check error.code
/ error.statusCode
error.code
or similar is defined
error.message
is the only property - I have to JSON.parse
it to get the statusCode
Firstly, thanks for writing a sweet API!
Secondly, the following code would be very useful and not difficult to implement:
//Find user by id
client.users.find({ id: '1234' }, callback);
would be better represented as:
//Find user by id
(client.users.find({ user_id: '1234' }, callback);
as this would be less misleading. This would not be a difficult fix either and would be much more practical to use.
As well as the above issue, the following would be extremely useful:
// Find user by email
client.users.find({ email: '[email protected]' }, callback);
It could be implemented in user.js using:
client.get('/users/?email=${email}', {}, callback);
Cheers!
Hi team,
I've been looking at switching to the official client from this unoffical one.
The two main problems:
Sticking to the other library in the meantime!
intercom docs state "Personal Access Tokens should never be shared outside of your company" . I am integrating intercom in a React SPA, thus was concerned if its safe to disclose access token on client side.
intercom-node 2.6
node 5.5
I am trying to fetch a list of my conversations, but when I use usePromises
it throws an error. If I use it with callbacks, it works as expected.
Update: Turns out you need to pass an empty object instead of undefined if you want to fetch all. I would add this to the docs or default the query to {}
if null/undefined.
const Intercom = require('intercom-client');
const INTERCOM_API_KEY = process.env.INTERCOM_PRODUCTION_RO_API_KEY;
const INTERCOM_APP_ID = process.env.INTERCOM_PRODUCTION_APP_ID;
const client = new Intercom.Client(INTERCOM_APP_ID, INTERCOM_API_KEY)
.usePromises();
client.conversations.list()
.then((res) => {
console.log(res);
});
kel@Wombat:~/Projects/intercom-explorer (master #)$ node index.js
/Users/kel/Projects/intercom-explorer/node_modules/unirest/index.js:214
if (!value.length) return $this;
^
TypeError: Cannot read property 'length' of undefined
at Object.$this.query (/Users/kel/Projects/intercom-explorer/node_modules/unirest/index.js:214:19)
at Client.get (/Users/kel/Projects/intercom-explorer/node_modules/intercom-client/dist/client.js:155:144)
at Conversation.list (/Users/kel/Projects/intercom-explorer/node_modules/intercom-client/dist/conversation.js:21:26)
at Object.<anonymous> (/Users/kel/Projects/intercom-explorer/index.js:8:22)
at Module._compile (module.js:413:34)
at Object.Module._extensions..js (module.js:422:10)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Function.Module.runMain (module.js:447:10)
at startup (node.js:139:18)
at node.js:999:3
Can you guys please update your "babel-core" dependency from 5.5 to version 6. This has a fix for an unpublished dependency thank you.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.