التشغيل السريع: إجراء مكالمة صادرة باستخدام أتمتة المكالمات

تعد واجهات برمجة تطبيقات Azure Communication Services Call Automation طريقة قوية لإنشاء تجارب اتصال تفاعلية. في هذه البداية السريعة، نغطي طريقة لإجراء مكالمة صادرة والتعرف على الأحداث المختلفة في المكالمة.

المتطلبات الأساسية

  • حساب Azure مع اشتراك نشط. أنشئ حساباً مجاناً.
  • تم نشر مورد Communication Services. إنشاء مورد Communication Services
  • رقم هاتف في مورد Azure Communication Services يمكنه إجراء مكالمات صادرة. إذا كان لديك اشتراك مجاني، يمكنك الحصول على رقم هاتف تجريبي.
  • إنشاء نفق Azure Dev واستضافته. التعليمات هنا.
  • إنشاء خدمات Azure الذكاء الاصطناعي متعددة الخدمات وتوصيلها بمورد Azure Communication Services.
  • إنشاء مجال فرعي مخصص لمورد خدمات Azure الذكاء الاصطناعي.
  • (اختياري) مستخدم Microsoft Teams لديه ترخيص هاتف تم تمكينه voice . مطلوب ترخيص هاتف Teams لإضافة مستخدمي Teams إلى المكالمة. تعرف على المزيد حول تراخيص Teams هنا. تعرف على كيفية تمكين نظام الهاتف من voiceهنا.

التعليمة البرمجية العينة

قم بتنزيل أو استنساخ نموذج التعليمات البرمجية للتشغيل السريع من GitHub.

انتقل إلى CallAutomation_OutboundCalling المجلد وافتح الحل في محرر التعليمات البرمجية.

إعداد Azure DevTunnel واستضافته

Azure DevTunnels هي خدمة Azure تمكنك من مشاركة خدمات الويب المحلية المستضافة على الإنترنت. قم بتشغيل الأوامر لتوصيل بيئة التطوير المحلية بالإنترنت العام. ينشئ DevTunnels عنوان URL ثابت لنقطة النهاية والذي يسمح بالوصول المجهول. نستخدم نقطة النهاية هذه لإعلام تطبيقك باستدعاء الأحداث من خدمة Azure Communication Services Call Automation.

devtunnel create --allow-anonymous
devtunnel port create -p 8080
devtunnel host

تحديث تكوين التطبيق الخاص بك

بعد ذلك، قم بتحديث الملف بالقيم Program.cs التالية:

  • acsConnectionString: سلسلة الاتصال لمورد Azure Communication Services. يمكنك العثور على Azure Communication Services سلسلة الاتصال باستخدام الإرشادات هنا.
  • callbackUriHost: بمجرد تهيئة مضيف DevTunnel، قم بتحديث هذا الحقل باستخدام عنوان URI هذا.
  • acsPhonenumber: قم بتحديث هذا الحقل برقم هاتف Azure Communication Services الذي حصلت عليه. يجب أن يستخدم رقم الهاتف هذا تنسيق رقم هاتف E164 (على سبيل المثال + 18881234567)
  • targetPhonenumber: حقل التحديث برقم الهاتف الذي ترغب في أن يتصل به تطبيقك. يجب أن يستخدم رقم الهاتف هذا تنسيق رقم هاتف E164 (على سبيل المثال + 18881234567)
  • cognitiveServiceEndpoint: تحديث الحقل باستخدام نقطة نهاية خدمات Azure الذكاء الاصطناعي.
  • targetTeamsUserId: (اختياري) حقل التحديث مع معرف مستخدم Microsoft Teams الذي ترغب في إضافته إلى المكالمة. راجع استخدام واجهة برمجة تطبيقات Graph للحصول على معرف مستخدم Teams.
// Your ACS resource connection string 
var acsConnectionString = "<ACS_CONNECTION_STRING>"; 

// Your ACS resource phone number will act as source number to start outbound call 
var acsPhonenumber = "<ACS_PHONE_NUMBER>"; 
 
// Target phone number you want to receive the call. 
var targetPhonenumber = "<TARGET_PHONE_NUMBER>";

// Base url of the app 
var callbackUriHost = "<CALLBACK_URI_HOST_WITH_PROTOCOL>"; 

// Your cognitive service endpoint 
var cognitiveServiceEndpoint = "<COGNITIVE_SERVICE_ENDPOINT>";

// (Optional) User Id of the target teams user you want to receive the call.
var targetTeamsUserId = "<TARGET_TEAMS_USER_ID>";

إجراء مكالمة صادرة

لإجراء الاستدعاء الصادر من Azure Communication Services، يستخدم targetPhonenumber هذا النموذج الذي حددته سابقا في التطبيق لإنشاء الاستدعاء باستخدام CreateCallAsync واجهة برمجة التطبيقات. سيقوم هذا الرمز بإجراء مكالمة صادرة باستخدام رقم الهاتف الهدف.

PhoneNumberIdentifier target = new PhoneNumberIdentifier(targetPhonenumber);
PhoneNumberIdentifier caller = new PhoneNumberIdentifier(acsPhonenumber);
var callbackUri = new Uri(callbackUriHost + "/api/callbacks");
CallInvite callInvite = new CallInvite(target, caller);
var createCallOptions = new CreateCallOptions(callInvite, callbackUri) {
  CallIntelligenceOptions = new CallIntelligenceOptions() {
    CognitiveServicesEndpoint = new Uri(cognitiveServiceEndpoint)
  }
};
CreateCallResult createCallResult = await callAutomationClient.CreateCallAsync(createCallOptions);

معالجة أحداث أتمتة المكالمات

في وقت سابق من تطبيقنا، قمنا بتسجيل callbackUriHost إلى خدمة أتمتة المكالمات. يشير المضيف إلى نقطة النهاية التي تتطلبها الخدمة لإعلامنا باستدعاء الأحداث التي تحدث. يمكننا بعد ذلك التكرار من خلال الأحداث والكشف عن أحداث محددة يريد تطبيقنا فهمها. في التعليمات البرمجية أدناه، نستجيب للحدث CallConnected .

app.MapPost("/api/callbacks", async (CloudEvent[] cloudEvents, ILogger < Program > logger) => {
  foreach(var cloudEvent in cloudEvents) {
    logger.LogInformation($"Event received: {JsonConvert.SerializeObject(cloudEvent)}");
    CallAutomationEventBase parsedEvent = CallAutomationEventParser.Parse(cloudEvent);
    logger.LogInformation($"{parsedEvent?.GetType().Name} parsedEvent received for call connection id: {parsedEvent?.CallConnectionId}");
    var callConnection = callAutomationClient.GetCallConnection(parsedEvent.CallConnectionId);
    var callMedia = callConnection.GetCallMedia();
    if (parsedEvent is CallConnected) {
      //Handle Call Connected Event
    }
  }
});

(اختياري) إضافة مستخدم Microsoft Teams إلى المكالمة

يمكنك إضافة مستخدم Microsoft Teams إلى المكالمة باستخدام AddParticipantAsync الأسلوب مع MicrosoftTeamsUserIdentifier معرف مستخدم Teams و. تحتاج أولا إلى إكمال خطوة المتطلبات الأساسية التخويل لمورد Azure Communication Services لتمكين الاتصال لمستخدمي Microsoft Teams. اختياريا، يمكنك أيضا تمرير للتحكم في SourceDisplayName النص المعروض في الإعلام المنبثق لمستخدم Teams.

await callConnection.AddParticipantAsync(
    new CallInvite(new MicrosoftTeamsUserIdentifier(targetTeamsUserId))
    {
        SourceDisplayName = "Jack (Contoso Tech Support)"
    });

بدء تسجيل مكالمة

تتيح خدمة أتمتة المكالمات أيضا القدرة على بدء تسجيل وتخزين تسجيلات المكالمات الصوتية ومكالمات الفيديو. يمكنك معرفة المزيد حول الإمكانات المختلفة في واجهات برمجة التطبيقات لتسجيل المكالمات هنا.

CallLocator callLocator = new ServerCallLocator(parsedEvent.ServerCallId);
var recordingResult = await callAutomationClient.GetCallRecording().StartAsync(new StartRecordingOptions(callLocator));
recordingId = recordingResult.Value.RecordingId;

تشغيل رسالة الترحيب والتعرف عليها

TextSourceباستخدام ، يمكنك تزويد الخدمة بالنص الذي تريد تركيبه واستخدامه لرسالة الترحيب. تقوم خدمة Azure Communication Services Call Automation بتشغيل هذه الرسالة عند CallConnected الحدث.

بعد ذلك، نقوم بتمرير النص إلى CallMediaRecognizeChoiceOptions ثم استدعاء StartRecognizingAsync. يسمح هذا للتطبيق الخاص بك بالتعرف على الخيار الذي يختاره المتصل.

if (parsedEvent is CallConnected callConnected) {
  logger.LogInformation($"Start Recording...");
  CallLocator callLocator = new ServerCallLocator(parsedEvent.ServerCallId);
  var recordingResult = await callAutomationClient.GetCallRecording().StartAsync(new StartRecordingOptions(callLocator));
  recordingId = recordingResult.Value.RecordingId;

  var choices = GetChoices();

  // prepare recognize tones 
  var recognizeOptions = GetMediaRecognizeChoiceOptions(mainMenu, targetPhonenumber, choices);

  // Send request to recognize tones 
  await callMedia.StartRecognizingAsync(recognizeOptions);
}

CallMediaRecognizeChoiceOptions GetMediaRecognizeChoiceOptions(string content, string targetParticipant, List < RecognitionChoice > choices, string context = "") {
  var playSource = new TextSource(content) {
    VoiceName = SpeechToTextVoice
  };

  var recognizeOptions = new CallMediaRecognizeChoiceOptions(targetParticipant: new PhoneNumberIdentifier(targetParticipant), choices) {
    InterruptCallMediaOperation = false,
      InterruptPrompt = false,
      InitialSilenceTimeout = TimeSpan.FromSeconds(10),
      Prompt = playSource,
      OperationContext = context
  };
  return recognizeOptions;
}

List < RecognitionChoice > GetChoices() {
  return new List < RecognitionChoice > {
    new RecognitionChoice("Confirm", new List < string > {
      "Confirm",
      "First",
      "One"
    }) {
      Tone = DtmfTone.One
    },
    new RecognitionChoice("Cancel", new List < string > {
      "Cancel",
      "Second",
      "Two"
    }) {
      Tone = DtmfTone.Two
    }
  };
}

معالجة أحداث الاختيار

يقوم Azure Communication Services Call Automation بتشغيل api/callbacks خطاف الويب الذي قمنا بإعداده وسيعلمنا بالحدث RecognizeCompleted . يمنحنا الحدث القدرة على الاستجابة للمدخلات المستلمة وتشغيل إجراء. ثم يقوم التطبيق بتشغيل رسالة إلى المتصل استنادا إلى الإدخال المحدد المستلم.

if (parsedEvent is RecognizeCompleted recognizeCompleted) {
  var choiceResult = recognizeCompleted.RecognizeResult as ChoiceResult;
  var labelDetected = choiceResult?.Label;
  var phraseDetected = choiceResult?.RecognizedPhrase;

  // If choice is detected by phrase, choiceResult.RecognizedPhrase will have the phrase detected,  
  // If choice is detected using dtmf tone, phrase will be null  
  logger.LogInformation("Recognize completed succesfully, labelDetected={labelDetected}, phraseDetected={phraseDetected}", labelDetected, phraseDetected);

  var textToPlay = labelDetected.Equals(ConfirmChoiceLabel, StringComparison.OrdinalIgnoreCase) ? ConfirmedText : CancelText;

  await HandlePlayAsync(callMedia, textToPlay);
}

