# How the Intercom Integration Powers User Support in Maybe

> Learn how Maybe Finance integrates Intercom for user support. Discover how the intercom-rails gem, Rails initializer, and Stimulus controller streamline customer service.

- Repository: [Maybe/maybe](https://github.com/maybe-finance/maybe)
- Tags: architecture
- Published: 2026-03-07

---

**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`](https://github.com/maybe-finance/maybe/blob/main/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:

```ruby
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:

```ruby
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`](https://github.com/maybe-finance/maybe/blob/main/app/javascript/controllers/intercom_controller.js).

### The Intercom Controller

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

```javascript
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:

```erb
<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`](https://github.com/maybe-finance/maybe/blob/main/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`](https://github.com/maybe-finance/maybe/blob/main/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`](https://github.com/maybe-finance/maybe/blob/main/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.