Связываю базу данных и конструктор мобильных приложений через Integromat - часть I

На простом примере показываю, как работает синхронизации данных между конструктором приложений Adalo и онлайн базой данных QuintaDB через Integromat (без программирования).

В коллаже использован фрагмент картины «Сотворение Адама», Микеланджело
В коллаже использован фрагмент картины «Сотворение Адама», Микеланджело

Эта заметка будет полезна тем, кто впервые сталкивается с потребностью связывания данных между двумя облачными сервисами без программирования и решил попробовать сделать это с помощью сервиса Integromat. Ну и тем, кто как и я не шибко силён в области IT, а тем более в программирование.

Будет рассмотрено создания нескольких простых сценариев синхронизации данных между двумя сервисами для решения конкретной задачи.

Описанная методология во многом похожа на методологию создания сценариев интеграции в Zapier (аналог сервиса Integromat) и, по сути, во многом опирается на логику API запросов. Т.е. даже если вы не планируете использовать сервис Integromat, эта заметка поможет вам лучше понимать и нюансы настройки Zapier, и работы API.

Главный герой - сервис Integromat. Участники - QuintaDB и Adalo. Будут упомянуты - API, Zapier.

QuintaDB - онлайн конструктор баз данных, CRM и прочих веб-приложений для автоматизации бизнес-процессов без использования языков программирования и SQL. No-code.

Adalo - конструктор нативных мобильных приложений без использования языков программирования, как с возможностью публикации в Google Play и App Store, так и в формате PWA. No-code.

Integromat - позволяет подключать приложения и автоматизировать рабочие процессы в несколько кликов, без использования языков программирования. No-code.

Содержание:

Задача

Я разрабатываю мобильное приложение в но-кодинговом конструкторе Adalo. Имеющаяся там БД для моих задач слишком лаконична и не обладает достаточным для меня функционалом, поэтому саму базу данных я веду на сервисе QuintaDB (здесь описаны причины, по которым я остановился именно на этом сервисе).

Изначально, всю информацию я завожу (создаю) через БД QuintaDB и мне важно, чтобы в момент создания там новых записей они автоматически передавалась в конструктор мобильного приложения Adalo (равно как и в само мобильное приложение, когда с ним работает пользователь).

Часть информации у меня генерируется уже в самом мобильном приложении (статистика, заметки пользователей и проч.) и мне важно передать её обратно в мою БД.

В итоге мне надо, что бы со стороны QuntaDB в сторону Adalo передавалась информация:

  1. новые записи (созданные через форму создания новых записей);
  2. клонированные записи (созданные, за счёт клонирования существующей записи);
  3. импортированные записи (созданные, за счёт импорта в QuintaDB записей из Excel);
  4. обновлённые записи (полностью или частично).

И обратно, со стороны Adalo в сторону QuintaDB, мне необходимо передавать:

  1. обновленные записи новой информацией уже из мобильного приложения.

Эту задачу можно было бы решить вовсе избежав необходимости в использование третьего сервиса, просто связав два сервиса по API (Application programming interface) и здесь я описываю этот кейс.

Или, как поступают чаще, использовать более популярный сервис Zapier, который работает аналогично Integromat, но проигрывает ему по ряду причин - стоимость пользования им выше, а функционал по сложности развития сценариев интеграций хуже.

В общем, у меня 5 подзадач. Поехали решать их через Intrgromat, благо для обоих моих сервисов блок интеграции в Integromat разработан.

В Integromat мой аккаунт уже очищен от всех предварительных настроек, так что все необходимые действия для решения задачи будут показаны ниже.

Решение

Прежде, чем приступить непосредственно к разработке сценариев интеграции (синхронизации) в Integromat, нам необходимо сделать ряд подготовительных действий.

А - подготовка таблиц

У меня уже созданы идентичные тестовые таблицы в обоих сервисах - в QuintaDB и в Adalo.

Таблица "Список" на сервисе QuintaDB
Таблица "Список" на сервисе QuintaDB
Таблица "Список" на сервисе Adalo
Таблица "Список" на сервисе Adalo

Важно! Чтобы настроить синхронизацию, в двух таблицах должна быть заранее создана хотя бы одна запись, иначе Integromat увидит по этим таблицам лишь атрибутивную информацию, но не набор конкретных колонок.

Добавим по одной записи в каждую таблицу так, что бы потом можно было явно идентифицировать какая запись из какого сервиса к нам прилетела.