async Task HandlePlayAsync(CallMedia callConnectionMedia, string text) {
  // Play goodbye message 
  var GoodbyePlaySource = new TextSource(text) {
    VoiceName = "en-US-NancyNeural"
  };
  await callConnectionMedia.PlayToAllAsync(GoodbyePlaySource);
}

قطع التسجيل وإيقافه

وأخيرا، عندما نكتشف شرطا منطقيا بالنسبة لنا لإنهاء المكالمة، يمكننا استخدام HangUpAsync الأسلوب لتعليق المكالمة.

if ((parsedEvent is PlayCompleted) || (parsedEvent is PlayFailed))
{
    logger.LogInformation($"Stop recording and terminating call.");
    callAutomationClient.GetCallRecording().Stop(recordingId);
    await callConnection.HangUpAsync(true);
}

تشغيل التعليمات البرمجية

لتشغيل التطبيق باستخدام VS Code، افتح نافذة Terminal وقم بتشغيل الأمر التالي

dotnet run

المتطلبات الأساسية

  • حساب Azure مع اشتراك نشط. أنشئ حساباً مجاناً.
  • تم نشر مورد Communication Services. إنشاء مورد Communication Services
  • رقم هاتف في مورد Azure Communication Services يمكنه إجراء مكالمات صادرة. إذا كان لديك اشتراك مجاني، يمكنك الحصول على رقم هاتف تجريبي.
  • إنشاء نفق Azure Dev واستضافته. التعليمات هنا.
  • إنشاء خدمات Azure الذكاء الاصطناعي متعددة الخدمات وتوصيلها بمورد Azure Communication Services.
  • إنشاء مجال فرعي مخصص لمورد خدمات Azure الذكاء الاصطناعي.
  • Java Development Kit (JDK) الإصدار 11 أو أعلى.
  • Apache Maven.
  • (اختياري) مستخدم Microsoft Teams لديه ترخيص هاتف تم تمكينه voice . مطلوب ترخيص هاتف Teams لإضافة مستخدمي Teams إلى المكالمة. تعرف على المزيد حول تراخيص Teams هنا. لمزيد من المعلومات لتمكينه voice على نظام الهاتف، راجع إعداد نظام الهاتف.

التعليمة البرمجية العينة

قم بتنزيل أو استنساخ نموذج التعليمات البرمجية للتشغيل السريع من GitHub.

انتقل إلى CallAutomation_OutboundCalling المجلد وافتح الحل في محرر التعليمات البرمجية.

إعداد Azure DevTunnel واستضافته

Azure DevTunnels هي خدمة Azure تمكنك من مشاركة خدمات الويب المحلية المستضافة على الإنترنت. قم بتشغيل أوامر DevTunnel لتوصيل بيئة التطوير المحلية بالإنترنت العام. يقوم DevTunnels بعد ذلك بإنشاء نفق بعنوان URL لنقطة النهاية الثابتة والذي يسمح بالوصول المجهول. تستخدم Azure Communication Services نقطة النهاية هذه لإعلام التطبيق الخاص بك باستدعاء الأحداث من خدمة Azure Communication Services Call Automation.

devtunnel create --allow-anonymous
devtunnel port create -p MY_SPRINGAPP_PORT
devtunnel host

تحديث تكوين التطبيق الخاص بك

ثم افتح application.yml الملف في /resources المجلد لتكوين القيم التالية:

  • connectionstring: سلسلة الاتصال لمورد Azure Communication Services. يمكنك العثور على Azure Communication Services سلسلة الاتصال باستخدام الإرشادات هنا.
  • basecallbackuri: بمجرد تهيئة مضيف DevTunnel، قم بتحديث هذا الحقل باستخدام عنوان URI هذا.
  • callerphonenumber: قم بتحديث هذا الحقل برقم هاتف Azure Communication Services الذي حصلت عليه. يجب أن يستخدم رقم الهاتف هذا تنسيق رقم هاتف E164 (على سبيل المثال + 18881234567)
  • targetphonenumber: حقل التحديث برقم الهاتف الذي ترغب في أن يتصل به تطبيقك. يجب أن يستخدم رقم الهاتف هذا تنسيق رقم هاتف E164 (على سبيل المثال + 18881234567)
  • cognitiveServiceEndpoint: تحديث الحقل باستخدام نقطة نهاية خدمات Azure الذكاء الاصطناعي.
  • targetTeamsUserId: (اختياري) حقل التحديث مع معرف مستخدم Microsoft Teams الذي ترغب في إضافته إلى المكالمة. راجع استخدام واجهة برمجة تطبيقات Graph للحصول على معرف مستخدم Teams.
acs:
  connectionstring: <YOUR ACS CONNECTION STRING> 
  basecallbackuri: <YOUR DEV TUNNEL ENDPOINT> 
  callerphonenumber: <YOUR ACS PHONE NUMBER ex. "+1425XXXAAAA"> 
  targetphonenumber: <YOUR TARGET PHONE NUMBER ex. "+1425XXXAAAA"> 
  cognitiveServiceEndpoint: <YOUR COGNITIVE SERVICE ENDPOINT>
  targetTeamsUserId: <(OPTIONAL) YOUR TARGET TEAMS USER ID ex. "ab01bc12-d457-4995-a27b-c405ecfe4870">

إجراء مكالمة صادرة وتشغيل الوسائط

لإجراء الاستدعاء الصادر من Azure Communication Services، يستخدم targetphonenumber هذا النموذج الذي حددته في application.yml الملف لإنشاء الاستدعاء باستخدام createCallWithResponse واجهة برمجة التطبيقات.

