مقدمة
لقد مرت الفترة التي كُرست فيها كل مقالة ثانية عن حبرابر لكتابة روبوت برقية. أيضا ، مرت فترة من الوقت عندما يمكن وضع البوت دون صعوبات على جهاز الكمبيوتر الخاص بك أو الاستضافة في روسيا. منذ ستة أشهر ، بدأ الروبوت الخاص بي للتو على جهاز كمبيوتر محمول ولم يواجه أي مشاكل في الاتصال بواجهة برمجة التطبيقات. ولكن الآن ، عندما فكرت في إعادته إلى العمل ، أدركت أنه لن يكون بهذه السهولة. لم أرغب في البحث عن خادم وكيل وتكوينه ، بل وأكثر من ذلك في الخارج. أيضا ، قبل ذلك كتبت البوت في Wolfram Language ولم يكن لدي أي فكرة عن كيفية عمل اللغة مع الخوادم الوكيلة ، لأنني لم أستخدمها بعد. ثم جاءت فكرة عظيمة! استخدم Wolfram Cloud. في هذه المقالة ، أريد أن أبين مدى بساطة التسجيل ، ولكن بدون الرسائل النصية القصيرة ، يمكنك أن تبدأ روبوت برقية بسيط مكتوب بلغة Wolfram. من الأدوات تحتاج فقط إلى متصفح.
قليلا عن سحابة ولفرام
للوصول إلى السحابة ، تحتاج إلى إنشاء حساب Wolfram. للقيام بذلك ، انتقل إلى https://account.wolfram.com واتبع التعليمات بعد النقر فوق الزر إنشاء واحد.

بعد الانتهاء من جميع التلاعبات ، سيتم عرض جميع المنتجات وخططها على الصفحة الرئيسية للسحابة على https://www.wolframcloud.com . يجب عليك تحديد منصة التنمية وإنشاء دفتر ملاحظات جديد.

سيتم تنفيذ جميع التعليمات البرمجية الواردة لاحقًا في دفتر الملاحظات السحابي هذا.
قليلا عن الروبوتات برقية
هناك العديد من المقالات المخصصة لهم. هنا من الضروري فقط القول أنه قبل تنفيذ جميع الإجراءات الأخرى ، يجب إنشاء البوت بالطريقة القياسية. أي ، ما عليك سوى بدء محادثة مع بوتBotFather وأرسل له الأمر:
/newbot
ثم تحتاج فقط إلى اتباع التعليمات وإدخال الاسم وتسجيل الدخول. دع اسمه يكون Wolfram Cloud Bot وقم بتسجيل الدخول @ WolframCloud5973827Bot.

