How the Intercom Integration Powers User Support in Maybe

Maybe uses the intercom-rails gem to automatically embed Intercom’s messenger and identify authenticated users, configured through a Rails initializer and controlled via a Stimulus controller.

The open-source personal finance application Maybe leverages Intercom to provide contextual user support directly within the interface. The integration combines server-side configuration in Ruby with lightweight client-side JavaScript to deliver personalized messaging while respecting user privacy and environment constraints.

Server-Side Configuration with Intercom-Rails

The backbone of the integration resides in config/initializers/intercom.rb, where the intercom-rails gem is configured to inject the Intercom JavaScript snippet and populate it with user-specific data.

Environment Variables and Security

The initializer requires two critical environment variables to authenticate with Intercom’s API:

  • INTERCOM_APP_ID – Identifies the specific Intercom workspace.
  • INTERCOM_IDENTITY_VERIFICATION_KEY – Enables identity verification to prevent impersonation attacks.

The messenger is explicitly restricted to production environments via config.enabled_environments = ["production"], ensuring that staging or development instances do not trigger live support conversations or pollute analytics.

User Identification and Custom Attributes

Maybe identifies the current user through the global Current.user accessor, configured as a Proc in the initializer:

config.user.current = Proc.new { Current.user }

Beyond standard attributes (email, user ID), the integration transmits custom data to Intercom for richer segmentation:

  • Family ID – Links the user to their household account.
  • Display Name – The user’s preferred name for personalized messaging.
  • Role – The user’s permission level within the family (e.g., admin, member).
  • Connections – Count of linked financial institutions.
  • AI Enabled – Boolean flag indicating access to AI features.

Company Context for Family Accounts

Maybe treats the family unit as a company within Intercom’s data model, allowing support agents to view household-level context:

config.company.current = Proc.new { Current.family }

The company payload includes a custom accounts_count attribute, representing the total number of financial accounts associated with the family. This enables support teams to troubleshoot issues based on account complexity.

Additionally, the configuration explicitly enables the messenger for logged-out visitors via config.include_for_logged_out_users = true, ensuring that prospective users can access help before creating an account.

Client-Side Implementation with Stimulus

While the Rails initializer handles script injection and data payload, user interactions are managed through a dedicated Stimulus controller located at app/javascript/controllers/intercom_controller.js.

The Intercom Controller

The controller provides a minimal wrapper around Intercom’s global JavaScript API:

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  show() {
    Intercom("show")
  }
}

This single show method invokes the standard Intercom command to display the messenger widget.

Triggering the Messenger from Views

Developers can attach the controller to any DOM element using Stimulus data attributes. For example, a help button in an ERB template:

<button
  data-controller="intercom"
  data-action="click->intercom#show"
  class="text-primary bg-container rounded px-4 py-2">
  Need Help?
</button>

This declarative approach keeps JavaScript logic centralized while allowing flexible placement of support triggers throughout the application interface.

Production-Only Deployment Strategy

The integration is architected to remain invisible in non-production environments. By restricting enabled_environments to ["production"], the initializer prevents the Intercom script from loading in development or test modes. This safeguards against accidental data leakage and ensures that support conversations only originate from genuine user sessions.

When running in production, the script automatically initializes with the user and company context defined in the initializer, requiring no additional frontend configuration beyond the Stimulus controller for manual trigger points.

Summary

  • Server-side setup: The intercom-rails gem in config/initializers/intercom.rb configures the Intercom messenger with identity verification, user attributes, and company (family) context.
  • Environment safety: The integration only activates in production environments, controlled via config.enabled_environments.
  • User context: Custom attributes like role, connections count, and AI-enabled status are passed to Intercom through Current.user and Current.family accessors.
  • Frontend control: A minimal Stimulus controller at app/javascript/controllers/intercom_controller.js provides declarative triggers to open the messenger via Intercom("show").

Frequently Asked Questions

What environment variables are required for the Intercom integration?

The integration requires INTERCOM_APP_ID and INTERCOM_IDENTITY_VERIFICATION_KEY to be set in the production environment. These values authenticate the application with your Intercom workspace and enable identity verification to prevent user impersonation.

How does Maybe identify users to Intercom?

Maybe uses the Current.user accessor to supply the current authenticated user to Intercom via a Proc in the initializer. The configuration transmits standard fields (email, user ID) along with custom attributes including family ID, display name, role, financial connections count, and AI feature access status.

Can logged-out visitors use the Intercom messenger?

Yes, the initializer explicitly sets config.include_for_logged_out_users = true, which enables the Intercom messenger for visitors who have not yet authenticated. This allows prospective users to ask questions before creating an account while the production-only restriction prevents the script from loading in development environments.

How is the Intercom messenger triggered from the frontend?

The application uses a Stimulus controller located at app/javascript/controllers/intercom_controller.js that exposes a show method calling Intercom("show"). Developers attach this controller to HTML elements using data-controller="intercom" and data-action="click->intercom#show" attributes, providing a declarative way to open the messenger on user interaction.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →