Scala SDK for ContactHub
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
bin
example/src/main/scala/example
macros/src/main/scala/contacthub/sdk
modelsGenerator/src/main/scala/model-generator
project
src
.gitignore
.hophoprc
.scalafmt.conf
.travis.yml
CONTRIBUTING.md
LICENSE
README.md
build.sbt

README.md

Contacthub Scala SDK

Build StatusLatest tag

Adding this library to your project dependencies

In your build.sbt:

libraryDependencies += "it.contactlab.hub" % "sdk-scala" % <version>

Importing this library into your project

import it.contactlab.hub.sdk.scala.ContactHub;

Authenticating

Find your token, workspaceId and nodeId in the Contacthub UI. Then instantiate a new Contacthub object as follows:

val auth = new Auth(token, workspaceId, nodeId)

val ch = new ContactHub(auth)

Custom API url

If you want to use a non-standard baseUrl for the API (for example to connect to a staging environment), you can add the API base URL as an optional parameter:

val apiUrl = "http://example.com/api/v2"
val auth = new Auth(token, workspaceId, nodeId, apiUrl);

If not specified, the SDK will use the default URL for the Contacthub API: https://api.contactlab.it/hub/v1

Pagination

When the API returns a paginated set of results, the SDK will return an instance of Paginated[T]. This class has the following methods:

  • elements: returns a List[T] containing the elements of the current page
  • page: returns an instance of Page containing some page metadata (current page number, total number of pages, etc.)
  • nextPage: sends a new API request and returns a new instance of Paginated[T] for the next page
  • previousPage: sends a new API request and returns a new instance of Paginated[T] for the previous page

nextPage and previousPage wrap the result in an Option. If you try to call nextPage when you have reached the last page, or previousPage from the first page, you will get an None.

Session API

createSessionId

Generate a new sessionId.

val sessionId = ch.createSessionId

addCustomerSession

Reconcile a sessionId with an existing Customer. Use this if you want to associate anonymous events (containing a sessionId) with an existing customerId.

val result: Future[Unit] = ch.addCustomerSession(customerId, sessionId)

Customer API

getCustomer

Retrieve a customer by their ID.

val customer: Future[Customer] = ch.getCustomer("a-valid-customer-id")

customers

Retrieve all the Customers in a node.

val customers: Future[Paginated[Customer]] = ch.getCustomers()

This method returns an instance of Paginated[T]. See Pagination.

customers with extra options

val customers: Future[Paginated[Customer]] = ch.customers(options)

options is an instance of GetCustomersOptions, which can contain one or more of the following attributes:

  • externalId: filters Customers by externalId
  • fields: a whitelist of Customer properties you are interested in
  • query: a QueryContainer (see Custom Queries).
  • sort: the field to order the results by
  • direction: the order of the sorting (asc or desc)
  • page: the page to retrieve (defaults to 0)

This method returns an instance of Paginated<T>. See Pagination.

getCustomerByExternalId

Retrieve all the Customers matching a specific external ID.

val customers: Future[Paginated[Customer]] = ch.customerByExternalId("an-external-id")

This method will return the same result you would get from this more verbose request:

val customers: Future[Paginated[Customer]] = ch.customers(
    GetCustomersOptions(externalId = Option("an-external-id"))
)

Please note you can have more than one customer with the same external ID, unless you include "external ID" in the "matching policies" for your workspace.

This method returns an instance of Paginated[T]. See Pagination.

addCustomer

Add a new Customer. This method returns a new Customer object including the ID that was assigned to the new customer by the API.

val newCustomer: Future[Customer] = ch.addCustomer(customer)

If the "Customer uniqueness" configuration for your workspace is set to "Merge" and the new customer data matches an existing customer according to the "matching policies", this method will return the merged Customer data.

deleteCustomer

Delete the Customer with the specified ID.

val result: Future[Unit] = ch.deleteCustomer("an-existing-id")

updateCustomer

Update an existing Customer by replacing all of their data with the data provided.

val updatedCustomer: Future[Customer] = ch.updateCustomer(newCustomer)

This method will fail if the ID of the newCustomer does not match an existing customer.

patchCustomer

Update an existing Customer (identified by id) by merging their existing data with the data provided.

val updatedCustomer: Future[Customer] = ch.patchCustomer(id, modifiedCustomer);

Customer properties that were already set and are included in the new data, will be overwritten.

Customer properties that were already set, but are not included, will be left untouched.

For example, if you want to update the email of a customer and nothing else, you can use:

val patchCustomer = Customer(
  base = Option(BaseProperties(
    contacts = Option(Contacts(
      email = Option("newemail@example.com")
    ))
  ))
)

