كتابة روبوت برقية في R (الجزء 3): كيفية إضافة دعم لوحة المفاتيح إلى الروبوت

هذه هي المقالة الثالثة في سلسلة “كتابة بوت برقية باللغة R”. تعلمنا في المنشورات السابقة كيفية إنشاء بوت تيليجرام وإرسال الرسائل من خلاله وإضافة الأوامر ومرشحات الرسائل إلى البوت. لذلك، قبل أن تبدأ بقراءة هذا المقال، أنصحك بشدة بقراءته سابق، لأن لن أتطرق هنا بعد الآن إلى الأساسيات الموصوفة مسبقًا لبناء الروبوتات.

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

كتابة روبوت برقية في R (الجزء 3): كيفية إضافة دعم لوحة المفاتيح إلى الروبوت

جميع المقالات من سلسلة "كتابة بوت برقية باللغة R"

  1. نقوم بإنشاء روبوت ونستخدمه لإرسال الرسائل في التليجرام
  2. أضف دعم الأوامر ومرشحات الرسائل إلى الروبوت
  3. كيفية إضافة دعم لوحة المفاتيح إلى الروبوت

محتوى

إذا كنت مهتمًا بتحليل البيانات ، فقد تكون مهتمًا ببرنامجي تيليجرام и موقع YouTube القنوات. معظم محتوياته مخصص للغة R.

  1. ما هي أنواع لوحات المفاتيح التي يدعمها روبوت التليجرام؟
  2. الرد على لوحة المفاتيح
  3. لوحة المفاتيح المضمنة
    3.1 مثال لروبوت بسيط يدعم أزرار InLine
    3.2 مثال لروبوت يُبلغ عن الطقس الحالي لمدينة محددة
    3.3 مثال لروبوت يعرض قائمة بأحدث المقالات مع روابط إلى المركز المحدد من habr.com
  4. اختتام

ما هي أنواع لوحات المفاتيح التي يدعمها روبوت التليجرام؟

في وقت كتابة هذه السطور telegram.bot يسمح لك بإنشاء نوعين من لوحات المفاتيح:

  • الرد - لوحة المفاتيح الرئيسية والعادية، والتي توجد أسفل لوحة إدخال نص الرسالة. تقوم لوحة المفاتيح هذه ببساطة بإرسال رسالة نصية إلى الروبوت، وكنص سترسل النص المكتوب على الزر نفسه.
  • مضمنة - لوحة المفاتيح المرتبطة برسالة روبوت محددة. ترسل لوحة المفاتيح هذه بيانات الروبوت المرتبطة بالزر الذي تم الضغط عليه؛ وقد تختلف هذه البيانات عن النص المكتوب على الزر نفسه. وتتم معالجة هذه الأزرار من خلال CallbackQueryHandler.

لكي يتمكن الروبوت من فتح لوحة المفاتيح، من الضروري عند إرسال رسالة عبر الطريقة sendMessage()، قم بتمرير لوحة المفاتيح التي تم إنشاؤها مسبقًا كوسيطة reply_markup.

أدناه سننظر في عدة أمثلة.

الرد على لوحة المفاتيح

كما كتبت أعلاه، هذه هي لوحة المفاتيح الرئيسية للتحكم في الروبوت.

مثال على إنشاء لوحة مفاتيح الرد من المساعدة الرسمية

bot <- Bot(token = "TOKEN")
chat_id <- "CHAT_ID"

# Create Custom Keyboard
text <- "Aren't those custom keyboards cool?"
RKM <- ReplyKeyboardMarkup(
  keyboard = list(
    list(KeyboardButton("Yes, they certainly are!")),
    list(KeyboardButton("I'm not quite sure")),
    list(KeyboardButton("No..."))
  ),
  resize_keyboard = FALSE,
  one_time_keyboard = TRUE
)

# Send Custom Keyboard
bot$sendMessage(chat_id, text, reply_markup = RKM)

ما ورد أعلاه هو مثال من المساعدة الرسمية للحزمة telegram.bot. لإنشاء لوحة مفاتيح، استخدم الوظيفة ReplyKeyboardMarkup()، والذي بدوره يأخذ قائمة بقوائم الأزرار التي يتم إنشاؤها بواسطة الوظيفة KeyboardButton().