1-ая запись в таблице "Список" на сервисе QuintaDB
1-ая запись в таблице "Список" на сервисе QuintaDB
1-ая запись в таблице "Список" на сервисе Adalo
1-ая запись в таблице "Список" на сервисе Adalo

Б - подготовка идентификационной информации

Для разработки сценария в Integromat нам потребуется ряд исходной информации для того, что бы наш сценарий смог сначала авторизированно подключиться к нашей таблице на сервисе QuintaDB, а потом и на сервисе Adalo.

Чтобы потом, при разработке сценариев в Integromat, не отвлекаться от нюансов настройки конкретных блоков, давайте эту информацию сразу выясним и запишем у себя.

Что нам потребуется:

  • со стороны QuintaDB - API ключ. Всё остальное будет подгружаться динамически.
  • со стороны Adalo - API ключ, ID нашего приложения и ID конкретной таблицы.

Поехали.

Б1 - API ключ QuintaDB

Переходим в раздел Аккаунт\Поддержка

Связываю базу данных и конструктор мобильных приложений через Integromat - часть I

Далее в раздел "Разработчикам"

Связываю базу данных и конструктор мобильных приложений через Integromat - часть I

Далее в раздел "API ключи"

Связываю базу данных и конструктор мобильных приложений через Integromat - часть I

Вам откроется раздел для генерации вашего API ключа. Сгенерируйте его и скопируйте себе (в блокнот, допустим).

Связываю базу данных и конструктор мобильных приложений через Integromat - часть I

Ок, с QuintaDB всё. Поехали получать информация про Adalo.

Б2 - API ключ, ID приложения и таблицы в Adalo

Кликните на боковое меню вашей таблицы и перейдите в раздел "API Documentation"

Связываю базу данных и конструктор мобильных приложений через Integromat - часть I

У Вас откроется раздел со всей API информацией по всем таблицам вашего приложения. В нашем случае, переходим к вкладкам нашей таблицы "Список".

Связываю базу данных и конструктор мобильных приложений через Integromat - часть I

Раскрыв его, мы сразу видим всю необходимую нам информацию.

Связываю базу данных и конструктор мобильных приложений через Integromat - часть I
  1. ID код нашего приложения.
  2. ID код нашей таблицы.
  3. API ключ нашего приложения.

Также скопируйте себе информацию в блокнот.

Теперь мы готовы к тому, что бы начать разрабатывать необходимые сценарии для решения нашей задачи на сервисе Integromat.

У меня в блокноте теперь такая информацию, у Вас она будет своя
У меня в блокноте теперь такая информацию, у Вас она будет своя

С - создание сценариев в Integromat

После регистрации на сервисе, минуя все предложенные блоки обучения, вы попадаете в свой личный кабинет

У меня сейчас он пустой
У меня сейчас он пустой

Позже, когда наши сценарии будут созданы, то 3 важных составляющих любого сценария мы увидим в 3х разных разделах, но сейчас нам, в принципе, это не важно, но для общего понимания -

Связываю базу данных и конструктор мобильных приложений через Integromat - часть I

Переходим в раздел "Scenarios" и жмём на кнопку создания нового сценария.

Связываю базу данных и конструктор мобильных приложений через Integromat - часть I

Всего у нас 5 подзадач, которые раскладываются в нашем примере на 3 сценария:

  1. Сценарий 1 - передать все новые записи со стороны QuintaDB на сторону Adalo.
  2. Сценарий 2 - передать всё обновлённые задачи со стороны QuintaDB на сторону Adalo.
  3. Сценарий 3 - передача обновлённых записей в обратную сторону, уже со стороны Adalo на сторону QuintaDB.

В стартовом (первом) блоке сценария Интегромата мы указываем причину (триггер, вебхук) по которой этой сценарий должен сработать. Т.е. он мониторит наш сервис в фоновом режиме и в случае возникновения конкретной ситуации (срабатывании триггера) запускает работу конкретного сценария. У сервиса QuintaDB стартовый блок может отрабатывать одну из двух ситуаций - или ситуацию создания новой записи, или её обновления. Потому у нас и будет два сценария для передачи информации со стороны сервиса QuintaDB: - один для новых записей, а второй для обновлённых.

