1. Introduction
Micronaut Segment library allows you to integrate Segment into your Micronaut or Grails applications.
Segment lets you send your analytics data to any service you want, without having to integrate with each one individually.
The library provides the following beans:
-
Analytics
- official Segment Analytics for Java library analytics services -
SegmentService
- A server side service client to call Segment APIs, which is a wrapper around the official Segment Analytics for Java library.
2. Installation
Micronaut Segment is available in the Maven Central repository.
api 'com.agorapulse:micronaut-segment:2.0.0'
<dependency>
<groupId>com.agorapulse</groupId>
<artifactId>micronaut-segment</artifactId>
<version>2.0.0</version>
</dependency>
3. Configuration
You need to provide segment.api-key
configuration property to send information to Segment.
segment:
api-key: some-key (1)
options: (2)
language: fr
1 | Segment API key is required if you want to send records to Segment but can be ignored in the development environment |
2 | The legacy default options id , language , user-agent or intercom , use Message Transformation instead |
You can rely on SegmentService
bean being always present but if the API key is missing then no-op implementation is provided.
4. Usage
4.1. Segment Service
You can inject SegmentService
into your beans in order to call Segment APIs.
The bean is always present but no-op implementation is injected when the Segment API key is missing in the configuration.
Contrary to the native Analytics
builder methods, all the methods in the SegmentService
accepts maps with null
values
or null
values in general. null
arguments are ignored and maps containing null
values are cleaned up.
@Singleton
public class MyService {
private final SegmentService segmentService;
public MyService(SegmentService segmentService) {
this.segmentService = segmentService;
}
}
@Singleton
class MyService {
private final SegmentService segmentService
MyService(SegmentService segmentService) {
this.segmentService = segmentService
}
}
4.1.1. Creating Aliases
You can alias existing user to another ID.
See the documentation for the further information.
service.alias(PREVIOUS_ID, USER_ID);
service.alias(PREVIOUS_ID, USER_ID)
4.1.2. Group Association
You can associate a user with a group, including advanced properties.
See the documentation for the further information.
service.group(USER_ID, GROUP_ID, b -> b
.traits("category", CATEGORY)
.traits("section", SECTION)
.traits("nullable", null)
.timestamp(now)
.anonymousId(ANONYMOUS_ID)
.messageId(MESSAGE_ID)
.integrationOptions("Google Analytics", "clientId", GOOGLE_ANALYTICS_ID)
.enableIntegration("Something Enabled", true)
.enableIntegration("Something Disabled", false)
.context("ip", IP_ADDRESS)
.context("language", LANGUAGE)
.context("userAgent", USER_AGENT)
.context("Intercom", INTERCOM)
.context("nullable", null)
);
service.group(USER_ID, GROUP_ID) {
traits(
category: CATEGORY,
section : SECTION,
nullable: null
)
timestamp INSTANT_NOW
anonymousId ANONYMOUS_ID
integrationOptions 'Google Analytics', [clientId: GOOGLE_ANALYTICS_ID]
enableIntegration 'Something Enabled', true
enableIntegration 'Something Disabled', false
context(
ip: IP_ADDRESS,
language: LANGUAGE,
userAgent: USER_AGENT,
Intercom: INTERCOM,
nullable: null
)
}
4.1.3. Identification
You can identify users with their traits.
See the documentation for the further information.
service.identify(USER_ID, b -> b
.traits("category", CATEGORY)
.traits("nullable", null)
.timestamp(now)
.anonymousId(ANONYMOUS_ID)
.messageId(MESSAGE_ID)
.integrationOptions("Google Analytics", "clientId", GOOGLE_ANALYTICS_ID)
.enableIntegration("Something Enabled", true)
.enableIntegration("Something Disabled", false)
.context("ip", IP_ADDRESS)
.context("language", LANGUAGE)
.context("userAgent", USER_AGENT)
.context("Intercom", INTERCOM)
.context("nullable", null)
);
service.identify(USER_ID) {
traits(
category: CATEGORY,
nullable: null
)
timestamp INSTANT_NOW
anonymousId ANONYMOUS_ID
integrationOptions 'Google Analytics', [clientId: GOOGLE_ANALYTICS_ID]
enableIntegration 'Something Enabled', true
enableIntegration 'Something Disabled', false
context(
ip: IP_ADDRESS,
language: LANGUAGE,
userAgent: USER_AGENT,
Intercom: INTERCOM,
nullable: null
)
}
4.1.4. Page Views
You can record page view by the user with additional properties.
See the documentation for the further information.
service.page(USER_ID, NAME, b -> b
.properties("category", CATEGORY)
.properties("section", SECTION)
.properties("nullable", null)
.timestamp(now)
.anonymousId(ANONYMOUS_ID)
.messageId(MESSAGE_ID)
.integrationOptions("Google Analytics", "clientId", GOOGLE_ANALYTICS_ID)
.enableIntegration("Something Enabled", true)
.enableIntegration("Something Disabled", false)
.context("ip", IP_ADDRESS)
.context("language", LANGUAGE)
.context("userAgent", USER_AGENT)
.context("Intercom", INTERCOM)
.context("nullable", null)
);
service.page(USER_ID, NAME) {
properties(
category: CATEGORY,
section: SECTION,
nullable: null
)
timestamp INSTANT_NOW
anonymousId ANONYMOUS_ID
integrationOptions 'Google Analytics', [clientId: GOOGLE_ANALYTICS_ID]
enableIntegration 'Something Enabled', true
enableIntegration 'Something Disabled', false
context(
ip: IP_ADDRESS,
language: LANGUAGE,
userAgent: USER_AGENT,
Intercom: INTERCOM,
nullable: null
)
}
4.1.5. Screen Views
You can record screen view by the user with additional properties.
See the documentation for the further information.
service.screen(USER_ID, NAME, b -> b
.properties("category", CATEGORY)
.properties("section", SECTION)
.properties("nullable", null)
.timestamp(now)
.anonymousId(ANONYMOUS_ID)
.messageId(MESSAGE_ID)
.integrationOptions("Google Analytics", "clientId", GOOGLE_ANALYTICS_ID)
.enableIntegration("Something Enabled", true)
.enableIntegration("Something Disabled", false)
.context("ip", IP_ADDRESS)
.context("language", LANGUAGE)
.context("userAgent", USER_AGENT)
.context("Intercom", INTERCOM)
.context("nullable", null)
);
service.screen(USER_ID, NAME) {
properties(
category: CATEGORY,
section: SECTION,
nullable: null
)
timestamp INSTANT_NOW
anonymousId ANONYMOUS_ID
integrationOptions 'Google Analytics', [clientId: GOOGLE_ANALYTICS_ID]
enableIntegration 'Something Enabled', true
enableIntegration 'Something Disabled', false
context(
ip: IP_ADDRESS,
language: LANGUAGE,
userAgent: USER_AGENT,
Intercom: INTERCOM,
nullable: null
)
}
4.1.6. Tracking Events
You can track user events with additional properties.
See the documentation for the further information.
service.track(USER_ID, EVENT, b -> b
.properties("category", CATEGORY)
.properties("section", SECTION)
.properties("nullable", null)
.timestamp(now)
.anonymousId(ANONYMOUS_ID)
.messageId(MESSAGE_ID)
.integrationOptions("Google Analytics", "clientId", GOOGLE_ANALYTICS_ID)
.enableIntegration("Something Enabled", true)
.enableIntegration("Something Disabled", false)
.context("ip", IP_ADDRESS)
.context("language", LANGUAGE)
.context("userAgent", USER_AGENT)
.context("Intercom", INTERCOM)
.context("nullable", null)
);
service.track(USER_ID, EVENT) {
properties(
category: CATEGORY,
section : SECTION,
nullable: null
)
timestamp INSTANT_NOW
anonymousId ANONYMOUS_ID
integrationOptions 'Google Analytics', [clientId: GOOGLE_ANALYTICS_ID]
enableIntegration 'Something Enabled', true
enableIntegration 'Something Disabled', false
context(
ip: IP_ADDRESS,
language: LANGUAGE,
userAgent: USER_AGENT,
Intercom: INTERCOM,
nullable: null
)
}
4.2. Customization
You can declare message transformers and interceptors. They are only taken into account when the real implementation is used. They are ignored when no-op implementation is used.
4.2.1. Message Transformation
You can declare MessageTransformer
beans to change the payload before sending. Here is the example of transformer which adds default value if not present:
import com.segment.analytics.MessageTransformer;
import com.segment.analytics.messages.Message;
import com.segment.analytics.messages.MessageBuilder;
import jakarta.inject.Singleton;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Sets the default context value if missing.
*/
@Singleton
public class DefaultContextMessageTransformer implements MessageTransformer {
@Override
@SuppressWarnings("unchecked")
public boolean transform(MessageBuilder builder) {
Message message = builder.build();
Map<String, ?> context = message.context();
if (context == null) {
builder.context(Collections.singletonMap("FromTransformer", "Value"));
return true;
}
if (!context.containsKey("FromTransformer")) {
Map<String, Object> newContext = new LinkedHashMap<>(context);
newContext.put("FromTransformer", "Value");
builder.context(newContext);
}
return true;
}
}
4.2.2. Message Interceptors
You can declare MessageInterceptor
beans to intercept sending of the messages. Here is an example of the interceptor which holds the latest message sent:
import com.segment.analytics.MessageInterceptor;
import com.segment.analytics.messages.Message;
import jakarta.inject.Singleton;
/**
* Keeps the reference to the last message.
*/
@Singleton
public class LastMessageHolder implements MessageInterceptor {
private Message lastMessage;
public Message getLastMessage() {
return lastMessage;
}
@Override
public Message intercept(Message message) {
this.lastMessage = message;
return message;
}
}
5. Bugs
To report any bug, please, use the project issues section on GitHub.