لماذا في ReplyKeyboardMarkup() هل تحتاج إلى تمرير ليس مجرد قائمة، بل قائمة القوائم؟ الحقيقة هي أنك تقوم بتمرير القائمة الرئيسية، وفيها تحدد كل صف من الأزرار في قوائم منفصلة، ​​لأن يمكنك وضع عدة أزرار في صف واحد.

حجة resize_keyboard يتيح لك تحديد الحجم الأمثل لأزرار لوحة المفاتيح والوسيطة تلقائيًا one_time_keyboard يسمح لك بإخفاء لوحة المفاتيح بعد الضغط على كل زر.

لنقم بكتابة روبوت بسيط يحتوي على 3 أزرار:

  • معرف الدردشة - طلب معرف الدردشة للحوار مع الروبوت
  • اسمي - اطلب اسمك
  • تسجيل الدخول الخاص بي - اطلب اسم المستخدم الخاص بك في برقية

الرمز 1: روبوت بسيط مزود بلوحة مفاتيح للرد

library(telegram.bot)

# создаём экземпляр класса Updater
updater <- Updater('ТОКЕН ВАШЕГО БОТА')

# создаём методы
## метод для запуска клавиатуры
start <- function(bot, update) {

  # создаём клавиатуру
  RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(KeyboardButton("Чат ID")),
      list(KeyboardButton("Моё имя")),
      list(KeyboardButton("Мой логин"))
    ),
    resize_keyboard = FALSE,
    one_time_keyboard = TRUE
  )

  # отправляем клавиатуру
  bot$sendMessage(update$message$chat_id,
                  text = 'Выберите команду', 
                  reply_markup = RKM)

}

## метод возвразающий id чата
chat_id <- function(bot, update) {

  bot$sendMessage(update$message$chat_id, 
                  text = paste0("Чат id этого диалога: ", update$message$chat_id),
                  parse_mode = "Markdown")

}

## метод возвращающий имя
my_name <- function(bot, update) {

  bot$sendMessage(update$message$chat_id, 
                  text = paste0("Вас зовут ", update$message$from$first_name),
                  parse_mode = "Markdown")

}

## метод возвращающий логин
my_username <- function(bot, update) {

  bot$sendMessage(update$message$chat_id, 
                  text = paste0("Ваш логин ", update$message$from$username),
                  parse_mode = "Markdown")

}

# создаём фильтры
## сообщения с текстом Чат ID
MessageFilters$chat_id <- BaseFilter(function(message) {

  # проверяем текст сообщения
  message$text == "Чат ID"

}
)

## сообщения с текстом Моё имя
MessageFilters$name <- BaseFilter(function(message) {

  # проверяем текст сообщения
  message$text == "Моё имя"

}
)

## сообщения с текстом Мой логин
MessageFilters$username <- BaseFilter(function(message) {

  # проверяем текст сообщения
  message$text == "Мой логин"
)

# создаём обработчики
h_start    <- CommandHandler('start', start)
h_chat_id  <- MessageHandler(chat_id, filters = MessageFilters$chat_id)
h_name     <- MessageHandler(my_name, filters = MessageFilters$name)
h_username <- MessageHandler(my_username, filters = MessageFilters$username)

# добавляем обработчики в диспетчер
updater <- updater + 
            h_start +
            h_chat_id +
            h_name +
            h_username

# запускаем бота 
updater$start_polling()

قم بتشغيل مثال الكود أعلاه، بعد استبدال "YOUR BOT TOKEN" بالرمز الحقيقي الذي تلقيته عند إنشاء الروبوت عبر الأب (تحدثت عن إنشاء روبوت في المادة الأولى).

بعد الإطلاق، أعطِ الروبوت أمرًا /start، لأن هذا هو بالضبط ما حددناه لتشغيل لوحة المفاتيح.

كتابة روبوت برقية في R (الجزء 3): كيفية إضافة دعم لوحة المفاتيح إلى الروبوت

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

أنشأنا 4 طرق:

  • ابدأ - قم بتشغيل لوحة المفاتيح
  • chat_id - طلب معرف الدردشة
  • my_name — اطلب اسمك
  • my_username — اطلب تسجيل الدخول الخاص بك

ليعترض مرشحات الرسائل تمت إضافة 3 مرشحات للرسائل بناءً على نصها:

  • chat_id — رسائل تحتوي على نص "Чат ID"
  • الاسم — رسائل تحتوي على نص "Моё имя"
  • اسم المستخدم — الرسائل التي تحتوي على نص "Мой логин"

وقمنا بإنشاء 4 معالجات، بناءً على الأوامر والمرشحات المحددة، ستقوم بتنفيذ الطرق المحددة.

# создаём обработчики
h_start    <- CommandHandler('start', start)
h_chat_id  <- MessageHandler(chat_id, filters = MessageFilters$chat_id)
h_name     <- MessageHandler(my_name, filters = MessageFilters$name)
h_username <- MessageHandler(my_username, filters = MessageFilters$username)

يتم إنشاء لوحة المفاتيح نفسها داخل الطريقة start() الفريق ReplyKeyboardMarkup().

RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(KeyboardButton("Чат ID")),
      list(KeyboardButton("Моё имя")),
      list(KeyboardButton("Мой логин"))
    ),
    resize_keyboard = FALSE,
    one_time_keyboard = TRUE
)

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

RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(
          KeyboardButton("Чат ID"),
          KeyboardButton("Моё имя"),
          KeyboardButton("Мой логин")
     )
    ),
    resize_keyboard = FALSE,
    one_time_keyboard = TRUE
)

كتابة روبوت برقية في R (الجزء 3): كيفية إضافة دعم لوحة المفاتيح إلى الروبوت

يتم إرسال لوحة المفاتيح إلى الدردشة باستخدام الطريقة sendMessage()، في الحجة reply_markup.

  bot$sendMessage(update$message$chat_id,
                  text = 'Выберите команду', 
                  reply_markup = RKM)

لوحة المفاتيح المضمنة

كما كتبت أعلاه، ترتبط لوحة المفاتيح المضمنة برسالة محددة. يعد العمل بها أكثر صعوبة إلى حد ما من لوحة المفاتيح الرئيسية.

في البداية، تحتاج إلى إضافة طريقة إلى الروبوت لاستدعاء لوحة المفاتيح المضمنة.

للرد على نقرة زر مضمنة، يمكنك أيضًا استخدام طريقة bot answerCallbackQuery()والتي يمكنها عرض إشعار في واجهة التليجرام للمستخدم الذي يضغط على الزر المضمّن.

البيانات المرسلة من الزر المضمن ليست نصًا، لذا لمعالجتها تحتاج إلى إنشاء معالج خاص باستخدام الأمر CallbackQueryHandler().

الكود الخاص بإنشاء لوحة مفاتيح مضمنة والموجود في المساعدة الرسمية للحزمة telegram.bot.

رمز لبناء لوحة مفاتيح مضمنة من المساعدة الرسمية

# Initialize bot
bot <- Bot(token = "TOKEN")
chat_id <- "CHAT_ID"

# Create Inline Keyboard
text <- "Could you type their phone number, please?"
IKM <- InlineKeyboardMarkup(
  inline_keyboard = list(
    list(
      InlineKeyboardButton(1),
      InlineKeyboardButton(2),
      InlineKeyboardButton(3)
    ),
    list(
      InlineKeyboardButton(4),
      InlineKeyboardButton(5),
      InlineKeyboardButton(6)
    ),
    list(
      InlineKeyboardButton(7),
      InlineKeyboardButton(8),
      InlineKeyboardButton(9)
    ),
    list(
      InlineKeyboardButton("*"),
      InlineKeyboardButton(0),
      InlineKeyboardButton("#")
    )
  )
)

# Send Inline Keyboard
bot$sendMessage(chat_id, text, reply_markup = IKM)

تحتاج إلى إنشاء لوحة مفاتيح مضمنة باستخدام الأمر InlineKeyboardMarkup()، على نفس مبدأ لوحة المفاتيح الرد. في InlineKeyboardMarkup() من الضروري تمرير قائمة بقوائم الأزرار المضمنة، ويتم إنشاء كل زر على حدة بواسطة الوظيفة InlineKeyboardButton().

يمكن للزر المضمن تمرير بعض البيانات إلى الروبوت باستخدام وسيطة callback_dataأو افتح أي صفحة HTML محددة باستخدام الوسيطة url.

