Go Source Library
How it works
Our Go library helps you record source events from your server-side code. This lets your Go-based app send requests to our servers, and we route your data to your cloud-mode destinations.
Like our other libraries, you can log anonymous activity with an anonymousId
. When you identify
a person, you can pass the anonymousId
and we’ll associate the anonymous activity with the identified person.
This library uses a configurable buffer to batch messages, optimized to reduce network activity.
Getting Started
Go to the tab and click Sources.
Click Add Source and pick Go.
Give the source a Name and click Complete Setup. The name is simply a friendly name to help you find and recognize your source in Customer.io.
Install
analytics-go
usinggo get
:go get github.com/customerio/cdp-analytics-go
Import the library and initialize an instance with your source’s API Key. You’ll find your key in your source’s Settings tab.
package main import ( "os" "github.com/customerio/cdp-analytics-go" ) func main() { client := analytics.New("YOUR_API_KEY") // Use the client. // Flush queued messages and close the client. defer client.Close() }
This creates a
client
that you can use to send data to Data Pipelines. The client uses our default, production settings but you can tune these settings to fit your need. While you develop your integration, you may want to use development settings so it’s easier to test and debug your work!
Now you’re ready to send requests to Customer.io. Check out our API reference, or read further to see example requests and understand the types of requests you can make using our Go library.
Identify
The identify
method tells Data Pipelines who the current website visitor is, and lets you assign unique traitsA key-value pair that you associate with a person or an object—like a person’s name, the date they were created in your workspace, or a company’s billing date etc. Use attributes to target people and personalize messages. to a person.
You should call identify
when a user creates an account, logs in, etc. You can also call it again whenever a person’s traits change. We’ve shown a typical call with a traits
object, but we’ve listed all the fields available in an identify
call below.
You can send an identify call with an anonymousId
and/or userId
.
anonymousId
only: This assign traits to a person before you know who they are.userId
only: Identifies a user and sets traits.- both
userId
andanonymousId
: Associates the data sent in previous anonymouspage
,track
, andidentify
calls with the person you identify byuserId
.
client.Enqueue(analytics.Identify{
UserId: "019mr8mf4r",
Traits: analytics.NewTraits().
SetName("Cool Person").
SetEmail("cool.person@example.com").
Set("plan", "Enterprise").
Set("fav_number", 42),
})
In most cases, you’ll simply provide userId
, anonymousId
, and traits
, but we’ve provided the full list of writable-fields below. You’ll find the complete source payload in our API documentation.
- anonymousId stringA unique substitute for a User ID in cases when you don’t have an absolutely unique identifier. Our libraries generate this value automatically to help you track people before they sign up, log in, provide their email, etc.
-
- active boolean
Whether a user is active.
This is usually used to flag an .identify() call to just update the traits but not “last seen.”
- channel stringThe channel the event originated from.
Accepted values:
browser
,server
,mobile
- ip stringThe user’s IP address. This isn’t captured by our libraries, but by our servers when we receive client-side events (like from our JavaScript source).
- locale stringThe local string for the current user, e.g.
en-US
. - userAgent stringThe user agent of the device making the request
-
- content string
- medium stringThe type of traffic a person/event originates from, like
email
, orreferral
. - name stringThe campaign name.
- source stringThe source of traffic—like the name of your email list, Facebook, Google, etc.
- term stringThe keyword term(s) a user came from.
- Additional UTM Parameters* string
-
- keywords array of [ strings ]A list/array of keywords describing the page’s content. The keywords are likely the same as, or similar to, the keywords you would find in an HTML
meta
tag for SEO purposes. This property is mainly used by content publishers that rely heavily on pageview tracking. This isn’t automatically collected. - name stringThe name of the page. Reserved for future use.
- path stringThe path portion of the page’s URL. Equivalent to the canonical
path
which defaults tolocation.pathname
from the DOM API. - referrer stringThe previous page’s full URL. Equivalent to
document.referrer
from the DOM API. - search stringThe query string portion of the page’s URL. Equivalent to
location.search
from the DOM API. - title stringThe page’s title. Equivalent to
document.title
from the DOM API. - url stringA page’s full URL. Segment first looks for the canonical URL. If the canonical URL is not provided, Segment uses
location.href
from the DOM API.
-
- Enabled/Disabled integrations* boolean
- messageId stringA unique identifier for a Data Pipelines event, ensuring that each individual event is unique.
- receivedAt string (date-time)The ISO-8601 timestamp when Data Pipelines receives an event.
- sentAt string (date-time)The ISO-8601 timestamp when a library sends an event to Data Pipelines.
- timestamp string (date-time)The ISO-8601 timestamp when the event originally took place. This is mostly useful when you backfill data past events. If you’re not backfilling data, you can leave this field empty and we’ll use the current time or server time.
-
- createdAt string (date-time)We recommend that you pass date-time values as ISO 8601 date-time strings. We convert this value to fit destinations where appropriate.
- email stringA person’s email address. In some cases, you can pass an empty
userId
and we’ll use this value to identify a person. - Additional Traits* anyTraits that you want to set on a person. These can take any JSON shape.
- type stringThe event type. This is set automatically by the request method/endpoint.
Accepted values:
identify
- userId stringThe unique identifier for a person. This value should be unique across systems, so you recognize the same person in your sources and destinations.
- version numberThe version of the API that received the event, automatically set by Customer.io.
Track
The track
method tells us about actions people take—the events people perform—on your site. Every track
call represents an event. When you send an event with a track
call, you can provide associated properties about the event. For more information, see the track method reference.
You should track events that are indicators on your site, or the kinds of things that you want to know that your audience does on your website, like Video Viewed, Item Purchased or Article Bookmarked. In some products—like Customer.io Journeys—you can use events to trigger messages and other downstream actions.
You can send events with an anonymousId
or a userId
. Calls that you make with an anonymousId
are associated with a userId
when you identify
someone by their userId
.
Track calls typically contain an event
name—so you know what a user did—and a series of properties
, which contain additional information about the event. The examples below show added_to_cart
events, containing properties that let you know about the product
a person added to their shopping cart.
client.Enqueue(analytics.Track{
UserId: "f4ca124298",
Event: "added_to_cart",
Properties: analytics.NewProperties().
Set("product", "shoes"),
Set("price", 39.95),
})
client.Enqueue(analytics.Track{
anonymousId: "48d213bb-95c3-4f8d-af97-86b2b404dcfe",
Event: "added_to_cart",
Properties: analytics.NewProperties().
Set("product", "shoes"),
Set("price", 39.95),
})
In most cases, you’ll simply provide an ID for the user, the event
, and properties
, but we’ve provided the full list of writable-fields below. You’ll find the complete source payload in our API documentation.
-
- active boolean
Whether a user is active.
This is usually used to flag an .identify() call to just update the traits but not “last seen.”
- channel stringThe channel the event originated from.
Accepted values:
browser
,server
,mobile
- ip stringThe user’s IP address. This isn’t captured by our libraries, but by our servers when we receive client-side events (like from our JavaScript source).
- locale stringThe local string for the current user, e.g.
en-US
. - userAgent stringThe user agent of the device making the request
-
- content string
- medium stringThe type of traffic a person/event originates from, like
email
, orreferral
. - name stringThe campaign name.
- source stringThe source of traffic—like the name of your email list, Facebook, Google, etc.
- term stringThe keyword term(s) a user came from.
- Additional UTM Parameters* string
-
- keywords array of [ strings ]A list/array of keywords describing the page’s content. The keywords are likely the same as, or similar to, the keywords you would find in an HTML
meta
tag for SEO purposes. This property is mainly used by content publishers that rely heavily on pageview tracking. This isn’t automatically collected. - name stringThe name of the page. Reserved for future use.
- path stringThe path portion of the page’s URL. Equivalent to the canonical
path
which defaults tolocation.pathname
from the DOM API. - referrer stringThe previous page’s full URL. Equivalent to
document.referrer
from the DOM API. - search stringThe query string portion of the page’s URL. Equivalent to
location.search
from the DOM API. - title stringThe page’s title. Equivalent to
document.title
from the DOM API. - url stringA page’s full URL. Segment first looks for the canonical URL. If the canonical URL is not provided, Segment uses
location.href
from the DOM API.
- event stringRequired The name of the event
-
- Enabled/Disabled integrations* boolean
- messageId stringA unique identifier for a Data Pipelines event, ensuring that each individual event is unique.
-
- Event Properties* anyAdditional properties that you want to capture in the event. These can take any JSON shape.
- receivedAt string (date-time)The ISO-8601 timestamp when Data Pipelines receives an event.
- sentAt string (date-time)The ISO-8601 timestamp when a library sends an event to Data Pipelines.
- timestamp string (date-time)The ISO-8601 timestamp when the event originally took place. This is mostly useful when you backfill data past events. If you’re not backfilling data, you can leave this field empty and we’ll use the current time or server time.
- type stringRequired The event type. This is set automatically by the request method/endpoint.
Accepted values:
track
- userId stringRequired The unique identifier for a person. This value should be unique across systems, so you recognize the same person in your sources and destinations.
- version numberThe version of the API that received the event, automatically set by Customer.io.
Page
The Page method records page views on your website, along with optional extra information about the page a person visited.
If you’re using Customer.io’s client-side set up in combination with the Go library, page calls are already tracked for you by default on any page that loads the client-side script.
But, if you have a single page app or you don’t use our JavaScript client library on your website, you’ll need to send your own page calls.
client.Enqueue(analytics.Page{
UserId: "f4ca124298",
Name: "Customer.io CDP",
Category: "Docs",
Properties: analytics.NewProperties().
SetURL("https://customer.io/docs/cdp/"),
})
In most cases, you’ll simply provide an ID for the user and the page name
, but we’ve provided the full list of writable-fields below. You’ll find the complete source payload in our API documentation.
-
- active boolean
Whether a user is active.
This is usually used to flag an .identify() call to just update the traits but not “last seen.”
- channel stringThe channel the event originated from.
Accepted values:
browser
,server
,mobile
- ip stringThe user’s IP address. This isn’t captured by our libraries, but by our servers when we receive client-side events (like from our JavaScript source).
- locale stringThe local string for the current user, e.g.
en-US
. - userAgent stringThe user agent of the device making the request
-
- content string
- medium stringThe type of traffic a person/event originates from, like
email
, orreferral
. - name stringThe campaign name.
- source stringThe source of traffic—like the name of your email list, Facebook, Google, etc.
- term stringThe keyword term(s) a user came from.
- Additional UTM Parameters* string
-
- keywords array of [ strings ]A list/array of keywords describing the page’s content. The keywords are likely the same as, or similar to, the keywords you would find in an HTML
meta
tag for SEO purposes. This property is mainly used by content publishers that rely heavily on pageview tracking. This isn’t automatically collected. - name stringThe name of the page. Reserved for future use.
- path stringThe path portion of the page’s URL. Equivalent to the canonical
path
which defaults tolocation.pathname
from the DOM API. - referrer stringThe previous page’s full URL. Equivalent to
document.referrer
from the DOM API. - search stringThe query string portion of the page’s URL. Equivalent to
location.search
from the DOM API. - title stringThe page’s title. Equivalent to
document.title
from the DOM API. - url stringA page’s full URL. Segment first looks for the canonical URL. If the canonical URL is not provided, Segment uses
location.href
from the DOM API.
-
- Enabled/Disabled integrations* boolean
- messageId stringA unique identifier for a Data Pipelines event, ensuring that each individual event is unique.
- name stringRequired The name of the page.
-
- category stringThe category of the page. This might be useful if you have a single page routes or have a flattened URL structure.
- Page Properties* anyAdditional properties tha tyou want to send with the page event. By default, we capture `url`, `title`, and stuff.
- receivedAt string (date-time)The ISO-8601 timestamp when Data Pipelines receives an event.
- sentAt string (date-time)The ISO-8601 timestamp when a library sends an event to Data Pipelines.
- timestamp string (date-time)The ISO-8601 timestamp when the event originally took place. This is mostly useful when you backfill data past events. If you’re not backfilling data, you can leave this field empty and we’ll use the current time or server time.
- type stringRequired The event type. This is set automatically by the request method/endpoint.
Accepted values:
page
- userId stringRequired The unique identifier for a person. This value should be unique across systems, so you recognize the same person in your sources and destinations.
- version numberThe version of the API that received the event, automatically set by Customer.io.
Group
The Group method associates an identified person with a group—like a company, organization, project, online class or any other collective noun you come up with for the same concept. In Customer.io Journeys, we call groups objectsNot to be confused with a JSON object, an object in Customer.io is a non-person entity that you can associate with one or more people—like a company, account, or online course. You can use objects to message people based on changes to their company, account, or colege course itinerary..
Group calls are useful for destinations where you maintain relationships between people and larger organizations, like in Customer.io! In Customer.io Journeys, you can store groups as objectsNot to be confused with a JSON object, an object in Customer.io is a non-person entity that you can associate with one or more people—like a company, account, or online course. You can use objects to message people based on changes to their company, account, or colege course itinerary., and trigger campaigns based on a person’s relationship to an object—like an account, online class, and so on.
Find more details about group
, including the group
payload, in our API spec.
client.Enqueue(analytics.Group{
UserId: "019mr8mf4r",
GroupId: "56",
Traits: map[string]interface{}{
"name": "Initech",
"description": "Accounting Software",
},
})
In most cases, you’ll simply provide an ID for the user, the groupId
, and traits
, but we’ve provided the full list of writable-fields below. You’ll find the complete source payload in our API documentation.
-
- active boolean
Whether a user is active.
This is usually used to flag an .identify() call to just update the traits but not “last seen.”
- channel stringThe channel the event originated from.
Accepted values:
browser
,server
,mobile
- ip stringThe user’s IP address. This isn’t captured by our libraries, but by our servers when we receive client-side events (like from our JavaScript source).
- locale stringThe local string for the current user, e.g.
en-US
. - userAgent stringThe user agent of the device making the request
-
- content string
- medium stringThe type of traffic a person/event originates from, like
email
, orreferral
. - name stringThe campaign name.
- source stringThe source of traffic—like the name of your email list, Facebook, Google, etc.
- term stringThe keyword term(s) a user came from.
- Additional UTM Parameters* string
-
- keywords array of [ strings ]A list/array of keywords describing the page’s content. The keywords are likely the same as, or similar to, the keywords you would find in an HTML
meta
tag for SEO purposes. This property is mainly used by content publishers that rely heavily on pageview tracking. This isn’t automatically collected. - name stringThe name of the page. Reserved for future use.
- path stringThe path portion of the page’s URL. Equivalent to the canonical
path
which defaults tolocation.pathname
from the DOM API. - referrer stringThe previous page’s full URL. Equivalent to
document.referrer
from the DOM API. - search stringThe query string portion of the page’s URL. Equivalent to
location.search
from the DOM API. - title stringThe page’s title. Equivalent to
document.title
from the DOM API. - url stringA page’s full URL. Segment first looks for the canonical URL. If the canonical URL is not provided, Segment uses
location.href
from the DOM API.
- groupId stringRequired ID of the group
-
- Enabled/Disabled integrations* boolean
- messageId stringA unique identifier for a Data Pipelines event, ensuring that each individual event is unique.
- receivedAt string (date-time)The ISO-8601 timestamp when Data Pipelines receives an event.
- sentAt string (date-time)The ISO-8601 timestamp when a library sends an event to Data Pipelines.
- timestamp string (date-time)The ISO-8601 timestamp when the event originally took place. This is mostly useful when you backfill data past events. If you’re not backfilling data, you can leave this field empty and we’ll use the current time or server time.
-
- Group Traits* any
- type stringRequired The event type. This is set automatically by the request method/endpoint.
Accepted values:
group
- userId stringRequired The unique identifier for a person. This value should be unique across systems, so you recognize the same person in your sources and destinations.
- version numberThe version of the API that received the event, automatically set by Customer.io.
Alias
The Alias method combines two previously unassociated user identities. Some destinations automatically reconcile profiles with different identifiers based on whether you send anonymousId
, userId
, or another trait that the destination expects to be unique. But for destinations that don’t, you may need to send alias
requests to do this.
In general, you won’t need to use the alias
call; we try to handle user identification gracefully, so that you don’t need to merge profiles. But you may need to send alias
calls to manage user identities in some destinations.
For example, in Mixpanel it’s used to associate an anonymous user with an identified user once they sign up.
Here’s how you might use the alias
call. In this case, we start with an anonymous_user
and switch to an email address when a person provides their userId
.
// the anonymous user does actions ...
client.Enqueue(analytics.Track{
Event: "Anonymous Event",
UserId: anonymousUser,
})
// the anonymous user signs up and is aliased
client.Enqueue(analytics.Alias{
PreviousId: anonymousUser,
UserId: "019mr8mf4r",
})
// the identified user is identified
client.Enqueue(analytics.Identify{
UserId: "019mr8mf4r",
Traits: map[string]interface{}{
"name": "Michael Bolton",
"email": "mbolton@example.com",
"plan": "Enterprise",
"friends": 42,
},
})
// the identified user does actions ...
client.Enqueue(analytics.Track{
Event: "Item Viewed",
UserId: "019mr8mf4r",
Properties: map[string]interface{}{
"item": "lamp",
},
})
- previousId stringRequired The userId that you want to merge into the canonical profile.
- userId stringRequired The userId that you want to keep. This is required if you haven’t already identified someone with one of our web or server-side libraries.
Development settings
While implementing Data Pipelines, you might want to make our library flush after every outgoing call. This can help you test your implementation and make sure that all of your calls work properly before you use this library in your production environment.
Set the BatchSize
field in your configuration to 1 to make the library flush every after each request, so that you can make sure your calls are working properly.
func main() {
client, _ := analytics.NewWithConfig("YOUR_API_KEY", analytics.Config{
BatchSize: 1,
})
}
Logging
The Verbose
field of your configuration controls the level of logging, while the Logger
field provides a hook to capture the log output:
func main() {
client, _ := analytics.NewWithConfig("YOUR_API_KEY", analytics.Config{
Verbose: true,
Logger: analytics.StdLogger(log.New(os.Stderr, "customerio ", log.LstdFlags)),
})
}
Selecting Destinations
You can pass an integrations
object to alias
, group
, identify
, page
and track
calls that lets you turn certain destinations on or off. By default all destinations are enabled. Passing false
for an integration disables the call to that destination.
You can also disable destinations in the user interface
If you disable a destination in the UI, you can’t enable a destination through the integrations
object. Disabling an integration in the UI prevents Data Pipelines from sending source data to a destination all together.
You might want to do this for things like alias
calls, which aren’t supported by all destinations.
In this case, Customer.io specifies the track
to only go to Mixpanel. All: false
disables all destinations except the ones you explicitly specify.
client.Enqueue(analytics.Track{
Event: "Membership Upgraded",
UserId: "019mr8mf4r",
Integrations: map[string]interface{}{
"All": false,
"Mixpanel": true,
},
})
Destination flags are case sensitive and match the destination’s name in the docs.
You can filter track calls on the source’s Schema tab
We recommend that you filter events in our UI if you can. It’s easier than writing code, and you can update your source or make changes to your filters without involving developers!
Backfilling historical data
You can backfill data by adding a timestamp
to your calls. This can be helpful if you’ve just switched to Customer.io.
You can only do this for destinations that accept timestamped data—most analytics tools like Mixpanel and Amplitude do. The notable destination that doesn’t support timestampped data is Google Analytics.
Leave out the timestamp if you’re tracking real-time events
If you’re only tracking things as they happen, you can leave the timestamp
out of your calls and we’ll timestamp requests for you.
Context
Context fields provide “context” for the events that you send—things like your app’s version. Our library sets some defined context fields by default, but you can override these fields or set custom context fields in a couple of different ways:
- Globally, for all calls
- At the event/call level
You can set custom context fields—fields outside the ones we’ve defined. You must set custom context in the Extra
field. We’ll automatically inline these properties in the serialized context
structure.
client, _ := analytics.NewWithConfig("h97jamjwbh", analytics.Config{
DefaultContext: &analytics.Context{
App: analytics.AppInfo{
Name: "myapp",
Version: "myappversion",
},
},
})
client.Enqueue(analytics.Identify{
UserId: "019mr8mf4r",
Traits: analytics.NewTraits().
Set("friends", 42),
Context: &analytics.Context{
Extra: map[string]interface{}{
"active": true,
},
},
})
If you added both the global and event-level context changes above, then the identify call under Event-level context above would be serialized to:
{
"type": "identify",
"userId": "019mr8mf4r",
"traits": {
"friends": 42,
},
"context": {
"active": true,
"library": {
"name": "analytics-go",
"version": "3.0.0"
}
}
}
Batching
Our libraries are built to support high performance environments. It’s safe to use this library on a web server that serves hundreds of requests per second.
But every method you invoke does not result in an HTTP request. Instead, we queue requests in memory and then flush them in batches, which allows for more efficient operation.
If batch messages do not arrive in your debugger and don’t throw errors, you may want to slow your script down. We run a message batching loop in a go-routine so if the script runs too quickly it won’t execute network calls before it exits the loop.
By default, our Go source library flushes:
- every 20 messages (control with
FlushAt
) - if 5 seconds has passed since the last flush (control with
FlushAfter
)
There is a maximum of 500KB
per batch request and 32KB
per call. If you don’t want to batch messages, you can turn batching off by setting the flushAt
option to 1
.