Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

notify

Send a templated message to a configured notification channel.

rflow_version: 1
name: usdc-mirror
 
config:
  port: 3940
  db_connection: ${DATABASE_URL}
 
networks:
  - name: ethereum
    chain_id: 1
    rpc: ${ETH_RPC}
 
# DEV ONLY raw mnemonic - swap in a production signer before real funds
signer:
  raw:
    mnemonic: ${RAW_DANGEROUS_MNEMONIC}
 
relayers:
  hot-wallet:
    networks: [ethereum]
 
contracts:
  USDC:
    abi: ./abis/erc20.json
    network: ethereum
    address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
 
notifications:
  channels:
    ops:
      telegram:
        bot_token: ${TG_BOT_TOKEN}
        chat_id: ${TG_CHAT_ID}
 
workflows:
  mirror-usdc:
    trigger:
      event:
        contract: USDC
        name: Transfer
        network: ethereum
    steps:
      - id: mirror
        send_transaction:
          network: ethereum
          relayer: hot-wallet
          contract: USDC
          function: "transfer(address,uint256)"
          args: ["${{ trigger.args.to }}", "${{ trigger.args.value }}"]
      - id: report
        notify: 
          channel: ops
          message: "mirrored ${{ format_units(trigger.args.value, 6) }} USDC — ${{ steps.mirror.tx.hash }}"

Fields

FieldRequiredDescription
channel✅A channel declared under notifications.channels
message✅Full template; any expression works

Behavior

  • The message renders against the full run context: trigger, prior steps, constants, relayer addresses.
  • Values from secrets: are log-redacted.
  • Delivery goes through rflow's own senders (telegram / slack / discord), not a third-party relay.
  • The step output is { "channel": "...", "status": <http status> }.
  • Delivery failures follow normal step failure handling: 5xx/timeouts are retryable under a retry: block; a bad token or webhook is terminal.
  • If delivery succeeds but the process stops before journaling it, recovery can send the notification again. Provider failures can also prevent delivery; use the run journal to establish workflow outcome instead of treating one alert as proof. See Reliability.

Pattern: alert-only workflows

Monitoring needs no signer and no relayer; an event trigger plus notify is a complete project:

rflow_version: 1
name: large-transfer-alerts
 
config:
  port: 3940
  db_connection: ${DATABASE_URL}
 
networks:
  - name: ethereum
    chain_id: 1
    rpc: ${ETH_RPC}
 
contracts:
  USDC:
    abi: ./abis/erc20.json
    network: ethereum
    address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
 
notifications:
  channels:
    ops:
      telegram:
        bot_token: ${TG_BOT_TOKEN}
        chat_id: ${TG_CHAT_ID}
 
workflows: 
  large-transfers: 
    trigger: 
      event: 
        contract: USDC
        name: Transfer
        network: ethereum
        where: "${{ trigger.args.value > wei('1000000', 6) }}"
    steps: 
      - id: alert
        notify: 
          channel: ops
          message: "🚨 ${{ format_units(trigger.args.value, 6) }} USDC from ${{ trigger.args.from }}"