ستكون النتيجة قائمة يكون كل عنصر فيها أيضًا عبارة عن قائمة من الأزرار المضمنة التي يجب دمجها في صف واحد.

بعد ذلك، سنلقي نظرة على عدة أمثلة للروبوتات ذات الأزرار المضمنة.

مثال لروبوت بسيط يدعم أزرار InLine

أولاً، سنكتب روبوتًا للاختبار السريع لفيروس كوفيد-19. بالأمر /test، سترسل لك لوحة مفاتيح تحتوي على زرين، حسب الزر الذي قمت بالضغط عليه، سترسل لك رسالة تحتوي على نتائج الاختبار.

الكود 2: أبسط روبوت مزود بلوحة مفاتيح مضمنة

library(telegram.bot)

# создаём экземпляр класса Updater
updater <- Updater('ТОКЕН ВАШЕГО БОТА')

# метод для отправки InLine клавиатуры
test <- function(bot, update) {

  # создаём InLine клавиатуру
  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton("Да", callback_data = 'yes'),
        InlineKeyboardButton("Нет", callback_data = 'no')
      )
    )
  )

  # Отправляем клавиатуру в чат
  bot$sendMessage(update$message$chat_id, 
                  text = "Вы болете коронавирусом?", 
                  reply_markup = IKM)
}

# метод для обработки нажатия кнопки
answer_cb <- function(bot, update) {

  # полученные данные с кнопки
  data <- update$callback_query$data

  # получаем имя пользователя, нажавшего кнопку
  uname <- update$effective_user()$first_name

  # обработка результата
  if ( data == 'no' ) {

    msg <- paste0(uname, ", поздравляю, ваш тест на covid-19 отрицательный.")

  } else {

    msg <- paste0(uname, ", к сожалени ваш тест на covid-19 положительный.")

  }

  # Отправка сообщения
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text = msg)

  # сообщаем боту, что запрос с кнопки принят
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id) 
}

# создаём обработчики
inline_h      <- CommandHandler('test', test)
query_handler <- CallbackQueryHandler(answer_cb)

# добавляем обработчики в диспетчер
updater <- updater + inline_h + query_handler

# запускаем бота
updater$start_polling()

قم بتشغيل مثال الكود أعلاه، بعد استبدال "YOUR BOT TOKEN" بالرمز الحقيقي الذي تلقيته عند إنشاء الروبوت عبر الأب (تحدثت عن إنشاء روبوت في المادة الأولى).

النتيجة:
كتابة روبوت برقية في R (الجزء 3): كيفية إضافة دعم لوحة المفاتيح إلى الروبوت

أنشأنا طريقتين:

  • تجربه بالعربي - للإرسال إلى لوحة المفاتيح المضمنة للدردشة
  • Answer_cb — لمعالجة البيانات المرسلة من لوحة المفاتيح.

يتم تحديد البيانات التي سيتم إرسالها من كل زر في الوسيطة callback_data، عند إنشاء زر. يمكنك استلام البيانات المرسلة من الزر باستخدام الإنشاء update$callback_query$data، داخل الطريقة Answer_cb.

لكي يتفاعل الروبوت مع لوحة المفاتيح المضمنة، الطريقة Answer_cb يتم معالجتها بواسطة معالج خاص: CallbackQueryHandler(answer_cb). الذي يقوم بتشغيل الطريقة المحددة عند النقر فوق الزر Inline. معالج CallbackQueryHandler يأخذ حجتين:

  • callback - الطريقة التي يجب تشغيلها
  • pattern - التصفية حسب البيانات المرتبطة بالزر باستخدام وسيطة callback_data.

وبناء على ذلك، باستخدام الحجة pattern يمكننا كتابة طريقة منفصلة للضغط على كل زر:

الكود 3: طرق منفصلة لكل زر مضمن

library(telegram.bot)

# создаём экземпляр класса Updater
updater <- Updater('ТОКЕН ВАШЕГО БОТА')

