В этой части я хочу показать как связывать сценарии между собой, познакомлю с еще парой нод, и покажу как сделать SubFlow (подсценарий). И на этом я наверное закончу подробно описывать создание бота на Node-RED. Я думаю для начала достаточно информации, с чего начать и как. Кому интересно, будете разбираться - пишите, мне и самому будет интересно обменяться опытом. Я еще не волшебник, а только учусь. Возможно я еще буду делиться своими находками.
Про бота я не буду забывать, пока буду его для себя развивать и как говорил может быть выложу в открытый доступ. @on0tole говорит, что скоро будет релиз новой версии бота, где помимо вотинга и комментариев будет более продвинутый функционал. Я подожду, может этого будет достаточно. В данный момент благодаря голосу и моему словоблудию у меня появились монетки, коими хочу попробовать торговать и думаю сделать бота следящего по умному за курсом валют и предупреждающем о падении курса.
Но давайте вернемся к нашим ботам. В предыдущем блоге мы получили от сервера список записей из истории аккаунта и отфильтровали только новые. Все записи через ноду Link будем отправлять на другой сценарий, где мы будем формировать понятные сообщения и эти сообщения будем уже отправлять боту.
В предыдущем блоге я создал новый сценарий и назвал его “Сообщения для бота” и переместил на него две ноды. “Msg; Движуха” и исходящая нода “Голос бот”.
В качестве источника сообщений для этого сценария мы добавим входную ноду Link и в свойствах этой ноды выберем исходящий Link на сценарии “Вестник голоса”.
Мы будем получать на вход записи разных типов
Тип | Назначение |
---|---|
vote | Голосование. Может быть вами отданный голос ли бо кем то отданный вам голос |
curation_reward | Награда за кураторство в Силе Голоса (GESTS). |
comment | Комментарий. Аналогично голосованию, это может ваш комментарий к чужому посту, а также комментарий оставленный к вашему блогу или комментарию |
author_reward | Авторское вознаграждение. Часть золотом (GBG), атрибут sbd_payout , часть Силой Голоса (GESTS), атрибут vesting_payout |
transfer | Перевод валюты. |
Все эти типы записей я извлек из своей истории. Вероятно есть больше, но пока я ограничусь этими.
Нам надо будет перенаправлять сообщения в зависимости от типа в соответствующие потоки, где мы их и будем обрабатывать. Для этого создадим диспетчер (англ. Dispatcher) из Switch ноды.
Обратите внимание, что сравниваем с msg.payload[0]. Первый элемент это тип записи, второй это сама запись. Для каждого типа записи я добавил свой оператор сравнения. По числу операторов и число выходов.
Давайте сформируем сообщения для отданного голоса. Тип записи "vote".
"op": ["vote", {
"voter": "demon",
"author": "ropox",
"permlink": "hoversurf-pokoryaet-nebesa",
"weight": 10000
}]
Во первых нас интересует второй элемент массива с записью. Во вторых в истории записываются отданные голоса за вас, а так же голоса отданные вами. Отличие в атрибутах voter (англ. Голосующий) и author (англ. Автор). Естественно нас интересуют только записи с author = “ropox”. Второе, что было бы интересно знать это с какой силой за вас проголосовали. Это записано в атрибуте “weight” (англ. Вес). Как видно сила отданного голоса записана без десятичной дроби в виде целого числа, видимо для удобства хранения. Поэтому для сообщения нам надо будет разделить заначение weight на 100.
Добавим ноду Change, что бы извлечь из массива объект и заодно поделим вес на сто.
Как видно первым делом мы присваиваем msg.payload второй элемент массива msg.payload[1]. (В javascript нумерация элементов массива начинается с нуля). А затем используя присваивание с типом функции, в которой мы делим силу голоса на 100.
Добавим ноду Switch, чтобы отфильтровать голоса отданные за нас. Другие не интересны.
Собственно осталось только склеить само сообщение из того, что есть. Для этого используем новую ноду Template. Нода Template (англ. Шаблон) задает шаблон, по которому будет сформирован конечный текст. В шаблоне, в двойных фигурных скобках мы можем задать названия переменных , которые позднее будут заменены значениями этих переменных. Шаблон сообщения об отданном голосе может выглядеть следующим образом.
{{payload.voter}} проголосовал за вас с весом {{payload.weight}}%
В шаблоне переменные будут заменены на значения и мы получим что-то вроде.
on0tole проголосовал за вас с весом 100%
Подключим выход ноды Template ко входу ноды “msg: Движуха” и поправим свойства последней. Так как мы в этой Change ноде модифицируем payload, а payload содержит сообщение, то мы первым делом это сообщение сохраним в дополнительном атрибуте msg.message. Javascript нам сам создаст этот атрибут если его еще нет. И вместо текста “Движение в вашем аккаунте” мы присвоим msg.payload.content содержимое msg.message.
Получилась вот такая цепочка.
Я задеплоил и испытал результат. В чате бота я получил мои сообщения!
Не так информативно как в чате от on0tole но относительно затраченных усилий тоже неплохо. Интересно конечно было бы создать ссылку на пост или комментарий за который был отдан голос. Интересно было бы также знать какая сила голоса у голосующего. Для этого надо отсылать дополнительные запросы серверу. Для этого можно сделать отдельный подсценарий и подключить его к формированию сообщения.
Дальше я чисто механически копировал ноды и адаптировал их под соответствующий тип записи. Единственное, что я хотел знать оба варианта. Кому я перевел и кто мне перевел. Для контроля. Получился вот такой вот интересный сценарий. Больше похоже на электрическую схему, что недалеко от сути Node-RED разрабатываемого по большей части для интернета вещей.
А это сообщения которые я получил от бота.
Как видно валюта указана сокращениями GBG, GESTS, GOLOS. Можно было бы и так оставить, но мне захотелось перевести соответственно в “золотой”, “сила голоса” и “голос”. Честно говоря я с наскока не нашел чем заменить подстроку в тексте. Потому я решил воспользоваться средствами предоставляемыми javascript. Заодно решил познакомить с нодой Function. Эта нода решение как раз для таких случаев, когда нет подходящей ноды или когда проще все таки написать код, чем плести сложно-сочлененные сценарии.
Для трансляции обозначений валюты к человеческому языку я поместил ноду Function перед нодой “msg: Движуха” формирующей команду для бота. Нода Function это по сути прямой аналог функции javascript. В качестве параметра она получает msg объект. Function нода возвращает msg объект. Можно также задать количество выходов и тогда надо будет вернуть массив с соответствующим числом объектов msg.
Function получает на вход msg.payload с нашим сообщением. Нам нужно только воспользоваться методом replace предоставляемым типом string.
msg.payload = msg.payload.replace(“GESTS”, “силы голоса”);
msg.payload = msg.payload.replace(“GBG”, “золотых”);
msg.payload = msg.payload.replace(“GOLOS”, “голосов”);
Все ноды формирующие сообщения я подключил к ноде Function, переводчику валютных обозначений.
После тестирования смотрим результат - то, что и требовалось.
Конечно оно немного глючит. Не все особенности формата возвращаемого сервером голоса учитываются. К примеру посты которые я создаю в своем блоге тоже записываются в историю как комментарии. Но это все решаемо. Отладка приложения это то, чего не избежать. Красота Node-RED в малом количестве кода, который надо написать, что бы создать достаточно мощные сценарии. Меньше кода - меньше возможностей напортачить и как следствие меньше ошибок. Там где Node-RED пробуксовывает всегда можно использовать javascript.
Спасибо за внимание.