如何将Segment.io服务器和客户端事件连接到同一个匿名用户?

时间:2021-03-30 13:02:37

I'm working on implementing the Segment analytics hub on an existing .NET e-commerce application for use with Mixpanel, among a few other services. I understand the API docs in general for both Analytics.js and the Segment .NET API, but I am confused how to connect anonymous events to the same user.

我正在努力在现有的.NET电子商务应用程序上实现Segment分析中心,以便与其他一些服务中的Mixpanel一起使用。我理解了Analytics.js和Segment .NET API的API文档,但我很困惑如何将匿名事件连接到同一个用户。

For example, say I am tracking that an item is added to the cart. I am doing this server-side, as there are multiple pages that items can be added to the cart but only one controller. A user can do this without logging in, and we are assigning them a customer ID already, so my code looks something like this:

例如,假设我正在跟踪项目是否已添加到购物车中。我正在这个服务器端,因为有多个页面可以将项目添加到购物车但只有一个控制器。用户可以在不登录的情况下执行此操作,并且我们已经为他们分配了客户ID,因此我的代码如下所示:

Analytics.Client.Track(cartItem.CustomerId, "Added Product", new Properties() {
    { "sku", cartItem.Sku },
    { "quantity", quantity }
});

Then, say the user views a product category page. Since this is a relatively trivial action, I am currently doing it client-side, so my code looks something like this:

然后,假设用户查看产品类别页面。由于这是一个相对简单的操作,我目前正在客户端,所以我的代码看起来像这样:

analytics.track('Viewed Product Category', {
    category: '@Model.CategoryName',
    subCategory: '@Model.SubCategoryName'
});

I see in the Analytics.js spec:

我在Analytics.js规范中看到:

You won’t need to call identify for anonymous visitors to your site. We’ll automatically assign them an anonymousId, so just calling page and track will still work just fine without identify.

您无需为您网站的匿名访问者致电身份识别。我们会自动为它们分配一个anonymousId,所以只是调用页面和轨道仍然可以正常工作而无需识别。

My main question is, how do I tell Segment that it was the same (currently anonymous) user that performed both of these actions? As a secondary question, do I need to call Identify before the server-side call, even though the Track call includes a user id?

我的主要问题是,如何告诉Segment它是执行这两个操作的同一个(当前是匿名的)用户?作为次要问题,我是否需要在服务器端呼叫之前呼叫识别,即使Track呼叫包含用户ID?

1 个解决方案

#1


10  

I work at Segment. Tying anonymous activity across client and server-side calls with Segment is tricky, for a few reasons:

我在Segment工作。使用Segment在客户端和服务器端调用之间绑定匿名活动很棘手,原因如下:

  • Segment's server-side libraries are totally stateless and naive to the request context, so it's up to you to grab the relevant information and pass it through in the call to Segment.

    Segment的服务器端库完全没有状态且对请求上下文很幼稚,因此您可以在调用Segment时获取相关信息并将其传递给您。

  • Moreover, on the client, the bundled 3rd party tools you've integrated with will be managing their respective anonymous/session identifiers themselves.

    此外,在客户端上,您集成的捆绑第三方工具将自行管理其各自的匿名/会话标识符。

  • Some server side integrations have a special context field for their anonymous identifier, (like GA), but most don't, so you'll need to write a wrapper that abstracts over the example case below (sending multiple calls with different anonymousIds while dictating which should be sent to which service).

    一些服务器端集成有一个特殊的上下文字段用于他们的匿名标识符(如GA),但大多数没有,所以你需要编写一个包装器,它在下面的示例案例中进行抽象(在发出指令时发送多个不同anonymousIds的调用)应该发送到哪个服务)。

Note: The customerId approach will work if that will remain their unique identifier even after purchase, so that you can always use that as the userId. But it's worth bearing in mind if you intend to use it as an intermediary pseudo-anonymous identifier that not all tools have the ability to alias multiple IDs, so you might not be able to keep cohesive user profiles in all your tools if you take that approach.

注意:如果即使在购买后它仍然是唯一标识符,customerId方法将起作用,因此您始终可以将其用作userId。但是,如果您打算将其用作中间伪匿名标识符,并非所有工具都能够为多个ID设置别名,那么值得记住,因此如果您采用该标识,则可能无法在所有工具中保留内聚的用户配置文件做法。

But accomplishing this effectively in the case when you don't have a de-facto userId (which I imagine will be the case for other folks who arrive @ this question) is really a question of which tools you're using; for each of them, you'll need to grab their respective anonymous identifier off the request (they're typically available in cookies) and attach it to its respective field in the server side call to Segment.