# метод для отправки InLine клавиатуры
test <- function(bot, update) {  

  # создаём InLine клавиатуру
  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton("Да", callback_data = 'yes'),
        InlineKeyboardButton("Нет", callback_data = 'no')
      )
    )
  )

  # Отправляем клавиатуру в чат
  bot$sendMessage(update$message$chat_id, 
                  text = "Вы болете коронавирусом?", 
                  reply_markup = IKM)
}

# метод для обработки нажатия кнопки Да
answer_cb_yes <- function(bot, update) {

  # получаем имя пользователя, нажавшего кнопку
  uname <- update$effective_user()$first_name

  # обработка результата
  msg <- paste0(uname, ", к сожалени ваш текст на covid-19 положительный.")

  # Отправка сообщения
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text = msg)

  # сообщаем боту, что запрос с кнопки принят
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id) 
}

# метод для обработки нажатия кнопки Нет
answer_cb_no <- function(bot, update) {

  # получаем имя пользователя, нажавшего кнопку
  uname <- update$effective_user()$first_name

  msg <- paste0(uname, ", поздравляю, ваш текст на covid-19 отрицательный.")

  # Отправка сообщения
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text = msg)

  # сообщаем боту, что запрос с кнопки принят
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id) 
}

# создаём обработчики
inline_h          <- CommandHandler('test', test)
query_handler_yes <- CallbackQueryHandler(answer_cb_yes, pattern = 'yes')
query_handler_no  <- CallbackQueryHandler(answer_cb_no, pattern = 'no')

# добавляем обработчики в диспетчер
updater <- updater + 
            inline_h + 
            query_handler_yes +
            query_handler_no

# запускаем бота
updater$start_polling()

قم بتشغيل مثال الكود أعلاه، بعد استبدال "YOUR BOT TOKEN" بالرمز الحقيقي الذي تلقيته عند إنشاء الروبوت عبر الأب (تحدثت عن إنشاء روبوت في المادة الأولى).

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

query_handler_yes <- CallbackQueryHandler(answer_cb_yes, pattern = 'yes')
query_handler_no  <- CallbackQueryHandler(answer_cb_no, pattern = 'no')

ينتهي رمز الطريقة Answer_cb الفريق bot$answerCallbackQuery(callback_query_id = update$callback_query$id)، والذي يخبر الروبوت بأنه قد تم استلام البيانات من لوحة المفاتيح المضمنة.

مثال لروبوت يُبلغ عن الطقس الحالي لمدينة محددة

دعونا نحاول كتابة روبوت يطلب بيانات الطقس.

منطق عملها سيكون على النحو التالي. في البداية من قبل الفريق /start يمكنك الاتصال بلوحة المفاتيح الرئيسية، والتي تحتوي على زر "الطقس" واحد فقط. بالضغط على هذا الزر ستتلقى رسالة باستخدام لوحة المفاتيح المضمنة لتحديد المدينة التي تريد معرفة الطقس الحالي فيها. اختر إحدى المدن واحصل على الطقس الحالي.

في مثال الكود هذا سوف نستخدم عدة حزم إضافية:

  • httr — حزمة للعمل مع طلبات HTTP، والتي على أساسها تم بناء العمل مع أي API. في حالتنا سوف نستخدم واجهة برمجة التطبيقات المجانية openweathermap.org.
  • stringr — حزمة للعمل مع النص، في حالتنا سوف نستخدمها لإنشاء رسالة حول الطقس في المدينة المحددة.

الرمز 4: روبوت يُبلغ عن الطقس الحالي للمدينة المحددة

library(telegram.bot)
library(httr)
library(stringr)

# создаём экземпляр класса Updater
updater <- Updater('ТОКЕН ВАШЕГО БОТА')

# создаём методы
## метод для запуска основной клавиатуры
start <- function(bot, update) {

  # создаём клавиатуру
  RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(
        KeyboardButton("Погода")
      )
    ),
    resize_keyboard = TRUE,
    one_time_keyboard = TRUE
  )

  # отправляем клавиатуру
  bot$sendMessage(update$message$chat_id,
                  text = 'Выберите команду', 
                  reply_markup = RKM)

}