val updatedCustomer: Future[Customer] = ch.patchCustomer(customerId, patchCustomer);

How to use the Customer class

When you create a new Customer, you have to set at least one between base, extended and externalId. Most properties are optional.

When you read a Customer from the API, you get an immutable instance of Customer with a few additional properties:

  • an id
  • a registedAt property
  • an updatedAt property

To update a Customer, you need to retrieve it and create a modified immutable copy using the copy constructor (e.g. customer.copy(externalId = Option("123"))).

To patch a Customer, you create a "patch" instance in the same way you create a new Customer, but you set only the fields you want to patch. All the fields that are not explicitly set in the "patch" object will be left untouched.

Education API

The following methods are useful ways to add/update/remove the Education objects of a Customer.

addEducation

val updatedCustomer: Future[Customer] = ch.addEducation(customerId, education)

updateEducation

val updatedCustomer: Future[Customer] = ch.updateEducation(customerId, education)

removeEducation

val updatedCustomer: Future[Customer] = ch.removeEducation(customerId, educationId)

Like API

The following methods are useful ways to add/update/remove the Like objects of a Customer.

addLike

val updatedCustomer: Future[Customer] = ch.addLike(customerId, like)

updateLike

val updatedCustomer: Future[Customer] = ch.updateLike(customerId, like)

removeLike

val updatedCustomer: Future[Customer] = ch.removeLike(customerId, likeId)

Job API

The following methods are useful ways to add/update/remove the Job objects of a Customer.

addJob

val updatedCustomer: Future[Customer] = ch.addJob(customerId, job)

updateJob

val updatedCustomer: Future[Customer] = ch.updateJob(customerId, job)

removeJob

val updatedCustomer: Future[Customer] = ch.removeJob(customerId, jobId)

Tag API

addTag

Add a tag to a Customer. If the tag is already present, nothing is changed.

val updatedCustomer: Future[Customer] = ch.addTag(customerId, "a-new-tag")

removeTag

Remove a tag from a Customer. If the tag is already present, nothing is changed.

val updatedCustomer: Future[Customer] = ch.addTag(customerId, "a-tag-to-remove")

Custom Queries

Advanced searches and filtering of Customers can be performed using Custom Queries.

val options = GetCustomersOptions(query = Option(customQuery))
val customers: Future[Paginated[Customer]] = ch.customers(options)

A Custom Query is an instance of QueryContainer that can be generated in two ways:

Basic custom queries

val customQuery: QueryContainer = ch.createQuery("base.firstName", Operator.EQUALS, "Mario")
val customQuery: QueryContainer = ch.createQuery("base.pictureUrl", Operator.IS_NOT_NULL)

Advanced custom queries

The SDK lets you use the full power of the ContactHub API query language. The SDK methods closely mirror the structure of the API query format. Refer to the API documentation for more details.

val customQuery = QueryContainer(
  name = Optional("An optional name for your query")
  query = SimpleQuery(
    are = ConditionContainer(
      condition = AtomicCondition(
        attribute = "base.firstName",
        operator = Operator.Equals,
        value = "Mario"
      ))))

Event API

getEvent

Retrieve an event using its ID.

val event: Future[Event] = ch.getEvent("a-valid-event-id")

getEvents

Retrieve all the events for a customer.

val events: Future[Paginated[Event]] = ch.getEvents(customerId)

This method returns an instance of Paginated[T]. See Pagination.

addEvent

Add a new Event. The API will process the insertion asynchronously, and it can take a few seconds for an event to actually be stored.

val result: Future[Unit] = ch.addEvent(event)

To create an Event instance,you should instantiate one the Event subtypes object. Currently there are 9 Event subtypes, that are characterized by their context: they are ContactCenterEvent,DigitalCampaignEvent,EcommerceEvent,IotEvent,MobileEvent,OtherEvent, RetailEvent,SocialEvent and WebEvent.

WebEvent(
  customerId = Option(customerId),
  `type` = EventType.ViewedPage,
  properties = eventProperties
)

eventProperties must be of type Map<String, Object>. The structure of this object varies according to the event type, and always contains a number of optional fields. You should only include the properties that you need.

Example:

This will generate a valid eventProperties object for a ViewedPage event:

val eventProperties = Map(
  "url" -> "https://example.com",
  "title" -> "Page Title"
)

Examples

See the example subproject for working examples that you can download and try out.

Contributing to this library

sbt compile will compile all the sources.

sbt doc will generate an HTML Scaladoc in target/api

sbt test will run the tests. To run the tests you need a valid ContactHub account and a test workspace, refer to the notes in the example to set the correct environment variables.