但是如果你没有事实上的userId(我想其他人来到@这个问题的情况就是这种情况),那么有效地完成这个实际上是你正在使用哪些工具的问题;对于它们中的每一个,您需要从请求中获取它们各自的匿名标识符(它们通常在cookie中可用)并将其附加到服务器端对Segment的调用中的相应字段。

Here's how that might look if you're using KISSmetrics, Mixpanel and Google Analytics:

如果您正在使用KISSmetrics,Mixpanel和Google Analytics,这可能会是这样的:

str gaClientId, kmAnonId, mpAnonId;

HttpCookieCollection cookies = Request.Cookies;

//GA clientId is stored as part of the _ga cookie
if (cookies["_ga"] != null)
{
    string gaCookie = Request.Cookies["_ga"];
    string[] parts = gaCookie.Split('.')
    gaClientId = Strint.Format("{0}.{1}", parts[2], parts[3])
}

// KM anonId
if (cookies["km_ai"] != null)
{
    kmAnonId = Request.Cookies["km_ai"];
}

// for brevity, I'll omit retrieving mixpanel distinctId
// from their cookie. You will need to serialize the value of 
// "mp_<acesstoken>_mixpanel" to JSON and take the `distinct_id` value
// see here: http://marcmezzacca.com/integrating-mixpanel-with-asp-net-mvc-server-side-and-javascript-client-side/

Analytics.Model.Options kmCallOptions = new Options()
  .SetIntegration("all", false)
  .SetIntegration("Kissmetrics", true)
  .SetIntegration("Google Analytics", true)
  .SetContext (new Context () {
    { "ip", GetUserIP() },
    { "Google Analytics", new Dict() {
      { "clientId", gaClientId }
    } 
    },
    { "AnonymousId", kmAnonId }
  }
});

Analytics.Model.Options mpCallOptions = new Options()
  .SetIntegration("all", false)
  .SetIntegration("Mixpanel", true)
  .SetContext (new Context () {
    { "ip", GetUserIP() },
    },
    { "AnonymousId", mpAnonId }
  }
});

// Send to KM and GA
Analytics.Client.Track(null, "Added Product", new Properties() {
    { "sku", cartItem.Sku },
    { "quantity", quantity }
}, kmCallOptions);

// Send to Mixpanel
Analytics.Client.Track(null, "Added Product", new Properties() {
    { "sku", cartItem.Sku },
    { "quantity", quantity }
}, mpCallOptions);

One quick note: Segment definitely intends to pave over this headache and make life easier in accomplishing this, but rather than complicating the API to accommodate multiple anonymous identifiers per tool we intend to solve the problem in a manner that obviates the need for that entirely. In the interim, to avoid the complexity, we really recommend keeping all your anonymous tracking in one place, either server-side (using a sessionId or the like for the anonymousId) or (preferably) client side. If you want to mix and match, server side tracking is best reserved for logged in users with a userId.

一个简单的注意事项:Segment肯定打算铺平这种头痛并使生活更容易实现这一点,但不是使API复杂化以适应每个工具的多个匿名标识符,我们打算以完全不需要它的方式解决问题。在此期间,为避免复杂性,我们建议您将所有匿名跟踪保存在一个位置,服务器端(使用sessionId或anonymousId等)或(最好)客户端。如果要混合和匹配,最好为具有userId的登录用户保留服务器端跟踪。

Also, don't ever hesitate to contact support directly @ friends@segment.com!

此外,请不要犹豫直接联系支持@ friends@segment.com!

#1


10  

I work at Segment. Tying anonymous activity across client and server-side calls with Segment is tricky, for a few reasons:

我在Segment工作。使用Segment在客户端和服务器端调用之间绑定匿名活动很棘手,原因如下:

  • Segment's server-side libraries are totally stateless and naive to the request context, so it's up to you to grab the relevant information and pass it through in the call to Segment.

    Segment的服务器端库完全没有状态且对请求上下文很幼稚,因此您可以在调用Segment时获取相关信息并将其传递给您。

  • Moreover, on the client, the bundled 3rd party tools you've integrated with will be managing their respective anonymous/session identifiers themselves.

    此外,在客户端上,您集成的捆绑第三方工具将自行管理其各自的匿名/会话标识符。

  • Some server side integrations have a special context field for their anonymous identifier, (like GA), but most don't, so you'll need to write a wrapper that abstracts over the example case below (sending multiple calls with different anonymousIds while dictating which should be sent to which service).

    一些服务器端集成有一个特殊的上下文字段用于他们的匿名标识符(如GA),但大多数没有,所以你需要编写一个包装器,它在下面的示例案例中进行抽象(在发出指令时发送多个不同anonymousIds的调用)应该发送到哪个服务)。

