Привет! Меня зовут Карина Суворова, в «Северстали» я занимаюсь автоматизацией пользовательских процессов. Как часто вам приходят письма и встречи с задачами, которые надо выполнить в определённые сроки? Мне много. А моим коллегам, особенно тем, чей рабочий день состоит из таких «почтовых задач», ещё больше.
Чтобы ничего не забыть, нужен удобный инструмент управления, с категоризацией и возможностью анализа загрузки, повторяемости и фактически затраченного времени. И он есть — Jira.
Но процесс регистрации в Jira тоже отнимает время — скопировать тему и имя заказчика, отметить затрачиваемое на задачу время и выполнить ещё кучу скучных действий. Из-за такой рутины многие управления продолжают вести списки задач в блокнотах и экселе.
Чтобы избавиться от этого разрыва, мы разработали прекрасное решение, которое доступно всем и не требует подготовки для поддержки. Работает оно с Outlook. Нужны только Jira для размещения и структурированного хранения задач и Visual Basic for Applications (VBA) для их создания.
![](https://habrastorage.org/getpro/habr/upload_files/21a/9d7/426/21a9d7426d57744436f13c3476153cf3.jpg)
Для кого и как работает посредник, который переносит данные из почты в Jira
Наше решение будет полезно тем, кто уже работает с Jira и хочет упростить процесс создания задач (или вообще его обойти). И тем, кто активно ведёт таймшиты в старых добрых Excel, а потом мучается с общим доступом, подвисанием, обновлением, объединением… ну вы сами всё знаете. Посмотрим, как выглядит эта штука со стороны пользователя и со стороны разработки.
Работа со стороны пользователя
Опишу пошаговые действия пользователя.
Шаг 1. Выбрать письмо или назначенное собрание, по которому необходимо создать задачу в Jira. Это может быть открытое окно письма (встречи):
![](https://habrastorage.org/getpro/habr/upload_files/4cf/956/7bb/4cf9567bbd111844533861aa5dfdd3cd.png)
Или просто выделенный элемент Outlook:
![](https://habrastorage.org/getpro/habr/upload_files/14c/543/869/14c543869ca3bbfeed9afe67d4b912ac.png)
Шаг 2. Запустить макрос. Кнопка запуска может располагаться как в основном окне Outlook, так и в самом письме (встрече):
![](https://habrastorage.org/getpro/habr/upload_files/24d/976/eeb/24d976eeb9bf27040c018a4dffb64d92.png)
![](https://habrastorage.org/getpro/habr/upload_files/5d7/9ec/5dc/5d79ec5dcebb927b392924a438a86ea5.png)
Вид и название кнопки можно менять.
Шаг 3. Откроется окно с формой, в которую затягиваются элементы из письма (встречи). Это гибкая форма — там можно настраивать любые выпадающие списки и окна, полезные для создания задачи. В примере ниже заполняются данные из текста, отправитель, дата, время встречи. Длительность встречи автоматом подтягивается в поле для журнала работ.
![](https://habrastorage.org/getpro/habr/upload_files/a7e/a29/22f/a7ea2922f7f510fd0dd3a375dd121fc9.png)
Шаг 4. Можно отредактировать какие-то поля формы. Например, выбрать нужный тип задачи и исполнителя из выпадающего списка. Сохранить.
Шаг 5. После того как вы нажали «Сохранить», происходит проверка полей на корректность ввода (например, даты и времени). Если есть ошибки, макрос об этом сообщит и предложит изменить. После успешной проверки создаётся задача.
В текущем примере выполняется ряд изменений: назначается исполнитель, ведётся журнал работ (если он был проставлен), меняется статус задачи, прикрепляется исходное письмо (встреча) как вложение, задача открывается у пользователя в браузере.
![](https://habrastorage.org/getpro/habr/upload_files/7cf/2f0/068/7cf2f00683ce5e9337e747e3417dd19b.png)
Шаг 6. На этом этапе вы должны начать испытывать удовольствие.
Работа со стороны разработки
Инструменты для реализации:
Проект в Jira, в котором будут вестись задачи.
Outlook, если необходимо переносить письма и встречи в Jira. Если задачи не привязаны к элементам Outlook, можно использовать любой другой продукт Microsoft, в котором поддерживается VBA. Но наша история про дружбу с Outlook.
Созданный технический пользователь 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.
![](https://habrastorage.org/getpro/habr/upload_files/549/6e5/07a/5496e507a5bc256d6e62c998ceb9c42b.png)
Шаг 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 из календаря собраний?