تنفيذ API
نحن نستفيد من توصياتBotFather ونفحص بإيجاز HTTP API الخاص ببرامج الروبوت في برقية. إن مهمة تنفيذ API بالكامل لا تستحق ذلك بعد. لكتابة روبوت ، يكفي جزء صغير فقط. تحقق من إمكانية الوصول إلى واجهة برمجة التطبيقات ومن وجود برنامج الروبوت الذي يحمل الرمز المميز أعلاه. للقيام بذلك ، فقط قم بخط واحد:
URLExecute["https://api.telegram.org/bot753681357:AAFqdRFN_QoODJxsBy3VN2sVwWTPKJEqteY/getMe"]
خارج [..]: = ... {"ok" -> True, "result" -> {"id" -> 753681357, "is_bot" -> True, "first_name" -> "Wolfram Cloud Bot", "username" -> "WolframCloud5973827Bot"}}
الأمر أعلاه هو أسهل طريقة لتقديم طلب HTTP من لغة Wolfram. ولكن دعنا نعقده قليلاً حتى يكون من السهل تنفيذ جميع طرق API الأخرى. لنقم بإنشاء طريقة عامة لتنفيذ طلب API:
TelegramBot::usage = "TelegramBot[token]"; $telegramAPI = "https://api.telegram.org"; telegramExecute[ TelegramBot[token_String], method_String, parameters: {(_String -> _)...}: {} ] := Module[{ request, requestURL, requestRules, requestBody, response, responseBody }, requestURL = URLBuild[{$telegramAPI, "bot" <> token, method}]; requestRules = DeleteCases[parameters, _[_String, Automatic | Null | None]]; requestBody = ImportString[ExportString[requestRules, "JSON"], "Text"]; request = HTTPRequest[requestURL, <| Method -> "POST", "ContentType" -> "application/json; charset=utf-8", "Body" -> requestBody |>]; response = URLRead[request]; responseBody = response["Body"]; Return[ImportString[responseBody, "RawJSON"]] ]
تحقق مما إذا كان هذا يعمل على الطريقة التي تم اختبارها بالفعل أعلاه:
token = "753681357:AAFqdRFN_QoODJxsBy3VN2sVwWTPKJEqteY"; bot = TelegramBot[token]; telegramExecute[bot, "getMe"]
خارج [..]: = ... <|"ok" -> True, "result" -> <|"id" -> 753681357, "is_bot" -> True, "first_name" -> "Wolfram Cloud Bot", "username" -> "WolframCloud5973827Bot"|>|>
عظيم. دعنا ننشئ وظيفة منفصلة لإجراء فحص بوت:
getMe::usage="getMe[bot]"; TelegramBot /: getMe[bot_TelegramBot] := telegramExecute[bot, "getMe"] getMe[bot]
خارج [..]: = ... <|"ok" -> True, "result" -> <|"id" -> 753681357, "is_bot" -> True, "first_name" -> "Wolfram Cloud Bot", "username" -> "WolframCloud5973827Bot"|>|>
الآن ، وبنفس الطريقة ، يبقى إضافة الطرق الأساسية اللازمة لإنشاء روبوت في السحابة:
- getUpdates - يحصل على أحدث الرسائل المكتوبة في البوت
getUpdates::usage = "getUpdates[bot, opts]"; Options[getUpdates] = { "offset" -> Automatic, "limit" -> Automatic, "timeout" -> Automatic, "allowed_updates" -> Automatic }; TelegramBot /: getUpdates[bot_TelegramBot, opts: OptionsPattern[getUpdates]] := telegramExecute[bot, "getUpdates", Flatten[{opts}]]
setWebhook::usage = "setWebhook[bot, url, opts]"; Options[setWebhook] = { "certificate" -> Automatic, "max_connections" -> Automatic, "allowed_updates" -> Automatic }; TelegramBot /: setWebhook[bot_TelegramBot, url_String, opts: OptionsPattern[setWebhook]] := telegramExecute[bot, "setWebhook", Join[{"url" -> url}, Flatten[{opts}]]]
deleteWebhook::usage = "deleteWebhook[bot]"; TelegramBot /: deleteWebhook[bot_TelegramBot] := telegramExecute[bot, "deleteWebhook"]
getWebhookInfo::usage = "getWebhookInfo[bot]"; TelegramBot /: getWebhookInfo[bot_TelegramBot] := telegramExecute[bot, "getWebhookInfo"]
sendMessage::usage = "sendMessage[bot, chat, text]"; Options[sendMessage] = { "parse_mode" -> Automatic, "disable_web_page_preview" -> Automatic, "disable_notification" -> Automatic, "reply_to_message_id" -> Automatic, "reply_markup" -> Automatic }; TelegramBot /: sendMessage[bot_TelegramBot, chat_Integer, text_String, opts: OptionsPattern[sendMessage]] := telegramExecute[ bot, "sendMessage", Join[{"chat_id" -> chat, "text" -> text}, Flatten[{opts}]] ]
الإصدار الأدنى من واجهة برمجة التطبيقات جاهز. دعونا نتحقق من كيفية إرسال رسالة وتلقي التحديثات. للقيام بذلك ، قم بإنشاء محادثة مع الروبوت الخاص بنا. عندما يتم إنشاء البوت ، سيتم إرسال الرسالة الأولى مع / start text. دعونا نرى ما إذا كان قد دخل في قائمة التحديثات:
updates = getUpdates[bot]
خارج [..]: = ... <|"ok" -> True, "result" -> {<|"update_id" -> 570790461, "message" -> <|"message_id" -> 1, "from" -> <|"id" -> 490138492, "is_bot" -> False, "first_name" -> "Kirill", "last_name" -> "Belov", "username" -> "KirillBelovTest"|>, "chat" -> <|"id" -> 490138492, "first_name" -> "Kirill", "last_name" -> "Belov", "username" -> "KirillBelovTest", "type" -> "private"|>, "date" -> 1542182547, "text" -> "/start", "entities" -> {<|"offset" -> 0, "length" -> 6, "type" -> "bot_command"|>}|>|>}|>
يمكنك الحصول على أحدث بيانات التحديث من قائمة التحديثات كما يلي:
lastUpdate = updates["result"][[-1]]
خارج [..]: = ... <|"update_id" -> 570790461, "message" -> <|"message_id" -> 1, "from" -> <|"id" -> 490138492, "is_bot" -> False, "first_name" -> "Kirill", "last_name" -> "Belov", "username" -> "KirillBelovTest"|>, "chat" -> <|"id" -> 490138492, "first_name" -> "Kirill", "last_name" -> "Belov", "username" -> "KirillBelovTest", "type" -> "private"|>, "date" -> 1542182547, "text" -> "/start", "entities" -> {<|"offset" -> 0, "length" -> 6, "type" -> "bot_command"|>}|>|>
وهذه هي الطريقة التي يمكنك من خلالها الحصول على الدردشة التي جاءت منها الرسالة ونص الرسالة نفسها:
chat = lastUpdate["message", "chat", "id"] text = lastUpdate["message", "text"]
كما ترى من النتيجة ، كل شيء في مكانه. الآن سنرسل رسالة نيابة عن برنامج التتبُّع باستخدام sendMessage.
sendMessage[bot, chat, "hello"]
خارج [..]: = ... <|"ok" -> True, "result" -> <|"message_id" -> 2, "from" -> <|"id" -> 753681357, "is_bot" -> True, "first_name" -> "Wolfram Cloud Bot", "username" -> "WolframCloud5973827Bot"|>, "chat" -> <|"id" -> 490138492, "first_name" -> "Kirill", "last_name" -> "Belov", "username" -> "KirillBelovTest", "type" -> "private"|>, "date" -> 1542182601, "text" -> "hello"|>| >