PhoneNumberIdentifier caller = new PhoneNumberIdentifier(appConfig.getCallerphonenumber());
PhoneNumberIdentifier target = new PhoneNumberIdentifier(appConfig.getTargetphonenumber());
CallInvite callInvite = new CallInvite(target, caller);
CreateCallOptions createCallOptions = new CreateCallOptions(callInvite, appConfig.getCallBackUri());
CallIntelligenceOptions callIntelligenceOptions = new CallIntelligenceOptions().setCognitiveServicesEndpoint(appConfig.getCognitiveServiceEndpoint());
createCallOptions = createCallOptions.setCallIntelligenceOptions(callIntelligenceOptions);
Response<CreateCallResult> result = client.createCallWithResponse(createCallOptions, Context.NONE);

(اختياري) إضافة مستخدم Microsoft Teams إلى المكالمة

يمكنك إضافة مستخدم Microsoft Teams إلى المكالمة باستخدام addParticipant الأسلوب مع MicrosoftTeamsUserIdentifier معرف مستخدم Teams و. تحتاج أولا إلى إكمال خطوة المتطلبات الأساسية التخويل لمورد Azure Communication Services لتمكين الاتصال لمستخدمي Microsoft Teams. اختياريا، يمكنك أيضا تمرير للتحكم في SourceDisplayName النص المعروض في الإعلام المنبثق لمستخدم Teams.

client.getCallConnection(callConnectionId).addParticipant(
    new CallInvite(new MicrosoftTeamsUserIdentifier(targetTeamsUserId))
        .setSourceDisplayName("Jack (Contoso Tech Support)"));

بدء تسجيل مكالمة

تتيح خدمة أتمتة المكالمات أيضا القدرة على بدء تسجيل وتخزين تسجيلات المكالمات الصوتية ومكالمات الفيديو. يمكنك معرفة المزيد حول الإمكانات المختلفة في واجهات برمجة التطبيقات لتسجيل المكالمات هنا.

ServerCallLocator serverCallLocator = new ServerCallLocator(
    client.getCallConnection(callConnectionId)
        .getCallProperties()
        .getServerCallId());
        
StartRecordingOptions startRecordingOptions = new StartRecordingOptions(serverCallLocator);

Response<RecordingStateResult> response = client.getCallRecording()
    .startWithResponse(startRecordingOptions, Context.NONE);

recordingId = response.getValue().getRecordingId();

الاستجابة لاستدعاء الأحداث

في وقت سابق من تطبيقنا، قمنا بتسجيل basecallbackuri إلى خدمة أتمتة المكالمات. يشير URI إلى نقطة النهاية التي ستستخدمها الخدمة لإعلامنا باستدعاء الأحداث التي تحدث. يمكننا بعد ذلك التكرار من خلال الأحداث والكشف عن أحداث محددة يريد تطبيقنا فهمها. في التعليمات البرمجية أدناه، نستجيب للحدث CallConnected .

List<CallAutomationEventBase> events = CallAutomationEventParser.parseEvents(reqBody);
for (CallAutomationEventBase event : events) {
    String callConnectionId = event.getCallConnectionId();
    if (event instanceof CallConnected) {
        log.info("CallConnected event received");
    }
    else if (event instanceof RecognizeCompleted) {
        log.info("Recognize Completed event received");
    }
}

تشغيل رسالة الترحيب والتعرف عليها

TextSourceباستخدام ، يمكنك تزويد الخدمة بالنص الذي تريد تركيبه واستخدامه لرسالة الترحيب. تقوم خدمة Azure Communication Services Call Automation بتشغيل هذه الرسالة عند CallConnected الحدث.

بعد ذلك، نقوم بتمرير النص إلى CallMediaRecognizeChoiceOptions ثم استدعاء StartRecognizingAsync. يسمح هذا للتطبيق الخاص بك بالتعرف على الخيار الذي يختاره المتصل.

var playSource = new TextSource().setText(content).setVoiceName("en-US-NancyNeural");

var recognizeOptions = new CallMediaRecognizeChoiceOptions(new PhoneNumberIdentifier(targetParticipant), getChoices())
  .setInterruptCallMediaOperation(false)
  .setInterruptPrompt(false)
  .setInitialSilenceTimeout(Duration.ofSeconds(10))
  .setPlayPrompt(playSource)
  .setOperationContext(context);

client.getCallConnection(callConnectionId)
  .getCallMedia()
  .startRecognizing(recognizeOptions);

private List < RecognitionChoice > getChoices() {
  var choices = Arrays.asList(
    new RecognitionChoice().setLabel(confirmLabel).setPhrases(Arrays.asList("Confirm", "First", "One")).setTone(DtmfTone.ONE),
    new RecognitionChoice().setLabel(cancelLabel).setPhrases(Arrays.asList("Cancel", "Second", "Two")).setTone(DtmfTone.TWO)
  );

  return choices;
}

معالجة أحداث الاختيار

يقوم Azure Communication Services Call Automation بتشغيل api/callbacks خطاف الويب الذي قمنا بإعداده وسيعلمنا بالحدث RecognizeCompleted . يمنحنا الحدث القدرة على الاستجابة للمدخلات المستلمة وتشغيل إجراء. ثم يقوم التطبيق بتشغيل رسالة إلى المتصل استنادا إلى الإدخال المحدد المستلم.

else if (event instanceof RecognizeCompleted) {
  log.info("Recognize Completed event received");

  RecognizeCompleted acsEvent = (RecognizeCompleted) event;

  var choiceResult = (ChoiceResult) acsEvent.getRecognizeResult().get();

  String labelDetected = choiceResult.getLabel();

  String phraseDetected = choiceResult.getRecognizedPhrase();

  log.info("Recognition completed, labelDetected=" + labelDetected + ", phraseDetected=" + phraseDetected + ", context=" + event.getOperationContext());

  String textToPlay = labelDetected.equals(confirmLabel) ? confirmedText : cancelText;

  handlePlay(callConnectionId, textToPlay);
}