Если более опытный пользователь Integromat знает, как сделать сценарий (настроить роутер) так, чтобы было достаточно одного сценария, как для отработки новых записей, так и для обновлённых, то напишите, плз, об этом в комментариях, буду очень признателен!

Сценарий 1

часть а - отработка новых записей

Жмём на кнопку создания нового сценария
Жмём на кнопку создания нового сценария
Интегромат предлагает нам выбрать готовые блоки интеграций из пула сервисов. Мы пропускаем этот вариант разработки сценария - жмём "Пропустить"
Интегромат предлагает нам выбрать готовые блоки интеграций из пула сервисов. Мы пропускаем этот вариант разработки сценария - жмём "Пропустить"
Мы попадаем на экран разработки (правки) любого сценария с нуля.
Мы попадаем на экран разработки (правки) любого сценария с нуля.

В центре рабочего пространства мы видим иконку, которая состоит из двух блоков:

  • Иконка с часами - отвечает за временной режим работы сценария (мы пока её не трогаем).
  • И более крупная иконка со знаком "?" - как раз просит нас указать, какой сервис мы хотим связать. Кликнем по ней
У нас раскрывается список с различными сервисами, для которых разработаны блоки интеграции у Интегромата. В поле поиска начинаем вводить нужный нам сервис - QuintaDB
У нас раскрывается список с различными сервисами, для которых разработаны блоки интеграции у Интегромата. В поле поиска начинаем вводить нужный нам сервис - QuintaDB
Достаточно ввести первые несколько символов названия сервиса, что бы в списке остался лишь нужный. Его и кликнем.
Достаточно ввести первые несколько символов названия сервиса, что бы в списке остался лишь нужный. Его и кликнем.
Раскрывается список триггеров, по которым мы можем с нашим конкретным сервисом работать. Нас интересует первый тригер, который как раз отслеживает создание или обновление новых записей на стороне QuintaDB. Его и выбираем.
Раскрывается список триггеров, по которым мы можем с нашим конкретным сервисом работать. Нас интересует первый тригер, который как раз отслеживает создание или обновление новых записей на стороне QuintaDB. Его и выбираем.
После клика, нам сразу предлагают выбрать из списка уже авторизированный ранее триггер, но так как у нас пока ничего нет, то кликаем на "добавить" и создаём нужный нам.
После клика, нам сразу предлагают выбрать из списка уже авторизированный ранее триггер, но так как у нас пока ничего нет, то кликаем на "добавить" и создаём нужный нам.
Выскакивает окно добавления триггера и нам предлагают его обозвать, далее выбрать уже авторизированный коннекшн. У нас его пока тоже нет - так что сразу и создаём. Жмём "Add" - добавить.
Выскакивает окно добавления триггера и нам предлагают его обозвать, далее выбрать уже авторизированный коннекшн. У нас его пока тоже нет - так что сразу и создаём. Жмём "Add" - добавить.
Указываем имя нового коннекшена. И вот нам как уже раз нужен наш API ключ (который мы берём из блокнота). Если вы работаете в русской версии сервиса QuintaDB, то выберите из списка доменов русский вариант домена. Жмём "Continue" - продолжить.
Указываем имя нового коннекшена. И вот нам как уже раз нужен наш API ключ (который мы берём из блокнота). Если вы работаете в русской версии сервиса QuintaDB, то выберите из списка доменов русский вариант домена. Жмём "Continue" - продолжить.
Мы снова возвращаемся к окну создания нового триггера, где наш созданный новый конекшн уже подставлен.  Нам надо выбрать тип действия (action) - новая запись или обновление. А потом выбрать наш проект из динамически подгружаемого списка с сервиса QuintaDB.
Мы снова возвращаемся к окну создания нового триггера, где наш созданный новый конекшн уже подставлен. Нам надо выбрать тип действия (action) - новая запись или обновление. А потом выбрать наш проект из динамически подгружаемого списка с сервиса QuintaDB.
Выбираю  - отслеживание новых записей.
Выбираю  - отслеживание новых записей.
Как только выбрал нужный проект (у вас он может называться иначе), сразу появилось поле для выбора уже конкретной таблицы из него.
Как только выбрал нужный проект (у вас он может называться иначе), сразу появилось поле для выбора уже конкретной таблицы из него.
Ок - выбираю и нашу таблицу "Список" и жму "Save"
Ок - выбираю и нашу таблицу "Список" и жму "Save"
Мы возвращаемся к начальному окну выбора сервиса этого блока сценария и просто жмём "Ok"
Мы возвращаемся к начальному окну выбора сервиса этого блока сценария и просто жмём "Ok"
Обратите внимание, как изменился сам блок. Теперь у нас вместо иконки"?" - указано, что работаем с сервисом QuintaDB. Иконка с часиками тоже изменилась - теперь там есть варианты режимов запуска. Изучим их позже.
Обратите внимание, как изменился сам блок. Теперь у нас вместо иконки"?" - указано, что работаем с сервисом QuintaDB. Иконка с часиками тоже изменилась - теперь там есть варианты режимов запуска. Изучим их позже.

