12
12
using AutoMapper ;
13
13
using SmartTalk . Core . Constants ;
14
14
using Microsoft . AspNetCore . Http ;
15
+ using OpenAI . Chat ;
16
+ using SmartTalk . Core . Services . Agents ;
17
+ using SmartTalk . Core . Services . Http ;
15
18
using SmartTalk . Messages . Constants ;
16
19
using SmartTalk . Core . Services . Jobs ;
17
20
using SmartTalk . Core . Services . PhoneOrder ;
26
29
using SmartTalk . Messages . Events . AiSpeechAssistant ;
27
30
using SmartTalk . Messages . Commands . AiSpeechAssistant ;
28
31
using SmartTalk . Messages . Commands . PhoneOrder ;
32
+ using SmartTalk . Messages . Dto . Agent ;
29
33
using SmartTalk . Messages . Enums . PhoneOrder ;
30
34
using JsonSerializer = System . Text . Json . JsonSerializer ;
31
35
using RecordingResource = Twilio . Rest . Api . V2010 . Account . Call . RecordingResource ;
@@ -53,6 +57,9 @@ public class AiSpeechAssistantService : IAiSpeechAssistantService
53
57
private readonly OpenAiSettings _openAiSettings ;
54
58
private readonly TwilioSettings _twilioSettings ;
55
59
private readonly ZhiPuAiSettings _zhiPuAiSettings ;
60
+ private readonly IAgentDataProvider _agentDataProvider ;
61
+ private readonly IPhoneOrderService _phoneOrderService ;
62
+ private readonly ISmartTalkHttpClientFactory _httpClientFactory ;
56
63
private readonly IPhoneOrderDataProvider _phoneOrderDataProvider ;
57
64
private readonly ISmartTalkBackgroundJobClient _backgroundJobClient ;
58
65
private readonly IAiSpeechAssistantDataProvider _aiSpeechAssistantDataProvider ;
@@ -62,6 +69,9 @@ public AiSpeechAssistantService(
62
69
OpenAiSettings openAiSettings ,
63
70
TwilioSettings twilioSettings ,
64
71
ZhiPuAiSettings zhiPuAiSettings ,
72
+ IAgentDataProvider agentDataProvider ,
73
+ IPhoneOrderService phoneOrderService ,
74
+ ISmartTalkHttpClientFactory httpClientFactory ,
65
75
IPhoneOrderDataProvider phoneOrderDataProvider ,
66
76
ISmartTalkBackgroundJobClient backgroundJobClient ,
67
77
IAiSpeechAssistantDataProvider aiSpeechAssistantDataProvider )
@@ -70,6 +80,9 @@ public AiSpeechAssistantService(
70
80
_openAiSettings = openAiSettings ;
71
81
_twilioSettings = twilioSettings ;
72
82
_zhiPuAiSettings = zhiPuAiSettings ;
83
+ _phoneOrderService = phoneOrderService ;
84
+ _agentDataProvider = agentDataProvider ;
85
+ _httpClientFactory = httpClientFactory ;
73
86
_backgroundJobClient = backgroundJobClient ;
74
87
_phoneOrderDataProvider = phoneOrderDataProvider ;
75
88
_aiSpeechAssistantDataProvider = aiSpeechAssistantDataProvider ;
@@ -146,6 +159,28 @@ public async Task ReceivePhoneRecordingStatusCallbackAsync(ReceivePhoneRecording
146
159
147
160
record . Url = command . RecordingUrl ;
148
161
record . Status = PhoneOrderRecordStatus . Sent ;
162
+
163
+ var agent = await _agentDataProvider . GetAgentByIdAsync ( record . AgentId , cancellationToken : cancellationToken ) . ConfigureAwait ( false ) ;
164
+
165
+ ChatClient client = new ( "gpt-4o-audio-preview" , _openAiSettings . ApiKey ) ;
166
+ var audioFileRawBytes = await _httpClientFactory . GetAsync < byte [ ] > ( record . Url , cancellationToken ) . ConfigureAwait ( false ) ;
167
+ var audioData = BinaryData . FromBytes ( audioFileRawBytes ) ;
168
+ List < ChatMessage > messages =
169
+ [
170
+ new SystemChatMessage ( "你是一名電話錄音的分析員,通過聽取錄音內容和語氣情緒作出精確分析,冩出一份分析報告。\n \n 分析報告的格式:交談主題:xxx\n \n 內容摘要:xxx \n \n 客人情感與情緒: xxx \n \n 待辦事件: \n 1.xxx\n 2.xxx \n \n 客人下單內容(如果沒有則忽略):1. 牛肉(1箱)\n 2.雞腿肉(1箱)" ) ,
171
+ new UserChatMessage ( ChatMessageContentPart . CreateInputAudioPart ( audioData , ChatInputAudioFormat . Wav ) ) ,
172
+ new UserChatMessage ( "幫我根據錄音生成分析報告:" )
173
+ ] ;
174
+
175
+ ChatCompletionOptions options = new ( ) { ResponseModalities = ChatResponseModalities . Text } ;
176
+
177
+ ChatCompletion completion = await client . CompleteChatAsync ( messages , options , cancellationToken ) ;
178
+ Log . Information ( "sales record analyze report:" + completion . Content . FirstOrDefault ( ) ? . Text ) ;
179
+ record . TranscriptionText = completion . Content . FirstOrDefault ( ) ? . Text ;
180
+
181
+ if ( ! string . IsNullOrEmpty ( agent . WechatRobotKey ) )
182
+ await _phoneOrderService . SendWorkWeChatRobotNotifyAsync ( audioFileRawBytes , agent . WechatRobotKey , "錄音分析報告:\n " + record . TranscriptionText , cancellationToken ) . ConfigureAwait ( false ) ;
183
+
149
184
await _phoneOrderDataProvider . UpdatePhoneOrderRecordsAsync ( record , cancellationToken : cancellationToken ) . ConfigureAwait ( false ) ;
150
185
}
151
186
@@ -200,7 +235,9 @@ private async Task<WebSocket> ConnectOpenAiRealTimeSocketAsync(Domain.AISpeechAs
200
235
var url = string . IsNullOrEmpty ( assistant . Url ) ? AiSpeechAssistantStore . DefaultUrl : assistant . Url ;
201
236
202
237
await openAiWebSocket . ConnectAsync ( new Uri ( url ) , cancellationToken ) . ConfigureAwait ( false ) ;
238
+
203
239
await SendSessionUpdateAsync ( openAiWebSocket , assistant , prompt ) . ConfigureAwait ( false ) ;
240
+
204
241
return openAiWebSocket ;
205
242
}
206
243
@@ -401,7 +438,7 @@ private async Task SendToTwilioAsync(WebSocket twilioWebSocket, WebSocket openAi
401
438
}
402
439
}
403
440
404
- if ( ! context . InitialConversationSent )
441
+ if ( ! context . InitialConversationSent && ! string . IsNullOrEmpty ( context . Assistant . Greetings ) )
405
442
{
406
443
await SendInitialConversationItem ( openAiWebSocket , context ) ;
407
444
context . InitialConversationSent = true ;
@@ -697,7 +734,7 @@ private async Task SendSessionUpdateAsync(WebSocket openAiWebSocket, Domain.AISp
697
734
turn_detection = new { type = "server_vad" } ,
698
735
input_audio_format = "g711_ulaw" ,
699
736
output_audio_format = "g711_ulaw" ,
700
- voice = "alloy" ,
737
+ voice = string . IsNullOrEmpty ( assistant . Voice ) ? "alloy" : assistant . Voice ,
701
738
instructions = prompt ,
702
739
modalities = new [ ] { "text" , "audio" } ,
703
740
temperature = 0.8 ,
0 commit comments