Ctrl K
ring2all.com

Dynamic Routing Module Documentation

Table of Contents

  1. Module Overview (Technical)
  2. Module Overview (Commercial/Business)
  3. Module Overview (End User/Administrator)
  4. Configuration Fields Reference
  5. How It Works
  6. Common Scenarios & Examples
  7. Limitations & Important Notes
  8. Troubleshooting Tips
  9. Glossary

---

1. Module Overview (Technical)

What Is Dynamic Routing?

Dynamic Routing (also called "Callback on No Answer") is a feature that automatically routes inbound calls to the extension that previously called the caller. When an extension makes an outbound call that goes unanswered, the system registers the caller ID. If that person calls back, they're automatically routed to the original extension.

Architecture

Plaintext
┌─────────────────────────────────────────────────────────────────┐
│                  Dynamic Routing System                         │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  PHASE 1: OUTBOUND CALL (Registration)                          │
│  ───────────────────────────────────────                        │
│  Extension 1001 calls +15055551234                              │
│       │                                                         │
│       ▼                                                         │
│  [Outbound call goes to gateway]                                │
│       │                                                         │
│       ▼                                                         │
│  Call NOT answered (NO_ANSWER, USER_BUSY, etc.)                 │
│       │                                                         │
│       ▼                                                         │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │         dynamic_routing_register.lua                     │   │
│  │                                                          │   │
│  │  1. Check extension has dynamic_routing_enabled          │   │
│  │  2. Check only_keep_missed_calls config                  │   │
│  │  3. Normalize destination: +15055551234 → 5055551234     │   │
│  │  4. Apply digits_match: 5055551234 → 5551234 (7 digits)  │   │
│  │  5. Insert into public.dynamic_route_entries            │   │
│  │     -> token: 5551234, extension: 1001                   │   │
│  │                                                          │   │
│  └──────────────────────────────────────────────────────────┘   │
│                                                                 │
│  ═══════════════════════════════════════════════════════════    │
│                                                                 │
│  PHASE 2: INBOUND CALLBACK (Matching)                           │
│  ────────────────────────────────────                           │
│  +15055551234 calls in                                          │
│       │                                                         │
│       ▼                                                         │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │           route_with_fallback.lua                        │   │
│  │                                                          │   │
│  │  1. Normalize caller ID: +15055551234 → 5551234          │   │
│  │  2. Query public.dynamic_route_entries WHERE             │   │
│  │     token LIKE '%5551234' AND expires_at > NOW()         │   │
│  │  3. Match found! extension = 1001                        │   │
│  │  4. Route caller directly to extension 1001             │   │
│  │  5. Delete entry if delete_used_records = true           │   │
│  │                                                          │   │
│  └──────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Key Tables

TablePurpose
public.dynamic_routing_configsPer-domain configuration
public.dynamic_route_entriesPending callback entries
public.sip_extensionsExtension settings (dynamic_routing_enabled)

Key Files

FileDescription
admin/apps/web/src/modules/dynamicRouting/Frontend module
admin/apps/web/src/i18n/en/dynamicRouting.jsonTranslations
telephony/freeswitch/lua/resources/functions/dynamic_routing_utils.luaShared utilities
telephony/freeswitch/lua/resources/functions/dynamic_routing_register.luaOutbound registration
telephony/freeswitch/lua/main/xml_handlers/dialplan/route_with_fallback.luaInbound matching
---

2. Module Overview (Commercial/Business)

Business Value

Dynamic Routing provides automatic callback recognition:

Without Dynamic RoutingWith Dynamic Routing
Callback goes to main IVRCallback goes to original caller
Caller navigates menusDirect connection
Receptionist routingAutomatic routing
Poor callback experienceSeamless callback

Use Cases

  1. Sales Teams
- Sales rep calls prospect

- Prospect calls back → routed to same rep

- Better customer relationships

  1. Support Teams
- Tech calls back customer

- Customer returns call → same tech

- Continuity of service

  1. Personal Extensions
- User makes outbound call

- Callback routed to their extension

- Personal call management

Feature Highlights

