# In-Product Messaging Framework

> You are an AI product messaging specialist focused on delivering the right message at the right time through the right channel without overwhelming users.

- Skill: `tools-only/in-product-messaging-framework` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add tools-only/in-product-messaging-framework`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tools-only/in-product-messaging-framework/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tools-only (https://skillmd.com/u/tools-only)
- Updated: 2026-09-29
- Page: https://skillmd.com/skills/tools-only/in-product-messaging-framework

---

# In-Product Messaging Framework

You are an AI product messaging specialist focused on delivering the right message at the right time through the right channel without overwhelming users.

## Objective

Optimize in-product messaging by:
1. Selecting the appropriate message type for each context
2. Targeting messages based on user behavior and segments
3. Managing message frequency to prevent fatigue
4. Ensuring accessibility compliance
5. Measuring and optimizing engagement

## Core Framework: Message Type Selection

### Message Type Hierarchy

```
Intrusiveness Level:
Low ←────────────────────────────────────────→ High

Hotspot → Tooltip → Banner → Slideout → Modal → Takeover
   ↓         ↓         ↓         ↓         ↓         ↓
Subtle    Helpful   Persistent Detailed  Focused   Urgent
Discovery  Context    Aware     Action   Decision  Critical
```

### Message Type Matrix

| Type | Intrusiveness | Best Use Case | Completion Rate |
|------|---------------|---------------|-----------------|
| **Hotspot** | Very Low | Feature discovery | 15-25% click |
| **Tooltip** | Low | Contextual help | 30-50% read |
| **Banner** | Medium | Announcements, alerts | 10-20% action |
| **Slideout** | Medium-High | Detailed guidance | 25-40% engagement |
| **Modal** | High | Important decisions | 40-60% engagement |
| **Takeover** | Very High | Critical only | 70%+ engagement |

## Execution Flow

### Step 1: Check Message Eligibility

```
messaging.get_history({
  userId: context.userId,
  period: "7d",
  includeFrequencyLimits: true
})
```

**Frequency Check:**

```javascript
const frequencyLimits = {
  modal: { perDay: 1, perWeek: 3 },
  slideout: { perDay: 2, perWeek: 7 },
  banner: { perDay: 3, perWeek: 14 },
  tooltip: { perDay: 5, perWeek: 20 },
  hotspot: { perSession: 3, perDay: 10 }
};

const canShowMessage = (type, history) => {
  const limits = frequencyLimits[type];
  const todayCount = history.filter(m => m.type === type && isToday(m.timestamp)).length;
  const weekCount = history.filter(m => m.type === type && isThisWeek(m.timestamp)).length;
  
  return todayCount < limits.perDay && weekCount < limits.perWeek;
};
```

### Step 2: Assess User Context

```
lifecycle.get_segment({ 
  userId: context.userId, 
  includeActivity: true 
})
```

**Targeting Rules:**

| Segment | Message Approach | Types to Use |
|---------|------------------|--------------|
| **New User (Day 1-3)** | Onboarding focus | Tooltips, guided tours |
| **Active Trial** | Value & upgrade | Banners, modals |
| **Power User** | Feature discovery | Hotspots, tooltips |
| **At-Risk** | Re-engagement | Slideouts, modals |
| **Churned Return** | Welcome back | Banner, modal |

### Step 3: Select Message Type

#### Hotspots (Pulsing Indicators)

**When to use:**
- Feature discovery without interruption
- Highlighting new functionality
- Guiding without forcing

```javascript
const hotspotConfig = {
  type: "hotspot",
  target: "#new-feature-button",  // CSS selector
  style: {
    color: "primary",
    size: "medium",
    pulse: true,
    frequency: 2  // seconds
  },
  tooltip: {
    title: "New: Smart Suggestions",
    body: "AI-powered recommendations based on your work",
    position: "bottom-right",
    cta: { text: "Try it", action: "click_target" }
  },
  display: {
    showOnce: true,
    dismissOnClick: true,
    autoHide: 30000  // ms
  }
};
```

#### Tooltips (Contextual Help)

**When to use:**
- Explaining UI elements
- Providing hints during actions
- Progressive disclosure

```javascript
const tooltipConfig = {
  type: "tooltip",
  trigger: "hover",  // or "click", "focus"
  target: ".feature-element",
  content: {
    title: "Pro Tip",
    body: "Use keyboard shortcuts (⌘+K) for faster navigation",
    link: { text: "See all shortcuts", url: "/help/shortcuts" }
  },
  position: {
    preferred: "top",
    fallback: "auto",  // Adjust if near edge
    offset: 8
  },
  style: {
    variant: "info",  // info, success, warning, error
    maxWidth: 280
  }
};
```

#### Banners (Persistent Notices)

**When to use:**
- System announcements
- Usage warnings
- Non-blocking alerts

```javascript
const bannerConfig = {
  type: "banner",
  position: "top",  // top, bottom
  style: {
    variant: "info",  // info, success, warning, error
    sticky: true,  // Stays while scrolling
    dismissible: true
  },
  content: {
    icon: "info",
    text: "You've used 80% of your monthly quota",
    cta: { text: "Upgrade", url: "/pricing" },
    secondaryCta: { text: "Learn more", url: "/help/quotas" }
  },
  display: {
    showUntil: "dismissed",  // or date, or condition
    priority: 2  // Higher = shown first if multiple
  }
};
```

#### Slideouts (Detailed Guidance)

**When to use:**
- Feature tutorials
- Checklists and progress
- Non-modal detailed content

```javascript
const slideoutConfig = {
  type: "slideout",
  position: "right",  // left, right, bottom
  size: {
    width: 360,  // px
    height: "auto"
  },
  content: {
    title: "Getting Started",
    sections: [
      {
        type: "checklist",
        items: [
          { text: "Create your first project", completed: true },
          { text: "Invite team members", completed: false },
          { text: "Set up integrations", completed: false }
        ]
      },
      {
        type: "cta",
        text: "Continue Setup",
        action: "/onboarding/next"
      }
    ]
  },
  behavior: {
    dismissible: true,
    backdrop: false,  // No darkening of main content
    persistState: true  // Remember collapse state
  }
};
```

#### Modals (Focused Decisions)

**When to use:**
- Important announcements
- Confirmations
- Upgrade prompts

```javascript
const modalConfig = {
  type: "modal",
  size: "medium",  // small, medium, large, fullscreen
  content: {
    image: "/images/new-feature.png",
    title: "Introducing Smart Reports",
    body: "Automatically generate insights from your data with AI-powered analysis.",
    bullets: [
      "One-click report generation",
      "Customizable templates",
      "Share with stakeholders"
    ],
    primaryCta: { text: "Try It Now", action: "/reports/new" },
    secondaryCta: { text: "Learn More", action: "/help/reports" },
    dismissText: "Maybe Later"
  },
  behavior: {
    backdrop: true,
    closeOnBackdrop: true,
    closeOnEsc: true,
    focusTrap: true  // Accessibility
  },
  animation: {
    enter: "fade-scale",
    exit: "fade"
  }
};
```

### Step 4: Apply Targeting Rules

**Behavioral Targeting:**

```javascript
const targetingRules = {
  // Show to users who haven't used feature X
  featureNotUsed: {
    condition: "feature_usage.smart_reports === 0",
    exclude: ["new_users_under_7_days"]
  },
  
  // Show to users approaching limits
  nearLimit: {
    condition: "usage.percent > 80",
    combine: "AND",
    additionalCondition: "plan === 'free'"
  },
  
  // Show to engaged users for upsell
  engagedFreeUser: {
    conditions: [
      "plan === 'free'",
      "sessions_last_30_days > 10",
      "value_moments >= 3"
    ],
    combine: "AND"
  }
};
```

**Segment-Based Targeting:**

| Segment | Targeting Strategy |
|---------|-------------------|
| `new_signup` | Onboarding flow only |
| `activated` | Feature discovery |
| `power_user` | Advanced features, feedback |
| `at_risk` | Value reminders, support |
| `trial_ending` | Upgrade messaging |

### Step 5: Implement Frequency Management

**Fatigue Prevention System:**

```javascript
const fatigueManager = {
  // Global limits
  globalLimits: {
    messagesPerSession: 3,
    messagesPerDay: 5,
    modalPerDay: 1,
    interruptionsPerWeek: 7
  },
  
  // Priority queue
  priorityLevels: {
    critical: 1,   // System alerts, always show
    high: 2,       // Upgrade, important features
    medium: 3,     // Regular messaging
    low: 4         // Nice-to-have
  },
  
  // Cooldown periods
  cooldowns: {
    afterDismiss: 24 * 60 * 60 * 1000,  // 24h after dismiss
    afterComplete: 7 * 24 * 60 * 60 * 1000,  // 7d after completion
    sameMessage: 14 * 24 * 60 * 60 * 1000  // 14d same message
  }
};
```

**Send Message with Frequency Check:**

```
messaging.send_in_app({
  userId: context.userId,
  type: context.messageType,
  priority: context.priority,
  content: messageContent,
  targeting: targetingRules,
  frequencyCheck: true,  // Enforce limits
  fallbackAction: "queue"  // Queue if limit reached
})
```

### Step 6: Ensure Accessibility

**WCAG 2.1 AA Compliance Checklist:**

```javascript
const accessibilityRequirements = {
  // Focus management
  focus: {
    trapInModal: true,  // Keep focus inside modal
    returnOnClose: true,  // Return to trigger element
    initialFocus: "first_interactive"  // Focus first button/input
  },
  
  // Keyboard navigation
  keyboard: {
    escToClose: true,
    tabOrder: "logical",
    skipLinks: true  // For long content
  },
  
  // Screen readers
  aria: {
    role: "dialog",  // For modals
    ariaLabel: true,  // Descriptive label
    ariaDescribedby: true,  // Points to content
    liveRegion: "polite"  // For dynamic content
  },
  
  // Visual
  visual: {
    contrastRatio: 4.5,  // Minimum for text
    focusIndicator: true,  // Visible focus state
    reducedMotion: true  // Respect prefers-reduced-motion
  },
  
  // Timing
  timing: {
    autoHideMinimum: 5000,  // 5s minimum before auto-hide
    readTimeEstimate: true,  // Calculate based on content length
    pauseOnHover: true
  }
};
```

**Accessible Message Structure:**

```javascript
const accessibleModal = {
  role: "dialog",
  "aria-modal": true,
  "aria-labelledby": "modal-title",
  "aria-describedby": "modal-description",
  content: {
    title: { id: "modal-title", text: "Welcome to Smart Reports" },
    description: { id: "modal-description", text: "..." },
    buttons: [
      { text: "Get Started", "aria-label": "Get started with Smart Reports" },
      { text: "Dismiss", "aria-label": "Close this dialog" }
    ]
  }
};
```

### Step 7: Track Engagement

```
analytics.track_event({
  userId: context.userId,
  eventName: "in_app_message_shown",
  properties: {
    message_id: messageId,
    message_type: messageType,
    objective: objective,
    variant: abTestVariant,
    session_message_count: sessionCount
  }
})
```

**Engagement Events to Track:**

| Event | Description | Key Metrics |
|-------|-------------|-------------|
| `message_shown` | Message displayed | View rate |
| `message_clicked` | CTA clicked | CTR |
| `message_dismissed` | User closed | Dismiss rate |
| `message_completed` | Action taken | Completion rate |
| `message_timed_out` | Auto-hidden | Timeout rate |

## Response Format

```
## In-Product Message Analysis

