RORK LABJP
RORKMAX — Rork Max generates pure Swift instead of React Native, enabling true native apps across iPhone, iPad, Watch, TV, Vision Pro, and iMessageAPPLE — Rork's 2026 direction has a clear theme of native empowerment across the Apple ecosystemEXPO — Standard builds run on React Native and Expo, so you're left with a real project structure and code you can keep working onFUNDING — Rork recently raised $15M and now sees over 743,000 monthly visits with 85% growthPRICING — Rork is free to start, with paid plans from $25/month and Rork Max at $200/monthCROSS — Rork builds iOS, Android, and web from a single prompt, finished off with a bit of follow-up tweakingRORKMAX — Rork Max generates pure Swift instead of React Native, enabling true native apps across iPhone, iPad, Watch, TV, Vision Pro, and iMessageAPPLE — Rork's 2026 direction has a clear theme of native empowerment across the Apple ecosystemEXPO — Standard builds run on React Native and Expo, so you're left with a real project structure and code you can keep working onFUNDING — Rork recently raised $15M and now sees over 743,000 monthly visits with 85% growthPRICING — Rork is free to start, with paid plans from $25/month and Rork Max at $200/monthCROSS — Rork builds iOS, Android, and web from a single prompt, finished off with a bit of follow-up tweaking
Articles/Business
Business/2026-03-22Advanced

Automate In-App Recommendation Revenue with Rork × AI Agents — Personalized Billing Strategy Guide

Build an AI-powered recommendation engine for your Rork app that automatically generates personalized billing offers per user. Includes behavior tracking, Gemini-based agent logic, and React Native implementation.

Rork504AI agents5recommendationsauto-monetizationpersonalization2Stripe17app revenue2

Recommendations × AI Agents = Automated Revenue Maximization

In app monetization, showing "the right offer to the right user at the right time" is both the most important and most challenging problem. Traditional rule-based approaches (showing everyone the same ad, sending a discount after 7 days) can't adapt to diverse user behavior patterns.

AI agents change this equation. They analyze user behavior data in real time and automatically generate individualized billing offers. This article details the design and implementation of a personalized recommendation revenue engine for Rork apps.

How the Personalized Revenue Engine Works

Three Core Components

  1. Behavior Analysis Engine — Tracks and scores in-app user behavior
  2. Recommendation AI Agent — Generates optimal offers based on behavior data
  3. Billing Execution Layer — Integrates with Stripe to present offers and process payments

Data Flow

User behavior → Analysis → AI agent decision → Recommendation displayed
     ↑                                              ↓
     └────────── Result feedback ←──── Purchase/dismiss outcome

Implementing the Behavior Analysis Engine

// services/behavior-tracker.ts
// User behavior analysis engine
interface UserBehavior {
  userId: string;
  sessionCount: number;
  avgSessionDuration: number;        // seconds
  featuresUsed: string[];
  lastActiveAt: Date;
  purchaseHistory: {
    amount: number;
    date: Date;
    product: string;
  }[];
  premiumFeatureAttempts: number;     // premium feature tap count
  referralCount: number;
}
 
interface EngagementScore {
  overall: number;          // 0-100
  purchaseIntent: number;   // 0-100
  churnRisk: number;        // 0-100
  optimalTiming: string;    // best moment to show recommendation
}
 
function calculateEngagementScore(
  behavior: UserBehavior
): EngagementScore {
  // Calculate engagement score
  const sessionScore = Math.min(behavior.sessionCount * 2, 30);
  const durationScore = Math.min(behavior.avgSessionDuration / 60 * 5, 20);
  const featureScore = Math.min(behavior.featuresUsed.length * 3, 20);
  const premiumScore = Math.min(behavior.premiumFeatureAttempts * 10, 30);
 
  const overall = sessionScore + durationScore + featureScore + premiumScore;
 
  // Purchase intent (higher with more premium feature taps)
  const purchaseIntent = Math.min(
    behavior.premiumFeatureAttempts * 15 +
    (behavior.sessionCount > 10 ? 20 : 0) +
    (behavior.avgSessionDuration > 300 ? 15 : 0),
    100
  );
 
  // Churn risk (based on days since last activity)
  const daysSinceActive = Math.floor(
    (Date.now() - behavior.lastActiveAt.getTime()) / 86400000
  );
  const churnRisk = Math.min(daysSinceActive * 10, 100);
 
  // Optimal timing
  let optimalTiming = "session_end";  // default
  if (purchaseIntent > 70) {
    optimalTiming = "premium_feature_tap";  // high intent → offer immediately
  } else if (purchaseIntent > 40) {
    optimalTiming = "session_mid";  // moderate → mid-session
  }
 
  return { overall, purchaseIntent, churnRisk, optimalTiming };
}
 