private void handlePlay(final String callConnectionId, String textToPlay) {
  var textPlay = new TextSource()
    .setText(textToPlay)
    .setVoiceName("en-US-NancyNeural");

  client.getCallConnection(callConnectionId)
    .getCallMedia()
    .playToAll(textPlay);
}

إغلاق الاتصال

وأخيرا، عندما نكتشف شرطا منطقيا بالنسبة لنا لإنهاء المكالمة، يمكننا استخدام hangUp الأسلوب لتعليق المكالمة.

client.getCallConnection(callConnectionId).hangUp(true);

تشغيل التعليمات البرمجية

انتقل إلى الدليل الذي يحتوي على ملف pom.xml واستخدم أوامر mvn التالية:

  • تحويل التطبيق برمجيا: mvn compile
  • إنشاء الحزمة: mvn package
  • تنفيذ التطبيق: mvn exec:java

المتطلبات الأساسية

  • حساب Azure مع اشتراك نشط. أنشئ حساباً مجاناً.
  • تم نشر مورد Communication Services. إنشاء مورد Communication Services
  • رقم هاتف في مورد Azure Communication Services يمكنه إجراء مكالمات صادرة. إذا كان لديك اشتراك مجاني، يمكنك الحصول على رقم هاتف تجريبي.
  • إنشاء نفق Azure Dev واستضافته. التعليمات هنا.
    • إنشاء خدمات Azure الذكاء الاصطناعي متعددة الخدمات وتوصيلها بمورد Azure Communication Services.
  • إنشاء مجال فرعي مخصص لمورد خدمات Azure الذكاء الاصطناعي.
  • Node.js تثبيت LTS.
  • تم تثبيتVisual Studio Code.
  • (اختياري) مستخدم Microsoft Teams لديه ترخيص هاتف تم تمكينه voice . مطلوب ترخيص هاتف Teams لإضافة مستخدمي Teams إلى المكالمة. تعرف على المزيد حول تراخيص Teams هنا. لمزيد من المعلومات لتمكينه voice على نظام الهاتف، راجع إعداد نظام الهاتف.

التعليمة البرمجية العينة

قم بتنزيل أو استنساخ نموذج التعليمات البرمجية للتشغيل السريع من GitHub.

انتقل إلى CallAutomation_OutboundCalling المجلد وافتح الحل في محرر التعليمات البرمجية.

إعداد البيئة

قم بتنزيل نموذج التعليمات البرمجية وانتقل إلى دليل المشروع وقم بتشغيل npm الأمر الذي يقوم بتثبيت التبعيات الضرورية وإعداد بيئة المطور الخاصة بك.

npm install

إعداد Azure DevTunnel واستضافته

Azure DevTunnels هي خدمة Azure تمكنك من مشاركة خدمات الويب المحلية المستضافة على الإنترنت. استخدم أوامر DevTunnel CLI لتوصيل بيئة التطوير المحلية بالإنترنت العام. نستخدم نقطة النهاية هذه لإعلام تطبيقك باستدعاء الأحداث من خدمة Azure Communication Services Call Automation.

devtunnel create --allow-anonymous
devtunnel port create -p 8080
devtunnel host

تحديث تكوين التطبيق الخاص بك

ثم قم بتحديث الملف بالقيم .env التالية:

  • CONNECTION_STRING: سلسلة الاتصال لمورد Azure Communication Services. يمكنك العثور على Azure Communication Services سلسلة الاتصال باستخدام الإرشادات هنا.
  • CALLBACK_URI: بمجرد تهيئة مضيف DevTunnel، قم بتحديث هذا الحقل باستخدام عنوان URI هذا.
  • TARGET_PHONE_NUMBER: حقل التحديث برقم الهاتف الذي ترغب في أن يتصل به تطبيقك. يجب أن يستخدم رقم الهاتف هذا تنسيق رقم هاتف E164 (على سبيل المثال + 18881234567)
  • ACS_RESOURCE_PHONE_NUMBER: قم بتحديث هذا الحقل برقم هاتف Azure Communication Services الذي حصلت عليه. يجب أن يستخدم رقم الهاتف هذا تنسيق رقم هاتف E164 (على سبيل المثال + 18881234567)
  • COGNITIVE_SERVICES_ENDPOINT: تحديث الحقل باستخدام نقطة نهاية خدمات Azure الذكاء الاصطناعي.
  • TARGET_TEAMS_USER_ID: (اختياري) حقل التحديث مع معرف مستخدم Microsoft Teams الذي ترغب في إضافته إلى المكالمة. راجع استخدام واجهة برمجة تطبيقات Graph للحصول على معرف مستخدم Teams.
CONNECTION_STRING="<YOUR_CONNECTION_STRING>" 
ACS_RESOURCE_PHONE_NUMBER ="<YOUR_ACS_NUMBER>" 
TARGET_PHONE_NUMBER="<+1XXXXXXXXXX>" 
CALLBACK_URI="<VS_TUNNEL_URL>" 
COGNITIVE_SERVICES_ENDPOINT="<COGNITIVE_SERVICES_ENDPOINT>" 
TARGET_TEAMS_USER_ID="<TARGET_TEAMS_USER_ID>"

إجراء مكالمة صادرة وتشغيل الوسائط

لإجراء المكالمة الصادرة من Azure Communication Services، يمكنك استخدام رقم الهاتف الذي قدمته للبيئة. تأكد من أن رقم الهاتف بتنسيق رقم هاتف E164 (على سبيل المثال + 18881234567)

تجري التعليمات البرمجية مكالمة صادرة باستخدام target_phone_number التي قدمتها وقمت بإجراء مكالمة صادرة لهذا الرقم:

const callInvite: CallInvite = {
	targetParticipant: callee,
	sourceCallIdNumber: {
		phoneNumber: process.env.ACS_RESOURCE_PHONE_NUMBER || "",
	},
};

const options: CreateCallOptions = {
	cognitiveServicesEndpoint: process.env.COGNITIVE_SERVICES_ENDPOINT
};

console.log("Placing outbound call...");
acsClient.createCall(callInvite, process.env.CALLBACK_URI + "/api/callbacks", options);

(اختياري) إضافة مستخدم Microsoft Teams إلى المكالمة

يمكنك إضافة مستخدم Microsoft Teams إلى المكالمة باستخدام addParticipant الأسلوب مع الخاصية microsoftTeamsUserId . تحتاج أولا إلى إكمال خطوة المتطلبات الأساسية التخويل لمورد Azure Communication Services لتمكين الاتصال لمستخدمي Microsoft Teams. اختياريا، يمكنك أيضا تمرير للتحكم في sourceDisplayName النص المعروض في الإعلام المنبثق لمستخدم Teams.

await acsClient.getCallConnection(callConnectionId).addParticipant({
    targetParticipant: { microsoftTeamsUserId: process.env.TARGET_TEAMS_USER_ID },
    sourceDisplayName: "Jack (Contoso Tech Support)"
});

بدء تسجيل مكالمة

تتيح خدمة أتمتة المكالمات أيضا القدرة على بدء تسجيل وتخزين تسجيلات المكالمات الصوتية ومكالمات الفيديو. يمكنك معرفة المزيد حول الإمكانات المختلفة في واجهات برمجة التطبيقات لتسجيل المكالمات هنا.

const callLocator: CallLocator = {
    id: serverCallId,
    kind: "serverCallLocator",
};

const recordingOptions: StartRecordingOptions = {
    callLocator: callLocator,
};

const response = await acsClient.getCallRecording().start(recordingOptions);

recordingId = response.recordingId;

الاستجابة لاستدعاء الأحداث

في وقت سابق من تطبيقنا، قمنا بتسجيل CALLBACK_URI إلى خدمة أتمتة المكالمات. يشير URI إلى نقطة النهاية التي تستخدمها الخدمة لإعلامنا باستدعاء الأحداث التي تحدث. يمكننا بعد ذلك التكرار من خلال الأحداث والكشف عن أحداث محددة يريد تطبيقنا فهمها. نحن نستجيب للحدث CallConnected للحصول على إشعار وبدء عمليات انتقال البيانات من الخادم. TextSourceباستخدام ، يمكنك تزويد الخدمة بالنص الذي تريد تركيبه واستخدامه لرسالة الترحيب. تقوم خدمة Azure Communication Services Call Automation بتشغيل هذه الرسالة عند CallConnected الحدث.

بعد ذلك، نقوم بتمرير النص إلى CallMediaRecognizeChoiceOptions ثم استدعاء StartRecognizingAsync. يسمح هذا للتطبيق الخاص بك بالتعرف على الخيار الذي يختاره المتصل.

callConnectionId = eventData.callConnectionId;
serverCallId = eventData.serverCallId;
console.log("Call back event received, callConnectionId=%s, serverCallId=%s, eventType=%s", callConnectionId, serverCallId, event.type);
callConnection = acsClient.getCallConnection(callConnectionId);
const callMedia = callConnection.getCallMedia();

if (event.type === "Microsoft.Communication.CallConnected") {
 	console.log("Received CallConnected event");
 	await startRecording();
	await startRecognizing(callMedia, mainMenu, "");
}

async function startRecognizing(callMedia: CallMedia, textToPlay: string, context: string) {
	const playSource: TextSource = {
 		text: textToPlay,
 		voiceName: "en-US-NancyNeural",
 		kind: "textSource"
 	};

 	const recognizeOptions: CallMediaRecognizeChoiceOptions = {
 		choices: await getChoices(),
 		interruptPrompt: false,
 		initialSilenceTimeoutInSeconds: 10,
 		playPrompt: playSource,
 		operationContext: context,
 		kind: "callMediaRecognizeChoiceOptions"
 	};

 	await callMedia.startRecognizing(callee, recognizeOptions)
 }

معالجة أحداث الاختيار

يقوم Azure Communication Services Call Automation بتشغيل api/callbacks خطاف الويب الذي قمنا بإعداده وسيعلمنا بالحدث RecognizeCompleted . يمنحنا الحدث القدرة على الاستجابة للمدخلات المستلمة وتشغيل إجراء. ثم يقوم التطبيق بتشغيل رسالة إلى المتصل استنادا إلى الإدخال المحدد المستلم.

else if (event.type === "Microsoft.Communication.RecognizeCompleted") { 
	if(eventData.recognitionType === "choices"){ 
        	console.log("Recognition completed, event=%s, resultInformation=%s",eventData, eventData.resultInformation); 
        	var context = eventData.operationContext; 
            	const labelDetected = eventData.choiceResult.label;  
            	const phraseDetected = eventData.choiceResult.recognizedPhrase; 
            	console.log("Recognition completed, labelDetected=%s, phraseDetected=%s, context=%s", labelDetected, phraseDetected, eventData.operationContext); 
            	const textToPlay = labelDetected === confirmLabel ? confirmText : cancelText;            
            	await handlePlay(callMedia, textToPlay); 
        } 
}  
 
async function handlePlay(callConnectionMedia:CallMedia, textContent:string){ 
	const play : TextSource = { text:textContent , voiceName: "en-US-NancyNeural", kind: "textSource"} 
	await callConnectionMedia.playToAll([play]); 
} 

إغلاق الاتصال

وأخيرا، عندما نكتشف شرطا منطقيا بالنسبة لنا لإنهاء المكالمة، يمكننا استخدام hangUp() الأسلوب لتعليق المكالمة.

  await acsClient.getCallRecording().stop(recordingId);
  callConnection.hangUp(true);

