Adding Listen, Whisper, and Barge to FreePBX or Asterisk

If you are running a call center on FreePBX or Asterisk, most likely you will want the ability to listen in on agents calls, also known as joining multiple calls, or connected two calls to a manager, or other variations of barging in on a bridged channel.

For the purpose of this article, we will define manager as the callee who is the spying channel, agent who is the spied-on channel, and client who is the bridged channel / 3rd party. We define listen, whisper, and barge as follows:

Listen: Monitor an agents call. The manager can hear both the agent and client channels, but no-one can hear the manager.

Whisper:  Whisper to the agent. The manager can hear both the agent and client channels, and the agent can also hear the manager, but the client can only hear the agent, hence “whisper.”

Barge: Barge in on both channels. The manager channel is joined onto the agent and client channels, and all parties can hear each other. Be warned, if the original agent leaves the call, the call is dropped. This is not a 3-way call.
(However you can barge in, and when comfortable, initiate a 3way call to your extension so you can continue the call without the agent. This procedure varies from client to client (soft/hard phones))

One more note: We can also provide 3-way calling [live transfer] services on the server side, however this is outside the scope of this document. Please contact us for details.

Enough chit-chat, let’s get to the dialplan!

Note: In newer versions of FreePBX, custom includes are disabled by default.
This means that the new “ext-local-custom” context’s that we are about to create won’t be imported into the PBX “Brain”. To fix this, go to :
Settings->Advanced Settings
Find the “Dialplan and Operational” section, and change Disable -custom Context Includes? to False.
Be sure to click on the little checkbox that appears to the right to save the setting, then Apply Settings to rebuild the files. This is required or else the ext-local-custom context that we add won’t be included into the engine.

This should be placed in /etc/asterisk/extensions_custom.conf for FreePBX

exten => _*222x.#,1,Macro(user-callerid,)
exten => _*222x.#,n,Answer
exten => _*222x.#,n,NoCDR
exten => _*222x.#,n,Wait(1)
exten => _*222x.#,n,ChanSpy(sip/${EXTEN:4},q)
exten => _*222x.#,n,Hangup

exten => _*223x.#,1,Macro(user-callerid,)
exten => _*223x.#,n,Answer
exten => _*223x.#,n,NoCDR
exten => _*223x.#,n,Wait(1)
exten => _*223x.#,n,ChanSpy(sip/${EXTEN:4},qw)
exten => _*223x.#,n,Hangup

exten => _*224x.#,1,Macro(user-callerid,)
exten => _*224x.#,n,Answer
exten => _*224x.#,n,NoCDR
exten => _*224x.#,n,Wait(1)
exten => _*224x.#,n,ChanSpy(SIP/${EXTEN:4},qB)
exten => _*224x.#,n,Hangup

For custom solutions, or troubleshooting support, call us @ 888.235.o5o5
If you found this useful, please donate $5, $10, or $25:

Let’s break it down:
Dialing *222970 would initiate listen on channel 970. *224401 would barge in on 401’s call speaking to both parties.

We start by finding (or adding) the ext-local-custom context, and declaring: exten => _*222x.# which will catch calls going to *222 followed by a sequence of numbers.

We define the first line with priority 1, and initiate Macro(user-callerid,) which basically sets the environment and loads up details about the extension, like caller id, and display name.

On the 2nd and subsequent lines, we start them the same way, and instead set priorty to n, this will let asterisk generate priorities automatically, so you don’t always have to change each priority just to add new code.

Expert Tip: We could have used same => n,Answer() and continued to use same. This is shorthand that was added later to asterisk, and just simplifies it that much more.

We answer the call on priority 2, then we tell asterisk’s cdr_mysql module not to store this “call” as a CDR record.

We wait a second with Wait(1) to give everything time to get ready, then we initialize the ChanSpy app. There are various options you can use, we chose q (which prevents “SIP.6626” or whatever from being spoken when you start spying.) w, which is “whisper mode”, and B which is barge. Do not get this confused with b (lowercase) which is for only joining bridged calls.

Lastly we hangup to prevent a floating channel, and we’re done!

Contact me: robert {-at-} ezpcweb {dot} com
To order a commercial feature, or to order a custom feature, call us at: 888.235.o5o5

If you found this useful, please consider sending a donation, I wouldn’t be asking if I didn’t think it was fair.
I give away these tools that are highly valuable for free, so if you can afford to do so, please donate towards web costs, and other endeavors.

Tagged with: , ,
Posted in FreePBX
50 comments on “Adding Listen, Whisper, and Barge to FreePBX or Asterisk
  1. Tom says:

    What if you want to monitor certain extensions that start with 8 such as 8001. Also, what if you want extension 8001 to be the ONLY one doing this functions (barge, listen, and whisper).
    Great post, thanks!

    • hackrr says:

      Glad you liked the post, hopefully it helped you.
      I have answers for your questions:

      To monitor only specific channels, for example 8100 – 8199, set the chanprefix parameter like so:
      exten => _*22481x.#,n,Chanspy(SIP/${EXTEN:4},qB)

      This would let you monitor channels starting with SIP/81. (Potentially change SIP/ to Local/, Agent/, or whatever your channel type is)

      This is a very simple method that will allow only a single extension the authority to barge. If you need to be able to manage a list of “authorized users”, then you should order our one of our commercial packages:

      exten => _*224x.#/8001,1,Macro(user-callerid,)
      exten => _*224x.#/8001,n,Answer

      You can also use the same notation to repeat the above expression, so if you wanted to allow people with extensions 8000-8009 (ie managers or something), you could do: (Don’t forget the _ before the CID this time as it denotes a pattern.)
      exten => _*224x.#/_800X,1,Macro(user-callerid,)
      same => n,Answer

  2. Jeff says:

    How many simultaneous barge/listen sessions can you do to a single call with this method? Is there a particular version of Asterisk that supports this?

    • hackrr says:

      I just tested 2 simultaneous listens, barges should work as well. You should be able to connect an unspecified number of calls to a session, basically chanspy just continues attaching (/bridging) the monitor channels to the original, almost like a conference call.

      Be aware however, I have found that under presently unknown circumstances, something can cause a ChanSpy’d channel to not ever be disconnected until asterisk is restarted. (Or possibly someone didn’t hang up, but it looks like the channel was just locked virtually). Errors would come up every 10 seconds (10000ms) because the channel couldn’t be terminated and “termination rescheduled for 10000”

      It is supported in asterisk since at least Asterisk 1.8, and still works in 10 + 11, anything prior is unsupported, and may or may not work at your own risk.

  3. Yehuda says:

    Thank you very much for all the detailed guide i found a lot gouides for this specific subject but none of them with such explain.

    Is it possible to use ChanSpy on recorded channel?

    • hackrr says:

      Yes, it’s definitely possible to use ChanSpy on recorded channels.

      If you want detailed help, consider using our forum, or else you could post a comment with your question, and I could write a reply with the details you need.

      Thanks for reading!

  4. Sung says:

    Thank you very much.
    Can I ask you question?
    Some of customer ask me to barge into a call.
    For example, ext 201 and ext 202 are now on the line, and ext 300 call the ext 201.
    At this time, ext 300 want to barge in ext 201 directly without line busy.
    Can I do this with the above?
    Thank you in advance.

    • hackrr says:

      I’m not sure what you’re asking.

      It sounds like 201 and 202 are on the phone with each other, and 300 wants to listen in. That’s exactly what this guide will work for. If you need more help please leave a detailed response.

  5. larry says:

    Hi, first of all thank you for your efforts for the telephony field. Which is too digital, Could i ask you a question and a solution. I have installed a PBX for our non-business purpose, its been working so great.. All the features are good.. but based on your article i pasted your script in extensions_custom.conf.. after that i reloaded.. it doesnt seems to be working.. when i dial *222 i get to listen nothing.. at the sametime there is no alert or beep as well.. is the sript i entered is it really acknowledged? Not sure what could have gone wrong.. Could you please review.. Thanks a lot.

    • hackrr says:

      *222 is just the beginning, after that you need to dial the extension that you wish to dial.

      The full number to dial would be *2225555 (*222extension)

  6. Abhishek says:


    First of all thank a lot for providing such a good guide, and God bless you for every thing which you need in your life.

    I have a question, please help me to find the solution.

    Currently I am running 5 Elastix/Freepbx server for 500 + users, for call making internal calls i have created sip trunk could you please tell me how to listen live calls of different servers from one server.

    • hackrr says:

      We have the code for this as well, however it falls under the “Commercial” class of code, so please contact us if you would like this or any other services!

  7. Marcin says:

    Thank you for your example, but how to listen to random calls and see in asterisk -rx ‘core show channels verbose’ information about what channel is tapped?

  8. Eskdale says:

    Thanks for the posting – works great although I have one question.
    One of my extensions is a DECT headset sometimes it would be nice to use an extension to dial DTMF tones the Barge (*224) connects a phone to the headset but the tones from the phone don’t get transmitted is – there anyway of doing this? – Thanks

    Alternatively is there a way of taking the call from the extension (Headset) back to a phone as there are no keys on the headset – as it it is, once its on the headset it can’t go anywhere after. It would be nice to conference with the headset and then let the headset drop the call with the phone taking it over – or any other method to this effect.


  9. Ali Hameed says:

    Very nice article but I found that any user can dial and listen/whisper/barge i,e you manager can listen to you and you can do the same to him if you know the feature code. It would be great if it will be only allowed from specific extensions with a pass code.



    • hackrr says:

      This can definitely be done, if anyone is interested in such functionality, please comment or email me, and you can purchase such code from us. We also offer support/troubleshooting, programming, etc.

  10. Rogerio Reis says:


    First of all, thanks a lot for que tip! Great job.

    Do you know if its possible to change the behavior between whisper or listen during the call?

    For example, you dial *222970 and start listen to the conversation, then you decide to whisper and press some key to change the behaviour.

    A hug from Brazil!


    • hackrr says:

      Yes it is possible.

      If you add the “d” option to the ChanSpy app, then you can switch between modes by pressing 4, 5, +6 (4: listen, 5: whisper, 6: barge)

      ;Change the line with ChanSpy on it to include the d flag. The q flag means ‘quiet’, you can try without it to hear the difference.
      exten => _*222x.#,n,ChanSpy(sip/${EXTEN:4},qd)

  11. Slaven says:


    This is a great post, I find a good use for it, and in matter of minutes I set it up, thanks to you “hackrr” 🙂

    I was wondering, is there a way only to allow certain extensions, let’s say 210 and 310 to be able to listen only 610 and 710 and with password protection as well.


    • hackrr says:

      This can be done with one of our commercial modules.

      You will then be able to manage authorized users by adding or removing extensions to a special Manager Queue in the FreePBX interface.

  12. Slaven says:


    This is my sample code now in extension_custom.conf:


    exten => _*222x.#/100,1,Macro(user-callerid,)
    exten => _*222x.#/100,n,Answer
    exten => _*222x.#/100,n,NoCDR
    exten => _*222x.#/100,n,Wait(1)
    exten => _*222x.#/100,n,ChanSpy(sip/65,q)
    exten => _*222x.#/100,n,Hangup

    This code above would allow only extension 100 to be able to listen on extensions that begins with 65, so that would be from 650-659.

    I was wondering if someone can help out with certain limitations that I would like to test, I would like to limit only 2 extensions to be able to listen on the other 2 extensions, so let’s say 200 and 300 should be able to listen to 210 and 310 only. Is this possible at all to do it?

    Thank you.

    Best Regards,


    • hackrr says:

      This can be accomplished using callerid pattern matching.
      This is accomplished the same as with extension pattern matching, see example:

      Instead of:
      exten => _*222x.#/100,1,Macro(user-callerid,)

      exten => _*222x.#/_[23]10,1,Macro(user-callerid,)

      I apologize for the tardiness of this comment, and be quicker in the future.

  13. Xavier says:

    In what file should I be adding this code?

    • hackrr says:

      If this is a pure asterisk installation, it should be in extensions.conf (the “goto” file loaded by the PBX system)

      However, if this is TrixBox/FreePBX/Elastix or similar, it should be added in extensions_custom.conf

      Just make sure that somewhere in extensions.conf you see the line:
      #include extensions_custom.conf

  14. Phil Curtis says:

    Great and timely article! I followed your instructions, however, when I dial *2221351 to Listen on ext 1351 the call fails and the Asterisk debug says rejected because extension not found in context ‘from-internal’.

    I’m using FreePBX version and Asterisk version 11.9.0

    Any ideas?

    • hackrr says:

      In newer versions of FreePBX, custom includes are disabled by default.

      To change this, go to
      Settings->Advanced Settings
      Find the “Dialplan and Operational” section, and change Disable -custom Context Includes? to False.
      Be sure to click on the little checkbox that appears to the right to save the setting, then Apply Settings to rebuild the files.

      I will update the main post with this issue.

  15. Ean Price says:

    Fantastic document. Very helpful. I do have a quick question. Is it possible to simply exclude a few select extensions of say the executive team? Otherwise using the basic configuration example at the start of the post.

    Thanks in advance!

    • hackrr says:

      The simple way to do this is to segregate executives from regular users.

      Let’s say you have executives in the block 200 – 299 and regular users are 300 – 999.

      In this case, you would only want to enable listening, etc for the regular users.

      All you have to do is change the part after *222 / *223 / *224 to this: [3456789]XX.

      The final code would like [for barge only, you need to interpolate the others]:

      exten => _*224[3456789]XX,1,Macro(user-callerid,)
      exten => _*224[3456789]XX,n,Answer
      exten => _*224[3456789]XX,n,NoCDR
      exten => _*224[3456789]XX,n,Wait(1)
      exten => _*224[3456789]XX,n,ChanSpy(SIP/${EXTEN:4},qB)
      exten => _*224[3456789]XX,n,Hangup

      This would allow barges only to extensions that begin with 3,4,5,6,7,8, or 9 and followed by any 2 digits.

  16. msamyk says:

    Is it possible to add a passcode so that only the managers are able to activate this function. The code works great, but now everyone can listen in on everyone else.

  17. Bruce says:


    Thanks for posting this.

    I’m having a problem, however. I tried modifying your script to only allow listening to extensions 140-149. When I try to listen, I get a busy signal. Your original script works fine. Here is what I changed:
    exten => _*22214x.#,1,Macro(user-callerid,)
    exten => _*22214x.#,n,Answer
    exten => _*22214x.#,n,NoCDR
    exten => _*22214x.#,n,Wait(1)
    exten => _*22214x.#,n,ChanSpy(sip/${EXTEN:4},q)
    exten => _*22214x.#,n,Hangup


    • hackrr says:

      I’m sure you’ve solved it by now, but if anyone needs help with a similar problem in the future, it is important to upload the verbose logs from a test call. Use a service like to upload log data.

      You’re problem is you’re adding the . after the X, which matches 1 or more characters. Since you already have X representing the number 0-9, you don’t need the dot.

  18. chuck says:

    I need to be pointed to a reference so I can parse lines like: exten=>_88XXXX,1,Chanspy(SIP/${EXTEN:2},b)
    I need to be able to read this line and understand all the component pieces. Is there such a reference?

    I see lots of references to options etc, but the basic layout, the syntax of all of this is something I am missing. If I can learn how to parse the examples and to assembly my own I should be up and running. I have lots of code writing since 1977 in may languages including several assembly languages, so code writing is nothing new to me. But Asterisk is.

  19. M. zaker says:

    so thanks for your helpful article
    In my company there are two sales manager that I want let theme spy on their own clerks.
    for example
    my ext number is 110 and sales managers ext numbers are 200 and 250
    I want that I have the authorization to listen whisper and barge all ext from my own ext (110)
    and the sales managers as shown below:
    ext 200 can spy on just ext [201,202,…,249]
    ext 250 can spy on just ext [251,252,…,299]
    ext 110 can spy all extensions

    respectfully yours.

    • hackrr says:

      We do this all the time! It does require a paid consultancy, however. If you’re interested, the phone number is on this page 🙂

  20. Richard Welsing says:

    PLEASE I an a newbie to FreePBX and i would want to implement the LISTEN, WHISPER AND BARGE.

    With the code you put up where and how do i find where to input the “ext-local-custom context” codes?

  21. Aeon says:

    Ok I like the walkthrough and the explaination and everything but it doesnt say where I go to actually create the custom file or how I do that.

    So I read this part:-

    “This means that the new “ext-local-custom” or “from-internal-custom” context’s that we just created won’t be imported into the PBX “Brain”.”

    and was like….what when did we create that.

    Some additional info on how I actually create the ext-local-custom file and how i reference it would be nice. Company is looking for a feature like this.

    • hackrr says:

      This was never intended to be a walk-through, however over time I have updated it to help people better, though it may require a small amount of experience.

      “ext-local-custom” is not a file, it is a context. And it is defined in the extensions_custom.conf file (in FreePBX/elastix/etc. On plain asterisk use extensions.conf)

      Good luck!

  22. GMAN says:

    Is it possible to notify the monitored extension that they are being monitored? The imitating extension hears an alert instead of the monitored extension.

  23. Mark Fitzpatrick says:

    Hi Robert,

    I have followed your instructions and I don’t seem to be able to get this working. I have the codes in extensions-custom.conf and I have ensured 555 feature code is disabled and “Disable -custom Context Includes” is set to false.

    I have rebooted everything.

    All I get is “All circuits are busy” when trying to dial to an extension to listen, for example 555201.


    exten => *555x.#,1,Macro(user-callerid,)
    exten => 555x.#,n,Answer
    exten => _555x.#,n,NoCDR
    exten => *555x.#,n,Wait(1)
    exten => 555x.#,n,ChanSpy(SIP/${EXTEN:4},q)
    exten => _555x.#,n,Hangup

    Any ideas if I have missed something.

    • hackrr says:

      Would need to see the logs related to the call, with verbose logging on. (full) Only the section related to the call, of course. Use to upload logs.

      However, I can tell just from your dialplan that you’re doing something wrong.

      You have a mix of *555x, 555x, _555x, which is dead wrong. The extension patterns need to all be the same. In your case, they should all be _555x#

      As in:

      exten => _555x.#,1,Macro(user-callerid,)
      exten => _555x.#,n,Answer
      exten => _555x.#,n,NoCDR
      exten => _555x.#,n,Wait(1)
      exten => _555x.#,n,ChanSpy(SIP/${EXTEN:4},q)
      exten => _555x.#,n,Hangup

      Also, if you still have trouble, it doesn’t hurt to double check extensions.conf and make sure that extensions_custom.conf is included

  24. Mike says:


    is there a way to require a password for the listen feature? whether it be after the *222 or after the extension?


    • hackrr says:

      Yes, this can be done.

      If interested in hiring us to do it, you may call 888.235.o5o5. (Estimated cost $300)

      Otherwise you can study the asterisk book online for free, which should tell you everything you need to know you do it.

  25. Ralph says:

    Hi were curently running trixbox v2.2.2 with asterisk After followed the steps on this forum. Im not able to barge to specific extension ican only listen to their conversation. I cant join to their conversation. PLease help how i able to do the barging when ican both talk to them when i do the barging.

    • Ralph says:

      Here’s what i did i install new trixbox v2.6.2.2 with Asterisk 1.4.22-3 but i have no luck make it work.

      when i try to dial *224+ the ext number.. im only hearing there conversation but not able to barge to their conversation. what i did wrong??

      here’s the script i copy to this forum in extnesion_custom.conf

      exten => _*222x.#,1,Macro(user-callerid,)
      exten => _*222x.#,n,Answer
      exten => _*222x.#,n,NoCDR
      exten => _*222x.#,n,Wait(1)
      exten => _*222x.#,n,ChanSpy(sip/${EXTEN:4},q)
      exten => _*222x.#,n,Hangup

      exten => _*223x.#,1,Macro(user-callerid,)
      exten => _*223x.#,n,Answer
      exten => _*223x.#,n,NoCDR
      exten => _*223x.#,n,Wait(1)
      exten => _*223x.#,n,ChanSpy(sip/${EXTEN:4},qw)
      exten => _*223x.#,n,Hangup

      exten => _*224x.#,1,Macro(user-callerid,)
      exten => _*224x.#,n,Answer
      exten => _*224x.#,n,NoCDR
      exten => _*224x.#,n,Wait(1)
      exten => _*224x.#,n,ChanSpy(SIP/${EXTEN:4},qB)
      exten => _*224x.#,n,Hangup

    • hackrr says:

      The barge option is not available in asterisk 1.2

Leave a Reply

Your email address will not be published. Required fields are marked *