元問い合わせメールに返信したときの統合処理

元問い合わせメールに返信したときの統合処理

ワークフロー作成したので備忘録です。

Zoho Desk で作成したメールアドレス宛てに既存のメールアドレスにきた問合せ先メールを転送してチケット作成を行っています。
元の問い合わせメールに返信、転送した際にRe,RE,re,Fw,FW,fwが件名の頭に付くため、その度に新規起票が乱立します。

メールの頭にRe,RE,re,Fw,FW,fwがある時それを除いた件名と同じ件名が既にチケット作成されていれば統合するワークフローを作成しました。
条件が緩いので既存チケットの検索で完了済みや5日以上前に作成したものは除いてもいいとは思います。

【ワークフロー作成】

実行タイミング:作成する

条件: (1かつ(((2または3)または4)または5))

1、経路、が次の値と等しい、Email かつ
2、件名、が次の値で始まる、Re: または
3、件名、が次の値で始まる、RE: または
4、件名、が次の値で始まる、FW: または
5、件名、が次の値で始まる、Fw: 

処理
メソッド名:Tickets
1、ticketId、問い合わせ ID
2、subject、件名

  1. orgId = ;YourAPI
  2. // 組織ID

  3. // ====== Workflow Arguments ======
  4. // ticketId -> Ticket Id
  5. // subject  -> Subject
  6. newTicketIdText = ticketId.toString();
  7. newTicketId = ticketId.toLong();
  8. subjectText = ifnull(subject,"");
  9. originalSubject = subjectText.trim();
  10. info "New Ticket ID: " + newTicketIdText;
  11. info "Original Subject: " + originalSubject;
  12. if(originalSubject != "")
  13. {
  14. lowerOriginalSubject = originalSubject.toLowerCase();
  15. isReplyOrForward = false;
  16. if(lowerOriginalSubject.startsWith("re:") || lowerOriginalSubject.startsWith("fw:"))
  17. {
  18. isReplyOrForward = true;
  19. }
  20. if(isReplyOrForward == true)
  21. {
  22. // ====== prefix 除去処理 ======
  23. // RE: / FW: が複数重なっている場合も除去する
  24. // 例: "Re: FW: 問い合わせ" -> "問い合わせ"
  25. baseSubject = originalSubject;
  26. dummyList = "".leftpad(10).toList("");
  27. for each  dummy in dummyList
  28. {
  29. tempLower = baseSubject.toLowerCase().trim();
  30. if(tempLower.startsWith("re:"))
  31. {
  32. baseSubject = baseSubject.trim().subString(3).trim();
  33. }
  34. else if(tempLower.startsWith("fw:"))
  35. {
  36. baseSubject = baseSubject.trim().subString(3).trim();
  37. }
  38. }
  39. info "Base Subject: " + baseSubject;
  40. if(baseSubject != "")
  41. {
  42. // ====== 既存チケット検索 ======
  43. searchValue = Map();
  44. searchValue.put("subject",baseSubject);
  45. searchResponse = zoho.desk.searchRecords(orgId,"tickets",searchValue,0,100);
  46. info "Search Response:";
  47. info searchResponse;
  48. targetTicketId = null;
  49. targetTicketSubject = "";
  50. if(searchResponse != null && searchResponse.get("data") != null)
  51. {
  52. ticketList = searchResponse.get("data");
  53. for each  existingTicket in ticketList
  54. {
  55. existingTicketIdText = existingTicket.get("id").toString();
  56. // 自分自身は除外
  57. if(existingTicketIdText != newTicketIdText)
  58. {
  59. existingSubjectText = ifnull(existingTicket.get("subject"),"");
  60. existingSubject = existingSubjectText.trim();
  61. // 既存チケット側の件名にも RE:/FW: が付いていた場合は除去して比較
  62. normalizedExistingSubject = existingSubject;
  63. existingDummyList = "".leftpad(10).toList("");
  64. for each  existingDummy in existingDummyList
  65. {
  66. existingLower = normalizedExistingSubject.toLowerCase().trim();
  67. if(existingLower.startsWith("re:"))
  68. {
  69. normalizedExistingSubject = normalizedExistingSubject.trim().subString(3).trim();
  70. }
  71. else if(existingLower.startsWith("fw:"))
  72. {
  73. normalizedExistingSubject = normalizedExistingSubject.trim().subString(3).trim();
  74. }
  75. }
  76. info "Compare Existing Ticket: " + existingTicketIdText + " / " + normalizedExistingSubject;
  77. // prefix 除去後の件名が完全一致したら統合先にする
  78. if(normalizedExistingSubject == baseSubject)
  79. {
  80. targetTicketId = existingTicket.get("id").toLong();
  81. targetTicketSubject = existingSubject;
  82. break;
  83. }
  84. }
  85. }
  86. }
  87. if(targetTicketId != null)
  88. {
  89. // ====== チケット統合 ======
  90. // targetTicketId が親チケット
  91. // newTicketId が統合される新規チケット
  92. paramValue = {"ids":{newTicketId}};
  93. info "Merge new ticket " + newTicketIdText + " into existing ticket " + targetTicketId.toString();
  94. response = zoho.desk.ticket.merge(orgId,targetTicketId,paramValue);
  95. info "Merge Response:";
  96. info response;
  97. }
  98. else
  99. {
  100. info "No matching existing ticket found. Stop.";
  101. }
  102. }
  103. else
  104. {
  105. info "Base subject is empty after removing prefix. Stop.";
  106. }
  107. }
  108. else
  109. {
  110. info "Subject does not start with RE: or FW:. Stop.";
  111. }
  112. }
  113. else
  114. {
  115. info "Subject is empty. Stop.";
  116. }