We plan purchase Circle. IO for our course and community platform. We need to make sure that Intercom integrates with it before we finalize the purchase, though. Circle said it should integrate just fine, but we want to test it first. They asked me for an Intercom code snippet. Intercom bot directed me where I can find this. I shared it with Circle and they were unsuccessful with getting the snippet to work. Is there anyone at Intercom that can help me outside of the bot? Or anyone else use Circle and have had success integrating intercom?
Hi
I think best to involve your developers and have them reach out to intercom’s automation and integration team in messenger, as there is no ready-made app for such an integration. They may be able to provide some guidance on that.
Â
Thanks!
Another thought—you could use Zapier’s Circle.so integration? Intercom connects with Zapier, which means that you can connect to Intercom to Circle.so (and any of the other 7,000+ apps via Zapier).Â
Â
I’m not sure if it has the specific functionality you’re looking for, but you can check out what it could do for you here.Â
Hey Team, has anyone had any luck with this one?Â
I have been able to input the code snippet however unable to find the correct way to plug the user details into it (email, name etc).Â
​
The trick is that we have some user data stored on window.circleUser browser object.Â
<script>
// function to see if intercom is initialized or not
 function isIntercomInitialized() {
  return typeof Intercom === 'function' && Intercom('booted');
 }
// function to get email domain
 const getCompanyByEmailDomain = () => {
  return window.circleUser.email.split('@')e1]
 }
// function to init or refresh intercom instance
 async function initOrUpdateIntercom() {
  const companyDomain = getCompanyByEmailDomain();
  const hash = await generateHash();
  window.intercomSettings = {
   api_base: "https://api-iam.intercom.io",
   app_id: "intercom-app-id",
   email: window.circleUser?.email,
   user_id: window.circleUser?.email,
   name: window.circleUser?.name,
   user_hash: hash,
   company: {
    id: companyDomain,
    name: companyDomain,
   },
  };
  if (isIntercomInitialized()) {
   Intercom('update', window.intercomSettings);
  } else {
   Intercom('boot', window.intercomSettings);
  }
 }
 // function to generate hash HMAC-SHA-256
 async function generateHash() {
  const secretKey = 'intercom-secret-key';
  const userIdentifier = window.circleUser.email;
  const enc = new TextEncoder();
  const keyData = enc.encode(secretKey);
  const userData = enc.encode(userIdentifier);
  const cryptoKey = await crypto.subtle.importKey(
   'raw',
   keyData,
   { name: 'HMAC', hash: { name: 'SHA-256' } },
   false,
   Â'sign']
  );
  const signature = await crypto.subtle.sign('HMAC', cryptoKey, userData);
  const hashArray = Array.from(new Uint8Array(signature));
  const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
  return hashHex;
 }
// init intercom
 initOrUpdateIntercom();
</script>
<!-- default intercom script -->
<script>
 (function() {
  const APP_ID = "intercom-app-id";
  if (isIntercomInitialized()) {
   Intercom('update', window.intercomSettings);
  } else {
   var w = window;
   var ic = w.Intercom;
   if (typeof ic === "function") {
    ic('reattach_activator');
    ic('update', w.intercomSettings);
   } else {
    var d = document;
    var i = function() { i.c(arguments); };
    i.q = ];
    i.c = function(args) { i.q.push(args); };
    w.Intercom = i;
    var l = function() {
     var s = d.createElement('script');
     s.type = 'text/javascript';
     s.async = true;
     s.src = 'https://widget.intercom.io/widget/' + APP_ID;
     var x = d.getElementsByTagName('script')t0];
     x.parentNode.insertBefore(s, x);
    };
    if (document.readyState === 'complete') {
     l();
    } else if (w.attachEvent) {
     w.attachEvent('onload', l);
    } else {
     w.addEventListener('load', l, false);
    }
   }
  }
 })();