Теперь нам надо создать второй (конечный) блок нашего простого сценария - блок приёма. Т.е. настроить аналогичную историю для блока Adalo, но уже со своими нюансами. Продолжу просто картинками, всё будет аналогично, но где будут нюансы - подпишу.

Подводим курсор мыши к правой части нашего начального блока и там появляется бабл с плюсом - кликаем по нему.
Подводим курсор мыши к правой части нашего начального блока и там появляется бабл с плюсом - кликаем по нему.
Создаётся аналогичный блок в пустом состоянии и список для выбора сервиса, кликаем на добавить иной сервис.
Создаётся аналогичный блок в пустом состоянии и список для выбора сервиса, кликаем на добавить иной сервис.
Выбираем наш Adalo
Выбираем наш Adalo
Здесь нам важно, что бы в случае появления новых записей в QuintaDB в Adalo создавалась новая аналогичная запись, так что выбираем "Добавить запись"
Здесь нам важно, что бы в случае появления новых записей в QuintaDB в Adalo создавалась новая аналогичная запись, так что выбираем "Добавить запись"
Создаём новый авторизированный конекшн, но уже с Adalo
Создаём новый авторизированный конекшн, но уже с Adalo
В открывшемся окне параметров коннекшена вставляем данные из нашего блокнота
В открывшемся окне параметров коннекшена вставляем данные из нашего блокнота
1 - наш API ключ в Adalo; 2 - ID нашего приложения; 3 - ID нашей таблицы "Список"
1 - наш API ключ в Adalo; 2 - ID нашего приложения; 3 - ID нашей таблицы "Список"

Как создался конекшн и я нажал "Продолжить", у меня сразу выскакивает форма, в которой надо соотнести столбы из таблицы на Квиньте со столбцами таблицы в Адало. Но у вас может подтормаживать и форма может не выскочить сразу. Не страшно. Я её закрою и вызовы вновь.

Закрою через "Ок", что бы показать, как её вызвать вновь.
Закрою через "Ок", что бы показать, как её вызвать вновь.
Закрыл. Теперь видим все два блока нашего сценария. Достаточно кликнуть по центру второго блока "Adalo", что бы снова вызвать форму для соотнесения колонок из разных таблиц.
Закрыл. Теперь видим все два блока нашего сценария. Достаточно кликнуть по центру второго блока "Adalo", что бы снова вызвать форму для соотнесения колонок из разных таблиц.
ок - форма открылась вновь.
ок - форма открылась вновь.

Для вызова окна соотнесения колонок, достаточно кликнуть в любом пустом поле, а потом методом драг-энд-дроп просто перетащить в каждое поле Адало название аналогичного поля из таблицы Квинты

перетаскиваем email
перетаскиваем email
ок
ок

Делаем для всех колонок (полей) аналогично

Все соответствующие перетащили - жмём ок
Все соответствующие перетащили - жмём ок
Снова видим все блоки нашего сценария. Пора сохраниться - сам интегромат автоматом этого не делает.
Снова видим все блоки нашего сценария. Пора сохраниться - сам интегромат автоматом этого не делает.

Проверим работоспособность нашего сценария - нажмём "Run once" (для ручного запуска работы сценария), а потом посмотрим, что изменилось в двух наших таблицах.

Связываю базу данных и конструктор мобильных приложений через Integromat - часть I

Ваш сценарий перейдёт в режим фонового ожидания срабатывания триггера. В данном случае, триггер - это появления новой записи в таблице "Список" на сервисе QuintaDB.

