SMS

Reply to text messages and send links by SMS during a call.

SMS auto-reply

Every text to your number gets an instant reply, with dedicated answers for HELP, HOURS and CONTACT, and each message lands in your inbox and your CRM.

How it works

  1. Someone texts your number.
  2. The first word of the text picks the answer: HELP, HOURS, CONTACT or your default reply.
  3. A copy of the message goes to your inbox and to your server, which can save the lead.
  4. The answer is then sent back right away from the number they texted.

Starts on: inbound-sms
Actions used: log@v1, javascript@v1, email@v1, fetch@v3, sms@v1, mixpanel@v1
Guide: Receive SMS

# SMS auto-reply: every text sent to your number gets an instant answer.
# The first word picks the answer: HELP, HOURS and CONTACT have their own,
# any other text gets the default reply. Each message is first forwarded
# to your inbox and to your server (CRM, helpdesk, Zapier, Make...),
# then the reply is sent.
#
# What to edit: $replies (add your own keywords), $defaultReply,
# $forwardEmail and $webhookUrl.
#
# Needs: an SMS-capable number assigned to this scenario.
# In Build Mode, SMS are only sent to your Testing Numbers:
# text the number from one of them to try it.
#
# If your server filters by IP address, allow the Callr subnets:
# https://docs.callr.com/docs/ip-subnets
#
# Step-by-step guide:
# https://docs.callr.com/docs/receive-sms

description: "SMS auto-reply"

compat:
  version: "2025-09-01"

defaults:
  # SMS only: no speech in this scenario
  language: en-US

variables:
  $text: ""
  $keyword: ""
  $reply: ""

  # MODIFIABLE VARIABLES BELOW
  # one answer per keyword (first word of the text; case and accents ignored)
  $replies:
    HELP: Reply HOURS for our opening hours, or CONTACT to reach us.
    HOURS: We are open Monday to Friday, 9 am to 6 pm.
    CONTACT: "Email us at [email protected] or call us on +33 1 99 00 42 42."
  # answer to any other text
  $defaultReply: Thanks for your message! We will get back to you soon.
  # receives a copy of every text, e.g. [email protected]
  $forwardEmail: null
  # receives every text as JSON (POST), e.g. https://api.example.com/callr/sms
  $webhookUrl: null
  # sender of the reply; null replies from the number that received the text
  $smsFrom: null

branches:
  inbound-sms:
    actions:
      - action: log@v1
        params:
          message: SMS received ${{ JSON.stringify(sms) }}

      # Read the text and pick the answer from its first word
      - action: javascript@v1
        params:
          code: |
            $text = sms.body?.text ?? ''
            const first = $text.trim().split(/\s+/)[0] ?? ''
            const norm = (w) => w.normalize('NFD').replace(/[^a-zA-Z0-9]/g, '').toUpperCase()
            $keyword = norm(first)
            const key = Object.keys($replies).find((k) => norm(k) === $keyword)
            $reply = key ? $replies[key] : $defaultReply

      - if: $forwardEmail
        action: email@v1
        params:
          to:
            - ${{ $forwardEmail }}
          subject: SMS from ${{ sms.from }}
          text: |
            From: ${{ sms.from }}
            To: ${{ sms.to }}
            Keyword: ${{ $keyword || '(none)' }}

            ${{ $text }}

      # Upsert the lead in your CRM
      # (no result: the request runs in the background)
      - if: $webhookUrl
        action: fetch@v3
        params:
          url: ${{ $webhookUrl }}
          method: POST
          headers:
            Content-Type: application/json
          body: |
            {
              "sid": ${{ JSON.stringify(sms.sid) }},
              "from": ${{ JSON.stringify(sms.from) }},
              "to": ${{ JSON.stringify(sms.to) }},
              "keyword": ${{ JSON.stringify($keyword) }},
              "text": ${{ JSON.stringify($text) }}
            }

      # Reply last, once the message is saved.
      # Transactional answer: nature ALERTING, never MARKETING
      - action: sms@v1
        params:
          to:
            - ${{ sms.from }}
          from: ${{ $smsFrom ?? sms.to }}
          body: ${{ $reply }}
          nature: ALERTING

      # Optional: also count each lead in Mixpanel (Service Account, Admin role).
      # - action: mixpanel@v1
      #   params:
      #     username: my-service-account.mp-service-account
      #     secret: my-service-account-secret
      #     project_id: 1234567
      #     event: lead_captured
      #     properties:
      #       channel: sms
      #       keyword: ${{ $keyword }}