Note: The customerId approach will work if that will remain their unique identifier even after purchase, so that you can always use that as the userId. But it's worth bearing in mind if you intend to use it as an intermediary pseudo-anonymous identifier that not all tools have the ability to alias multiple IDs, so you might not be able to keep cohesive user profiles in all your tools if you take that approach.

注意:如果即使在购买后它仍然是唯一标识符,customerId方法将起作用,因此您始终可以将其用作userId。但是,如果您打算将其用作中间伪匿名标识符,并非所有工具都能够为多个ID设置别名,那么值得记住,因此如果您采用该标识,则可能无法在所有工具中保留内聚的用户配置文件做法。

But accomplishing this effectively in the case when you don't have a de-facto userId (which I imagine will be the case for other folks who arrive @ this question) is really a question of which tools you're using; for each of them, you'll need to grab their respective anonymous identifier off the request (they're typically available in cookies) and attach it to its respective field in the server side call to Segment.

但是如果你没有事实上的userId(我想其他人来到@这个问题的情况就是这种情况),那么有效地完成这个实际上是你正在使用哪些工具的问题;对于它们中的每一个,您需要从请求中获取它们各自的匿名标识符(它们通常在cookie中可用)并将其附加到服务器端对Segment的调用中的相应字段。

Here's how that might look if you're using KISSmetrics, Mixpanel and Google Analytics:

如果您正在使用KISSmetrics,Mixpanel和Google Analytics,这可能会是这样的:

str gaClientId, kmAnonId, mpAnonId;

HttpCookieCollection cookies = Request.Cookies;

//GA clientId is stored as part of the _ga cookie
if (cookies["_ga"] != null)
{
    string gaCookie = Request.Cookies["_ga"];
    string[] parts = gaCookie.Split('.')
    gaClientId = Strint.Format("{0}.{1}", parts[2], parts[3])
}

// KM anonId
if (cookies["km_ai"] != null)
{
    kmAnonId = Request.Cookies["km_ai"];
}

// for brevity, I'll omit retrieving mixpanel distinctId
// from their cookie. You will need to serialize the value of 
// "mp_<acesstoken>_mixpanel" to JSON and take the `distinct_id` value
// see here: http://marcmezzacca.com/integrating-mixpanel-with-asp-net-mvc-server-side-and-javascript-client-side/

Analytics.Model.Options kmCallOptions = new Options()
  .SetIntegration("all", false)
  .SetIntegration("Kissmetrics", true)
  .SetIntegration("Google Analytics", true)
  .SetContext (new Context () {
    { "ip", GetUserIP() },
    { "Google Analytics", new Dict() {
      { "clientId", gaClientId }
    } 
    },
    { "AnonymousId", kmAnonId }
  }
});

Analytics.Model.Options mpCallOptions = new Options()
  .SetIntegration("all", false)
  .SetIntegration("Mixpanel", true)
  .SetContext (new Context () {
    { "ip", GetUserIP() },
    },
    { "AnonymousId", mpAnonId }
  }
});

// Send to KM and GA
Analytics.Client.Track(null, "Added Product", new Properties() {
    { "sku", cartItem.Sku },
    { "quantity", quantity }
}, kmCallOptions);

// Send to Mixpanel
Analytics.Client.Track(null, "Added Product", new Properties() {
    { "sku", cartItem.Sku },
    { "quantity", quantity }
}, mpCallOptions);

One quick note: Segment definitely intends to pave over this headache and make life easier in accomplishing this, but rather than complicating the API to accommodate multiple anonymous identifiers per tool we intend to solve the problem in a manner that obviates the need for that entirely. In the interim, to avoid the complexity, we really recommend keeping all your anonymous tracking in one place, either server-side (using a sessionId or the like for the anonymousId) or (preferably) client side. If you want to mix and match, server side tracking is best reserved for logged in users with a userId.

一个简单的注意事项:Segment肯定打算铺平这种头痛并使生活更容易实现这一点,但不是使API复杂化以适应每个工具的多个匿名标识符,我们打算以完全不需要它的方式解决问题。在此期间,为避免复杂性,我们建议您将所有匿名跟踪保存在一个位置,服务器端(使用sessionId或anonymousId等)或(最好)客户端。如果要混合和匹配,最好为具有userId的登录用户保留服务器端跟踪。

Also, don't ever hesitate to contact support directly @ friends@segment.com!

此外,请不要犹豫直接联系支持@ friends@segment.com!