تشغيل التعليمات البرمجية

لتشغيل التطبيق، افتح نافذة Terminal وقم بتشغيل الأمر التالي:

  npm run dev

المتطلبات الأساسية

  • حساب Azure مع اشتراك نشط. أنشئ حساباً مجاناً.
  • تم نشر مورد Communication Services. إنشاء مورد Communication Services
  • رقم هاتف في مورد Azure Communication Services يمكنه إجراء مكالمات صادرة. إذا كان لديك اشتراك مجاني، يمكنك الحصول على رقم هاتف تجريبي.
  • إنشاء نفق Azure Dev واستضافته. التعليمات هنا.
  • إنشاء خدمات Azure الذكاء الاصطناعي متعددة الخدمات وتوصيلها بمورد Azure Communication Services.
  • إنشاء مجال فرعي مخصص لمورد خدمات Azure الذكاء الاصطناعي.
  • Python 3.7+.
  • (اختياري) مستخدم Microsoft Teams لديه ترخيص هاتف تم تمكينه voice . مطلوب ترخيص هاتف Teams لإضافة مستخدمي Teams إلى المكالمة. تعرف على المزيد حول تراخيص Teams هنا. لمزيد من المعلومات لتمكينه voice على نظام الهاتف، راجع إعداد نظام الهاتف.

التعليمة البرمجية العينة

قم بتنزيل أو استنساخ نموذج التعليمات البرمجية للتشغيل السريع من GitHub.

انتقل إلى CallAutomation_OutboundCalling المجلد وافتح الحل في محرر التعليمات البرمجية.

إعداد بيئة Python

إنشاء وتنشيط بيئة python وتثبيت الحزم المطلوبة باستخدام الأمر التالي. يمكنك معرفة المزيد حول إدارة الحزم هنا

pip install -r requirements.txt

إعداد Azure DevTunnel واستضافته

Azure DevTunnels هي خدمة Azure تمكنك من مشاركة خدمات الويب المحلية المستضافة على الإنترنت. استخدم الأوامر لتوصيل بيئة التطوير المحلية بالإنترنت العام. ينشئ DevTunnels نفقا بعنوان URL لنقطة النهاية الثابتة والذي يسمح بالوصول المجهول. نستخدم نقطة النهاية هذه لإعلام تطبيقك باستدعاء الأحداث من خدمة Azure Communication Services Call Automation.

devtunnel create --allow-anonymous
devtunnel port create -p 8080
devtunnel host

تحديث تكوين التطبيق الخاص بك

ثم قم بتحديث الملف بالقيم main.py التالية:

  • ACS_CONNECTION_STRING: سلسلة الاتصال لمورد Azure Communication Services. يمكنك العثور على Azure Communication Services سلسلة الاتصال باستخدام الإرشادات هنا.
  • CALLBACK_URI_HOST: بمجرد تهيئة مضيف DevTunnel، قم بتحديث هذا الحقل باستخدام عنوان URI هذا.
  • TARGET_PHONE_NUMBER: حقل التحديث برقم الهاتف الذي ترغب في أن يتصل به تطبيقك. يجب أن يستخدم رقم الهاتف هذا تنسيق رقم هاتف E164 (على سبيل المثال + 18881234567)
  • ACS_PHONE_NUMBER: قم بتحديث هذا الحقل برقم هاتف Azure Communication Services الذي حصلت عليه. يجب أن يستخدم رقم الهاتف هذا تنسيق رقم هاتف E164 (على سبيل المثال + 18881234567)
  • COGNITIVE_SERVICES_ENDPOINT: تحديث الحقل باستخدام نقطة نهاية خدمات Azure الذكاء الاصطناعي.
  • TARGET_TEAMS_USER_ID: (اختياري) حقل التحديث مع معرف مستخدم Microsoft Teams الذي ترغب في إضافته إلى المكالمة. راجع استخدام واجهة برمجة تطبيقات Graph للحصول على معرف مستخدم Teams.
# Your ACS resource connection string 
ACS_CONNECTION_STRING = "<ACS_CONNECTION_STRING>" 

# Your ACS resource phone number will act as source number to start outbound call 
ACS_PHONE_NUMBER = "<ACS_PHONE_NUMBER>" 

# Target phone number you want to receive the call. 
TARGET_PHONE_NUMBER = "<TARGET_PHONE_NUMBER>" 

# Callback events URI to handle callback events. 
CALLBACK_URI_HOST = "<CALLBACK_URI_HOST_WITH_PROTOCOL>" 
CALLBACK_EVENTS_URI = CALLBACK_URI_HOST + "/api/callbacks" 

#Your Cognitive service endpoint 
COGNITIVE_SERVICES_ENDPOINT = "<COGNITIVE_SERVICES_ENDPOINT>" 

#(OPTIONAL) Your target Microsoft Teams user Id ex. "ab01bc12-d457-4995-a27b-c405ecfe4870"
TARGET_TEAMS_USER_ID = "<TARGET_TEAMS_USER_ID>"

إجراء مكالمة صادرة

لإجراء المكالمة الصادرة من Azure Communication Services، عليك أولا توفير رقم الهاتف الذي تريد تلقي المكالمة. لتسهيل الأمر، يمكنك تحديث target_phone_number برقم هاتف بتنسيق رقم هاتف E164 (على سبيل المثال + 18881234567)

قم بإجراء مكالمة صادرة باستخدام target_phone_number التي قدمتها:

target_participant = PhoneNumberIdentifier(TARGET_PHONE_NUMBER) 
source_caller = PhoneNumberIdentifier(ACS_PHONE_NUMBER) 
call_invite = CallInvite(target=target_participant, source_caller_id_number=source_caller) 
call_connection_properties = call_automation_client.create_call(call_invite, CALLBACK_EVENTS_URI, 
cognitive_services_endpoint=COGNITIVE_SERVICES_ENDPOINT) 
    app.logger.info("Created call with connection id: %s",
call_connection_properties.call_connection_id) 
return redirect("/") 

