@@ -32,7 +32,7 @@ public TwilioVoiceController(TwilioSetting settings, IServiceProvider services,
32
32
/// <exception cref="ArgumentNullException"></exception>
33
33
[ ValidateRequest ]
34
34
[ HttpPost ( "twilio/voice/welcome" ) ]
35
- public async Task < TwiMLResult > InitiateConversation ( VoiceRequest request , [ FromQuery ] string states , [ FromQuery ] string intent )
35
+ public async Task < TwiMLResult > InitiateConversation ( VoiceRequest request , [ FromQuery ] string [ ] states , [ FromQuery ] string intent )
36
36
{
37
37
if ( request ? . CallSid == null )
38
38
{
@@ -44,7 +44,7 @@ public async Task<TwiMLResult> InitiateConversation(VoiceRequest request, [FromQ
44
44
VoiceResponse response ;
45
45
if ( string . IsNullOrWhiteSpace ( intent ) )
46
46
{
47
- var url = $ "twilio/voice/{ conversationId } /receive/0?states= { states } ";
47
+ var url = $ "twilio/voice/{ conversationId } /receive/0?{ GenerateStatesParameter ( states ) } ";
48
48
response = twilio . ReturnNoninterruptedInstructions ( new List < string > { "twilio/welcome.mp3" } , url , true , timeout : 2 ) ;
49
49
}
50
50
else
@@ -62,14 +62,14 @@ public async Task<TwiMLResult> InitiateConversation(VoiceRequest request, [FromQ
62
62
States = ParseStates ( states )
63
63
} ;
64
64
await messageQueue . EnqueueAsync ( callerMessage ) ;
65
- response = new VoiceResponse ( ) . Redirect ( new Uri ( $ "{ _settings . CallbackHost } /twilio/voice/{ conversationId } /reply/{ seqNum } ?states= { states } ") , HttpMethod . Post ) ;
65
+ response = new VoiceResponse ( ) . Redirect ( new Uri ( $ "{ _settings . CallbackHost } /twilio/voice/{ conversationId } /reply/{ seqNum } ?{ GenerateStatesParameter ( states ) } ") , HttpMethod . Post ) ;
66
66
}
67
67
return TwiML ( response ) ;
68
68
}
69
69
70
70
[ ValidateRequest ]
71
71
[ HttpPost ( "twilio/voice/{conversationId}/receive/{seqNum}" ) ]
72
- public async Task < TwiMLResult > ReceiveCallerMessage ( [ FromRoute ] string conversationId , [ FromRoute ] int seqNum , [ FromQuery ] string states , VoiceRequest request , [ FromQuery ] int attempts = 1 )
72
+ public async Task < TwiMLResult > ReceiveCallerMessage ( [ FromRoute ] string conversationId , [ FromRoute ] int seqNum , [ FromQuery ] string [ ] states , VoiceRequest request , [ FromQuery ] int attempts = 1 )
73
73
{
74
74
var twilio = _services . GetRequiredService < TwilioService > ( ) ;
75
75
var messageQueue = _services . GetRequiredService < TwilioMessageQueue > ( ) ;
@@ -99,7 +99,7 @@ public async Task<TwiMLResult> ReceiveCallerMessage([FromRoute] string conversat
99
99
} ;
100
100
await messageQueue . EnqueueAsync ( callerMessage ) ;
101
101
102
- response = new VoiceResponse ( ) . Redirect ( new Uri ( $ "{ _settings . CallbackHost } /twilio/voice/{ conversationId } /reply/{ seqNum } ?states= { states } ") , HttpMethod . Post ) ;
102
+ response = new VoiceResponse ( ) . Redirect ( new Uri ( $ "{ _settings . CallbackHost } /twilio/voice/{ conversationId } /reply/{ seqNum } ?{ GenerateStatesParameter ( states ) } ") , HttpMethod . Post ) ;
103
103
}
104
104
else
105
105
{
@@ -117,11 +117,11 @@ public async Task<TwiMLResult> ReceiveCallerMessage([FromRoute] string conversat
117
117
speechPaths . Add ( $ "twilio/say-it-again-{ Random . Shared . Next ( 1 , 5 ) } .mp3") ;
118
118
speechPaths . Add ( $ "twilio/voice/speeches/{ conversationId } /{ lastRepy . SpeechFileName } ") ;
119
119
}
120
- response = twilio . ReturnInstructions ( speechPaths , $ "twilio/voice/{ conversationId } /receive/{ seqNum } ?states= { states } ", true ) ;
120
+ response = twilio . ReturnInstructions ( speechPaths , $ "twilio/voice/{ conversationId } /receive/{ seqNum } ?{ GenerateStatesParameter ( states ) } ", true ) ;
121
121
}
122
122
else
123
123
{
124
- response = twilio . ReturnInstructions ( null , $ "twilio/voice/{ conversationId } /receive/{ seqNum } ?states= { states } &attempts={ ++ attempts } ", true ) ;
124
+ response = twilio . ReturnInstructions ( null , $ "twilio/voice/{ conversationId } /receive/{ seqNum } ?{ GenerateStatesParameter ( states ) } &attempts={ ++ attempts } ", true ) ;
125
125
}
126
126
}
127
127
return TwiML ( response ) ;
@@ -130,7 +130,7 @@ public async Task<TwiMLResult> ReceiveCallerMessage([FromRoute] string conversat
130
130
[ ValidateRequest ]
131
131
[ HttpPost ( "twilio/voice/{conversationId}/reply/{seqNum}" ) ]
132
132
public async Task < TwiMLResult > ReplyCallerMessage ( [ FromRoute ] string conversationId , [ FromRoute ] int seqNum ,
133
- [ FromQuery ] string states , VoiceRequest request )
133
+ [ FromQuery ] string [ ] states , VoiceRequest request )
134
134
{
135
135
var nextSeqNum = seqNum + 1 ;
136
136
var sessionManager = _services . GetRequiredService < ITwilioSessionManager > ( ) ;
@@ -185,7 +185,7 @@ public async Task<TwiMLResult> ReplyCallerMessage([FromRoute] string conversatio
185
185
segIndex ++ ;
186
186
}
187
187
}
188
- response = twilio . ReturnInstructions ( speechPaths , $ "twilio/voice/{ conversationId } /reply/{ seqNum } ?states= { states } ", true ) ;
188
+ response = twilio . ReturnInstructions ( speechPaths , $ "twilio/voice/{ conversationId } /reply/{ seqNum } ?{ GenerateStatesParameter ( states ) } ", true ) ;
189
189
await sessionManager . RemoveReplyIndicationAsync ( conversationId , seqNum ) ;
190
190
}
191
191
else
@@ -208,7 +208,7 @@ public async Task<TwiMLResult> ReplyCallerMessage([FromRoute] string conversatio
208
208
instructions . Add ( $ "twilio/typing-{ typingIndex } .mp3") ;
209
209
}
210
210
211
- response = twilio . ReturnInstructions ( instructions , $ "twilio/voice/{ conversationId } /reply/{ seqNum } ?states= { states } ", true ) ;
211
+ response = twilio . ReturnInstructions ( instructions , $ "twilio/voice/{ conversationId } /reply/{ seqNum } ?{ GenerateStatesParameter ( states ) } ", true ) ;
212
212
}
213
213
}
214
214
else
@@ -226,7 +226,7 @@ public async Task<TwiMLResult> ReplyCallerMessage([FromRoute] string conversatio
226
226
response = twilio . ReturnInstructions ( new List < string >
227
227
{
228
228
$ "twilio/voice/speeches/{ conversationId } /{ reply . SpeechFileName } "
229
- } , $ "twilio/voice/{ conversationId } /receive/{ nextSeqNum } ?states= { states } ", true , hints : reply . Hints ) ;
229
+ } , $ "twilio/voice/{ conversationId } /receive/{ nextSeqNum } ?{ GenerateStatesParameter ( states ) } ", true , hints : reply . Hints ) ;
230
230
}
231
231
}
232
232
@@ -246,22 +246,30 @@ public async Task<FileContentResult> GetSpeechFile([FromRoute] string conversati
246
246
return result ;
247
247
}
248
248
249
- private Dictionary < string , string > ParseStates ( string ? states )
249
+ private Dictionary < string , string > ParseStates ( string [ ] states )
250
250
{
251
251
var result = new Dictionary < string , string > ( ) ;
252
- if ( string . IsNullOrWhiteSpace ( states ) )
252
+ if ( states is null || ! states . Any ( ) )
253
253
{
254
254
return result ;
255
255
}
256
- var kvps = states . Split ( ',' , StringSplitOptions . TrimEntries | StringSplitOptions . RemoveEmptyEntries ) ;
257
- foreach ( var kvp in kvps )
256
+ foreach ( var kvp in states )
258
257
{
259
- var parts = kvp . Split ( ':' ) ;
258
+ var parts = kvp . Split ( ':' , StringSplitOptions . TrimEntries | StringSplitOptions . RemoveEmptyEntries ) ;
260
259
if ( parts . Length == 2 )
261
260
{
262
261
result . Add ( parts [ 0 ] , parts [ 1 ] ) ;
263
262
}
264
263
}
265
264
return result ;
266
265
}
266
+
267
+ private string GenerateStatesParameter ( string [ ] states )
268
+ {
269
+ if ( states is null || states . Length == 0 )
270
+ {
271
+ return null ;
272
+ }
273
+ return string . Join ( "&" , states . Select ( x => $ "states={ x } ") ) ;
274
+ }
267
275
}
0 commit comments