ایجاد و یکپارچه سازی چت بات اندرویدی با Dialogflow – راهنمای مقدماتی
Dialogflow از سرویسهای گوگل است که قبلاً به نام API.ai شناخته میشد و پلتفرمی عالی برای توسعه چتباتها برای پلتفرمهای مختلف است. راهنماها و مستندات زیادی برای افرادی که به تازگی شروع به یادگیری و استفاده از این پلتفرم برای ساخت چتبات نمودهاند وجود دارند. با این وجود، پشتیبانی از اندروید و iOS به خوبی مستندسازی نشده است.
تا پیش از این که Dialogflow به نام API.ai نامیده میشد، کتابخانه کلاینت اندروید و iOS برای ادغام چتبات در اپلیکیشنهای موبایل ارائه شده بود؛ اما پس از ادغام آن در گوگل، کتابخانه موجود دیگر بهروزرسانی نشد و شاهد اضافه شدن Dialogflow به پلتفرم کلاود گوگل بودیم که API کلاینت جدیدی مبتنی بر جاوا در حال توسعه است.
در این مقاله، شیوه یکپارچهسازی چتبات توسعهیافته در Dialogflow با استفاده از کتابخانه API.ai قدیمی و API کلاینت جاوای جدید را توضیح میدهیم. بنابراین برای نمایش این موضوع یک چتبات ساده ایجاد میکنیم که اطلاعاتی در مورد دورههای مختلف فستیوال توسعهدهندگان دهلینو که از سوی GDG برگزار میشود ارائه میکند.
ابتدا باید اسکریپتی بنویسیم که کاربر بتواند با چتبات مکالمه کند.
User: I want the list of sessions at Dev Fest in New Delhi. Bot: Sure! There will be 4 tracks of sessions. For which track do you want the information? User: third track. Bot: 9:00–9:30 Registrations… Anything else? User: No. Bot: Thank you! Have a great day :)
سپس یک Agent برای Dialogflow میسازیم که Test_agent نام دارد.
برای API کلاینت جاوا باید روی حساب سرویس کلیک کرده و کلید JSON تولید شده از سوی کنسول IAM را به دست آوریم.
اینک اینتِنت (Intent) ها و نهادهایی را برای آموزش دادن ایجنت ایجاد میکنیم.
یک تابع کلاود برای مدیریت درخواست وبهوک ایجاد میکنیم. بر اساس شماره دوره تشخیص داده شده، پاسخ مناسبی به کاربر ارسال میشود.
اکنون ایجنت ما آماده ادغام با اپلیکیشن اندروید است.
در build.gradle (در سطح app) وابستگیهایی برای کتابخانه کلاینت اندروید و API کلاینت جاوا اضافه میکنیم چون این چتبات را برای هر دو مورد توسعه میدهیم.
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:28.0.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' // Dialogflow SDK dependencies implementation 'ai.api:sdk:2.0.7@aar' implementation 'ai.api:libai:1.6.12' // Java V2 implementation 'com.google.cloud:google-cloud-dialogflow:0.67.0-alpha' // for Remote Procedure Call to avoid "No functional channel service provider found" error while creating SessionsClient implementation 'io.grpc:grpc-okhttp:1.15.1' }
این چتبات در متد onCreate اکتیویتی اندروید آغاز میشود. ابتدا به پیکربندی ایجنت Dialogflow با استفاده از توکن دسترسی کلاینت با یا استفاده از کلید JSON میکنیم. سپس یک نشست (session) جدید با استفاده از ID یکتا ایجاد میکنیم و در نهایت بات آماده تعامل با کاربر خواهد بود.
کتابخانه کلاینت اندروید
private void initChatbot() { final AIConfiguration config = new AIConfiguration(BuildConfig.ClientAccessToken, AIConfiguration.SupportedLanguages.English, AIConfiguration.RecognitionEngine.System); aiDataService = new AIDataService(this, config); customAIServiceContext = AIServiceContextBuilder.buildFromSessionId(uuid);// helps to create new session whenever app restarts aiRequest = new AIRequest(); }
API کلاینت جاوا
private void initV2Chatbot() { try { InputStream stream = getResources().openRawResource(R.raw.test_agent_credentials); GoogleCredentials credentials = GoogleCredentials.fromStream(stream); String projectId = ((ServiceAccountCredentials)credentials).getProjectId(); SessionsSettings.Builder settingsBuilder = SessionsSettings.newBuilder(); SessionsSettings sessionsSettings = settingsBuilder.setCredentialsProvider(FixedCredentialsProvider.create(credentials)).build(); sessionsClient = SessionsClient.create(sessionsSettings); session = SessionName.of(projectId, uuid); } catch (Exception e) { e.printStackTrace(); } }
ما ارتباط چتبات با کاربر را به روش ناهمگام (Asynchronous) مدیریت میکنیم. این کار در متد AsyncTask صورت میگیرد که در آن کوئری درخواستی از کاربر به صورت یک درخواست به چتبات ارسال شده و پاسخ دریافت میشود.
مدیریت AsyncTask در فراخوانیهای کتابخانه کلاینت اندروید
public class RequestTask extends AsyncTask<AIRequest, Void, AIResponse> { Activity activity; private AIDataService aiDataService; private AIServiceContext customAIServiceContext; RequestTask(Activity activity, AIDataService aiDataService, AIServiceContext customAIServiceContext){ this.activity = activity; this.aiDataService = aiDataService; this.customAIServiceContext = customAIServiceContext; } @Override protected AIResponse doInBackground(AIRequest... aiRequests) { final AIRequest request = aiRequests[0]; try { return aiDataService.request(request, customAIServiceContext); } catch (AIServiceException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(AIResponse aiResponse) { ((MainActivity)activity).callback(aiResponse); } }
مدیریت AsyncTask برای فراخوانیهای API کلاینت جاوا
public class RequestJavaV2Task extends AsyncTask<Void, Void, DetectIntentResponse> { Activity activity; private SessionName session; private SessionsClient sessionsClient; private QueryInput queryInput; RequestJavaV2Task(Activity activity, SessionName session, SessionsClient sessionsClient, QueryInput queryInput) { this.activity = activity; this.session = session; this.sessionsClient = sessionsClient; this.queryInput = queryInput; } @Override protected DetectIntentResponse doInBackground(Void... voids) { try{ DetectIntentRequest detectIntentRequest = DetectIntentRequest.newBuilder() .setSession(session.toString()) .setQueryInput(queryInput) .build(); return sessionsClient.detectIntent(detectIntentRequest); } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(DetectIntentResponse response) { ((MainActivity) activity).callbackV2(response); } }
کاربر میتواند کوئری را از اپلیکیشن اندروید با استفاده از EditText ارسال کند و پاسخ در یک TextView نمایش مییابد.
درخواست و پاسخ که در کتابخانه کلاینت اندروید مدیریت میشوند
private void sendMessage(View view) { String msg = queryEditText.getText().toString(); if (msg.trim().isEmpty()) { Toast.makeText(MainActivity.this, "Please enter your query!", Toast.LENGTH_LONG).show(); } else { showTextView(msg, USER); queryEditText.setText(""); // Android client aiRequest.setQuery(msg); RequestTask requestTask = new RequestTask(MainActivity.this, aiDataService, customAIServiceContext); requestTask.execute(aiRequest); } } public void callback(AIResponse aiResponse) { if (aiResponse != null) { // process aiResponse here String botReply = aiResponse.getResult().getFulfillment().getSpeech(); Log.d(TAG, "Bot Reply: " + botReply); showTextView(botReply, BOT); } else { Log.d(TAG, "Bot Reply: Null"); showTextView("There was some communication issue. Please Try again!", BOT); } }
مدیریت درخواست و پاسخ در API کلاینت جاوا
private void sendMessage(View view) { String msg = queryEditText.getText().toString(); if (msg.trim().isEmpty()) { Toast.makeText(MainActivity.this, "Please enter your query!", Toast.LENGTH_LONG).show(); } else { showTextView(msg, USER); queryEditText.setText(""); // Android client // aiRequest.setQuery(msg); // RequestTask requestTask = new RequestTask(MainActivity.this, aiDataService, customAIServiceContext); // requestTask.execute(aiRequest); // Java V2 QueryInput queryInput = QueryInput.newBuilder().setText(TextInput.newBuilder().setText(msg).setLanguageCode("en-US")).build(); new RequestJavaV2Task(MainActivity.this, session, sessionsClient, queryInput).execute(); } } public void callback(AIResponse aiResponse) { if (aiResponse != null) { // process aiResponse here String botReply = aiResponse.getResult().getFulfillment().getSpeech(); Log.d(TAG, "Bot Reply: " + botReply); showTextView(botReply, BOT); } else { Log.d(TAG, "Bot Reply: Null"); showTextView("There was some communication issue. Please Try again!", BOT); } } public void callbackV2(DetectIntentResponse response) { if (response != null) { // process aiResponse here String botReply = response.getQueryResult().getFulfillmentText(); Log.d(TAG, "V2 Bot Reply: " + botReply); showTextView(botReply, BOT); } else { Log.d(TAG, "Bot Reply: Null"); showTextView("There was some communication issue. Please Try again!", BOT); } }
ااینک ادغام چتبات ما پایان یافته است. پس از افزودن تغییرات مورد نیاز در UI برای گرفتن کوئری کاربر و نمایش پاسخ بات، میتوانید نمونه چتبات نهایی را در ویدئوی زیر مشاهده کنید.
اگر این مطلب برایتان مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای برنامهنویسی اندروید
- مجموعه آموزشهای برنامهنویسی
- مجموعه آموزش های پروژه محور برنامه نویسی
- آموزش زبان برنامه نویسی Go: ساخت یک سرور چت به زبان ساده
- آموزش برنامه نویسی اندروید (Android) – پیشرفته
==