Фреймворк бота — неожиданная ошибка при вызове метода turnContext.sendActivity внутри функции обратного вызова Cron

#javascript #cron #botframework #anonymous-function

#javascript #cron #botframework #анонимная функция

Вопрос:

У меня возникли некоторые проблемы с отправкой запланированных уведомлений skype.

Ошибка:

 (node:3720) UnhandledPromiseRejectionWarning: TypeError: Cannot perform 'get' on a proxy that has been revoked

at CronJob.<anonymous> (C:botscleanbot.js:101:43)
at CronJob.fireOnTick (C:botscleannode_modulescronlibcron.js:554:23)
at Timeout.callbackWrapper [as _onTimeout] (C:botscleannode_modulescronlibcron.js:621:10)
at ontimeout (timers.js:498:11)
at tryOnTimeout (timers.js:323:5)
at Timer.listOnTimeout (timers.js:290:5)

(node:3720) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 61)
  

Мой код:

 await turnContext.sendActivity('Successful write to log.');        
var CronJob = require('cron').CronJob;
new CronJob('*/5 * * * * *', async function() {
    console.log('Executed');
    await turnContext.sendActivity('Executed'); //here is error
}, null, true, 'Europe/Riga');
  

Первый вызов sendActivity работает нормально, но второй в обратном вызове Cron — нет.

Даже если я попытаюсь вызвать внутри axios then() функцию, она также работает.. :

 axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(async function (response) {
     await turnContext.sendActivity('Executed');
  })
  

Есть ли способ, как вызвать sendActivity анонимную функцию Cron?

Ответ №1:

Попробуйте использовать метод async / await с вашим запросом Axios вместо метода then / catch. Я видел эти проблемы в прошлом при вызове sendActivity из функции обратного вызова.

 const res = await axios.get('/user', { params: { ID: 12345 }});
await turnContext.sendActivity('Executed');
  

Ответ №2:

Лучший вариант — настроить задание cron как внешнюю службу. Затем настройте задание cron так, чтобы оно выполняло вызов api для бота в соответствии с установленным вами расписанием. При нажатии на api он отправит упреждающее сообщение.

Существует множество способов настроить задание cron (или что-то подобное), включая создание функции Azure с запуском таймера (документ здесь).

Однако вы можете легко создать javascript-сервис на основе узла, который мог бы выполнять ваши вызовы api для бота.

Для начала вам сначала следует создать каталог и установить необходимые модули узла.

 mkdir cron-jobs-node cd cron-jobs-node
npm init -y

npm install express node-cron fs
  

Затем создайте проект. Вы бы выполнили свой вызов api (например, используя Axios) вместо console.log(). Вы можете прочитать больше о следующем фрагменте кода здесь.

 // index.js
const cron = require("node-cron");
const express = require("express");
const fs = require("fs");

app = express();

// schedule tasks to be run on the server   
cron.schedule("* * * * *", function() {
    console.log("running a task every minute");
});

app.listen(3128);
[...]
  

Пример 16.proactive-messages из репозитория Botbuilder-Samples демонстрирует, как создать API и настроить базовую систему упреждающих сообщений.

Надеюсь на помощь!