## Метод вызова Inine клавиатуры
weather <- function(bot, update) {

  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton(text = 'Москва', callback_data = 'New York,us'),
        InlineKeyboardButton(text = 'Санкт-Петербург', callback_data = 'Saint Petersburg'),
        InlineKeyboardButton(text = 'Нью-Йорк', callback_data = 'New York')
      ),
      list(
        InlineKeyboardButton(text = 'Екатеринбург', callback_data = 'Yekaterinburg,ru'),
        InlineKeyboardButton(text = 'Берлин', callback_data = 'Berlin,de'),
        InlineKeyboardButton(text = 'Париж', callback_data = 'Paris,fr')
      ),
      list(
        InlineKeyboardButton(text = 'Рим', callback_data = 'Rome,it'),
        InlineKeyboardButton(text = 'Одесса', callback_data = 'Odessa,ua'),
        InlineKeyboardButton(text = 'Киев', callback_data = 'Kyiv,fr')
      ),
      list(
        InlineKeyboardButton(text = 'Токио', callback_data = 'Tokyo'),
        InlineKeyboardButton(text = 'Амстердам', callback_data = 'Amsterdam,nl'),
        InlineKeyboardButton(text = 'Вашингтон', callback_data = 'Washington,us')
      )
    )
  )

  # Send Inline Keyboard
  bot$sendMessage(chat_id = update$message$chat_id, 
                  text = "Выберите город", 
                  reply_markup = IKM)
}

# метод для сообщения погоды
answer_cb <- function(bot, update) {

  # получаем из сообщения город
  city <- update$callback_query$data

  # отправляем запрос
  ans <- GET('https://api.openweathermap.org/data/2.5/weather', 
             query = list(q     = city,
                          lang  = 'ru',
                          units = 'metric',
                          appid = '4776568ccea136ffe4cda9f1969af340')) 

  # парсим ответ
  result <- content(ans)

  # формируем сообщение
  msg <- str_glue("{result$name} погода:n",
                  "Текущая температура: {result$main$temp}n",
                  "Скорость ветра: {result$wind$speed}n",
                  "Описание: {result$weather[[1]]$description}")

  # отправляем информацию о погоде
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text    = msg)

  bot$answerCallbackQuery(callback_query_id = update$callback_query$id) 
}

# создаём фильтры
## сообщения с текстом Погода
MessageFilters$weather <- BaseFilter(function(message) {

  # проверяем текст сообщения
  message$text == "Погода"

}
)

# создаём обработчики
h_start         <- CommandHandler('start', start)
h_weather       <- MessageHandler(weather, filters = MessageFilters$weather)
h_query_handler <- CallbackQueryHandler(answer_cb)

# добавляем обработчики в диспетчер
updater <- updater + 
              h_start +
              h_weather +
              h_query_handler

# запускаем бота
updater$start_polling()

قم بتشغيل مثال الكود أعلاه، بعد استبدال "YOUR BOT TOKEN" بالرمز الحقيقي الذي تلقيته عند إنشاء الروبوت عبر الأب (تحدثت عن إنشاء روبوت في المادة الأولى).

نتيجة لذلك، سيعمل الروبوت الخاص بنا على النحو التالي:
كتابة روبوت برقية في R (الجزء 3): كيفية إضافة دعم لوحة المفاتيح إلى الروبوت

من الناحية التخطيطية، يمكن تصوير هذا الروبوت على النحو التالي:
كتابة روبوت برقية في R (الجزء 3): كيفية إضافة دعم لوحة المفاتيح إلى الروبوت

لقد أنشأنا 3 طرق متاحة داخل روبوت الطقس الخاص بنا:

  • بداية - قم بتشغيل لوحة المفاتيح الرئيسية للبوت
  • طقس — قم بتشغيل لوحة المفاتيح المضمنة لتحديد مدينة
  • Answer_cb — الطريقة الرئيسية التي تطلب الطقس من واجهة برمجة التطبيقات (API) لمدينة معينة وترسله إلى الدردشة.

طريقة بداية نطلقه مع الأمر /start، والذي يتم تنفيذه بواسطة المعالج CommandHandler('start', start).

لتشغيل طريقة طقس لقد أنشأنا مرشحًا يحمل نفس الاسم:

# создаём фильтры
## сообщения с текстом Погода
MessageFilters$weather <- BaseFilter(function(message) {

  # проверяем текст сообщения
  message$text == "Погода"

}
)

ونسمي هذه الطريقة باستخدام معالج الرسائل التالي: MessageHandler(weather, filters = MessageFilters$weather).

