IVR Code Generation to Client

Hello, good morning!
I would like to ask a question.
My company works with customer service, and we would like that when a customer calls our IVR, he hears a “service protocol” code.
I mean, everytime that someone calls in our IVR, he should listen to a sequence of numbers, who matches the register of his call.
This procedure is very common here in Brazil, and it is interesting for customers, because when they write down the numbers they heard, they can pass it on to us later so that we can find their call easily.

How would we make FreePBX generate it too?
And how would the IVR speak the numbers to the client?
PS: I saw that each connection generates a code (CDR) within the platform, would it be possible that the code passed to the client was this one?
Or rather, could we generate custom code within known standards? (Like “2023031100002”)


As I’m using a translator, I think maybe the text got a little confusing, I’ll give an example of what I want:

When we call our Internet provider, the IVR tells us (in a robotic way, one digit at a time) a number/code referring to my call, which I can write down and, if necessary later, I can pass it on to them so that they can identify my call quickly and easily.

Every call generates this number, serving as an individual identifier for the calls.

I would like to implement this function in our FreePBX IVR as well.

The only natural number produced by Asterisk would be the LinkedID (the earliest unique ID for the call), but that is probably a bit long for customers to write down. You would be better getting a reference from your CRM system.

The other issue is how to get it read out. You would probably need some sort of custom destination and custom dialplan code, to achieve that. You would route the calls that currently go to the IVR to that, and then have it invoke the IVR on return.

I’m not sure if FreePBX includes LinkedID in its CDR reports, although, in many cases, teh UniqueID will be the same.

Hello david, good morning!
I hope everything is well with you!
I was doing some tests and I had a curious result.
I was testing the possibility of one of our DIDs serving an inbound route that leads to a custom destination, which leads to a custom dialplan so that it speaks the uniqueid of the call (just for testing).

doing some research, I did the test as follows:

I added a macro to extensions_custom.conf:
exten => s,1,SayDigits(${UNIQUEID})
exten => s,2,Hangup

I added a Custom Destination:
Target: custom-protocol,s,1
Description: protocol

I added a Misc Application:
Description: misc-app protocol
Destination: Custom Application protocol

I added an inbound route:
Description: Test Protocol
DID Number +557130348390
Destination: Custom Application protocol

After doing that and calling the number, it “worked”…but it really didn’t.

Analyzing the asterisk logs I can see that the call arrives at FreePBX and is “answered” and plays the digits of the UniqueID, but on my cell phone nothing happens, the call just tries to connect (without giving a ring tone) and hangs up after a few seconds. For my cell phone, it is as if the call is not being answered.

The log says the following when I call:

What could be wrong with these settings?
Do you think anything can be improved for these tests to continue?

PS: I tried to post the log on FreePBX pastebin, but it looks like the site is down :smiling_face_with_tear:

And another curious detail:
I configured the inbound route to force recordings, and in the recording of the calls I made to this DID, there is the audio from the FPBX saying the UNIQUEID digits. :flushed:

I’m not sure if SayDigits answers the call. You may have to explicitly answer, and possibly insert a delay.

Also there are reports that some providers can’t cope with an answer that isn’t preceded by ringing.

In some circumstances, it is useful to send early media. Playback has an option to suppress answer, As SayDigits doesn’t, it may require something else to do the answer.

In this case, if I changed the custom dialplan to play a message at the beginning of the call, like a greeting, put a slight delay, and then put saydigits to say the uniqueid, maybe it would work?

I’m thinking of the following strategy:

1 - Customer calls the number and hears a greeting, saying something like “hello! you called our company, write down this code to identify your call”

2 - Customer listens to the uniqueid number, by the saydigits code

3 - After listening, the customer goes to an IVR, where he selects his desired option

By the way, I agree with you about the UNIQUEID number being too long to pass on to the client… I’m studying about the integration with our CRM, but at this first moment we are finding these tests kinda interesting

Playback answers by default, but a delay before the message is useful as it may take a few hundred milliseconds to get media flowing smoothly, especially if NAT is involved.

it worked perfectly using the macro like this:

exten => s,1,wait(2)
exten => s,2,Playback(teste-protocolo)
exten => s,3,SayDigits(${UNIQUEID})
exten => s,4,Hangup

the “custom-protocolo” is the audio that greets the customer (in this case, just me doing tests), and right after that I hear the LinkedID numbers of my call.

I was so happy when I wrote down the numbers said by the PBX and when looking for them in “CDR Reports” I found my call and recording easily :sweat_smile:

now I will continue with the challenges - think of some way to improve this number, something like a shorter number, and a way to “register” this shorter number within the FPBX as an identifier for calls…

As currently formed, the first part is the time, in seconds, and the second is a count of channel creations. You could safely reduce the time part by dividing by the minimum time between Asterisk restarts (assuming that is shorter than the time to wrap the count round).

Alternatively, you could reduce the count part modulo the absolute maximum channel creations per second (which will be more than the number of calls).

I was actually suggesting putting the wait between answer an playback.

You don’t actually have a macro, and you don’t want one, as macros are going away. In the end, you probably want a subroutine.

I misunderstood your suggestion… problems with google translator :sweat_smile:

I was wondering about the LinkedID… would it be possible to modify it to fit a pattern?
Something like year, month, date, and an identifying number for the call?
Example: 2023031600001
20230316 = Year, month and date (In Brazil the date comes before the month, so we say that today is 16/03/2023)
00001 = Call (as this was the first call of the day)

The second call would generate LinkedID 2023031600002
The third call would generate LinkedID 2023031600003

And so on…
Is it possible?

The tools to do this are available in the dialplan (in particular, the CUT function, and the STRFTIME function), but note that the final part counts from the last restart, and there could be more than one restart in a day.

Would it be possible for me to schedule an automatic restart of Asterisk every day at 00:00?
So that in this way, every day the last part was “reset”

You can do so using crontab with either:

fwconsole restart (which restarts all asterisk/freepbx related services)


asterisk -x "core restart now" (which would restart only asterisk).

Hi david!
I modified the custom dialplan to this:

exten => s,1,Answer
exten => s,2,wait(2)
exten => s,3,Playback(teste-protocolo)
exten => s,n,Gosub(protocolo,s,1)
exten => s,n,Dial(SIP/2003)
exten => s,n,Hangup

exten => s,1,NoOP(Protocolo)
exten => s,n,set(Protocolo=${STRFTIME(${EPOCH},GMT-3,%C%y%m%d)}.${CUT(UNIQUEID,.,2)})
exten => s,n,SayDigits(${Protocolo})
exten => s,n,Set(CDR(accountcode)=${Protocolo})
exten => s,n,Return

After that, I’m hearing the code perfectly!
Exactly how I wanted it.
For example: when calling for the fifth time, I heard the code “202303165”, because it was the fifth call.

When calling for the twentieth time, I heard “2023031620”, because it was the twentieth call (after restarting asterisk).

Now one last detail…
How can I use this number as an identifier for calls made at the PABX?
I mean, would it be possible for it to serve as a kind of UniqueID?

You could record it in the CDR userfield, which would allow you to find it again using CDR reports.

hi lorne!
I’m happy to talk to you!

in the “cdr reports” tab I was able to identify the search field by Userfield… but I couldn’t understand very well how I would make this number generated by the custom dialplan be stored and be available for search.

how would I make that number be recorded in the cdr userfield?

I managed to make it work like this:

exten => s,1,NoOP(Protocolo)
exten => s,n,set(Protocolo=${STRFTIME(${EPOCH},GMT-3,%C%y%m%d)}.${CUT(UNIQUEID,.,2)})
exten => s,n,SayDigits(${Protocolo})
exten => s,n,Set(CDR(userfield)=${Protocolo})
exten => s,n,Return

when searching for the number said by the IVR by the “userfield” field of the CDR reports, the call is identified.

the last question… is there a possibility that every call have this code in the cdr userfield?
as if it were working as a secondary uniqueid

I ask this because generating these custom identifiers for internal calls would also be interesting :grinning:

Dialplan hooks: Hooking for fun and income

Guys, good afternoon everyone!
I apologize for the delay in updating you, I ended up having a health problem and left for a few days.

I managed to make it work with this dialplan hook:

exten => s,1,NoOP(Gancho de pré-discagem chamado)
exten => s,n,Gosub(protocolo,s,1)
exten => s,n,MacroExit

exten => s,1,NoOP(Protocolo)
exten => s,n,set(Protocolo=${STRFTIME(${EPOCH},GMT-3,%C%y%m%d)}${CUT(UNIQUEID,.,2)})
exten => s,n,Set(CDR(userfield)=${Protocolo})
exten => s,n,Return

However, I noticed that when using it, the call takes a long time to start calling, there is a difference of approximately 7 to 10 seconds of delay until the user begin to hear the dial tone.

Is there something wrong with my dialplan hook that could be causing this delay?