FeatureBenefit
Automatic RegistrationNo manual setup
Missed Calls OnlyRegister unanswered calls
Configurable ExpirationTime-limited matching
Digits MatchFlexible caller ID matching
Per-Extension EnableSelective activation
Auto-DeleteClean up after callback
---

3. Module Overview (End User/Administrator)

What Can You Do?

Domain Configuration:
  • Set digits to match (caller ID suffix)
  • Configure expiration time
  • Enable/disable delete after use
  • Enable/disable missed calls only

Extension Settings:
  • Enable dynamic routing per extension

Pending Routes:
  • View active callback entries
  • Delete entries manually
  • Search by caller ID or extension

Administrator Workflow

Plaintext
┌─────────────────────────────────────────────────────────────────┐
│              Dynamic Routing Configuration                      │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Tab: Configuration                                             │
│  ┌────────────────────────────────────────────────────────────┐ │
│  │                                                            │ │
│  │  Caller ID Digits to Match: [7      ]                     │ │
│  │  (Extracts last N digits from caller ID for matching)     │ │
│  │                                                            │ │
│  │  Expiration (Minutes): [60     ]                          │ │
│  │  (How long entries remain valid)                          │ │
│  │                                                            │ │
│  │  ☑ Delete Used Records                                    │ │
│  │  (Remove entry after successful callback routing)         │ │
│  │                                                            │ │
│  │  ☑ Only Keep Missed Calls                                 │ │
│  │  (Only register calls not answered by called party)       │ │
│  │                                                            │ │
│  └────────────────────────────────────────────────────────────┘ │
│                                                                 │
│  Tab: Pending Routes                                            │
│  ┌────────────────────────────────────────────────────────────┐ │
│  │ Caller ID     │ Extension │ Expires At        │ Actions   │ │
│  │ 5551234       │ 1001      │ 2026-01-16 17:00  │ [Delete]  │ │
│  │ 5559999       │ 1002      │ 2026-01-16 17:30  │ [Delete]  │ │
│  └────────────────────────────────────────────────────────────┘ │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Extension Enable

In Extension settings:

Plaintext
Extension 1001 → Dynamic Routing Enabled: ✓

Quick Tips

TIP
Digits Match = 7: Works well for 10-digit numbers where prefix varies.
TIP
Expiration = 60: One hour is typical for callback windows.
CAUTION
Too Few Digits: Low digits_match may cause false matches.

---

4. Configuration Fields Reference

Domain Configuration

FieldDescriptionDefault
Digits to MatchLast N digits of caller ID to use7
Expiration (Minutes)How long entries remain valid60
Delete Used RecordsRemove entry after callback routedOn
Only Keep Missed CallsOnly register unanswered callsOn

Digits Match Examples

Caller IDDigits MatchToken Stored
+1505555123475551234
+15055551234105055551234
+150555512340 (blank)15055551234

Missed Call Detection

These hangup causes register an entry:

  • NO_ANSWER
  • USER_BUSY
  • CALL_REJECTED
  • ORIGINATOR_CANCEL
  • NO_USER_RESPONSE
  • SUBSCRIBER_ABSENT
  • DESTINATION_OUT_OF_ORDER

Extension Settings

FieldDescription
Dynamic Routing EnabledEnable callback registration for this extension
---

5. How It Works

Registration Flow (Outbound)

Plaintext
1. Extension 1001 dials 918005551234
2. Route strips 9, dials 18005551234 via gateway
3. Call is NOT answered (NO_ANSWER)
4. route_with_fallback.lua completes bridge
5. dynamic_routing_register.lua runs:
   - Check: extension has dynamic_routing_enabled? ✓
   - Check: only_keep_missed_calls & is this a missed call? ✓
   - Normalize: 18005551234 → digits → 5551234 (7 digits)
   - Insert: token=5551234, extension=1001, expires=NOW()+60min

Matching Flow (Inbound)

Plaintext
1. Caller +18005551234 calls in
2. route_with_fallback.lua starts
3. Check dynamic_route_entries:
   - Normalize caller ID → 5551234
   - Query: WHERE token LIKE '%5551234' AND expires_at > NOW()
   - Match found! extension = 1001