بشكل عام ، هذه المجموعة من الوظائف كافية بالفعل. ومع ذلك ، فإن استخدام طريقة getUpdates ليست مريحة للغاية. تحتاج إلى ابتكار طريقة للتعامل مع الرسائل باستخدام الرد التلقائي على الويب.
إنشاء الرد التلقائي على الويب
لدى Wolram Langauge نوع خاص من الوظائف التي يتم إنشاؤها باستخدام وظيفة APIF. فيما يلي مثال لأحد هذه:
apiFunc = APIFunction[{"n" -> "Integer"}, Plot[Sin[#n * x], {x, -2Pi, 2Pi}]&, "PNG"]; apiFunc[{"n"->3}]
تم تصميم هذه الميزات خصيصًا للنشر في السحابة. ستقبل هذه الوظيفة معلمة طلب واحدة كمدخل. لنشرها في السحابة ، ما عليك سوى نقل الوظيفة نفسها إلى CloudDeploy.
apiObject = CloudDeploy[apiFunc, "Deploy/apiObject"]
خارج [..]: = ... CloudObject[https://www.wolframcloud.com/objects/kirillbelovtest/apiObject]
ثم يمكنك اتباع الرابط في المتصفح وإضافة معلمة استعلام:

تعاملت الوظيفة أعلاه معاملات الطلب. لذلك تحتاج إلى إنشاء نفس الوظيفة لمعالجة نص طلب HTTP الوارد من روبوت البرقية في شكل كائن تحديث. لإنشاء العنوان ، نستخدم رمزًا مميزًا للوصول إلى كائن السحابة كان أكثر صعوبة. يجب عليك أيضًا الإشارة إلى أن الكائن لديه وصول عام ، وإلا لن تتمكن البرقيات من الوصول إلى الرد التلقائي على الويب.
deployWebhook[bot_TelegramBot, handler_] := CloudDeploy[APIFunction[{}, handler[HTTPRequestData["Body"]] &], "Deploy/Webhooks/" <> Hash[bot, "SHA", "HexString"], Permissions -> "Public" ]
معالج هو معالج دالة آخر. اسمح للمعالج بتحويل سلسلة نص الطلب إلى اقتران ، واحصل على معرف الدردشة من هناك وأرسل كلمة "مرحبًا".
handlerHello[bot_TelegramBot][body_String] := Block[{json = ImportString[body, "RawJSON"], chat}, chat = json["message", "chat", "id"]; sendMessage[bot, chat, "hello"]; ]
الآن نشر غير تقليدي في السحابة.
webhookObject = deployWebhook[bot, handlerHello[bot]]
خارج [..]: = ... CloudObject[https://www.wolframcloud.com/objects/kirillbelovtest/Deploy/Webhooks/b9bd74f89348faecd6b683ba02637dd4d4028a28]
والخطوة الأخيرة هي نقل عنوان هذا الكائن إلى روبوت برقية.
setWebhook[bot, webhookObject[[1]]]
خارج [..]: = ... <|"ok" -> True, "result" -> True, "description" -> "Webhook was set"|>
الآن سنكتب شيئًا للبوت ونرى ما يقوله:

يمكن اعتبار الحوار صالحًا. لتغيير منطق معالج موجود ، فقط قم بإعادة نشر كائن السحابة. في الوقت نفسه ، لن تحتاج بعد الآن إلى تثبيت webhook للبوت.
منطق الإجابات
سيكون هذا هو الجزء الأخير في عملية إنشاء روبوت في سحابة Wolfram. علاوة على ذلك ، بنفس الطريقة ، يمكنك تعقيد المنطق وإضافة طرق API جديدة. الآن عن الحوار نفسه. افترض أنه بعد إرسال الأمر / start ، يقوم البوت بإرجاع استجابة "Hello" وتغيير لوحة مفاتيح المستخدم. يبقى فقط زرين في لوحة المفاتيح: "مرحبًا" و "من أنت؟" ندرك الحوار في شكل جمعية. ستكون المفاتيح هي الأوامر التي يرسلها المستخدم إلى البوت. القيم الأساسية هي استجابة الروبوت نفسها ولوحة المفاتيح الجديدة. في هذه الحالة ، يجب أن تتطابق العديد من المفاتيح والأزرار تمامًا. خلاف ذلك ، قد ينشأ موقف عندما لا يعرف البوت ما يجب الإجابة عليه. في مثل هذه الحالات ، بالطبع ، يمكنك إضافة إجابة افتراضية.
keyboard[buttons : {__String}] := {"keyboard" -> {Table[{"text" -> button}, {button, buttons}]}, "resize_keyboard" -> True} $answers = <| (*user_text-><|"answer"->bot_text,"keyboard"->next_text|>*) "/start"-><|"answer"->"","keyboard"-> keyboard[{""," ?"}]|>, ""-><|"answer"->" ?", "keyboard" -> keyboard[{" ?"}]|> , " ?"-><|"answer"->"", "keyboard" -> keyboard[{""}]|> , " ?"-><|"answer"->" Wolfram Language ", "keyboard"->keyboard[{" ?"," ?"}]|> , " ?"-><|"answer"->" :\nhttps://habr.com/post/422517/", "keyboard"->keyboard[{""," ?"}]|> , " ?"-><|"answer"->" :\n@KirillBelovTest", "keyboard"->keyboard[{" ?",""}]|> , ""-><|"answer"->"", "keyboard"->keyboard[{""," ?"}]|> |>; answer[text_String] /; KeyExistsQ[$answers, text] := $answers[text]
الآن قم بإنشاء معالج:
handlerAbout[bot_TelegramBot][body_String] := Block[{json = ImportString[body, "RawJSON"], chat, text}, chat = json["message", "chat", "id"]; text = json["message", "text"]; sendMessage[bot, chat, answer[text]["answer"], "reply_markup" -> answer[text]["keyboard"]]; ]
وأعد نشر كائن السحابة:
deployWebhook[bot, handlerAbout[bot]];
دعنا نتحقق مما حدث في الدردشة مع الروبوت. لكن أولاً ، لنقم بمسح محفوظات الرسالة:

تمديد الوظيفة
حتى الآن ، لا توجد اختلافات جوهرية عن العدد الهائل من الروبوتات الموجودة. ربما لا فائدة من شربه أيضًا؟ سيكون معنى كل العمل الذي تم القيام به أعلاه ، إذا فهمت مزايا مثل هذا الروبوت! بعد كل شيء ، يمكنه استخدام جميع ميزات Wolfram Language و Wolrfam Cloud. هل من الضروري أن يحل الروبوت المعادلات؟ من السهل جدا! تحتاج فقط إلى إعادة تعريف الجواب!
answer[text_String]["keyboard"] /; StringContainsQ[text, " "] := Automatic answer[text_String]["answer"] /; StringContainsQ[text, " "] := ToString[Flatten[Block[{args = StringSplit[text, " "]}, Solve[ToExpression[args[[1]]], ToExpression[args[[2]]]] ]]] deployWebhook[bot, handlerAbout[bot]];

إذا كان شخص ما مهتمًا أيضًا بقدرات السحابة ، فإن الوصف الجيد لوظائفها هنا .
القيود
Wolfram Cloud عبارة عن منصة تتيح لك استخدام لغة Wolfram مجانًا ، في حين أن المنتج الرئيسي لـ Wolfram Research ، Mathematica ، يكلف المال. وفقًا لذلك ، هناك قيود على الاستخدام وفي رأيي أنها قوية جدًا. عند استخدام الإصدار المجاني من منصة التطوير ، يتم منح 1000 اعتماد سحابي شهريًا للمستخدم. يمنح كل قرض سحابي الوقت لحساب نوع مختلف. نظرًا لأن المقالة تتحدث عن وظيفة CloudDeploy + APIF ، فإن هذه الكائنات المخزنة في السحابة تنفق رصيدًا واحدًا في 0.1 ثانية من وقت الحوسبة. من السهل حساب أنه يتم منح المستخدم مجانًا لمدة دقيقة واحدة و 40 ثانية فقط من وقت الخادم لتشغيل تطبيقه (في هذه الحالة ، الروبوت). ليس لدي ما أضيفه هنا - إنه صغير جدًا جدًا. ينصب التركيز الرئيسي على المستخدمين الذين يعملون بشكل مستقل في منصة التنمية باستخدام متصفح. في الواقع ، في هذا الوضع لا توجد حدود زمنية ، ولكن فقط وفقًا لمدة الجلسة والموارد المخصصة. مع هذا الاستخدام ، فإن منصة التطوير هي تقريبا رياضيات كاملة ، ولكنها لا تتطلب التثبيت والترخيص.
→ المادة والكود في Wolfram Cloud