LoginSignup
7
5

More than 5 years have passed since last update.

社内チャットの会話をWatsonで感情分析し、トラブルを未然に防ぐ。

Last updated at Posted at 2018-12-16

IBM Cloud Advent Calendar 2018 12月16日分です。

序文

Slackのようなツールを、社内のサーバールーム内のサーバーや、自社用にリソース専有させたクラウド環境等で使いたいというニーズは常にあります。気づけば10年以上グループウェアの世界に、提案側、開発側、導入側、ユーザー側として携わり、ヘルプデスク組織の運営などもやってきました。新卒一年目にPHPでWikiシステムを一から作っていたなぁ...とか思い出はあります。

社外からの問い合わせやSNSへの対応は今後のネタとして残しておくとして、社内での会話からトラブルにならないように、ネガティブコメントを注視しておく必要があります。特にお客様とのトラブルに発展しないようにフォローできる仕組みを、IBM Cloudで使用可能なWatsonを用いて構築してみましょう。

準備

下記のような環境を用意します。
image.png

社内チャットシステムとして、Mattermostサーバーを用意します。

構築自体は、公式のオンラインドキュメント通りに実施しています。DBのパスワード等は変えます。
使用したMattermostは、無料で使えるOpen Source Team Editionで、バージョン5.6です。

外向きのWebhookを設定します。

Mattermost内に投稿先としてチームを作成し、チーム作成後「統合機能」の画面から、「外向きのWebhook」の設定を行います。

サンプルとして、トリガーワードは#helpとしています。
image.png

Mattermostにおける「外向きのWebhook」については、以前書いた記事がありますので、興味がありましたらご確認ください。
参考資料:Mattermost向けチャットボットをNode-REDとWatson Assistantで実装

タスク管理システムとして、Jira Software環境を用意します。

下記の手順を用いて構築しました。もちろん、ここではIBM Cloud IaaS上に構築していますが、自社のプライベートクラウドや社内のサーバールームでも構いません。後述のNode-RED環境から接続できれば良いです。
構築手順:IBM Cloudを用いてJIRA Softwareで、日々のタスク管理をはじめる。

Jiraに登録するタスクは、「課題」と言います。Redmineではチケットと言いますし、CRMなどでは、ToDoと言います。言い方の違いで意味は同じです。

カスタムフィールド作成

Jiraには感情分析した値を格納する項目がないため、感情分析した結果として「怒り」「嫌悪」「恐れ」「楽しみ」の4つの感情スコアの値を格納する追加項目、カスタムフィールドを作成します。また作成したカスタムフィールドIDを確認しておきます。
後述のサンプルコードでは、次のように設定しています。

カスタムフィールド名 フィールドタイプ カスタムフィールドID Node-REDの「POST - Create Issue」の記述
怒り 数値フィールド 10206 "customfield_10206"
嫌悪 数値フィールド 10207 "customfield_10207"
恐れ 数値フィールド 10208 "customfield_10208"
楽しみ 数値フィールド 10209 "customfield_10209"

MattermostとJira Softwareのデータをつなぐために、Node-REDサーバーを用意します。

MattermostとJira Softwareの両方に接続できる環境に、Node-REDサーバーを構築します。MattermostとJira Softwaareの両方に接続できれば、パブリッククラウドやプライベートクラウド、社内のサーバールームでも構いません。Node-REDのインストールには、公式のオンラインドキュメントを使用しています。

Node-REDで実装

Node-REDに追加したノード

サーバーにNode-REDをインストールした後、標準では付属しないWatsonやJiraに接続するノードを追加します。
node-red-contrib-jira:https://flows.nodered.org/node/node-red-contrib-jira
node-red-node-watson:https://flows.nodered.org/node/node-red-node-watson

フロー図

Mattermostに投稿されたメッセージを感情分析しJiraに課題登録するフロー.PNG

処理の流れ

  1. Mattermostに投稿されたトリガーワード付きのメッセージをNode-REDで受信
  2. Node-REDで受信したメッセージを「Watson Language Translator」で日本語から英語に翻訳。翻訳する理由は、感情分析を行う「Watson Tone Analyzer」が2018年12月現在日本語未対応のため、英語に翻訳します。
  3. 「Watson Tone Analyzer」で感情分析します。
  4. 感情分析の結果、怒りのスコアが「0.05」以上の時に、タスク管理システムの「Jira」に課題として登録するためのJSON形式のデータを作成します。
  5. 作成したJSON形式のデータを「Jira」に渡し、要対応のネガティブコメントとして新規課題登録します。

サンプルコード

下記のサンプルコードをNode-REDで読み込み、「language translator」ノードや「tone analyzer」ノード、「jira-issue-create」ノードをそれぞれダブルクリックし設定します。