وفي النهاية، طريقتنا الرئيسية Answer_cb يتفاعل مع الضغط على الأزرار المضمنة، والتي يتم تنفيذها بواسطة معالج خاص: CallbackQueryHandler(answer_cb).

داخل طريقة Answer_cbنقرأ البيانات المرسلة من لوحة المفاتيح ونكتبها في متغير city: city <- update$callback_query$data. ثم نطلب بيانات الطقس من واجهة برمجة التطبيقات (API)، وننشئ رسالة ونرسلها، ثم نستخدم الطريقة أخيرًا answerCallbackQuery لإبلاغ الروبوت بأننا قمنا بمعالجة النقرة على الزر المضمّن.

مثال لروبوت يعرض قائمة بأحدث المقالات مع روابط إلى المركز المحدد من www.habr.com.

أقدم هذا الروبوت ليوضح لك كيفية عرض الأزرار المضمنة التي تؤدي إلى صفحات الويب.

منطق هذا الروبوت مشابه للمنطق السابق؛ في البداية نقوم بتشغيل لوحة المفاتيح الرئيسية باستخدام الأمر /start. بعد ذلك، يقدم لنا الروبوت قائمة بـ 6 محاور للاختيار من بينها، ونختار المحور الذي نهتم به، ونتلقى أحدث 5 منشورات من المحور المحدد.

كما تفهم، في هذه الحالة نحتاج إلى الحصول على قائمة بالمقالات، ولهذا سوف نستخدم حزمة خاصة habRوالتي تتيح لك طلب مقالات من هبرة وبعض الإحصائيات عنها في R.

ثبت المجموعة habR ممكن فقط من github، حيث ستحتاج إلى حزمة إضافية devtools. للتثبيت، استخدم الكود أدناه.

install.packages('devtools')
devtools::install_github('selesnow/habR')

الآن دعونا نلقي نظرة على الكود الخاص ببناء الروبوت الموصوف أعلاه:

الرمز 5: روبوت يعرض قائمة بأحدث المقالات على المركز المحدد

library(telegram.bot)
library(habR)

# создаём экземпляр класса Updater
updater <- Updater('ТОКЕН ВАШЕГО БОТА')

# создаём методы
## метод для запуска основной клавиатуры
start <- function(bot, update) {

  # создаём клавиатуру
  RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(
        KeyboardButton("Список статей")
      )
    ),
    resize_keyboard = TRUE,
    one_time_keyboard = TRUE
  )

  # отправляем клавиатуру
  bot$sendMessage(update$message$chat_id,
                  text = 'Выберите команду', 
                  reply_markup = RKM)

}

## Метод вызова Inine клавиатуры
habs <- function(bot, update) {

  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton(text = 'R', callback_data = 'R'),
        InlineKeyboardButton(text = 'Data Mining', callback_data = 'data_mining'),
        InlineKeyboardButton(text = 'Data Engineering', callback_data = 'data_engineering')
      ),
      list(
        InlineKeyboardButton(text = 'Big Data', callback_data = 'bigdata'),
        InlineKeyboardButton(text = 'Python', callback_data = 'python'),
        InlineKeyboardButton(text = 'Визуализация данных', callback_data = 'data_visualization')
      )
    )
  )

  # Send Inline Keyboard
  bot$sendMessage(chat_id = update$message$chat_id, 
                  text = "Выберите Хаб", 
                  reply_markup = IKM)
}

# метод для сообщения погоды
answer_cb <- function(bot, update) {

  # получаем из сообщения город
  hub <- update$callback_query$data

  # сообщение о том, что данные по кнопке получены
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id, 
                          text = 'Подождите несколько минут, запрос обрабатывается') 

  # сообщение о том, что надо подождать пока бот получит данные
  mid <- bot$sendMessage(chat_id = update$from_chat_id(),
                         text    = "Подождите несколько минут пока, я соберу данные по выбранному Хабу")

  # парсим Хабр
  posts <- head(habr_hub_posts(hub, 1), 5)

  # удаляем сообщение о том, что надо подождать
  bot$deleteMessage(update$from_chat_id(), mid$message_id) 

  # формируем список кнопок
  keys <- lapply(1:5, function(x) list(InlineKeyboardButton(posts$title[x], url = posts$link[x])))

  # формируем клавиатуру
  IKM <- InlineKeyboardMarkup(
    inline_keyboard =  keys 
    )

  # отправляем информацию о погоде
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text    = paste0("5 наиболее свежих статей из Хаба ", hub),
                  reply_markup = IKM)

}