// Usage example
const score = calculateEngagementScore({
  userId: "user_123",
  sessionCount: 15,
  avgSessionDuration: 420,
  featuresUsed: ["search", "favorites", "share", "compare"],
  lastActiveAt: new Date(),
  purchaseHistory: [],
  premiumFeatureAttempts: 5,
  referralCount: 2
});
console.log(score);
// Expected output:
// {
//   overall: 82,
//   purchaseIntent: 75,
//   churnRisk: 0,
//   optimalTiming: "premium_feature_tap"
// }

AI Agent Recommendation Generation

// services/recommendation-agent.ts
// AI agent for personalized recommendations
import { GoogleGenerativeAI } from "@google/generative-ai";
 
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY!);
const model = genAI.getGenerativeModel({ model: "gemini-2.5-pro" });
 
interface Recommendation {
  type: "subscription" | "one_time" | "upgrade" | "retention";
  plan: string;
  message_ja: string;
  message_en: string;
  discount?: number;
  urgency: "low" | "medium" | "high";
  displayTiming: string;
}
 
async function generateRecommendation(
  behavior: UserBehavior,
  score: EngagementScore
): Promise<Recommendation> {
  const prompt = `You are a mobile app revenue optimization agent.
Generate the optimal billing recommendation based on this user data.
 
User data:
- Sessions: ${behavior.sessionCount}
- Avg session duration: ${behavior.avgSessionDuration}s
- Features used: ${behavior.featuresUsed.join(", ")}
- Premium feature taps: ${behavior.premiumFeatureAttempts}
- Purchase history: ${behavior.purchaseHistory.length} items
- Referrals: ${behavior.referralCount}
 
Scores:
- Engagement: ${score.overall}/100
- Purchase intent: ${score.purchaseIntent}/100
- Churn risk: ${score.churnRisk}/100
- Optimal timing: ${score.optimalTiming}
 
Available plans:
- Tip: $1.50 (one-time)
- Pro monthly: $3
- Premium lifetime: $10
 
Respond in this JSON format:
{
  "type": "subscription" | "one_time" | "upgrade" | "retention",
  "plan": "plan name",
  "message_ja": "Japanese recommendation (under 50 chars)",
  "message_en": "English recommendation (under 50 words)",
  "discount": 0-30,
  "urgency": "low" | "medium" | "high",
  "displayTiming": "when to show"
}`;
 
  const response = await model.generateContent(prompt);
  const text = response.response.text();
 
  const jsonMatch = text.match(/\{[\s\S]*\}/);
  if (!jsonMatch) throw new Error("Failed to parse recommendation");
  return JSON.parse(jsonMatch[0]);
}
 
// Expected output:
// {
//   "type": "subscription",
//   "plan": "Pro monthly",
//   "message_en": "Unlock unlimited favorites with Pro — 20% off today",
//   "message_ja": "お気に入り機能を無制限で使えるProプラン、今なら20%オフ",
//   "discount": 20,
//   "urgency": "high",
//   "displayTiming": "premium_feature_tap"
// }

Displaying Recommendations in the Rork App

// components/SmartOffer.tsx
// AI-generated recommendation display component
import React, { useEffect, useState } from 'react';
import {
  View, Text, TouchableOpacity,
  Animated, StyleSheet
} from 'react-native';
 
interface OfferProps {
  userId: string;
  currentScreen: string;
  trigger: "session_end" | "premium_feature_tap" | "session_mid";
}
 