Пока не добавить новую запись в таблице в QuintaDB триггер не сработает и сценарий не запустится. Ждёт.
Пока не добавить новую запись в таблице в QuintaDB триггер не сработает и сценарий не запустится. Ждёт.
Добавляю новую запись и иду смотреть, как отреагирует сценарий
Добавляю новую запись и иду смотреть, как отреагирует сценарий
Интегромат в сценарии показывает, что он 1ну запись увидел в блоке Квинта и 1ну запись отработал в блоке Адало
Интегромат в сценарии показывает, что он 1ну запись увидел в блоке Квинта и 1ну запись отработал в блоке Адало
Подробности при клике на показатель в блоке Квинты
Подробности при клике на показатель в блоке Квинты
Подробности при клике на показатель в блоке Адало
Подробности при клике на показатель в блоке Адало

Идём в наше приложения в Adalo и смотрим, что изменилось там

Показывает, что записи уже 2 (была ранее лишь одна)
Показывает, что записи уже 2 (была ранее лишь одна)
Да, вот наша запись, которая прилетела из Квинты. То, что надо)
Да, вот наша запись, которая прилетела из Квинты. То, что надо)

Обратите внимание, что из нашей таблицы в QuintaDB первая запись не перенеслась в Adalo. Для нашего сценарий она не распознаётся вновь созданной (так как была уже создана ранее). Так что все старые записи надо или вручную перенести в Adalo (допустим через операцию импорт SVC), или заново импортировать в QuintaDB, прежде их экспортировав в Excel и удалив из БД.

Теперь проверим, что сценарий наш одинаково верно отрабатывает на клонированных и на импортированных записях.

часть b - отработка клонированных записей

Через функцию клонирования создал новую запись в Квиньте на основе нашей 1-ой записи
Через функцию клонирования создал новую запись в Квиньте на основе нашей 1-ой записи

Снова запускаю разово сценарий и вижу, что триггер сработал и запись прилетела. В Адало её увидел, но ...

... обратите внимание, что запись прилетела, но вот статус её остался прежним (изначальным)! - т.е. это полное состояние нашей 1-ой записи.
... обратите внимание, что запись прилетела, но вот статус её остался прежним (изначальным)! - т.е. это полное состояние нашей 1-ой записи.
В квиньте запись выглядит иначе
В квиньте запись выглядит иначе

В сервисе QuintaDB операция клонирования происходит в два шага:

1. Сначала создаётся новая запись - полная копия существующей.

2. А потом, если в ней что-то меняется, происходит операция обновления.

Так как наш сценарий отрабатывает лишь триггер создания новой записи, то на шаге создания он сработал и передал в Адало новую запись, а вот для триггера обновления наш сценарий не настроен. Так что у нас в QuinteDB сейчас одно состояние записи, а на сервисе Adalo эта же запись, но в другом состоянии. Позже, когда мы сделаем сценарий и для обновления записей, подобных коллизий у нас уже не будет.

Ок. Проверим, как сработает сценарий при импортировании пула записей.

часть c - отработка импортированных записей

Я заранее подготовил Excel файл для импорта

Связываю базу данных и конструктор мобильных приложений через Integromat - часть I

Прежде, чем делать импорт, запущу сценарий в режим постоянной работы, что бы он всё время "слушал" Квинту.

Тумблер переключателя "Расписание" надо перевести в положение "on"
Тумблер переключателя "Расписание" надо перевести в положение "on"
Теперь сценарий находится в режиме постоянного "прослушивания" нашей Квинты на предмет новых записей, в соответствии со своим режимом.
Теперь сценарий находится в режиме постоянного "прослушивания" нашей Квинты на предмет новых записей, в соответствии со своим режимом.
А режим у нас по умолчание стоит "немедленно" - т.е. как только появляется новая запись, то сценарий сразу её передаст в Адало. Т.е. этот сценарий находится в режиме постоянного фонового  прослушивания сервиса Квинта 
А режим у нас по умолчание стоит "немедленно" - т.е. как только появляется новая запись, то сценарий сразу её передаст в Адало. Т.е. этот сценарий находится в режиме постоянного фонового  прослушивания сервиса Квинта 
Но возможны и иные режимы - через регулярные промежутки времени, раз в день и проч.
Но возможны и иные режимы - через регулярные промежутки времени, раз в день и проч.
Как мы видим, в списке сценариев наш сценарий активен и работает в режиме моментального срабатывания (на это указывает иконка "молния").
Как мы видим, в списке сценариев наш сценарий активен и работает в режиме моментального срабатывания (на это указывает иконка "молния").