(اختياري) إضافة مستخدم Microsoft Teams إلى المكالمة

يمكنك إضافة مستخدم Microsoft Teams إلى المكالمة باستخدام add_participant الأسلوب مع MicrosoftTeamsUserIdentifier معرف مستخدم Teams و. تحتاج أولا إلى إكمال خطوة المتطلبات الأساسية التخويل لمورد Azure Communication Services لتمكين الاتصال لمستخدمي Microsoft Teams. اختياريا، يمكنك أيضا تمرير للتحكم في source_display_name النص المعروض في الإعلام المنبثق لمستخدم Teams.

call_connection_client.add_participant(target_participant = CallInvite(
    target = MicrosoftTeamsUserIdentifier(user_id=TARGET_TEAMS_USER_ID),
    source_display_name = "Jack (Contoso Tech Support)"))

بدء تسجيل مكالمة

تتيح خدمة أتمتة المكالمات أيضا القدرة على بدء تسجيل وتخزين تسجيلات المكالمات الصوتية ومكالمات الفيديو. يمكنك معرفة المزيد حول الإمكانات المختلفة في واجهات برمجة التطبيقات لتسجيل المكالمات هنا.

recording_properties = call_automation_client.start_recording(ServerCallLocator(event.data['serverCallId']))
recording_id = recording_properties.recording_id

الاستجابة لاستدعاء الأحداث

في وقت سابق من تطبيقنا، قمنا بتسجيل CALLBACK_URI_HOST إلى خدمة أتمتة المكالمات. يشير URI إلى نقطة النهاية التي تستخدمها الخدمة لإعلامنا باستدعاء الأحداث التي تحدث. يمكننا بعد ذلك التكرار من خلال الأحداث والكشف عن أحداث محددة يريد تطبيقنا فهمها. في التعليمات البرمجية أدناه، نستجيب للحدث CallConnected .

@app.route('/api/callbacks', methods=['POST'])
def callback_events_handler():
    for event_dict in request.json:
        event = CloudEvent.from_dict(event_dict)
        if event.type == "Microsoft.Communication.CallConnected":
            # Handle Call Connected Event
            ...
            return Response(status=200)

تشغيل رسالة الترحيب والتعرف عليها

TextSourceباستخدام ، يمكنك تزويد الخدمة بالنص الذي تريد تركيبه واستخدامه لرسالة الترحيب. تقوم خدمة Azure Communication Services Call Automation بتشغيل هذه الرسالة عند CallConnected الحدث.

بعد ذلك، نقوم بتمرير النص إلى CallMediaRecognizeChoiceOptions ثم استدعاء StartRecognizingAsync. يسمح هذا للتطبيق الخاص بك بالتعرف على الخيار الذي يختاره المتصل.


get_media_recognize_choice_options( 
    call_connection_client=call_connection_client, 
    text_to_play=MainMenu,  
    target_participant=target_participant, 
    choices=get_choices(),context="") 

def get_media_recognize_choice_options(call_connection_client: CallConnectionClient, text_to_play: str, target_participant:str, choices: any, context: str): 
    play_source =  TextSource (text= text_to_play, voice_name= SpeechToTextVoice) 
    call_connection_client.start_recognizing_media( 
        input_type=RecognizeInputType.CHOICES, 

        target_participant=target_participant,
        choices=choices, 
        play_prompt=play_source, 
        interrupt_prompt=False, 
        initial_silence_timeout=10, 
        operation_context=context 
    ) 

def get_choices(): 
    choices = [ 
        RecognitionChoice(label = ConfirmChoiceLabel, phrases= ["Confirm", "First", "One"], tone = DtmfTone.ONE), 
        RecognitionChoice(label = CancelChoiceLabel, phrases= ["Cancel", "Second", "Two"], tone = DtmfTone.TWO) 
    ] 
return choices 

معالجة أحداث الاختيار

يقوم Azure Communication Services Call Automation بتشغيل api/callbacks خطاف الويب الذي قمنا بإعداده وسيعلمنا بالحدث RecognizeCompleted . يمنحنا الحدث القدرة على الاستجابة للمدخلات المستلمة وتشغيل إجراء. ثم يقوم التطبيق بتشغيل رسالة إلى المتصل استنادا إلى الإدخال المحدد المستلم.

elif event.type == "Microsoft.Communication.RecognizeCompleted":
	app.logger.info("Recognize completed: data=%s", event.data)
if event.data['recognitionType'] == "choices":
	labelDetected = event.data['choiceResult']['label'];
phraseDetected = event.data['choiceResult']['recognizedPhrase'];
app.logger.info("Recognition completed, labelDetected=%s, phraseDetected=%s, context=%s", labelDetected, phraseDetected, event.data.get('operationContext'))
if labelDetected == ConfirmChoiceLabel:
	textToPlay = ConfirmedText
else:
	textToPlay = CancelText
handle_play(call_connection_client = call_connection_client, text_to_play = textToPlay)
def handle_play(call_connection_client: CallConnectionClient, text_to_play: str):
	play_source = TextSource(text = text_to_play, voice_name = SpeechToTextVoice)
call_connection_client.play_media_to_all(play_source)

إغلاق الاتصال

وأخيرا، عندما نكتشف شرطا منطقيا بالنسبة لنا لإنهاء المكالمة، يمكننا استخدام hang_up() الأسلوب لتعليق المكالمة. وأخيرا، يمكننا أيضا إيقاف عملية تسجيل المكالمات بأمان.

call_automation_client.stop_recording(recording_id)
call_connection_client.hang_up(is_for_everyone=True)

تشغيل التعليمات البرمجية

لتشغيل التطبيق باستخدام VS Code، افتح نافذة Terminal وقم بتشغيل الأمر التالي

python main.py