Overview
In this package:
- Hull Client
Most low level Hull Platform API client: const hull = new Hull({ configuration })
In the Hull-node package (which embeds this one):
- Hull Middleware
A bridge between Hull Client and a NodeJS HTTP application (e.g. express) which initializes context for every HTTP request:
app.use(Hull.Middleware({ configuration }))
- Hull Connector
A complete toolkit to operate with Hull Client in request handlers. Includes Hull Middleware and a set of official patterns to build highly scalable and efficient Connectors:
const connector = new Hull.Connector({ configuration })
Hull
This library makes it easy to interact with the Hull API, send tracking and properties and handle Server-side Events we send to installed Ships.
Creating a new Hull client is pretty straightforward:
import Hull from 'hull';
const client = new Hull({
id: 'HULL_ID',
secret: 'HULL_SECRET',
organization: 'HULL_ORGANIZATION_DOMAIN'
});
Calling the API
Once you have instantiated a client, you can use one of the get
, post
,
put
or delete
methods to perform actions of our APIs.
const params = {};
client.get(path, params).then(function(data) {
console.log(response);
}, function(err, response) {
console.log(err);
});
The first parameter is the route, the second is the set of parameters you want
to send with the request. They all return Promises so you can use the .then()
syntax if you're more inclined.
options
Every API client method get
, post
, put
and delete
accepts two options timeout
and retry
:
client.get(path, {}, {
timeout: 10000,
retry: 5000
});
- timeout - option controls if the client should retry the request if the client timeout error happens or if there is an error 503 returned serverside - the value of the option is applied for client side error
- retry - controls the time between timeout or 503 error occurence and the next retry being done
Instance Methods
client.configuration()
Returns the global configuration object.
client.configuration();
{ prefix: '/api/v1',
domain: 'hullapp.io',
protocol: 'https',
id: '58765f7de3aa14001999',
secret: '12347asc855041674dc961af50fc1',
organization: 'fa4321.hullbeta.io',
version: '0.7.4' }
client.userToken()
client.userToken({ email:'xxx@example.com', name:'FooBar' }, optionalClaims);
Used for Bring your own users.
Creates a signed string for the user passed in hash. userHash
needs an email
field.
You can then pass this client-side to Hull.js to authenticate users client-side and cross-domain
client.currentUserId()
client.currentUserId(userId, userSig)
Checks the validity of the signature relatively to a user id
Impersonating a User - client.asUser()
One of the more frequent use case is to perform API calls with the identity of a given user. We provide several methods to do so.
const user = client.asUser({ external_id: "dkjf565wd654e" });
const user = client.asUser({ id: "5718b59b7a85ebf20e000169" });
const user = client.asUser("5718b59b7a85ebf20e000169");
const user = client.asUser({ id: "5718b59b7a85ebf20e000169" }, { create: false });
user.get("/me").then(function(me) {
console.log(me);
});
user.userToken();
You can use an internal Hull id
, an ID from your database that we call external_id
, an email
address or anonymous_id
.
Assigning the user
variable doesn't make an API call, it scopes the calls to another instance of hull
client. This means user
is an instance of the hull
client scoped to this user.
The second parameter lets you define additional options (JWT claims) passed to the user resolution script:
- create - boolean - marks if the user should be lazily created if not found (default: true)
Possible usage
Return a hull client
scoped to the user identified by it's Hull ID. Not lazily created. Needs an existing User
client.asUser(userId);
Return a hull client
scoped to the user identified by it's Social network ID. Lazily created if Guest Users are enabled
client.asUser('instagram|facebook|google:userId');
Return a hull client
scoped to the user identified by it's External ID (from your dashboard). Lazily created if Guest Users are enabled
client.asUser({ external_id: 'externalId' });
Return a hull client
scoped to the user identified by it's External ID (from your dashboard). Lazily created if Guest Users are enabled
client.asUser({ anonymous_id: 'anonymousId' });
Return a hull client
scoped to the user identified by only by an anonymousId. Lets you start tracking and storing properties from a user before you have a UserID ready for him. Lazily created if Guest Users are enabled
When you have a UserId, just pass both to link them.
client.asUser({ email: "user@email.com" });
Methods for user-scoped instance
const externalId = "dkjf565wd654e";
const anonymousId = "44564-EJVWE-1CE56SE-SDVE879VW8D4";
const user = client.asUser({ external_id: externalId, anonymous_id: anonymousId });
When you do this, you get a new client that has a different behaviour. It's now behaving as a User would. It means it does API calls as a user and has new methods to track and store properties
user.track(event, props, context)
Stores a new event.
user.track('new support ticket', { messages: 3,
priority:'high'
}, {
source: 'zendesk',
type: 'ticket',
event_id: 'uuid1234'
ip: null,
referer: null,
created_at: '2013-02-08 09:30:26.123+07:00'
});
The context
object lets you define event meta-data. Everything is optional
- source: Defines a namespace, such as
zendesk
, mailchimp
, stripe
- type: Define a event type, such as
mail
, ticket
, payment
- created_at: Define an event date. defaults to
now()
- event_id: Define a way to de-duplicate events. If you pass events with the same unique
event_id
, they will overwrite the previous one. - ip: Define the Event's IP. Set to
null
if you're storing a server call, otherwise, geoIP will locate this event. - referer: Define the Referer.
null
for server calls.
user.traits(properties, context)
Stores Attributes on the user:
user.traits({
opened_tickets: 12
}, { source: 'zendesk' });
user.traits({ "zendesk/opened_tickets": 12, "clearbit/name": "foo" });
By default the traits
calls are grouped in background and send to the Hull API in batches, that will cause some small delay. If you need to be sure the properties are set immediately on the user, you can use the context param { sync: true }
.
user.traits({
fetched_at: new Date().toISOString()
}, {
source: 'mailchimp',
sync: true
});
Utils
traits.group()
The Hull API returns traits in a "flat" format, with '/' delimiters in the key.
client.utils.traits.group(user_report)
can be used to group those traits into subobjects:
import { group: groupTraits } from "hull-client/lib/trait";
groupTraits({
'email': 'romain@user',
'name': 'name',
'traits_coconut_name': 'coconut',
'traits_coconut_size': 'large',
'traits_cb/twitter_bio': 'parisian',
'traits_cb/twitter_name': 'parisian',
'traits_group/name': 'groupname',
'traits_zendesk/open_tickets': 18
});
{
'id' : '31628736813n1283',
'email': 'romain@user',
'name': 'name',
'traits': {
'coconut_name': 'coconut',
'coconut_size': 'large'
},
cb: {
'twitter_bio': 'parisian',
'twitter_name': 'parisian'
},
group: {
'name': 'groupname',
},
zendesk: {
'open_tickets': 18
}
};
This utility can be also used in following way:
const client = new Hull({ config });
const userGroupedTraits = client.utils.traits.group(user_report);
Logging Methods
The Logger comes in two flavors, Hull.logger.xxx
and hull.logger.xxx
- The first one is a generic logger, the second one injects the current instance of Hull
so you can retreive ship name, id and organization for more precision.
Uses Winston
Hull.logger.info("message", { object });
client.logger.info("message", { object });
Hull.logger.info("message", { object });
client.logger.info("message", { object });
import winstonSlacker from "winston-slacker";
Hull.logger.add(winstonSlacker, { ... });
Options
-
hostSecret
The ship hosted secret - consider this as a private key which is used to encrypt and decrypt req.hull.token
. The token is useful for exposing it outside the Connector <-> Hull Platform communication. For example the OAuth flow or webhooks. Thanks to the encryption no 3rd party will get access to Hull Platform credentials.
-
clientConfig
Additional config which will be passed to the new instance of Hull Client