eusi-sdk-node v1.1.1
eusi-sdk-node
The JS library which abstracts low level communication with EUSI delivery API is meant to be used within NodeJS environment.
EUSI is an API-first CMS that is user-friendly, beautifully designed and easy to use.
Table of content
- Installation
- Independent bundle
- Simple usage
- Configuration
- Authorization/Authentication
- Fetching content
- Purchasing content
- Advanced querying
- Handling forms
- Fetching taxonomy
- Wrapping up the access token
- More examples
Installation
NOTE: eus-sdk-node package is peer dependent on eusi-sdk-core package so please make sure you have installed them both !
npm install --save eusi-sdk-core eusi-sdk-node
or
yarn add eusi-sdk-core eusi-sdk-node
Simple usage
import eusiNode from 'eusi-sdk-node';
// both bucketKey and bucketSecret should be obtained form inside our eusi app under the settings tab
const eusi = eusiNode({
bucketKey: '46e5945b-789d-4cc2-8a40-608612425226',
bucketSecret: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJidWNrZXRfaWQiOiI0NmU1OTQ1Yi03ODlkLTRjYzItOGE0MC02MDg2MTI0MjUyMjYiLCJpZCI6IjU0MjBjYjA2LTRmMGYtNDMzMy1hODJhLTc5ZmFjMzU5YTU2ZSIsInRpbWVzdGFtcCI6MTUxNjYxMDU5NDc1Mn0.Li8Sb8v1CJnANDctUQumAQo90puBtNA3ywh4MmnxP-M'
});
// obtaining an anonymous access token
// (in case you are not using our membership system or
// you want guest access)
eusi.getAccess()
.then((response) => eusi.getById('44e8c09b-ed9e-4424-99e0-2de60adafa01', { token: response.token }))
.then(console.log);
Configuration
You can configure eusiNode factory with the following parameters:
- bucketKey (mandatory) - represents unique identificator of the bucket you are accessing
- bucketSecret (mandatory) - the secret token that you are given
- deliveryApi (optional) - represents a target URL of our delivery API. By default it is set to target our production ready API.
Authorization/Authentication
We use two step authorization system. First you need to acquire the bucket key (aka bucket id) and the bucket secret. Both of these you can obtain through our application.
- Go to the settings section.
- Click on the bucket keys tab where you will be able to create a new bucket key.
- Choose a name and select which parts should be turned on.
- Click save and you will be displayed with the bucket id (aka bucket key) and the bucket secret.
Now pass both of that data to SDK factory function and you will receive a client object.
const eusi = eusiNode({
bucketKey: '46e5945b-789d-4cc2-8a40-608612425226',
bucketSecret: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJidWNrZXRfaWQiOiI0NmU1OTQ1Yi03ODlkLTRjYzItOGE0MC02MDg2MTI0MjUyMjYiLCJpZCI6IjU0MjBjYjA2LTRmMGYtNDMzMy1hODJhLTc5ZmFjMzU5YTU2ZSIsInRpbWVzdGFtcCI6MTUxNjYxMDU5NDc1Mn0.Li8Sb8v1CJnANDctUQumAQo90puBtNA3ywh4MmnxP-M'
});
NOTE: that only parts of the API which are activated you will be able to use with that newly created key.
Next step is acquiring an access token. There are a few ways of doing it as described below.
login
If the user is already registered
eusi.login({
email: 'johndoe@mail.com',
password: '123'
}).then(response => {
const { token, member } = response;
// now you are ready to go
eusi.getById('060c99b0-b2db-42ca-a94d-c4873c2bda90', { token }).then(console.log);
// or you can wrap the token up so you dont pass it every time you request something
const withTokenClient = eusi(token);
withTokenClient.getById('060c99b0-b2db-42ca-a94d-c4873c2bda90').then(console.log);
withTokenClient.getByTitle('Some content title').then(console.log);
}).catch(error => {
console.log('Login failed'};
});
register
If you want to create a new user
eusi.register({
firstName: 'John',
lastName: 'Doe',
email: 'johndoe@mail.com',
password: '123'
}).then(response => {
const { token, member } = response;
// now you are ready to go
const withTokenClient = eusi(token);
withTokenClient.getById('060c99b0-b2db-42ca-a94d-c4873c2bda90').then(console.log);
withTokenClient.getByTitle('Some content title').then(console.log);
}).catch(error => {
console.log('Registration failed'};
});
NOTE: The register method will automatically login newly created user.
getAccess
If you are requesting resources as a guest user
eusi.getAccess().then(response => {
const withTokenClient = eusi(response.token);
return withTokenClient.getByTaxonomyName('teachers');
})
.then(console.log)
.catch(error => console.log('Obtaining temporary access token failed');
getUser
Retrieves info of the currently logged in user
eusi.getUser({ token }).then(user => console.log(user));
or if you have created withTokenClient
withTokenClient.getUser().then(user => console.log(user));
Fetching content
by key
eusi.getByKey('First-blog234', { token } ).then(console.log);
by id
eusi.getById('44e8c09b-ed9e-4424-99e0-2de60adafa01', { token });
by content model
eusi.get({
model: 'blog'
}, { token })
.then(console.log);
or
eusi.getByModel('blog', { token })
.then(console.log);
by content type
WARNING: This method is deprecated. Please use getByModel instead.
eusi.get({
type: 'blog'
}, { token })
.then(console.log);
or
eusi.getByType('blog', { token })
.then(console.log);
by content title
eusi.get({ title: 'Aussie open - first round'}, { token })
.then(console.log);
or
eusi.getByTitle('Aussie open - first round', { token })
.then(console.log);
by content name
WARNING: This method is deprecated. Please use getByTitle instead.
eusi.get({ name: 'Aussie open - first round'}, { token })
.then(console.log);
or
eusi.getByName('Aussie open - first round', { token })
.then(console.log);
by taxonomy id
eusi.get({
taxonomyId: '99e5945b-789d-4ac2-8a40-60861542777'
}).then(console.log);
or
eusi.getByTaxonomyId('99e5945b-789d-4ac2-8a40-60861542777')
.then(console.log);
by taxonomy name
eusi.get({
taxonommyName: 'sport-news'
}, { token })
.then(console.log);
or
eusi.getByTaxonomyName('sport-news', { token })
.then(console.log);
by taxonomy path
eusi.get({
taxonommyPath: 'sport-news.tennis.ao' // you can find the full path of every taxonomy item under taxonomy tab inside eusi app
}, { token })
.then(console.log);
or
eusi.getByTaxonomyPath('sport-news.tennis.ao')
.then(console.log);
by field
NOTE: currently we support searching only by textual fields
eusi.get({
field: {
'responsible-scientist': 'Nikola Tesla',
}
}, { token }).then(res => {
console.log(res);
// prints out all the content which have field key 'responsible-scientis' with the value 'Nikola Tesla'
});
or
eusi.getByField({
'responsible-scientist': 'Nikola Tesla'
}), { token }).then(res => {
console.log(res);
// prints out all the content which have field key 'responsible-scientis' with the value 'Nikola Tesla'
});
or you can search for a match by providing multiple field queries
eusi.getByField({
'responsible-scientist': 'Nikola Tesla',
'location': 'New York'
}, { token }).then(result => {
console.log(result);
// prints out all the content which have field
// 'responsible-scientist' with the value 'Nikola Tesla' and
// which have at the same time 'location' field with
// the value 'New York'
});
Pagination
We support pagination. In order to control the pagination you use two optional properties as part of a second object argument: pageSize and pageNumber. This signature is same for all content related API methods.
eusi.getByTitle('Some content title', {
token,
pageSize: 20,
pageNumber: 1
});
eusi.get({
title: 'Some content title',
taxonomyName: 'some taxonomy name'
}, {
token,
pageSize: 10,
pageNumber: 5
});
or if you have created withTokenClient
withTokenClient.getByType('blog', {
pageSize: 20,
pageNumber: 1
});
withTokenCient.get({
id: '82803b24-1ad5-11e8-accf-0ed5f89f718b'
}, {
pageSize: 10,
pageNumber: 5
});
Purchasing content using crypto currencies
Our platform allows your customers to purchase any content you have set price on it by using crypto currencies. At the moment we support payment with 6 most popular crypto currencies:
- Bitcoin (BTC)
- Bitcoin Cash (BCH)
- Litecoin (LTC)
- Dash (dash)
- Ethereum (ETH)
- Ripple (XRP)
Example
const contentId = '966364a6-877f-4747-9214-afd0172e4e32';
withTokenClient.purchaseContent(contentId, {
currency: 'ETH',
description: 'Buying my first content',
notifyUrl: 'https://my-payment-hook-url.com'
}).then(console.log);
// the response will be formatted like this
{
"id": "123f293c-79b1-4f62-935b-655e5a09f53d",
"member_id": "04eca9ce-3d4d-45c1-9fd9-d86515359447",
"content_id": "966364a6-877f-4747-9214-afd0172e4e32",
"amount": "2.000000000000000000",
"currency": "USD",
"requested_currency_to_pay_with": "ETH",
"address": "0xacd0f6319d5d22e978be085bb5dedd94ec93ff07",
"deposit": {
"address": "0xacd0f6319d5d22e978be085bb5dedd94ec93ff07"
},
"payment_url": "https://www.alfacoins.com/invoice/5b471b5c98046",
"iframe": "https://www.alfacoins.com/iframe/5b471b5c98046",
"status": "pending",
"updated_at": "2018-07-12T09:11:56.670Z",
"created_at": "2018-07-12T09:11:56.670Z"
}
Parameters
- contentId - id of the content to purchase
- currency - crypto currency code which you want to pay with
- description - payment description which is going to be sent to your customer as part of a notification email
- notifyUrl - the URL which is going to be POST requested with every status change of the payment
Validating integrity and authenticity of notification
As stated above notifyUrl is going to be called with POST request with every payment change. To avoid security issues we recommend to always check the signature of the request before you consume it's payload. We will include HMAC-SHA256 signature as part of the payload data. That way you can always be sure that the request is being made by us and it's integrity has not changed. The signature is being made by digesting complete notification request payload by using the first bucket secret key in your list as the signing key. The list of all bucket keys you can find under the bucket settings inside of our app.
Here is the pseudo code which depicts how the signatre is being created.
signature = HMACSHA256(JSON.stringify(notificationRequest.data), firstBucketSecretInYourList)
Using our SDK
We expose simple function on the root object of our sdk which will allow you to simply accomplish validating request signature.
const eusiNode = require('eusi-sdk-node');
eusiNode.isValidPaymentNotification(paymentNotificationRequest.hash, {
bucketSecret: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJidWNrZXRfaWQiOiI0NmU1OTQ1Yi03ODlkLTRjYzItOGE0MC02MDg2MTI0MjUyMjYiLCJpZCI6IjU0MjBjYjA2LTRmMGYtNDMzMy1hODJhLTc5ZmFjMzU5YTU2ZSIsInRpbWVzdGFtcCI6MTUxNjYxMDU5NDc1Mn0.Li8Sb8v1CJnANDctUQumAQo90puBtNA3ywh4MmnxP-M',
payload: paymentNotificationRequest.data
});
For more details please check our official API documentation.
Advanced querying
Our API provides you with an easy and elegant interface to make more complex queries. Instead of passing simple string to every method from above, you can pass a query object. Currently we support these operators: $like, $between, $in , $lg, $gt and by default for multiple query object props logical AND operator is used. They all work the same as related SQL operators.
$like
Matches substrings
eusi.getByField({
'responsible-scientist': {
location: 'New%'
},
}, { token }).then(result => {
console.log(result);
// prints out all the content which have field 'location' which value starts with 'New'
});
// You can combine queries with any number of quearible fields
eusi.get({
title: {
$like: 'Today%'
},
taxonomyPath: {
$like: 'news.%'
},
}).then(.../ fetches all the content which title starts with 'Today' and which has any taxnomy which is a descendant of taxonomy 'news'
NOTE: When using $like operator there is no case sensitivity.
$between
Matches interval
eusi.getByField({
salary: {
$between: [100000, 150000] // the value must be an array !
}
}, { token }).then(console.log); // prints out all the content which has a field salary between 100000 and 1500000
$in
Matches any of the supplied operands
eusi.getByTitle({
$in: ['Nikola Tesla', 'Mihajlo Pupin'] // // the value must be an array !
}, { token }).then(console.log); // prints out all the content which has title equal to either 'Nikola Tesla' or 'Mihajlo Pupin'
$lt
Matches all the number values lower then specified value
eusi.get({
field: {
maxAge: {
$lt: 10
}
}
}).then(console.log);
$gt
Matches all the number values greater then specified value
esui.getByField({
field: {
maxAge: {
$gt: 10
}
}
}).then(console.log);
combining operators
You can combine any number of fields with any number of existing operators to create complex queries.
NOTE: nesting operators is not supported
eusi.get({
title: {
$like: '%tennis%',
},
taxonomyName: 'sport-news',
field: {
longevity: {
$between: [5, 10]
},
salary: {
$gt: 5000
}
}
}, { token }).then(console.log);
Handling forms
We expose an API for managing web forms.
getForm
Requests the form metadata
const formId = '169ab8e4-18aa-11e8-accf-0ed5f89f718b';
eusi.getForm(formId, { token }).then(form => console.log(form));
// or by using more friendly form key
const formKey = 'login_form';
eusi.getForm(formId, { token }).then(form => console.log(form));
submitForm
Submits the form
const formKey = 'login_form';
withTokenClient.submitForm(formKey, {
userName: 'johndoe',
password: '123';
}).then(() => {
console.log('Submit successful');
});
testSubmitForm
Submits the test data. Handy if you want to check if your form is working correctly and triggering all the hooks but you don't want to be collected as a real submit by our system. It has the same signature as submitForm method.
const formKey = 'register_form';
withTokenClient.submitForm(formKey, {
firstName: 'John',
lastName: 'Smith',
email: 'john@smith.com',
password: 'smithy123'
}).then(() => {
console.log('Submit successful');
});
Fetching taxonomy
You can ask for a specific taxonomy and get all the info related to it including the whole tree of children items.
getTaxonomy
// you can pass either taxonomyKey or taxonomyId
const taxonomyKeyOrId = 'categories';
withTokenClient
.getTaxonomy(taxonomyKeyOrId)
.then(taxonomy => console.log(taxonomy);
Wrapping up the access token
Instead of passing the access token every time you request something you can wrap it up and receive an object with the identical API which will automatically pass the token for you any time you make a request.
const eusi = eusiNode({
bucketKey: '46e5945b-789d-4cc2-8a40-608612425226',
bucketSecret: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJidWNrZXRfaWQiOiI0NmU1OTQ1Yi03ODlkLTRjYzItOGE0MC02MDg2MTI0MjUyMjYiLCJpZCI6IjU0MjBjYjA2LTRmMGYtNDMzMy1hODJhLTc5ZmFjMzU5YTU2ZSIsInRpbWVzdGFtcCI6MTUxNjYxMDU5NDc1Mn0.Li8Sb8v1CJnANDctUQumAQo90puBtNA3ywh4MmnxP-M'
});
eusi.getAccess().then(response => {
const withTokenClient = eusi(response.toekn);
// now whenevery you request something by using 'withTokenClient' the token will be passed automatically
withTokenClient.get({
title: 'I just realized I dont need to pass the token every time'
}).then(console.log);
withTokenClient.getByTitle({
$like: '%token time has passed%'
}).then(console.log);
withTokenClient.getByTitle('This feels good').then(console.log);
});
NOTE: Only API methods which require access token are exposed on withTokenClient object.
More examples
For more examples please make sure you refer to our samples.