Send a link by SMS during a call

Callers press 1 during the call and instantly get your booking, payment or tracking link by SMS, and landline callers hear the address instead.

How it works

  1. A short message offers to send your link by SMS: the caller presses 1 or stays on the line.
  2. If the caller presses 1 from a mobile, the link is texted to them right away and they hear a confirmation.
  3. If they call from a landline or a hidden number, the address is read out twice instead.
  4. Then the call goes to your team, or ends with a goodbye if you have no team number.

Starts on: inbound-call
Actions used: gather@v4, sms@v1, play@v3, dial@v2, hangup@v1
Guide: Send SMS within a Call Flow

# Mid-call self-service: callers press 1 and get your link by SMS
# (booking, payment, tracking...). Callers on a landline or with a
# hidden number cannot receive SMS: they hear the address instead.
# Then the call goes to your team, or ends if you have no team number.
#
# What to edit: the variables below the MODIFIABLE VARIABLES line, and
# the menu sentence if your link is not a booking link.
# Needs: nothing else, SMS and text-to-speech only.
# Build Mode: SMS and calls only reach your Testing Numbers.
# Docs: https://docs.callr.com/docs/send-sms-in-a-call-flow

description: "Send a link by SMS during a call"

compat:
  version: "2025-09-01"

defaults:
  language: en-US
  voice: en-US-Harper:MAI-Voice-2

variables:
  $choice: null
  $dial: null

  # MODIFIABLE VARIABLES BELOW
  # Text sent to the caller, with your link
  $smsText: "Book your appointment here: https://www.example.com/book"
  # The same address, written the way it should be read aloud to landline callers
  $spokenLink: www dot example dot com, slash book.
  # Your team, called after the menu (null to end the call instead)
  $team: "+33199001020"

branches:
  inbound-call:
    actions:
      # Play the offer and wait for ONE key
      - action: gather@v4
        params:
          tts:
            text: Welcome. To receive our booking link by SMS, press 1. Otherwise, stay on the line.
          maxDigits: 1
          timeout: 10 # includes the time to play the sentence
        result: $choice

      # Key 1 on a mobile: send the link by SMS
      - if: $choice?.input === '1' && call.fromType == 'MOBILE' && call.fromNumber
        then:
          - action: sms@v1
            params:
              to:
                - ${{ call.fromNumber }}
              body: ${{ $smsText }}
              nature: ALERTING
              # Approved sender ID or one of your Callr numbers
              # from: MyCompany
          - action: play@v3
            params:
              tts:
                text: Done. The link is on its way, check your messages.

      # Key 1 on a landline or from a hidden number: read the address twice
      - if: $choice?.input === '1' && !(call.fromType == 'MOBILE' && call.fromNumber)
        action: play@v3
        params:
          tts:
            text: We cannot text this number. Our address is ${{ $spokenLink }} Once again, ${{ $spokenLink }}

      # Then: your team, or goodbye
      - if: $team
        then:
          - action: play@v3
            params:
              tts:
                text: Connecting you to our team.
          - action: dial@v2
            params:
              targets:
                - number: ${{ $team }}
                  timeout: 30
            result: $dial
          - if: "!$dial?.ok"
            action: play@v3
            params:
              tts:
                text: Our team is not available right now. Please call back later.

      - if: "!$team"
        action: play@v3
        params:
          tts:
            text: Thank you for calling. Goodbye.

      - action: hangup@v1

Did this page help you?