Hey There! I have a question about merging an anon...
# support
a
Hey There! I have a question about merging an anonymous user from one source with an identified user from another so that we can reconcile attribution across the two profiles (ideally these are also merged in the other destinations as well posthog, snowflake, customerio, etc) • Anonymous User comes and performs an event in source 1 • Later, this same user converts and is identified via source 2 • Because of a limitation that's outside of our control, we'd like to run a script nightly that merges the two identities together • I'm trying an alias call in which the previousId field = anonymousId from source one and the newId field = userId from source 2, but doesn't seem to be working Is the above possible? If so, any suggestions on how to accomplish if the above isn't correct? (currently on the free hosted plan)
m
Hey There! 👋 Your message has been received by the RudderStack team. We will forward this request to your Technical Account Manager, and they will get back to you shortly. Please use the thread for any additional comments.
a
When can I expect a response or support to reach out?
s
Hey Hi @average-monkey-86292 so I am assuming that First source is your website, Second source is your app • Where are you creating the Alias call? • What is the destination you are using since the Alias call merging happens in the destination. • We internally do identity resolution in this case (in the warehouse), where we try to find all the events that can be mapped to a single user. This may help you find some answers since it is similar to your usecase.
a
@shy-kite-21035 So, I figured out what the problem is but still unsure of the best way to fix it. The affected destination was PostHog running in device mode. I assumed that it would use RudderStack's anonymous ID as their anonymous ID, but it doesn't - it creates a new one which causes broken identities. So, the only solution for retroactive fix is to run alias calls for those affected users with the posthog SDK. Forward looking, is there any way you can recommend to force posthog to use rudderstack's anonymous ID when it's running in device mode?
m
Yes Rudderstack does not meddle in how Posthog in device mode sends the anonymousId. No there is a way in which you can use the Posthog id as the Anonymous id, but not sure if you can do the opposite. You can set the rudderstack anonymousId as that coming from Posthog using something like this
Copy code
rudderanalytics.setAnonymousId("my-anonymous-id");
a
@shy-kite-21035 anyway to figure out if it’s possible to pass to posthog? This pretty much makes the destination useless and other folks here have run into the same issue
m
Hi @Philip this ability to set an anonymous Id has to be provided by PostHog and we cannot over-write PostHog SDK logic, unless they provides this ability to set an anonymous Id.
a
@shy-kite-21035 you can just call the posthog identify function using the rudderstack anon ID. would love to see this pitfall added to the docs and the recommended workaround included as well for anyone else struggling with this
m
Oh ok. Thanks for pointing this out. Will get this added to the docs.
a
@shy-kite-21035 hey just wanted to follow up on this! Turns out Alias is actually the right way to fix this vs identify. Here's some code I wrote that works for us in case helpful:
Copy code
function resolveIDs() {
  return new Promise((resolve, reject) => {
    const maxRetries = 5; 
    let retries = 0;

    function checkAndResolve() {
      rudderanalytics.ready(() => {
        const rudderID = rudderanalytics.getAnonymousId();

        // If posthog is loaded, check the ID
        if (window.posthog && posthog.__loaded) {
          const posthogID = posthog.get_distinct_id();

          if (rudderID === posthogID) {
            resolve(rudderID); // Resolve if the IDs match
          } else {
            // Placeholder block for when the IDs are different
            // posthog.identify(rudderID);
            posthog.alias(posthogID, rudderID);
			console.log('identified');
            resolve({posthogID: posthogID, rudderID: rudderID})
          }
        } else if (retries < maxRetries) {
          // If posthog isn't loaded yet, retry after 3 seconds
          retries++;
          setTimeout(checkAndResolve, 3000);
        } else if (rudderID) {
          // If max retries reached and posthog isn't loaded, resolve with rudderID
          resolve(rudderID);
        } else {
          reject(new Error("Anonymous ID not found"));
        }
      });
    }

    checkAndResolve();
  });
}

async function main() {
  try {
    await resolveIDs();
    
  } catch (error) {
    console.error(error);
  }
}

main();
m
Oh ok. Thanks for sharing this. It could be helpful to other customers