Привет! Меня зовут Карина Суворова, в «Северстали» я занимаюсь автоматизацией пользовательских процессов. Как часто вам приходят письма и встречи с задачами, которые надо выполнить в определённые сроки? Мне много. А моим коллегам, особенно тем, чей рабочий день состоит из таких «почтовых задач», ещё больше.

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

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

Чтобы избавиться от этого разрыва, мы разработали прекрасное решение, которое доступно всем и не требует подготовки для поддержки. Работает оно с Outlook. Нужны только Jira для размещения и структурированного хранения задач и Visual Basic for Applications (VBA) для их создания.  

Для кого и как работает посредник, который переносит данные из почты в Jira

Наше решение будет полезно тем, кто уже работает с Jira и хочет упростить процесс создания задач (или вообще его обойти). И тем, кто активно ведёт таймшиты в старых добрых Excel, а потом мучается с общим доступом, подвисанием, обновлением, объединением… ну вы сами всё знаете. Посмотрим, как выглядит эта штука со стороны пользователя и со стороны разработки. 

Работа со стороны пользователя

Опишу пошаговые действия пользователя. 

Шаг 1. Выбрать письмо или назначенное собрание, по которому необходимо создать задачу в Jira. Это может быть открытое окно письма (встречи):

Или просто выделенный элемент Outlook: 

Шаг 2. Запустить макрос. Кнопка запуска может располагаться как в основном окне Outlook, так и в самом письме (встрече):

Вид и название кнопки можно менять. 

Шаг 3. Откроется окно с формой, в которую затягиваются элементы из письма (встречи). Это гибкая форма — там можно настраивать любые выпадающие списки и окна, полезные для создания задачи. В примере ниже заполняются данные из текста, отправитель, дата, время встречи. Длительность встречи автоматом подтягивается в поле для журнала работ.

Шаг 4. Можно отредактировать какие-то поля формы. Например, выбрать нужный тип задачи и исполнителя из выпадающего списка. Сохранить.

Шаг 5. После того как вы нажали «Сохранить», происходит проверка полей на корректность ввода (например, даты и времени). Если есть ошибки, макрос об этом сообщит и предложит изменить. После успешной проверки создаётся задача. 

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

Шаг 6. На этом этапе вы должны начать испытывать удовольствие. 

Работа со стороны разработки

Инструменты для реализации:

  1. Проект в Jira, в котором будут вестись задачи.

  2. Outlook, если необходимо переносить письма и встречи в Jira. Если задачи не привязаны к элементам Outlook, можно использовать любой другой продукт Microsoft, в котором поддерживается VBA. Но наша история про дружбу с Outlook. 

  3. Созданный технический пользователь Jira, от имени которого будут регистрироваться задачи. Можно сохранять задачи и от самих сотрудников.

Роли, права, доступы

Для всех сотрудников, которые будут участвовать в проекте, надо настроить определённые роли на создание и изменение элементов в Jira. Роли можно раздавать автоматически через группу Active Directory (AD) — очень удобная вещь!

Если задачи будут создаваться от имени технического пользователя, то надо выдать ему соответствующие права на проект. Нюанс: если необходимо, чтобы также фиксировалось время, затраченное на задачу в tempo, нужно создать команду в Jira-tempo, назначать руководителя и участников, а нашему техническому пользователю дать роль на управление планами команды. Так он сможет вести время за каждого сотрудника! Если же плагин tempo отсутствует, можно воспользоваться стандартным вариантом через worklog.

Дальше будет немного кода. 

Шаг 1. Авторизация пользователя. На этом этапе можно заложить различные процедуры первичной подготовки проекта к работе. Например, проверку обновлений по проекту и подключение к сетевым папкам, на которых находятся данные для выпадающих списков форм.

Шаг 2.  Так как у нас пример на базе Outlook с частичным заполнением данных из письма (встречи), то первый шаг — подключение к объекту Outlook: 

    Dim oInspector As Inspector

    Set oInspector = Application.ActiveInspector

    If oInspector Is Nothing Then

        '1 вариант если нет открытых активных писем, то макрос берёт выделенное в списке писем в работу

        Set MailItem = Application.ActiveExplorer.Selection.Item(1)

  Else

        '2 вариант если есть открытые письма, то берёт активное или последнее, с которым работал пользователь,

        'если код запущен из письма — берёт текущее открытое

        Set MailItem = oInspector.CurrentItem

  End If