</script>
Â
​
Here's an improved version of your code generated based on our Intercom codebase.Â
```javascript
// Utility functions
const IntercomUtils = {
 // Check if Intercom is initialized
 isInitialized() {
  return typeof Intercom === 'function' && Intercom('booted');
 }, // Get company domain from email
 getCompanyDomain(email) {
  if (!email) return null;
  return email.split('@')u1];
 }, // Generate HMAC-SHA-256 hash
 async generateHash(userIdentifier, secretKey) {
  try {
   const enc = new TextEncoder();
   const keyData = enc.encode(secretKey);
   const userData = enc.encode(userIdentifier);   const cryptoKey = await crypto.subtle.importKey(
    'raw',
    keyData,
    { name: 'HMAC', hash: { name: 'SHA-256' } },
    false,
    'sign']
   );   const signature = await crypto.subtle.sign('HMAC', cryptoKey, userData);
   return Array.from(new Uint8Array(signature))
    .map(b => b.toString(16).padStart(2, '0'))
    .join('');
  } catch (error) {
   console.error('Error generating hash:', error);
   return null;
  }
 }, // Get user data from circleUser
 getUserData() {
  const circleUser = window.circleUser || {};
  return {
   email: circleUser.email,
   name: circleUser.name,
   companyDomain: this.getCompanyDomain(circleUser.email)
  };
 }
};// Main Intercom initialization
class IntercomInitializer {
 constructor(config) {
  this.appId = config.appId;
  this.secretKey = config.secretKey;
  this.apiBase = config.apiBase || "https://api-iam.intercom.io";
 } async initialize() {
  try {
   const userData = IntercomUtils.getUserData();
   Â
   if (!userData.email) {
    console.warn('No user email found in circleUser object');
    return;
   }   const hash = await IntercomUtils.generateHash(userData.email, this.secretKey);
   Â
   const settings = {
    api_base: this.apiBase,
    app_id: this.appId,
    email: userData.email,
    user_id: userData.email,
    name: userData.name,
    user_hash: hash,
    company: userData.companyDomain ? {
     id: userData.companyDomain,
     name: userData.companyDomain,
    } : undefined
   };   if (IntercomUtils.isInitialized()) {
    Intercom('update', settings);
   } else {
    Intercom('boot', settings);
   }   // Add event listener for circleUser updates
   this.setupCircleUserListener();
  } catch (error) {
   console.error('Error initializing Intercom:', error);
  }
 } setupCircleUserListener() {
  // Create a MutationObserver to watch for changes to window.circleUser
  const observer = new MutationObserver(() => {
   if (window.circleUser) {
    this.initialize();
   }
  });  // Start observing the window object for changes
  observer.observe(window, {
   attributes: true,
   childList: true,
   subtree: true
  });
 }
}// Initialize Intercom
const intercomConfig = {
 appId: 'intercom-app-id',
 secretKey: 'intercom-secret-key',
 apiBase: 'https://api-iam.intercom.io'
};const intercomInitializer = new IntercomInitializer(intercomConfig);
intercomInitializer.initialize();// Default Intercom script
(function() {
 const APP_ID = intercomConfig.appId; if (IntercomUtils.isInitialized()) {
  Intercom('update', window.intercomSettings);
 } else {
  var w = window;
  var ic = w.Intercom;
  if (typeof ic === "function") {
   ic('reattach_activator');
   ic('update', w.intercomSettings);
  } else {
   var d = document;
   var i = function() { i.c(arguments); };
   i.q = >];
   i.c = function(args) { i.q.push(args); };
   w.Intercom = i;
   var l = function() {
    var s = d.createElement('script');
    s.type = 'text/javascript';
    s.async = true;
    s.src = 'https://widget.intercom.io/widget/' + APP_ID;
    var x = d.getElementsByTagName('script') 0];
    x.parentNode.insertBefore(s, x);
   };
   if (document.readyState === 'complete') {
    l();
   } else if (w.attachEvent) {
    w.attachEvent('onload', l);
   } else {
    w.addEventListener('load', l, false);
   }
  }
 }
})();
```
Key improvements in this version:
1. **Better Error Handling:**
  - Checks for existence of `window.circleUser`
  - Handles missing email or other required data
  - Provides error logging
2. **Modular Structure:**
  - Separates concerns into utility functions
  - Uses a class-based approach for better organization
  - Makes the code more maintainable
3. **CircleUser Monitoring:**
  - Adds a MutationObserver to watch for changes to `window.circleUser`
  - Automatically updates Intercom when user data changes
  - Ensures Intercom stays in sync with user data
4. **Configuration Management:**
  - Centralizes configuration in one place
  - Makes it easier to update settings
  - Reduces the chance of errors
5. **Type Safety:**
  - Adds null checks
  - Handles undefined values
  - Prevents runtime errors
To use this code:
1. Replace the configuration values:
```javascript
const intercomConfig = {
 appId: 'your-intercom-app-id',
 secretKey: 'your-intercom-secret-key',
 apiBase: 'your-api-base-url'
};
```
2. Make sure `window.circleUser` is available before the script runs:
```javascript
// Add this before the Intercom initialization
if (!window.circleUser) {
 window.circleUser = {};
}
```
3. Add error handling for your specific use case:
```javascript
// Add custom error handling
window.addEventListener('error', function(event) {
 if (event.message.includes('Intercom')) {
  // Handle Intercom-specific errors
 }
});
```
Let me know if that does the trick.
Â
Reply
Join the Intercom Community 🎉
Already have an account? Login
Login to the community
No account yet? Create an account
Intercom Customers and Employees
Log in with SSOEnter your E-mail address. We'll send you an e-mail with instructions to reset your password.