如何透過 Email 建立 Issue


議題追蹤 (Issue) 最重要的就是資料來源的管理,讓需要被關注的事情都放到同一個籃子 (Pool),然後才得以檢傷、分類、處理。而 SaaS 年代,如何讓使用者的聲音,快速的被蒐集與處理,則是非常重要的。

本文整理如何設定讓 Email 訊息,自動導入 Redmine,變成可以追蹤管理的設定方式。


準備

  • 客服信箱:準備一個信箱,通常是 客服專用的,例如 support@abc.com
    • 範例使用 IMAP 協議,所以這個信箱必須是 使用者帳戶,而不是 群組帳戶
    • 使用 GMail 做範例,設定 IMAP 請參閱 GMail IMAP 設定
    • 建立兩個 LABEL:ACCEPTEDREJECTED
  • 客服專案:在 Redmine 建立一個專案,用來專門收集回饋
    • 這個專案的成員必須加入 Anonymous users
    • 指定適當的 Tracker 作為 Tracker Type,本文以 Support 為例

設定

以下說明的前提與環境:

  • Run as redmine user
  • cd [REDMINE_HOME]
    • Redmine Log 位置:[REDMINE_HOME]/log/production.log
  • 都事先準備好這些參數:
    1
    2
    3
    4
    RAKEFILE="[REDMINE_HOME]/Rakefile"
    IMAP_HOST="imap.gmail.com"
    USERNAME="<EMAIL>"
    PASSWORD="<PASSWORD>"

一、確認可以收信

送一封測試信 (標題: test 1),到客服信箱 (support@abc.com),到 GMail 確認已經收到。然後使用 redmine 身份,執行以下:

1
2
3
4
5
6
7
rake -f ${RAKEFILE} redmine:email:receive_imap \
RAILS_ENV=production \
host=${IMAP_HOST} port=993 ssl=true \
username=${USERNAME} \
password=${PASSWORD} \
folder=Inbox \
--trace

順利的話,檢查 [REDMINE_HOME]/log/production.log 會看到以下訊息:

[REDMINE_HOME]/log/production.log
1
2
3
4
Creating scope :system. Overwriting existing method Enumeration.system.
Creating scope :sorted. Overwriting existing method Group.sorted.
Creating scope :sorted. Overwriting existing method User.sorted.
MailHandler: ignoring email from unknown user [xxxx@gmail.com]

Standard Out 訊息:

1
2
3
4
** Invoke redmine:email:receive_imap (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute redmine:email:receive_imap

而那封送到客服信箱的信,會被標示成以閱讀。

二、設定 ACCEPTED 和 REJECTED

新增執行後的 LABEL 設定,再送一封信 subject: test 2,確認收到後,執行以下:

1
2
3
4
5
6
7
8
9
rake -f ${RAKEFILE} redmine:email:receive_imap \
RAILS_ENV=production \
host=${IMAP_HOST} port=993 ssl=true \
username=${USERNAME} \
password=${PASSWORD} \
folder=Inbox \
move_on_success=ACCEPTED \
move_on_failure=REJECTED \
--trace

處理後,原始信件要搬移的位置,在 GMail 裡面就是 LABEL 名稱。

  • move_on_success: 如果處理成功,把信件搬移到位置
  • move_on_failure: 如果處理失敗,把信件搬移到位置

一開始設定時,要先到 GMail 建立這兩個 LABEL,比較方便除錯

檢查 log,發現一樣的訊息,如下,

[REDMINE_HOME]/log/production.log
1
2
3
4
Creating scope :system. Overwriting existing method Enumeration.system.
Creating scope :sorted. Overwriting existing method Group.sorted.
Creating scope :sorted. Overwriting existing method User.sorted.
MailHandler: ignoring email from unknown user [xxxx@gmail.com]

到客服信箱檢查,訊息 test 2 已經被搬到 REJECTED LABEL 了。

如果沒有預先建立指定的 LABLE (REJECTED or ACCEPTED),那麼會出現 exception,如下:

1
2
3
4
5
6
7
** Invoke redmine:email:receive_imap (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute redmine:email:receive_imap
rake aborted!
Net::IMAP::NoResponseError: No folder REJECTED (Failure)
... 略 ...

三、Receive Message from Anonymous User

接受 匿名的使用者 (anonymous) 的訊息,送一封信 subject: test 3 給客服信箱,確認收到後,回到 terminal,增加參數 unknown_user=accept,如下:

1
2
3
4
5
6
7
8
9
10
rake -f ${RAKEFILE} redmine:email:receive_imap \
RAILS_ENV=production \
host=${IMAP_HOST} port=993 ssl=true \
username=${USERNAME} \
password=${PASSWORD} \
folder=Inbox \
unknown_user=accept \
move_on_success=ACCEPTED \
move_on_failure=REJECTED \
--trace

檢查 log 會出現以下訊息:

[REDMINE_HOME]/log/production.log
1
MailHandler: missing information from Anonymous: Unable to determine target project

無法確認要送到哪一個 Project,表示 Redmine 已經接受這個訊息了。到客服信箱檢查,test 3 還是被搬到 REJECTED LABLE 了。

Receive Message and Create a New User

unknown_user 另外選項則是 create,也就是可以直接幫來信者建立 redmine 帳號。

實際執行後的 Log 訊息如下,同時使用者會收到一封系統使用者註冊通知信。

[REDMINE_HOME]/log/production.log
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Creating scope :system. Overwriting existing method Enumeration.system.
Creating scope :sorted. Overwriting existing method Group.sorted.
Creating scope :sorted. Overwriting existing method User.sorted.

MailHandler: [xxxxxxx@gmail.com] account created
[ActiveJob] [ActionMailer::DeliveryJob] [f07ab5c8-2eff-4839-8960-8e995547c766] Performing ActionMailer::DeliveryJob (Job ID: f07ab5c8-2eff-4839-8960-8e995547c766) from Inline(mailers) with arguments: "Mailer", "account_information", "deliver_now", #<GlobalID:0x0000000008613228 @uri=#<URI::GID gid://redmine-app/User/7>>, "Aj2WLfHG56"
[ActiveJob] [ActionMailer::DeliveryJob] [f07ab5c8-2eff-4839-8960-8e995547c766] Rendering mailer/account_information.text.erb within layouts/mailer
[ActiveJob] [ActionMailer::DeliveryJob] [f07ab5c8-2eff-4839-8960-8e995547c766] Rendered mailer/account_information.text.erb within layouts/mailer (1.6ms)
[ActiveJob] [ActionMailer::DeliveryJob] [f07ab5c8-2eff-4839-8960-8e995547c766] Rendering mailer/account_information.html.erb within layouts/mailer
[ActiveJob] [ActionMailer::DeliveryJob] [f07ab5c8-2eff-4839-8960-8e995547c766] Rendered mailer/account_information.html.erb within layouts/mailer (0.6ms)
[ActiveJob] [ActionMailer::DeliveryJob] [f07ab5c8-2eff-4839-8960-8e995547c766] Performed ActionMailer::DeliveryJob (Job ID: f07ab5c8-2eff-4839-8960-8e995547c766) from Inline(mailers) in 386.49ms
[ActiveJob] Enqueued ActionMailer::DeliveryJob (Job ID: f07ab5c8-2eff-4839-8960-8e995547c766) to Inline(mailers) with arguments: "Mailer", "account_information", "deliver_now", #<GlobalID:0x0000000008a2c828 @uri=#<URI::GID gid://redmine-app/User/7>>, "Aj2WLfHG56"

MailHandler: missing information from xxxx@gmail -: Unable to determine target project

最後還是因為沒有指定 project 所以沒有建立 issue 成功。實務上是否要這樣用,要看專案的狀況與需求。

四、ACCEPT Message

延續步驟三,指定 project 與 tracker 就可以讓系統接受訊息了。完整的設定如下:

receiving-email.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash
RAKEFILE="[REDMINE_HOME]/Rakefile"
IMAP_HOST="imap.gmail.com"
USERNAME="<EMAIL>"
PASSWORD="<PASSWORD>"
LOGFILE="[REDMINE_HOME]/log/receiving-email_${DATETIME}.log"

## 執行從 IMAP 收 Email
## project 設定 anonymous user
rake -f ${RAKEFILE} redmine:email:receive_imap \
RAILS_ENV=production \
host=${IMAP_HOST} port=993 ssl=true \
username=${USERNAME} \
password=${PASSWORD} \
folder=Inbox \
project=customer-support \
tracker=support \
unknown_user=accept \
allow_override=project,tracker \
move_on_success=ACCEPTED \
move_on_failure=REJECTED \
--trace >>${LOGFILE} 2>&1

要注意的是 project, tracker 等是使用名稱,不是數字 id。

將前述寫成檔案,並透過 crontab 定期執行:

1
2
# 每五分鐘檢查一次
*/5 * * * * cd [REDMINE_HOME] && ./receiving-email.sh

設定過程如何 Debug

除錯流程如下:

  1. tail -f [REDMINE_HOME]/log/production.log,可以看到執行的狀況與錯誤訊息
  2. 確認收信的信箱已經建立 LABEL,一開始可以協助確認能否正確收信

一些錯誤訊息

Error01: Anonymous 無法建立 Issue, 確認 project 是否有把 Anonymous user 加入 members

MailHandler: unauthorized attempt from Anonymous

Error02: 無法確認 project 名稱,要使用 project-name,不是數字 id

MailHandler: missing information from Anonymous: Unable to determine target project

Info01: 正確建立 Issue 會出現以下訊息

MailHandler: issue #89 created by Anonymous


結論

這幾年客服的方式已經從傳統的 Email 漸漸地改成更立即的 ChatBot 的形式,但是本質上來說,不變的還是 Issue Tracking 的想法,也就是透過工作流程 (Workflow) 確認需求狀態是否被完成。


延伸閱讀

系列文章

參考資料


Comments