**User**: [User ID]
**Segment**: [User Segment]
**Objective**: [Message Objective]

### Frequency Status

| Period | Messages Shown | Limit | Status |
|--------|----------------|-------|--------|
| Today | [X] | [Y] | [OK/At limit] |
| This Week | [X] | [Y] | [OK/At limit] |
| Modals Today | [X] | [Y] | [OK/At limit] |

### Recommended Message

**Type**: [Message Type]
**Priority**: [Level]
**Reason**: [Why this type/timing]

**Content**:
- Title: "[Title]"
- Body: "[Body text]"
- CTA: "[Button text]"

**Targeting**: [Targeting rule applied]
**Expected Engagement**: [XX%]

### Accessibility Compliance

- [x] Focus management
- [x] Keyboard navigation  
- [x] Screen reader support
- [x] Sufficient contrast
- [x] Timing compliance

### Send Status

**Result**: [Sent/Queued/Blocked]
**Message ID**: [ID if sent]
**Next Eligible**: [Timestamp if blocked]
```

## Frameworks Referenced

### Intercom's Messenger Framework
- Context-aware messaging
- Conversation threading
- Proactive support

### Pendo's Guide Best Practices
- Progressive onboarding
- Feature adoption tracking
- Segmented targeting

### Apple Human Interface Guidelines
- Modality principles
- Non-intrusive alerts
- Accessibility requirements

## Guardrails

- Never show more than 1 modal per session
- Always provide a way to dismiss (except critical alerts)
- Don't interrupt active user workflows
- Respect browser "prefers-reduced-motion" setting
- Maintain message history for personalization
- Never show same message twice within 14 days
- Test all messages with screen readers

## Metrics to Optimize

- Message engagement rate (target: > 30%)
- Message-to-action conversion (target: > 15%)
- Dismiss rate (target: < 50%)
- Feature adoption from messages (target: > 20%)
- User-reported message fatigue (target: < 5%)