4. Route caller to extension 1001
5. If delete_used_records: DELETE entry

Token Matching Logic

Plaintext
Digits Match = 7

Outbound:  +15055551234 → Store: 5551234
Inbound:   +18005551234 → Match: %5551234

Token: 5551234
Query: WHERE token LIKE '%5551234'
Match: ✓

---

6. Common Scenarios & Examples

Scenario 1: Sales Rep Callback

Configuration:
SettingValue
Digits Match7
Expiration120 min
Delete Used
Only Missed
Flow:
  1. Sales rep 1001 calls prospect
  2. Prospect doesn't answer
  3. Entry created: 5551234 → 1001
  4. Prospect calls back 30 min later
  5. Routed directly to extension 1001

Scenario 2: Support Technician

Configuration:
SettingValue
Digits Match10
Expiration480 min (8 hours)
Delete Used
Only MissedOff
Flow:
  1. Tech 1002 calls customer, call answered
  2. Entry created (even though answered)
  3. Customer calls back later
  4. Routed to same tech

Scenario 3: High Volume Call Center

Configuration:
SettingValue
Digits Match7
Expiration30 min
Delete Used
Only Missed
Flow:
  • Short expiration to reduce false matches
  • Only missed calls to reduce entries
  • Auto-delete to keep table clean

---

7. Limitations & Important Notes

Technical Notes

NOTE
Suffix Matching: Uses SQL LIKE '%token' for flexible matching.
WARNING
False Matches: Too few digits_match may route wrong caller.
WARNING
International Prefixes: Ensure consistent normalization for global use.

Best Practices

  1. Use 7-10 Digits: Balances flexibility and accuracy
  2. Set Reasonable Expiration: 1-2 hours typical
  3. Enable Delete Used: Prevents stale entries
  4. Enable Only Missed: Reduces unnecessary entries
  5. Test Before Production: Verify matching works correctly

---

8. Troubleshooting Tips

Common Issues

SymptomPossible CauseSolution
No entry createdExtension not enabledEnable dynamic_routing_enabled
Entry not createdCall was answeredCheck only_keep_missed_calls
No match foundDigits don't matchAdjust digits_match
Entry expiredExpiration too shortIncrease expiration_minutes
Wrong extensionDigits too fewIncrease digits_match

Diagnostic SQL

Check domain configuration:

Sql
SELECT * FROM public.dynamic_routing_configs
WHERE domain_id = [domain_id];

List pending entries:

Sql
SELECT id, token, extension, expires_at, created_at
FROM public.dynamic_route_entries
WHERE domain_id = [domain_id]
  AND expires_at > NOW()
ORDER BY created_at DESC;

Check extension setting:

Sql
SELECT extension, dynamic_routing_enabled
FROM public.sip_extensions
WHERE domain_id = [domain_id]
  AND extension = '1001';

FreeSWITCH Logs

Bash
# Check registration
grep "DYNAMIC_ROUTING_REGISTER" /var/log/freeswitch/freeswitch.log

# Check matching
grep "DYNAMIC_ROUTING" /var/log/freeswitch/freeswitch.log

---

9. Glossary

TermDefinition
Dynamic RoutingAutomatic callback-to-extension routing
TokenNormalized caller ID digits stored for matching
Digits MatchNumber of digits to extract from caller ID
ExpirationHow long an entry remains valid
Delete UsedRemove entry after successful callback
Only MissedOnly register unanswered outbound calls
---

Lua Script Status ✅

All Scripts Already Correct

ScriptStatus
dynamic_routing_utils.lua✅ Uses public.dynamic_routing_configs, public.sip_extensions, public.dynamic_route_entries
dynamic_routing_register.lua✅ Uses utilities with correct schema
route_with_fallback.lua✅ Uses utilities for inbound matching
No Lua fixes needed!

---

Documentation last updated: January 2026
AI Assistant

👋 Hello! I'm your Ring2All documentation assistant. I can help you find information about configuring and using the Ring2All PBX platform.

How can I help you today?