[{"id":"fa32047e.c96898","type":"tab","label":"感情分析によるタスク管理","disabled":false,"info":""},{"id":"d1690281.96fc","type":"http in","z":"fa32047e.c96898","name":"Mattermost POST","url":"/mmpost","method":"post","upload":false,"swaggerDoc":"","x":130,"y":40,"wires":[["272aba56.17d726"]]},{"id":"dcdc3ecc.d75f2","type":"debug","z":"fa32047e.c96898","name":"debug:Mattermost Imcoming Webhook","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":670,"y":40,"wires":[]},{"id":"272aba56.17d726","type":"function","z":"fa32047e.c96898","name":"Cut Trigger Word","func":"var message = msg.payload.text;\nvar cutmsg = message.slice(5);\nmsg.payload = cutmsg;\nreturn msg;","outputs":1,"noerr":0,"x":350,"y":40,"wires":[["dcdc3ecc.d75f2","2f8329a9.bc1e56","ebe4c8a3.3ca2d8"]]},{"id":"2f8329a9.bc1e56","type":"watson-translator","z":"fa32047e.c96898","name":"","action":"translate","basemodel":"en-tr","domain":"general","srclang":"ja","destlang":"en","password":"","apikey":"","custom":"","domainhidden":"general","srclanghidden":"ja","destlanghidden":"en","basemodelhidden":"","customhidden":"","filetype":"forcedglossary","trainid":"","lgparams2":true,"neural":false,"default-endpoint":true,"service-endpoint":"https://gateway.watsonplatform.net/language-translator/api","x":150,"y":160,"wires":[["7e04a1f.8bdb26"]]},{"id":"7e04a1f.8bdb26","type":"watson-tone-analyzer-v3","z":"fa32047e.c96898","name":"","tones":"emotion","sentences":"true","contentType":"false","tone-method":"generalTone","interface-version":"2016-05-19","inputlang":"en","default-endpoint":false,"service-endpoint":"https://gateway-tok.watsonplatform.net/tone-analyzer/api","x":380,"y":160,"wires":[["32339235.6f97ce","27c3ad11.5e6372"]]},{"id":"32339235.6f97ce","type":"debug","z":"fa32047e.c96898","name":"debug:感情分析","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":600,"y":160,"wires":[]},{"id":"9db37b51.23bfb8","type":"jira-issue-create","z":"fa32047e.c96898","name":"","server":"667cbe9c.e4b3e","x":600,"y":240,"wires":[["cc2c73ae.2807d"]]},{"id":"27c3ad11.5e6372","type":"switch","z":"fa32047e.c96898","name":"","property":"response.document_tone.tone_categories[0].tones[0].score","propertyType":"msg","rules":[{"t":"gte","v":"0.05","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":130,"y":247,"wires":[["f132ac7a.3a2d1"],[]]},{"id":"ebe4c8a3.3ca2d8","type":"function","z":"fa32047e.c96898","name":"variable:issue subject","func":"var message = msg.payload;\nvar msg = {\n    note: message\n    };\n    flow.set('desc',msg);\nreturn msg;","outputs":1,"noerr":0,"x":620,"y":100,"wires":[[]]},{"id":"f132ac7a.3a2d1","type":"function","z":"fa32047e.c96898","name":"POST - Create Issue","func":"var desc         = flow.get('desc');\nvar note         = desc.note;\nvar angerscore   = msg.response.document_tone.tone_categories[0].tones[0].score;\nvar disgustscore = msg.response.document_tone.tone_categories[0].tones[1].score;\nvar fearscore    = msg.response.document_tone.tone_categories[0].tones[2].score;\nvar joyscore     = msg.response.document_tone.tone_categories[0].tones[3].score;\nmsg.payload  = {\n        \"fields\": {\n            \"project\":{\"key\":\"EMOTION\"},\n            \"summary\":\"ネガティブコメントを確認\",\n            \"description\":note,\n            \"issuetype\":{\"id\": \"10002\"},\n            \"customfield_10206\":angerscore,\n            \"customfield_10207\":disgustscore,\n            \"customfield_10208\":fearscore,\n            \"customfield_10209\":joyscore\n        }\n    }\nreturn msg;","outputs":1,"noerr":0,"x":340,"y":240,"wires":[["9db37b51.23bfb8"]]},{"id":"cc2c73ae.2807d","type":"debug","z":"fa32047e.c96898","name":"debug:Jira Create Issue","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":630,"y":300,"wires":[]},{"id":"667cbe9c.e4b3e","type":"jira-server","z":"","url":"http://jira-dev.kolinzlabs.com:8080/jira/rest/api/latest/","name":"Jira Server"}]

language translatorノードの設定

IBM Cloudにアクセスし、Watson Language TranslatorのAPI鍵とエンドポイントURLを確認し設定します。
image.png

tone analyzerノードの設定

IBM Cloudにアクセスし、Watson Tone AnalyzerのAPI鍵とエンドポイントURLを確認し設定します。
image.png

jira-issue-createノードの設定

「jira-issue-create」ノードの編集画面で、Jira Softwaare用APIへの接続設定を行います。のドキュメントに無いため接続設定におけるURLは、お使いのJira Software環境におけるJira REST APIのURLになります。

https://your-jira-url/rest/api/latest/

image.png

動作確認

Mattermostにトリガーワード(サンプルコードでは、#help)をつけて、お客様から言われそうなメッセージを投稿します。Watson Tone Analyzerにより感情分析され、怒りや嫌悪といったネガティブコメントと判断された場合、Jira Softwareに新規課題として登録されることを確認できました。
image.png

まとめ

Node-REDを使用することで、社内チャットシステムのMattermostとタスク管理システムのJira Softwareを繋げて、ネガティブコメントがあればフォロー用のタスク(課題)を自動登録する動きを確認することができました。この仕組は、Mattermostを外部向けのSNSに変更することで、マーケティング活動や広報業務にも応用できるかもしれません。(次回のネタにします。)

7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5