# создаём фильтры
## сообщения с текстом Погода
MessageFilters$hubs <- BaseFilter(function(message) {

  # проверяем текст сообщения
  message$text == "Список статей"

}
)

# создаём обработчики
h_start         <- CommandHandler('start', start)
h_hubs          <- MessageHandler(habs, filters = MessageFilters$hubs)
h_query_handler <- CallbackQueryHandler(answer_cb)

# добавляем обработчики в диспетчер
updater <- updater + 
  h_start +
  h_hubs  +
  h_query_handler

# запускаем бота
updater$start_polling()

قم بتشغيل مثال الكود أعلاه، بعد استبدال "YOUR BOT TOKEN" بالرمز الحقيقي الذي تلقيته عند إنشاء الروبوت عبر الأب (تحدثت عن إنشاء روبوت في المادة الأولى).

ونتيجة لذلك سنحصل على هذه النتيجة:
كتابة روبوت برقية في R (الجزء 3): كيفية إضافة دعم لوحة المفاتيح إلى الروبوت

لقد قمنا بترميز قائمة المحاور المتاحة للاختيار في الطريقة habs:

## Метод вызова Inine клавиатуры
habs <- function(bot, update) {

  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton(text = 'R', callback_data = 'r'),
        InlineKeyboardButton(text = 'Data Mining', callback_data = 'data_mining'),
        InlineKeyboardButton(text = 'Data Engineering', callback_data = 'data_engineering')
      ),
      list(
        InlineKeyboardButton(text = 'Big Data', callback_data = 'bigdata'),
        InlineKeyboardButton(text = 'Python', callback_data = 'python'),
        InlineKeyboardButton(text = 'Визуализация данных', callback_data = 'data_visualization')
      )
    )
  )

  # Send Inline Keyboard
  bot$sendMessage(chat_id = update$message$chat_id, 
                  text = "Выберите Хаб", 
                  reply_markup = IKM)
}

نحصل على قائمة بالمقالات من المحور المحدد باستخدام الأمر habr_hub_posts()، من الحزمة habR. وفي الوقت نفسه نشير إلى أننا لا نحتاج إلى قائمة المقالات طوال الوقت، بل نحتاج فقط إلى الصفحة الأولى التي يوجد بها 20 مقالاً. من الجدول الناتج باستخدام الأمر head() نترك فقط الخمسة الأوائل، وهي أحدث المقالات.

  # парсим Хабр
  posts <- head(habr_hub_posts(hub, 1), 5)

المنطق مشابه جدًا للروبوت السابق، ولكن في هذه الحالة نقوم بإنشاء لوحة مفاتيح مضمنة تحتوي على قائمة من المقالات ديناميكيًا باستخدام الوظيفة lapply().

  # формируем список кнопок
  keys <- lapply(1:5, function(x) list(InlineKeyboardButton(posts$title[x], url = posts$link[x])))

  # формируем клавиатуру
  IKM <- InlineKeyboardMarkup(
    inline_keyboard =  keys 
    )

نقوم بإدراج عنوان المقال في نص الزر posts$title[x]، وفي الحجة url رابط المقال: url = posts$link[x].

بعد ذلك، نقوم بإنشاء مرشح ومعالجات ونطلق الروبوت الخاص بنا.

اختتام

الآن، ستكون الروبوتات التي تكتبها أكثر ملاءمة للاستخدام، نظرًا لأنه سيتم التحكم فيها من خلال لوحة المفاتيح، بدلاً من إدخال الأوامر. كحد أدنى، عند التفاعل مع الروبوت عبر الهاتف الذكي، ستعمل لوحة المفاتيح على تبسيط عملية استخدامه بشكل كبير.

في المقالة التالية سنتعرف على كيفية بناء حوار منطقي مع الروبوت والعمل مع قواعد البيانات.

المصدر: www.habr.com

إضافة تعليق