नोट
इस पेज तक पहुँच के लिए प्रमाणन की आवश्यकता होती है. आप साइन इन करने या निर्देशिकाओं को बदलने का प्रयास कर सकते हैं.
इस पेज तक पहुँच के लिए प्रमाणन की आवश्यकता होती है. आप निर्देशिकाओं को बदलने का प्रयास कर सकते हैं.
Customer Service के लिए ओमनीचैनल के साथ, आप Direct Line API 3.0 का उपयोग करके कस्टम मैसेजिंग चैनल को एकीकृत करने के लिए कनेक्टर लागू कर सकते हैं, जो कि .NET SDK का हिस्सा है। पूरा नमूना कोड दिखाता है कि आप अपना कनेक्टर कैसे बना सकते हैं। डायरेक्ट लाइन एपीआई 3.0 के बारे में अधिक जानने के लिए, डायरेक्ट लाइन 3.0 एपीआई में मुख्य अवधारणाएं देखें।
यह आलेख बताता है कि कैसे एक चैनल Microsoft Direct Line Bot Framework से जुड़ा है, जो आंतरिक रूप से Customer Service के लिए Omnichannel से जुड़ा हुआ है। निम्न अनुभाग में कोड स्निपेट शामिल हैं जो डायरेक्ट लाइन क्लाइंट बनाने के लिए डायरेक्ट लाइन एपीआई 3.0 और नमूना कनेक्टर बनाने के लिए इंटरफ़ेस का उपयोग करते हैं IChannelAdapter
।
नोट
स्रोत कोड और प्रलेखन इस बात के समग्र प्रवाह का वर्णन करते हैं कि चैनल डायरेक्ट लाइन के माध्यम से ग्राहक सेवा के लिए ओमनीचैनल से कैसे जुड़ सकता है, और विश्वसनीयता और मापनीयता के पहलुओं पर ध्यान केंद्रित नहीं करता है।
घटक
एडाप्टर वेबहुक एपीआई सेवा
जब उपयोगकर्ता एक संदेश दर्ज करता है, तो एडेप्टर एपीआई चैनल से लागू किया जाता है। यह इनबाउंड अनुरोध को संसाधित करता है और प्रतिक्रिया के रूप में सफलता या विफलता की स्थिति भेजता है। एडेप्टर एपीआई सेवा को इंटरफ़ेस को IChannelAdapter
लागू करना होगा, और अनुरोध को संसाधित करने के लिए संबंधित चैनल एडेप्टर को इनबाउंड अनुरोध भेजता है।
/// <summary>
/// Accept an incoming web-hook request from MessageBird Channel
/// </summary>
/// <param name="requestPayload">Inbound request Object</param>
/// <returns>Executes the result operation of the action method asynchronously.</returns>
[HttpPost("postactivityasync")]
public async Task<IActionResult> PostActivityAsync(JToken requestPayload)
{
if (requestPayload == null)
{
return BadRequest("Request payload is invalid.");
}
try
{
await _messageBirdAdapter.ProcessInboundActivitiesAsync(requestPayload, Request).ConfigureAwait(false);
}
catch (Exception ex)
{
_logger.LogError($"postactivityasync: {ex}");
return StatusCode(500, "An error occured while handling your request.");
}
return StatusCode(200);
}
चैनल एडेप्टर
चैनल एडाप्टर इनबाउंड और आउटबाउंड गतिविधियों को संसाधित करता है, और इंटरफ़ेस को IAdapterBuilder
लागू करना चाहिए।
इनबाउंड गतिविधियों को संसाधित करें
चैनल एडाप्टर निम्न आवक गतिविधियाँ निष्पादित करता है:
- इनबाउंड संदेश अनुरोध हस्ताक्षर सत्यापित करें.
चैनल से इनबाउंड अनुरोध हस्ताक्षर कुंजी के आधार पर मान्य है। यदि अनुरोध अमान्य है, तो एक "अमान्य हस्ताक्षर" अपवाद संदेश दिया जाता है। यदि अनुरोध मान्य है, तो यह निम्नानुसार आगे बढ़ता है:
/// <summary>
/// Validate Message Bird Request
/// </summary>
/// <param name="content">Request Content</param>
/// <param name="request">HTTP Request</param>
/// <param name="messageBirdSigningKey">Message Bird Signing Key</param>
/// <returns>True if there request is valid, false if there aren't.</returns>
public static bool ValidateMessageBirdRequest(string content, HttpRequest request, string messageBirdSigningKey)
{
if (string.IsNullOrWhiteSpace(messageBirdSigningKey))
{
throw new ArgumentNullException(nameof(messageBirdSigningKey));
}
if (request == null)
{
throw new ArgumentNullException(nameof(request));
}
if (string.IsNullOrWhiteSpace(content))
{
throw new ArgumentNullException(nameof(content));
}
var messageBirdRequest = new MessageBirdRequest(
request.Headers?["Messagebird-Request-Timestamp"],
request.QueryString.Value?.Equals("?",
StringComparison.CurrentCulture) != null
? string.Empty
: request.QueryString.Value,
GetBytes(content));
var messageBirdRequestSigner = new MessageBirdRequestSigner(GetBytes(messageBirdSigningKey));
string expectedSignature = request.Headers?["Messagebird-Signature"];
return messageBirdRequestSigner.IsMatch(expectedSignature, messageBirdRequest);
}
- इनबाउंड अनुरोध को बॉट गतिविधि में बदलें।
इनबाउंड अनुरोध पेलोड को एक गतिविधि में परिवर्तित किया जाता है जिसे बॉट फ्रेमवर्क समझ सकता है।
नोट
गतिविधि पेलोड 28 KB की संदेश आकार सीमा से अधिक नहीं होनी चाहिए।
इस गतिविधि ऑब्जेक्ट में निम्न विशेषताएँ शामिल हैं:
विशेषता | विवरण |
---|---|
से | चैनल खाता जानकारी संग्रहीत करता है जिसमें उपयोगकर्ता और नाम का अद्वितीय पहचानकर्ता (प्रथम नाम और अंतिम नाम का संयोजन, रिक्ति सीमांकक द्वारा अलग किया गया) शामिल होता है. |
चैनलआईडी | चैनल पहचानकर्ता को इंगित करता है। इनबाउंड अनुरोधों के लिए, चैनल आईडी है directline । |
serviceUrl | सेवा URL इंगित करता है. इनबाउंड अनुरोधों के लिए, सेवा URL है https://directline.botframework.com/ । |
प्रकार | गतिविधि प्रकार इंगित करता है. संदेश गतिविधियों के लिए, प्रकार है message । |
टेक्स्ट | संदेश सामग्री संग्रहीत करता है. |
पहचान | उस पहचानकर्ता को इंगित करता है जिसका उपयोग एडेप्टर आउटबाउंड संदेशों का प्रतिसाद देने के लिए करता है. |
चैनलडेटा | चैनल डेटा को इंगित करता है जिसमें channelType , conversationcontext , और customercontext . |
चैनल प्रकार | चैनल नाम को इंगित करता है जिसके माध्यम से ग्राहक संदेश भेज रहा है। उदाहरण के लिए, MessageBird, KakaoTalk, Snapchat |
वार्तालापसंदर्भ | एक शब्दकोश ऑब्जेक्ट को संदर्भित करता है जो कार्यप्रवाह में परिभाषित संदर्भ चर रखता है। Customer Service के लिए ओमनीचैनल इस जानकारी का उपयोग वार्तालाप को सही ग्राहक सेवा प्रतिनिधि (सेवा प्रतिनिधि या प्रतिनिधि) को रूट करने के लिए करता है. उदाहरण के लिए: "वार्तालाप": { "उत्पाद का नाम": "एक्सबॉक्स", "समस्या": "स्थापना" } इस उदाहरण में, संदर्भ वार्तालाप को उस सेवा प्रतिनिधि को रूट करता है जो Xbox स्थापना से संबंधित है. |
ग्राहक संदर्भ | एक शब्दकोश वस्तु को संदर्भित करता है जो ग्राहक विवरण जैसे फोन नंबर और ईमेल पता रखता है। Omnichannel for Customer Service उपयोगकर्ता के संपर्क रिकॉर्ड की पहचान करने के लिए इस जानकारी का उपयोग करता है. "customercontext":{ "ईमेल":email@email.com, "फोन नंबर":"1234567890" } |
/// <summary>
/// Build Bot Activity type from the inbound MessageBird request payload<see cref="Activity"/>
/// </summary>
/// <param name = "messagePayload"> Message Bird Activity Payload</param>
/// <returns>Direct Line Activity</returns>
public static Activity PayloadToActivity(MessageBirdRequestModel messagePayload)
{
if (messagePayload == null)
{
throw new ArgumentNullException(nameof(messagePayload));
}
if (messagePayload.Message?.Direction == ConversationMessageDirection.Sent ||
messagePayload.Type == ConversationWebhookMessageType.MessageUpdated)
{
return null;
}
var channelData = new ActivityExtension
{
ChannelType = ChannelType.MessageBird,
// Add Conversation Context in below dictionary object. Please refer the document for more information.
ConversationContext = new Dictionary<string, string>(),
// Add Customer Context in below dictionary object. Please refer the document for more information.
CustomerContext = new Dictionary<string, string>()
};
var activity = new Activity
{
From = new ChannelAccount(messagePayload.Message?.From, messagePayload.Contact?.DisplayName),
Text = messagePayload.Message?.Content?.Text,
Type = ActivityTypes.Message,
Id = messagePayload.Message?.ChannelId,
ServiceUrl = Constant.DirectLineBotServiceUrl,
ChannelData = channelData
};
return activity;
}
नमूना JSON पेलोड इस प्रकार है:
{
"type": "message",
"id": "bf3cc9a2f5de...",
"serviceUrl": https://directline.botframework.com/,
"channelId": "directline",
"from": {
"id": "1234abcd",// userid which uniquely identify the user
"name": "customer name" // customer name as First Name <space> Last Name
},
"text": "Hi,how are you today.",
"channeldata":{
"channeltype":"messageBird",
"conversationcontext ":{ // this holds context variables defined in Workstream
"ProductName" : "XBox",
"Issue":"Installation"
},
"customercontext":{
"email":email@email.com,
"phonenumber":"1234567890"
}
}
}
- गतिविधि को संदेश रिले प्रोसेसर पर भेजें।
गतिविधि पेलोड बनाने के बाद, यह गतिविधि को डायरेक्ट लाइन पर भेजने के लिए संदेश रिले प्रोसेसर की PostActivityAsync विधि को कॉल करता है। चैनल एडाप्टर को इवेंट हैंडलर भी पास करना चाहिए, जिसे रिले प्रोसेसर तब आमंत्रित करता है जब वह डायरेक्ट लाइन के माध्यम से ग्राहक सेवा के लिए ओमनीचैनल से एक आउटबाउंड संदेश प्राप्त करता है।
आउटबाउंड गतिविधियों को संसाधित करें
रिले प्रोसेसर संबंधित चैनल एडाप्टर के लिए आउटबाउंड गतिविधियों को भेजने के लिए इवेंट हैंडलर को आमंत्रित करता है, और एडेप्टर तब आउटबाउंड गतिविधियों को संसाधित करता है। चैनल एडाप्टर निम्न जावक गतिविधियाँ निष्पादित करता है:
- आउटबाउंड गतिविधियों को चैनल प्रतिसाद मॉडल में कनवर्ट करें।
डायरेक्ट लाइन गतिविधियों को चैनल-विशिष्ट प्रतिक्रिया मॉडल में परिवर्तित किया जाता है।
/// <summary>
/// Creates MessageBird response object from a Bot Framework <see cref="Activity"/>.
/// </summary>
/// <param name="activities">The outbound activities.</param>
/// <param name="replyToId">Reply Id of Message Bird user.</param>
/// <returns>List of MessageBird Responses.</returns>
public static List<MessageBirdResponseModel> ActivityToMessageBird(IList<Activity> activities, string replyToId)
{
if (string.IsNullOrWhiteSpace(replyToId))
{
throw new ArgumentNullException(nameof(replyToId));
}
if (activities == null)
{
throw new ArgumentNullException(nameof(activities));
}
return activities.Select(activity => new MessageBirdResponseModel
{
To = replyToId,
From = activity.ChannelId,
Type = "text",
Content = new Content
{
Text = activity.Text
}
}).ToList();
}
- चैनल आरईएसटी एपीआई के माध्यम से प्रतिक्रियाएं भेजें।
चैनल एडाप्टर शेष API चैनल के लिए एक आउटबाउंड प्रतिसाद भेजने के लिए कॉल करता है, जो तब उपयोगकर्ता को भेजा जाता है।
/// <summary>
/// Send Outbound Messages to Message Bird
/// </summary>
/// <param name="messageBirdResponses">Message Bird Response object</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public async Task SendMessagesToMessageBird(IList<MessageBirdResponseModel> messageBirdResponses)
{
if (messageBirdResponses == null)
{
throw new ArgumentNullException(nameof(messageBirdResponses));
}
foreach (var messageBirdResponse in messageBirdResponses)
{
using (var request = new HttpRequestMessage(HttpMethod.Post, $"{MessageBirdDefaultApi}/send"))
{
var content = JsonConvert.SerializeObject(messageBirdResponse);
request.Content = new StringContent(content, Encoding.UTF8, "application/json");
await _httpClient.SendAsync(request).ConfigureAwait(false);
}
}
}
संदेश रिले प्रोसेसर
संदेश रिले प्रोसेसर चैनल एडाप्टर से इनबाउंड गतिविधि प्राप्त करता है और गतिविधि मॉडल सत्यापन करता है। रिले प्रोसेसर यह जांचता है कि इस गतिविधि को डायरेक्ट लाइन पर भेजने से पहले बातचीत विशेष गतिविधि के लिए सक्रिय है या नहीं
यह देखने के लिए कि वार्तालाप सक्रिय है या नहीं, रिले प्रोसेसर एक शब्दकोश में सक्रिय वार्तालापों का संग्रह रखता है। इस शब्दकोश में उपयोगकर्ता आईडी के रूप में कुंजी है, जो विशिष्ट रूप से उपयोगकर्ता और मान को निम्न वर्ग की वस्तु के रूप में पहचानती है:
/// <summary>
/// Direct Line Conversation to store as an Active Conversation
/// </summary>
public class DirectLineConversation
{
/// <summary>
/// .NET SDK Client to connect to Direct Line Bot
/// </summary>
public DirectLineClient DirectLineClient { get; set; }
/// <summary>
/// Direct Line response after start a new conversation
/// </summary>
public Conversation Conversation { get; set; }
/// <summary>
/// Watermark to guarantee that no messages are lost
/// </summary>
public string WaterMark { get; set; }
}
यदि रिले प्रोसेसर द्वारा प्राप्त गतिविधि के लिए वार्तालाप सक्रिय नहीं है, तो यह निम्न चरणों का पालन करता है:
- Direct Line के साथ वार्तालाप प्रारंभ करता है और Direct Line द्वारा भेजे गए वार्तालाप ऑब्जेक्ट को उपयोगकर्ता ID के विरुद्ध शब्दकोश में संग्रहीत करता है.
/// <summary>
/// Initiate Conversation with Direct Line Bot
/// </summary>
/// <param name="inboundActivity">Inbound message from Aggregator/Channel</param>
/// <param name="adapterCallBackHandler">Call Back to send activities to Messaging API</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
private async Task InitiateConversation(Activity inboundActivity, EventHandler<IList<Activity>> adapterCallBackHandler)
{
var directLineConversation = new DirectLineConversation
{
DirectLineClient = new DirectLineClient(_relayProcessorConfiguration.Value.DirectLineSecret)
};
// Start a conversation with Direct Line Bot
directLineConversation.Conversation = await directLineConversation.DirectLineClient.Conversations.
StartConversationAsync().ConfigureAwait(false);
await directLineConversation.DirectLineClient.Conversations.
StartConversationAsync().ConfigureAwait(false);
if (directLineConversation.Conversation == null)
{
throw new Exception(
"An error occurred while starting the Conversation with direct line. Please validate the direct line secret in the configuration file.");
}
// Adding the Direct Line Conversation object to the lookup dictionary and starting a thread to poll the activities from the direct line bot.
if (ActiveConversationCache.ActiveConversations.TryAdd(inboundActivity.From.Id, directLineConversation))
{
// Starts a new thread to poll the activities from Direct Line Bot
new Thread(async () => await PollActivitiesFromBotAsync(
directLineConversation.Conversation.ConversationId, inboundActivity, adapterCallBackHandler).ConfigureAwait(false))
.Start();
}
}
- कॉन्फ़िगरेशन फ़ाइल में कॉन्फ़िगर किए गए मतदान अंतराल के आधार पर डायरेक्ट लाइन बॉट से आउटबाउंड गतिविधियों को पोल करने के लिए एक नया थ्रेड शुरू करता है। मतदान थ्रेड तब तक सक्रिय रहता है जब तक कि सीधी रेखा से वार्तालाप गतिविधि का अंत प्राप्त नहीं हो जाता।
/// <summary>
/// Polling the activities from BOT for the active conversation
/// </summary>
/// <param name="conversationId">Direct Line Conversation Id</param>
/// <param name="inboundActivity">Inbound Activity from Channel/Aggregator</param>
/// <param name="lineActivitiesReceived">Call Back to send activities to Messaging API</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
private async Task PollActivitiesFromBotAsync(string conversationId, Activity inboundActivity, EventHandler<IList<Activity>> lineActivitiesReceived)
{
if (!int.TryParse(_relayProcessorConfiguration.Value.PollingIntervalInMilliseconds, out var pollingInterval))
{
throw new FormatException($"Invalid Configuration value of PollingIntervalInMilliseconds: {_relayProcessorConfiguration.Value.PollingIntervalInMilliseconds}");
}
if (!ActiveConversationCache.ActiveConversations.TryGetValue(inboundActivity.From.Id,
out var conversationContext))
{
throw new KeyNotFoundException($"No active conversation found for {inboundActivity.From.Id}");
}
while (true)
{
var watermark = conversationContext.WaterMark;
// Retrieve the activity set from the bot.
var activitySet = await conversationContext.DirectLineClient.Conversations.
GetActivitiesAsync(conversationId, watermark).ConfigureAwait(false);
// Set the watermark to the message received
watermark = activitySet?.Watermark;
// Extract the activities sent from our bot.
if (activitySet != null)
{
var activities = (from activity in activitySet.Activities
where activity.From.Id == _relayProcessorConfiguration.Value.BotHandle
select activity).ToList();
if (activities.Count > 0)
{
SendReplyActivity(activities, inboundActivity, lineActivitiesReceived);
}
// Update Watermark
ActiveConversationCache.ActiveConversations[inboundActivity.From.Id].WaterMark = watermark;
if (activities.Exists(a => a.Type.Equals("endOfConversation", StringComparison.InvariantCulture)))
{
if (ActiveConversationCache.ActiveConversations.TryRemove(inboundActivity.From.Id, out _))
{
Thread.CurrentThread.Abort();
}
}
}
await Task.Delay(TimeSpan.FromMilliseconds(pollingInterval)).ConfigureAwait(false);
}
}
नोट
संदेश प्राप्त करता है जो कोड के दिल में लेता है और watermark
पैरामीटर के रूप में GetActivitiesAsync विधि हैConversationId
। पैरामीटर का watermark
उद्देश्य उन संदेशों को पुनर्प्राप्त करना है जो डायरेक्ट लाइन द्वारा वितरित नहीं किए गए हैं। यदि वॉटरमार्क पैरामीटर निर्दिष्ट किया जाता है, तो वार्तालाप वॉटरमार्क से फिर से चलता है, ताकि कोई संदेश खो न जाए।
गतिविधि को डायरेक्ट लाइन पर भेजें
/// <summary>
/// Send the activity to the bot using Direct Line client
/// </summary>
/// <param name="inboundActivity">Inbound message from Aggregator/Channel</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
private static async Task SendActivityToBotAsync(Activity inboundActivity)
{
if (!ActiveConversationCache.ActiveConversations.TryGetValue(inboundActivity.From.Id,
out var conversationContext))
{
throw new KeyNotFoundException($"No active conversation found for {inboundActivity.From.Id}");
}
await conversationContext.DirectLineClient.Conversations.PostActivityAsync(
conversationContext.Conversation.ConversationId, inboundActivity).ConfigureAwait(false);
}
यदि रिले प्रोसेसर द्वारा प्राप्त गतिविधि के लिए वार्तालाप सक्रिय है, तो यह गतिविधि को संदेश रिले प्रोसेसर को भेजता है।
बातचीत समाप्त करें
वार्तालाप समाप्त करने के लिए, सीधी रेखा में वार्तालाप समाप्त करें देखें.
अगले कदम
लाइव चैट और एसिंक्रोनस चैनलों के लिए समर्थन
कस्टम चैनलों में मार्कडाउन प्रारूप जो उपयोग करते हैं Direct Line
संबंधित जानकारी
कस्टम मैसेजिंग चैनल कॉन्फ़िगर करें
MessageBird API संदर्भ
बॉट्स को कॉन्फ़िगर करने के लिए सर्वोत्तम अभ्यास