Платформы для роботизированной автоматизации имеют широкий спектр возможностей и позволяют использовать множество готовых действий без программирования. Однако, бизнес-пользователям часто не хватает тех активностей, которые предоставляют RPA-платформы. В таких случаях весь проект роботизации уходит к программистам, которые могут написать любую программу.  Но есть проблема – они плохо понимают настоящие бизнес процессы, а на то, чтобы в них разобраться, уходит время. В этом посте рассказываем, как программисты могут разработать свои активности для бизнес-пользователей, чтобы те продолжали роботизировать свои задачи без передачи всего проекта программистам. Статья написана при поддержке технического эксперта UiPath: Валентина Драздова. В последние несколько лет все больше компаний переходит от классической автоматизации к роботизации с использованием RPA-технологий. Современные RPA-платформы предоставляют большой набор готовых действий для создания роботов. Они дают возможность эмулировать действия пользователя путем взаимодействия с разными системами через графический интерфейс, программировать в этом случае не нужно. Однако, всех потребностей бизнеса этими действиями не покроешь, поэтому платформы дают  возможность пользователю написать часть кода самому непосредственно в схеме робота. Этого вполне достаточно для вызова других библиотек и программ, но такой подход неудобен, когда роботизацией хотят заниматься не только программисты, а люди из бизнеса — citizen developers).  В этой статье мы на примере UiPath расскажем, как программисты могут создавать свои активности для RPA-платформы UiPath так, чтобы с ними могли работать бизнес-пользователи при роботизации процессов, не привлекая профессиональных разработчиков. Мы решили рассмотреть создание пользовательских активностей в UiPath на примере с универсальной библиотекой регистрации посещений выставок или бизнес-центров. Она предоставляет функционал работы с реестром посещений, позволяет регистрировать приходящие лица (метод AddVisitor) и получать таблицу посетителей (метод GetVisitors).  Список посетителей формируется в экземпляре класса Registrator, он существует от момента создания экземпляра класса до завершения работы с ним.  Рассмотрим разработку активностей в Microsoft Visual Studio с использованием специального расширения «UiPath Activity Creator», которое можно бесплатно установить из Visual Studio Marketplace: После установки расширения вам необходимо закрыть студию и принять лицензионное соглашение.  После установки расширения вам станет доступен новый шаблон проекта – «UiPath Standard Activity Project» Создайте свой проект используя этот шаблон. Наш проект мы назвали «UiPath.Habr.Visitors». В результате было создано решение из пяти проектов: UiPath.Shared.Activities – проект с общим кодом от UiPath, предназначен для облегчения разработки активностей (не изменяйте код этого проекта). UiPath.Shared.Activities.Design – Проект с общим кодом от UiPath, предназначен для облегчения разработки визуальной части активностей, которая будет отображаться в UiPath Studio (не изменяйте код этого проекта) ИМЯ_ВАШЕГО_ПРОЕКТА – Базовый проект решения, предназначен для бизнес-логики ваших активностей. ИМЯ_ВАШЕГО_ПРОЕКТА.Activities – Проект, содержащий классы с активностями. Именно в этом проекте должно происходить получение аргументов, вызов бизнес-логики и возврат аргументов. ИМЯ_ВАШЕГО_ПРОЕКТА.Activities.Design – Проект, содержащий визуальные компоненты активностей (.XAML), которые будут отображаться в UiPath Studio.  Для того, чтобы создать свою активность – необходимо добавить класс активности в проект ИМЯ_ВАШЕГО_ПРОЕКТА.Activities и визуальный компонент активности в проект ИМЯ_ВАШЕГО_ПРОЕКТА.Activities.Design Самый простой способ сделать это – воспользоваться мастером по созданию активностей, который доступен в меню «Расширения -> UiPath -> Add Activities» После открытия мастер предложит создать активности вручную или импортировать их из JSON-файла. Мы используем первый вариант. В открывшемся окне вы можете создать разные активности при помощи кнопки «+». Каждая активность содержит следующие параметры: Name – имя активности (рекомендуем писать на английском), которое будет отображено в списке активностей.  Description – описание активности, которое будет появляться во всплывающем окне Type – тип активности:  Simple – обычная активность (одно действие). Scope – активность с контейнером для других активностей, которые могут использовать данные из скоуп-активности. Properties – набор аргументов активности (поговорим об этом ниже). Timeout – переключатель «имеется ли у действия время ожидания?». Если включить этот параметр – можно будет настраивать время, через которое активность будет останавливаться, даже если она еще не завершилась. Icon – иконка для вашей активности. У каждой активности могут быть свои аргументы со следующими свойствами: Category – Раздел в панели «Свойства», в котором будет размещаться данный аргумент Name – Имя аргумента Description – Описание аргумента, которое будет появляться во всплывающем окне Direction – Направление передачи : In – Входной аргумент (передача информации от робота в активность) Out – Выходной аргумент (или результат - передача информации от активности к роботу)  InOut – Входной-Выходной аргумент (передача информации от робота в активность и обратно) None – Не использовать динамические значения (передаваемые через переменные), настройка вручную в UiPath Studio, рекомендуется использовать для Boolean (будет отображен в виде чекбокса), Enum (будет отображен в виде фиксированного списка)  Type – Тип данных для этого аргумента (любой тип данных .NET, в том числе из подключенных библиотек)  Options Required – является ли аргумент обязательным при настройке робота в  UiPath Studio После того, как вы создали свои первые активности при помощи специального расширения, мы можем рассмотреть подробнее из чего они состоят.  Классы активностей располагаются в проекте ИМЯ_ВАШЕГО_ПРОЕКТА.Activities, в подпапке «Activities»: Классы обычных (Simple) и скоуп (Scope) активностей похожи, но немного отличаются, поэтому рассмотрим их по отдельности.  Класс состоит из трех регионов: Содержит определение входящих и исходящих аргументов активности. Обратите внимание, что у каждого параметра имеются параметры с локализацией: LocalizedCategory – имя строки в ресурсах проекта, в которой содержится название категории (группы), которая будет отображена в списке аргументов в окне «Параметры» LocalizedDisplayName – имя строки в ресурсах, в которой содержится название аргумента LocalizedDescription – имя строки в ресурсах, в которой содержится описание аргумента, которое будет появляться при наведении мышкой. Также вы можете заметить, что все входные параметры используют тип InArgument, а выходные – OutArgument. Когда используется данный тип – в UiPath Studio будет предложено ввести в качестве параметра переменную типа, обрамленного в угловые скобки < >. В случае, если вы хотите, чтобы пользователи вашей активности имели возможность делать выбор из списка готовых значений (без возможности использовать значения переменных), то вместо InArgument<bool> вам надо использовать просто тип данных bool . Если вы хотите предоставить пользователю список из ограниченного списка значений – воспользуйтесь перечислением enum. Регион содержит конструктор класса. Если вам необходимо выполнять какие-либо действия до непосредственного выполнения активности – вы можете сделать их здесь. Регион содержит методы, отвечающие за работу активности Метод CacheMetadata предоставляет возможность провести проверку корректности использованных параметров на этапе проектирования робота Метод ExecuteAsync содержит код, который выполняется непосредственно при выполнении активности роботом. Условно разбит на три части: Часть Object Container и Inputs –происходит загрузка контейнера объектов (что позволяет получить данные из других активностей, в частности из Scope), а также входных параметров. Все параметры, использующие тип данных InArgument можно получить с использованием функции Get, указав в качестве параметра переменную с контекстом (context), например: var plannedNumberOfVisitors = PlannedNumberOfVisitors.Get(context) В случае, если вы используете «обычные» типы данных – вы можете обращаться к параметрам напрямую. Часть Add execution logic HERE – предназначена для вашего кода, где вы будете писать свой бизнес-код (или вызывать другие библиотеки). Часть Outputs – предназначена для вывода результатов из активности, выполняется с использованием анонимной структуры, где указывается параметр типа OutArgument с вызовом функции Set, где первый параметр – контекст (context), второй – значение. Например: return (ctx) => { Table.Set(ctx, resultDataTable); }  Рассмотрим основные отличия данного типа класса Помимо входящих и исходящих аргументов содержит: Body — коллекция дочерних активностей, ParentContainerPropertyTag - тэг родительской активности, желательно назвать уникально по своему _objectContainer – контейнер объектов для дочерних активностей Метод ExecuteAsync в отличие от метода из класса типа Simple, возвращает не содержимое для исходящих аргументов, а запускает выполнение дочерних активностей Метод OnFaulted выполняется в случае, если одна из дочерних активностей вызвала ошибку. Метод OnCompleted выполняется в случае, если все дочерние активности завершились успешно Метод Cleanup предназначен для освобождения памяти и занятых ресурсов. Чтобы работать с данными, которые были  инициализированы в рамках Scope-активности, вам необходимо сначала передать эти данные в контейнер объектов в Scope-активности. Сделать это можно в методе ExecuteAsync перед запуском дочерних активностей. Для примера, если вы хотите передать всю Scope-активность, вам достаточно написать следующий код: _objectContainer.Add(this); Чтобы получить нужный объект в Simple-активности, вам необходимо получить объект из контейнера объектов в методе ExecuteAsync после его инициализации. Для примера получим родительскую Scope-активность: var parentRegistrator = objectContainer.Get<Registrator>(); Если вы знаете как пользоваться консольной утилитой nuget.exe, вы можете пропустить этот раздел и сформировать пакет самостоятельно для проекта «ИМЯ_ВАШЕГО_ПРОЕКТА.Activities.Design».  Если у вас нет больших компетенций в формировании Nuget-пакетов, то вы можете воспользоваться очень простым способом. Для этого нажмите правой кнопкой мыши по проекту «ИМЯ_ВАШЕГО_ПРОЕКТА.Activities.Design» в обозревателе проектов и выберите пункт «Опубликовать…» (Publish…) По умолчанию в созданном из шаблона проекте нет профилей публикации, поэтому Visual Studio предложит вам создать собственный. Выберите профиль «Папка» (Folder) и укажите директорию на вашем компьютере, где у вас располагается локальный источник пакетов (если его еще нет – мы создадим его в следующем разделе, пока просто создайте директорию). В рамках примера для данной статьи будет использована директория «C:\MyNuGet» После создания профиля вы сможете публиковать ваш NuGet-пакет, а также управлять настройками публикации: При выполнении публикации будет осуществлена сборка решения в соответствии с указанными параметрами, после чего собранные библиотеки будет запакованы в NuGet-пакет и сохранены по указанному адресу. Если вы все сделали правильно – в целевой директории появится пакет с версией 0.1.0: Если вы внесете изменения в свою активность и соберете ее снова, то можете обнаружить, что вы снова получите пакет с версией 0.1.0. Так как версия пакета не поменялась – вы не сможете обновить активность через менеджер пакетов UiPath. Чтобы изменить номер версии – вам необходимо открыть в текстовом редакторе файл проекта «ИМЯ_ВАШЕГО_ПРОЕКТА.Activities.Design» (его расширение – csproj) Вам необходимо найти тэги «PackageVersion» и изменить версию с 0.1.0 на следующую. В случае, если вы использовали сторонние библиотеки или подключили дополнительные проекты в ваше решение, то могли заметить, что их нет в NuGet-пакете. Если вам необходимо сделать так, чтобы эти библиотеки или проекты появились в NuGet-пакете, добавьте их так же в проект «ИМЯ_ВАШЕГО_ПРОЕКТА.Activities.Design», установите свойство «Копировать локально» в «Да» (Copy Local - Yes), после чего откройте его в текстовом редакторе, найдите строчку <_ReferenceCopyLocalPaths Include="@(ReferenceCopyLocalPaths-&gt;WithMetadataValue('ReferenceSourceTarget', 'ProjectReference')-&gt;WithMetadataValue('PrivateAssets', 'All'))" /> И оставьте только: <_ReferenceCopyLocalPaths Include="@(ReferenceCopyLocalPaths)" /> Чтобы использовать ваш NuGet-пакет в UiPath вам необходимо добавить его в источник пакетов. Когда вы будете распространять свои активности на всю компанию – рекомендуется добавить его в источник пакетов вашего оркестратора.  Если вы только разрабатываете и отлаживаете свои активности, то вам лучше воспользоваться локальным источником пакетов. Чтобы создать локальный источник пакетов вам необходимо в окне «Проект» нажать правой кнопкой мыши по разделу «Зависимости», выбрать пункт «Управление».  В открывшемся окне перейдите на закладку «Настройки», справа над нижним списком будет кнопка «+» (плюс), нажмите ее, после чего в поле «Название» введите название для вашего локального источника (придумайте свое), а в поле «Источник» введите адрес директории с вашими пакетами (можете воспользоваться кнопкой «…» для простого выбора папки) и нажмите кнопку «Добавить». Перейдите на вкладку своего источника, где вы сможете увидеть свой пакет. Выбрав пакет вы сможете увидеть все версии пакета, доступные в вашем источнике пакетов. Установите ваш пакет как любой другой пакет, доступный вам в UiPath: После установки пакета ваши активности будут доступны в общем списке активностей: Иногда вам может потребоваться отладка ваших активностей непосредственно во время работы робота. Для этого вам необходимо поставить точку останова на вашей активности в UiPath Studio, запустите робота и дождитесь его остановки перед выполнением активности: Перейдите в Visual Studio, откройте класс, соответствующий вашей активности, поставьте точки останова в том месте метода ExecuteAsync, где вам требуется начать отладку, далее откройте меню «Отладка – Присоединиться к процессу» (Debug – Attach to process…) В открывшемся окне найдите «UiPath.Executor» в списке процессов и нажмите кнопку «Attach» После того, как Visual Studio запустит режим отладки, вернитесь в UiPath Studio и продолжите выполнение робота. После этого Visual Studio выполнит остановку исполнения кода именно в том месте, где вы поставили точку останова и вы сможете выполнить отладку. Если в Visual Studio открыт код более новой версии, чем находится в установленном в UiPath пакете, подключение может не удастся, либо процесс отладки будет выглядеть некорректным.    Если у вас не работает отладка – попробуйте при сборке NuGet-пакета выбрать конфигурацию Debug. В этой статье мы рассказали, как можно быстро начать разрабатывать свои активности для UiPath, чтобы дать больше возможностей при роботизации вашим коллегам. Часть советов из этой статьи можно назвать «вредными», так как в некоторых моментах стоит внимательней подойти к настройке каких-то деталей. Вот несколько рекомендаций, которые помогут вам сделать ваши активности более качественными: Сделайте свои активности более привлекательными, в проекте «ИМЯ_ВАШЕГО_ПРОЕКТА.Activities.Design» можно найти XAML-файлы, изменяя которые можно сделать более удобный интерфейс взаимодействия с вашими активностями в UiPath Studio. Разберитесь с файлами ресурсов, обратите внимание, что по умолчанию все текстовые надписи сделаны на «нейтральном» языке. Приведите локализацию в порядок, как правило нейтральный язык должен содержать английский вариант, а русский вариант должен быть реализован с использованием локализованного файла ресурсов. Если вы не знаете как настраивать локализацию через файлы ресурсов — мы вам расскажем об этом в одной из следующих статей. Если вы сделали универсальную активность, которая будет полезна не только лично для вас или вашей компании, но и для мирового сообщества, то вы можете опубликовать ее в магазине UiPath (и даже заработать на этом денег). Подробнее про публикацию своих активностей в магазине UiPath мы расскажем в следующих статьях. Позаботьтесь о модульном тестировании ваших активностей, а также не забудьте опубликовать исходный код в репозитории вашей компании. RPA-cпециалист