Ок, импортирую данные из excel файла в нашу таблицу "Список"

Импортирую данные из excel файл в в нашу таблицу на Квиньте
Импортирую данные из excel файл в в нашу таблицу на Квиньте
Записи успешно импортировались в таблицу
Записи успешно импортировались в таблицу

Проверим, что произошло в Интегромате

Зайдя в сценарий, мы видим сообщение, что в очереди есть ещё две необработанные записи. Так и должно быть. Мы импортировали 7 новых записей - значит интегромат этим сценарием распознает 7 раз триггер "новая запись" и 7 раз запустит сценарий. Немного ждём.
Зайдя в сценарий, мы видим сообщение, что в очереди есть ещё две необработанные записи. Так и должно быть. Мы импортировали 7 новых записей - значит интегромат этим сценарием распознает 7 раз триггер "новая запись" и 7 раз запустит сценарий. Немного ждём.
Пока я писал предыдущий блок, интегромат обработал все 7 записей и, судя по всему, без ошибок.
Пока я писал предыдущий блок, интегромат обработал все 7 записей и, судя по всему, без ошибок.
Да, прошлый раз в таблице в Адало у нас оставалось 3 записи, теперь их 10 - т.е. наши новые 7 прилетели.
Да, прошлый раз в таблице в Адало у нас оставалось 3 записи, теперь их 10 - т.е. наши новые 7 прилетели.
Всё ок - записи прилетели со всеми своими данными. Отлично.
Всё ок - записи прилетели со всеми своими данными. Отлично.

Теперь, если мы оставим сценарий в активном режиме и далее, то он так и будет работать уже без нашего участия - в случае создания новых записей в БД на сервисе QuintaDB в таблице "Список" он будет моментально опознавать этот триггер (так как работает в фоновом режиме постоянно) и запускать сценарий передачи этих новых записей в таблицу "Список" нашего приложения на Adalo.

Итоги

В итоге, в этой части рассмотрели ситуации и нашли решения:

  1. Создали сценарий в интегромате, который передаёт новые записи созданные через форму создания новых записей со стороны QuintaDB на сторону Adalo. Ок - решили подзадачу 1 нашей задачи.
  2. Рассмотрели, как этот сценарий отрабатывает ситуацию, когда запись создаётся путём клонирования существующей записи. Поняли почему часть информации прилетела в Адало не корректно. Ок - решили (частично) подзадачу 2.
  3. Рассмотрели, как наш сценарий отрабатывает записи, созданные путём импортирования новых записей из excel файла в нашу таблицу на QuintaDB. Всё ок - решили подзадачу 3.
  4. Посмотрели, как сценарий запускать в ручном режиме, а как его переводить в активный режим - когда он всё время далее работает в фоновом режиме.

В продолжении этой заметки (части 2 и 3) я опишу:

  1. Как сделать сценарий (2) для синхронизации обновлённых записей со стороны QuintaDB на сторону Adalo - тем самым мы доработаем подзадачу 2 и решим задачу 4. Кроме очевидного (что "сам сценарий будет аналогичен первому, лишь блок триггера надо заменить с "созданные" на "обновлённые"), там будет расписан не очевидный нюанс по синхронизации записей по разным внутренним ID записей (record ID), различных на сервисах QuintaDB и Adalo.
  2. Как сделать сценарий (3) для обратной синхронизации обновлённых данных, уже со стороны Adalo в сторону QuintaDB. Здесь снова придётся решать задачу по стыковке разных ID record на сервисах Adalo и QuintaDB, но в другую сторону он уже решается иначе. Плюс рассмотрим решение, как избежать ошибочного цикла в нашем наборе сценариев, когда запись обновляется на стороне Adalo и прилетает на Квинту (сценарий 3), но тогда срабатывает триггер сценария 2 - обновления записи в обратную сторону и запускается ошибочный цикл.
  3. Рассмотрим, как правильно отрабатывать ошибки, чтобы сценарий не прекращал работы аварийно.

Если это продолжение вам нужно или просто интересно, то напишите об этом в комментариях или поставьте плюсик этой заметке - и тогда я буду знать наверняка, что подобный узкоспециализированный материал кому-то нужен, кроме меня самого) Ну, и вообще будет приятно и мотивационно)

Поддержка от опытных пользователей и больше информации про но-кодинговые решения (зерокод) в сообществе Зерокодеров.

77
1 комментарий