Шаг 3. После того как объект Outlook выбран, пользователь получает форму для заполнения, в которую уже частично вошли данные из письма (встречи). При этом для считывания некоторых полей объекта Outlook необходимо сначала проверять, чем он является — письмом или встречей:

    If MailItem1.Class = olAppointment Then

        'если это встреча

        TextBox6 = MailItem.Organizer 'автор встречи автор

        TextBox7 = Format(MailItem.Start, "dd")

        

        TextBox12 = DateDiff("n", CDate(MailItem1.Start), CDate(MailItem.End))

   Else

        'если это письмо

        TextBox6 = MailItem.SenderName 'автор письма для заполнения поля автор

        TextBox7 = Format(Date, "dd")

        

        TextBox12 = 0

  End If

Шаг 4. Поля формы при нажатии «Сохранить» должны пройти логическую проверку. Допустим, проверку на правильный цифровой ввод, например, чтобы месяц был не более 12. Полученные данные передаются в словарь, объявленный ранее как public и получивший на входе нужные элементы:

  Public myDict As New Dictionary

'создание при старте элементов и заполнение нулевыми значениями

    myDict.Add "tema", vbNullString

    myDict.Add "body", vbNullString

    myDict.Add "aftor", vbNullString

    myDict.Add "ispolnitel", vbNullString

'передача данных , которые были выбраны/записаны в форму, в словарь при сохранении

    myDict.Item("tema") = TextBox2

    myDict.Item("body") = TextBox5

    myDict.Item("aftor") = TextBox6

    myDict.Item("ispolnitel") = ComboBox2.Value

'чистка при завершении

   myDict.RemoveAll

Шаг 5. Форма заполнена и прошла проверку. Создаём на основе полученных данных элемент Jira. Предварительно нужно собрать технические параметры проекта или задачи для постинга через просмотр кода веб-страницы: нужен ID проекта, ID типов задач. Вообще, нужен список всех параметров, которые мы передадим через post-запрос. Также параметры полей можно найти на официальном сайте api Jira, api tempo.

Шаг 6. Собрав ID полей, создаём формат JSON в VBA:

issue = "{ ""fields"": { ""assignee"":{""name"": """ & j_assignee & """}, ""summary"": """ & themeBIC & """, ""description"": """ & descriptionBIC & """, ""customfield_10808"": """ & j_reporter & """,""project"": { ""id"": """ & pid & """, ""name"": """ & ProgName & """ }, ""issuetype"": { ""id"": """ & issuetype & """ } } } }"

!Важное замечание. Постинг самой задачи правильно выполнять через MSXML2.xmlhttp, а вот внесение изменений в задачу через WinHttp.WinHttpRequest.5.1.

With xmlhttp

        .Open "post", "https://Jira.ваш домен.com/rest/api/2/issue", False

        .setRequestHeader "Authorization", "Basic " & EncodeBase64

        .setRequestHeader "Content-type", "application/json"

        .setRequestHeader "X-Atlassian-token", "no-check"

        .Send issue

        result = .responseText

        statusHml = .Status

End With

EncodeBase64 — функция, в которой мы передаём логин и пароль от пользователя Jira. Чтобы не хранить конфиденциальные данные в самом коде VBA, можно воспользоваться переменной среды окружения у пользователей этой разработки и посадить пароль туда. Это максимально безопасный вариант хранения пароля для VBA-проекта.

Private Function EncodeBase64() As String

     Text = "имя пользователя:" & Environ("имя переменной окружения, которую вы создали")

    With CreateObject("ADODB.Stream")

        .Open: .Type = 2: .Charset = "utf-8"

        .writetext Text: .Position = 0: .Type = 1: b = .Read

        With CreateObject("Microsoft.XMLDOM").createElement("b64")

            .DataType = "bin.base64": .nodeTypedValue = b

            EncodeBase64 = Replace(Mid(.Text, 5), vbLf, "")

        End With

        .Close

    End With

End Function

А вот пример того, как после создания задачи заносить время в журнал работ и комментарий по работам (который равен теме задачи). Обращаю внимание: для поиска параметров идём к api tempo*:

    Split_result = Split(result, """") 'разделяем результат работы от постинга задачи, в дальнейшем используем для получения ID созданной задачи 

    If masTik.Item("time") > vbNullString Then ' проверка, что пользователь занёс время работы в форму

        '!необходимо учитывать, что имя, которое мы использовали при создании задачи как assignee (исполнитель), может отличаться от worker — кому ведём журнал работ.

 issue = "{""started"": """ & myDict.Item("day") & """, ""timeSpentSeconds"": """ & myDict.Item("time") * 60 & """, ""worker"" :  """ & j_assignee & """,  ""comment"" :   """ & themeBIC & """  , originTaskId"": """ & Split_result(7) & """}"

        With xmlhttp

            .Open "post", " https://Jira.ваш домен.com /rest/tempo-timesheets/4/worklogs/", False 'обратить внимание, что здесь уже используется api tempo

            .setRequestHeader "Authorization", "Basic " & EncodeBase64

            .setRequestHeader "Content-type", "application/json"

            .setRequestHeader "X-Atlassian-token", "no-check"

            .Send issue

            result = .responseText

            statusHml = .Status

        End With

End if

*Вариант кода без tempo: 

Работы заносятся на того, кто создаёт задачу. В этом случае запуск будет от сотрудника с запросом пароля перед началом работы.

    issue = "{""started"": """ & DataJira & """, ""timeSpentSeconds"": """ & timeSpentSeconds & """}}"

        With xmlhttp1

        .Open "post", " https://Jira.ваш домен.com /rest/api/2/issue/" & Split_result(7) & "/worklog", False

            .setRequestHeader "Authorization", "Basic " & EncodeBase64

            .setRequestHeader "Content-type", "application/json"

            .setRequestHeader "X-Atlassian-token", "no-check"

            .Send issue

            result = .responseText

            statusHml = .Status

        End With

    End If

В этом проекте также используется изменение статуса задачи и прикрепление исходного письма (встречи) во вложение созданной задачи.

Эффекты от внедрения макроса 

В итоге у нас есть проект Jira, в котором удобно смотреть:

  • загруженность сотрудников; 

  • перекос по распределению задач; 

  • анализ избыточности запросов от клиентов; 

  • трудозатраты в разрезе исполнителей, задач или клиентов. 

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

Спасибо, что прочитали! В продолжение этой статьи у меня есть ещё две темы. Я пока не выбрала, о чём рассказывать в следующий раз. Что вам больше интересно: как Jira помогает в отслеживании поломок автоматизированных процессов на серверах или как автоматически (без сотрудников) собирать задачи в Jira из календаря собраний? 

Комментарии (10)


  1. GbrtR
    19.01.2023 17:24

    Посмотрите на уже существующие плагины интеграции outlook с jira, возьмёте оттуда хорошие идеи.

    Например, добавить возможность автоматического обновления тикета если новые письма в ветке появились. В комменты добавлять и.т.п.

    Код в статье ещё было бы неплохо оформить как вставки кода, а не просто текстом. Лучше бы выглядело.


    1. Skari76
      20.01.2023 14:38
      +1

      Добрый день! Да существующие плагины отличное прекрасное решение (активно используются в нашей компании), но к сожалению для этого проекта не подошли. В стандартных решениях необходимо чтобы письма шли в определенный почтовый ящик, задачи создаются по всем письмам в определенный проект с определенным типом. Наше же решение более гибкое, выбираются письма/встречи из любого, например личного почтового ящика, и только те которые нужны– по необходимости можно добавить выбор проекта, выбор типов задач и исполнителя – как в примере. Плюс в решениях стандартных нет возможности вести учет времени, тем более авто заполнение из встреч. Спасибо!


  1. pqbd
    19.01.2023 17:45
    +1

    aftor и т.п. слегка напрягает


    1. anador
      19.01.2023 21:08

      вернули 2007


  1. rybingleb
    19.01.2023 17:56

    Не боитесь, что завтра, или через месяц вам Джиру или Outlook отключат? Почему не переходите на что-то другое?


    1. severstal Автор
      19.01.2023 17:56
      +2

      Пока выбираем инструменты, позже поделимся опытом.


    1. AstorS1
      19.01.2023 21:20
      +1

      Практически уверен, что они развёрнуты on-premise и отключение будет управляемым, а не внезапным по инициативе третьих лиц.


    1. tmplts
      19.01.2023 22:37

      Удивительно, но в том же Б24 создание таск из писем реализовано из коробки/облака. Очень удобно.


  1. BlackValaR
    20.01.2023 09:15

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


    1. Skari76
      20.01.2023 14:57
      +1

      Добрый день!  Да, отличное замечание - существующие плагины не подошли, более подробно ответила в комментарии выше)