> ## Documentation Index
> Fetch the complete documentation index at: https://docs.snagsolutions.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Function Rule

> Create custom loyalty rules using JavaScript functions to evaluate complex conditions and determine rewards dynamically.

<head>
  <script type="application/ld+json">
    {JSON.stringify({
            "@context": "https://schema.org",
            "@type": "TechArticle",
            "headline": "Custom Function Rule",
            "description": "Create custom loyalty rules using JavaScript functions to evaluate complex conditions and determine rewards dynamically.",
            "author": {"@type": "Organization", "name": "Snag Solutions", "url": "https://www.snagsolutions.io/"},
            "publisher": {"@type": "Organization", "name": "Snag Solutions", "url": "https://www.snagsolutions.io/", "logo": {"@type": "ImageObject", "url": "https://assets.snagsolutions.io/public/docs/snag-logo-dark-no-bg.svg"}},
            "mainEntityOfPage": "https://docs.snagsolutions.io/loyalty/rules/stratus-function"
          })}
  </script>
</head>

## Overview

The Custom Function Rule allows you to create sophisticated loyalty rules using JavaScript code. This rule type leverages Stratus functions to evaluate complex conditions, perform calculations, and determine rewards based on custom logic that goes beyond standard rule types.

## Key Features

* **Custom Logic**: Write JavaScript functions to implement any evaluation logic
* **Dynamic Rewards**: Calculate variable reward amounts based on user data or conditions
* **External Data**: Access external APIs and services using approved modules
* **Complex Conditions**: Implement multi-step validation and conditional rewards
* **Flexible Output**: Return points, badges, or multipliers based on your logic

## Use Cases

<CardGroup cols={2}>
  <Card title="Gamification Logic" icon="gamepad">
    Reward users based on complex gaming achievements, streaks, or skill levels.
  </Card>

  <Card title="Social Scoring" icon="users">
    Calculate rewards based on social media engagement metrics or community
    participation.
  </Card>

  <Card title="Tiered Rewards" icon="chart-line">
    Implement dynamic reward structures based on user tier, activity level, or
    spending patterns.
  </Card>

  <Card title="Cross-Platform Integration" icon="link">
    Combine data from multiple platforms to create unified reward systems.
  </Card>
</CardGroup>

## How It Works

<Steps>
  <Step title="Write Your Function">
    Create a JavaScript function that receives user data and loyalty rule information as input.

    <Note>
      Your function must follow the Stratus function syntax and use only approved modules.
    </Note>
  </Step>

  <Step title="Define Evaluation Logic">
    Implement your custom logic to determine if a user qualifies for rewards and
    calculate the appropriate reward amount.
  </Step>

  <Step title="Return Reward Details">
    Your function returns a structured object describing the reward to grant
    (points, badges, or multipliers).
  </Step>

  <Step title="Automatic Execution">
    The platform automatically executes your function when users attempt to complete the rule.
  </Step>
</Steps>

## Function Requirements

Your custom function must:

* Accept `(input, output)` parameters
* Parse the input data containing user and rule information
* Call `output.setResult([rewardObject])` with your reward details
* Return `output.buildOutput()`
* Use only approved modules: `axios`, `lodash`, `viem`, and `viem/chains`

<Warning>
  Functions that don't follow the required syntax or use unauthorized modules
  will fail validation.
</Warning>

## Input Data Structure

Your function receives the following input structure:

```javascript theme={null}
{
  user: {
    id: string,
    walletAddress: string,
    walletType: string
  },
  loyaltyRule: {
    id: string,
    name: string,
    type: string,
    amount: number,
    metadata: object,
    startTime: string,
    endTime: string,
    interval: string,
    rewardType: string
  }
}
```

## Output Requirements

Your function must return an array with a single reward object containing:

* **walletAddress**: The user's wallet address to reward
* **amount**: Points to grant (for fixed point rewards)
* **idempotencyKey**: Unique identifier to prevent duplicate rewards
* **data**: Optional JSON string with additional context (max 1KB)
* **loyaltyBadgeId**: Optional badge to award instead of points
* **loyaltyMultiplierAmount**: Optional multiplier for range-based rules

## Example Use Cases

### Dynamic Point Calculation

```javascript theme={null}
// Calculate points based on user's social media followers
const followerCount = await getFollowerCount(user.socialId)
const basePoints = 10
const bonusPoints = Math.floor(followerCount / 1000) * 5
const totalPoints = basePoints + bonusPoints

output.setResult([
  {
    walletAddress: user.walletAddress,
    amount: totalPoints,
    idempotencyKey: `social-bonus-${user.id}-${Date.now()}`,
    data: JSON.stringify({ followerCount, bonusPoints }),
  },
])
```

### Conditional Badge Award

```javascript theme={null}
// Award special badge for high-value users
const userValue = await calculateUserValue(user.id)
const isHighValue = userValue > 1000

if (isHighValue) {
  output.setResult([
    {
      walletAddress: user.walletAddress,
      loyaltyBadgeId: 'high-value-user-badge-id',
      idempotencyKey: `high-value-${user.id}`,
    },
  ])
}
```

## Getting Started

<Steps>
  <Step title="Learn Function Syntax">
    Read the [Stratus Function Syntax](/stratus/syntax) guide to understand the required export patterns and validation rules.
  </Step>

  <Step title="Write Your Function">
    Follow the [Function Loyalty Rule Guide](/stratus/function-loyalty-rule) for a
    complete tutorial on creating custom loyalty rule functions.
  </Step>

  <Step title="Test Your Function">
    Use the function editor in the loyalty rule form to write and test your custom
    logic.
  </Step>

  <Step title="Deploy and Monitor">
    Save your rule and monitor function execution through the admin dashboard.
  </Step>
</Steps>

## Best Practices

<Tip>
  **Keep functions simple and focused** - Complex logic should be broken into
  smaller, testable functions.
</Tip>

<Tip>
  **Handle errors gracefully** - Always include try-catch blocks and meaningful
  error messages.
</Tip>

<Tip>
  **Use idempotency keys** - Ensure your functions can be safely retried without
  creating duplicate rewards.
</Tip>

<Tip>
  **Optimize for performance** - Minimize external API calls and use efficient
  data structures.
</Tip>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Function validation errors">
    * Ensure your function follows the exact syntax requirements
    * Check that you're only using approved modules
    * Verify your output structure matches the required format
  </Accordion>

  <Accordion title="Execution failures">
    * Review function logs for specific error messages - Test your function with
      sample data before deploying - Ensure all external dependencies are available
  </Accordion>

  <Accordion title="Performance issues">
    * Optimize external API calls and database queries
    * Consider caching frequently accessed data
    * Monitor function execution time and memory usage
  </Accordion>
</AccordionGroup>

## Related Documentation

* [Stratus Function Syntax](/stratus/syntax) - Learn the required function structure
* [Function Loyalty Rule Guide](/stratus/function-loyalty-rule) - Complete tutorial for writing loyalty rule functions
* [Function Templates](/stratus/function-templates) - Ready-to-use function examples
* [Loyalty API Reference](/api-reference/loyalty) - API documentation for loyalty rules