export default function SmartOffer({
  userId, currentScreen, trigger
}: OfferProps) {
  const [offer, setOffer] = useState<any>(null);
  const [visible, setVisible] = useState(false);
  const fadeAnim = useState(new Animated.Value(0))[0];
 
  useEffect(() => {
    fetchOffer();
  }, [trigger]);
 
  const fetchOffer = async () => {
    try {
      const res = await fetch(
        'https://api.your-app.com/recommendations',
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer TOKEN'
          },
          body: JSON.stringify({ userId, currentScreen, trigger }),
        }
      );
      const data = await res.json();
      if (data.recommendation) {
        setOffer(data.recommendation);
        setVisible(true);
        Animated.timing(fadeAnim, {
          toValue: 1,
          duration: 300,
          useNativeDriver: true,
        }).start();
      }
    } catch (e) {
      // Silent fail — don't disrupt UX for recommendation errors
    }
  };
 
  if (!visible || !offer) return null;
 
  return (
    <Animated.View style={[styles.container, { opacity: fadeAnim }]}>
      <Text style={styles.title}>{offer.message_en}</Text>
      {offer.discount > 0 && (
        <Text style={styles.discount}>{offer.discount}% OFF</Text>
      )}
      <TouchableOpacity
        style={styles.button}
        onPress={() => {
          // Navigate to Stripe Checkout
          // handlePurchase(offer.plan, offer.discount);
        }}
      >
        <Text style={styles.buttonText}>Learn More</Text>
      </TouchableOpacity>
      <TouchableOpacity onPress={() => setVisible(false)}>
        <Text style={styles.dismiss}>Maybe Later</Text>
      </TouchableOpacity>
    </Animated.View>
  );
}
 
const styles = StyleSheet.create({
  container: {
    position: 'absolute', bottom: 20, left: 16, right: 16,
    backgroundColor: '#FFF', borderRadius: 16, padding: 20,
    shadowColor: '#000', shadowOpacity: 0.15, shadowRadius: 10,
    elevation: 5,
  },
  title: { fontSize: 16, fontWeight: '600', marginBottom: 8 },
  discount: {
    fontSize: 24, fontWeight: 'bold', color: '#E91E63',
    marginBottom: 12
  },
  button: {
    backgroundColor: '#2196F3', padding: 14, borderRadius: 10,
    alignItems: 'center',
  },
  buttonText: { color: '#FFF', fontSize: 16, fontWeight: '600' },
  dismiss: {
    textAlign: 'center', color: '#999', marginTop: 12, fontSize: 14,
  },
});

Measurement and Feedback Loops

To continuously improve recommendations, feed outcome data back to the AI agent. Track click-through rates, purchase rates, and dismissal rates for every offer. Include this history in the next recommendation prompt, allowing the agent to learn patterns like "this user type responds better to feature highlights than discounts."

Wrapping Up — Revenue Without the Hard Sell

The essence of AI-powered recommendation monetization is maximizing revenue without degrading user experience. Presenting truly valuable offers at exactly the moment users need them — this "no hard sell" approach is the foundation of a sustainable business model.

Start with simple behavior scoring, then gradually introduce AI agent personalization as your data grows.

For more on app monetization, check out our Rork Subscription Revenue Model Design and Rork Monetization Masterplan.

Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

Business2026-05-12
I Built a Wallpaper App with Rork — An Honest Review from a Developer with 50M App Downloads
After running wallpaper and healing apps with 50M+ downloads since 2014, I prototype-tested Rork on the same genre. Here's my honest take on where it shines, where it struggles, and what it means for solo developers.
Business2026-04-22
Launching a Branded Video Streaming App with Rork as a Solo Developer — HLS Delivery, Stripe Subscriptions, Offline Playback, and Revoking Access on Cancellation
A realistic blueprint for shipping a membership video app with Rork — how to pick an HLS backend, keep Stripe subscription state in sync with playback permission, handle offline viewing securely, and decide whether DRM is actually worth the cost.
Business2026-03-25
The Complete Design for Automated Revenue Pipelines in Rork Apps— 5 Engines That Earn While You Sleep
A comprehensive guide to fully automating revenue for Rork-built apps through 5 pipeline engines: subscription retention, ad optimization, dynamic pricing, automated support, and review-driven improvement loops.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →