FusionPBX Valet Park Fix
Issue
In certain FusionPBX configurations, the valet parking feature may fail to operate correctly when calls are parked using the SIP REFER method.
The issue is caused by the default valet_park dialplan regex, which may not correctly parse the Refer-To header in this format:
sip:park+*5901@domain.com:5060
Where to make changes:
In FusionPBX, go to:
Dialplan → Dialplan Manager
Open the dialplan entry:valet_park
Then click: XML
Edit the XML and update the required regex.
What needs to be changed:
1.Update the Refer-To host parsing regex
Find this condition:
<condition field="${sip_refer_to}" expression="(?:sip:)?@([^:]+)(?::\d+)?" break="never">
<action application="set" data="referred_by_host=$1" inline="true"/>
</condition>Replace it with:
<condition field="${sip_refer_to}" expression="(?:sip:)?[^@]+@([^:;>]+)(?::\d+)?" break="never">
<action application="set" data="referred_by_host=$1" inline="true"/>
</condition>What this change does
This change updates the regex used to parse the Refer-To header.
The original regex may not correctly detect the domain when Refer-To contains a SUP URI like:
sip:park+*5901@domain.com:5060
The updated regex correctly extracts the domain from this value, so FusionPBX can use the correct valet parking context.
Optional: upgrade the parking number regex
The original regex usually matches parking numbers like:
*5901park+*5901
Originaly:^(park)?\+?\*(59(0[1-9]|[1-9][0-9]))$
Updated:^(park\+)?\*?(59[0-9]{2})$
The updated regex allows more formats:5901*5901park+5901park+*5901
Important: this version also allows 5900.
Full updated XML example:
<extension name="valet_park" continue="false" uuid="731c41db-c777-4b3d-b1e6-dd56237741cf">
<condition field="destination_number" expression="^(park\+)?\*?(59(0[1-9]|[1-9][0-9]))$" break="never"/>
<condition field="${sip_refer_to}" expression="^.+$" break="never"/>
<condition field="${sip_refer_to}" expression="(?:sip:)?[^@]+@([^:;>]+)(?::\d+)?" break="never">
<action application="set" data="referred_by_host=$1" inline="true"/>
</condition>
<condition field="${sip_h_Referred-By}" expression="(?:sip:)?(\d+)(?:@.*)?" break="never">
<action application="set" data="referred_by_user=$1" inline="true"/>
</condition>
<condition field="destination_number" expression="^(park\+)?\*?(59(0[1-9]|[1-9][0-9]))$" break="never"/>
<condition field="${referred_by_user}" expression="^.+$" break="never">
<action application="set" data="valet_context=${referred_by_host}" inline="true"/>
<anti-action application="set" data="valet_context=${domain_name}" inline="true"/>
</condition>
<condition field="destination_number" expression="^(park\+)?\*?(59(0[1-9]|[1-9][0-9]))$" break="never">
<action application="set" data="park_in_use=false" inline="true"/>
<action application="set" data="park_lot=$2" inline="true"/>
<action application="info" data=""/>
</condition>
<condition field="destination_number" expression="^(park\+)?\*?(59(0[1-9]|[1-9][0-9]))$"/>
<condition field="${referred_by_user}" expression="^.+$" break="never">
<action application="set" data="valet_info_park=${valet_info park@${valet_context}}|\*${park_lot}" inline="true"/>
<action application="set" data="park_in_use=${regex ${valet_info park@${valet_context}}|\*${park_lot}}" inline="true"/>
</condition>
<condition field="${park_in_use}" expression="true" break="never">
<action application="transfer" data="${referred_by_user} XML ${referred_by_host}"/>
<anti-action application="set" data="effective_caller_id_name=${cond ${regex ${direction} | inbound} == true ? 'park#${caller_id_name}' : 'park#${callee_id_name}'}" inline="true"/>
<anti-action application="set" data="valet_parking_timeout=900"/>
<anti-action application="set" data="valet_hold_music=${hold_music}"/>
<anti-action application="set" data="valet_parking_orbit_exten=${cond ${regex ${referred_by_user} | ^$} == true ? ${sip_from_user} : ${referred_by_user}}"/>
<anti-action application="answer" data=""/>
<anti-action application="valet_park" data="park@${valet_context} *${park_lot}"/>
</condition>
</extension>After applying the change
After saving the XML:
Save → Reload XML
Then test call parking again.
The expected result is that FusionPBX correctly parses the Refer-To header, extracts the host/domain, and parks the call in the correct valet parking context.