発表内容について
•Alfrescoのアクティビティフィード(後で簡単にご説明します)をSlackに流すためのカスタマイズ方法をご紹介します。
•あくまでもアクティビティフィードをSlackに送れることを試すためのものであり、全く完成版ではなく、実用化するためにはまだまだ改良が必要です。
•今回ご紹介するカスタマイズのソースコードはこちら
3
アクティビティとは
•コンテンツのアップロードや更新、ダウンロードといったユーザの操作が「アクティビティ」として記録されており、ダッシュボードに表示したりRSSフィードを取得したりすることができる。
5
なぜSlackに送る?
•メールで1日1回配信よりリアルタイムに近い形でSlack等(Slackじゃなくてもよい、Mattermostとか)に配信した方がちゃんと見るのではないか、というのが今回のモチベーション。
•メールを送る頻度を高めるという方法もあり、それならプロパティを書き換えるだけで簡単に実現できるが、システムからの通知がメールで大量に送られてくるのが個人的にあまり好きではないので・・・。
7
RSSフィードをSlackで受け取ればいいのでは?
•要件次第ではその選択肢もあり得る。
•コンテンツに対するアクセス権の問題があるため、アクティビティフィードの内容はユーザ毎に異なる。そのためRSSフィードのURLもユーザ毎に違うし認証も必要になる。
•Slackでユーザ毎にRSS購読の設定をすれば(そのようなことができるかどうかは未確認)実現できるかもしれないし、もしかしたらSlack側にちょうどよいアプリがあるかもしれないが今回はAlfresco側をカスタマイズして実現してみる。
8
SlackUserNotifierクラスの作成
•Eメール通知用の org.alfresco.repo.activities.feed.EmailUserNotifier をコピーして SlackUserNotifier クラスを作成し、#notifyUser の内容を書き換える。
10
protected void notifyUser(NodeRef personNodeRef, String subjectText, Object[] subjectParams, Map<String, Object> model, String templateNodeRef) { Gson gson = new Gson(); try { JSONArray activitiesArray = new JSONArray(gson.toJson(model.get("activities"))); String botName = "Alfresco"; for (int i = 0; i < activitiesArray.length(); i++) { // アクティビティの内容からSlackに送信する要素を抽出 JSONObject activity = activitiesArray.getJSONObject(i); String target = "@" + activity.getString("feedUserId"); … … … // 抽出した要素でSlackのIncoming WebHookに送るpayloadを作成 StringBuilder payload = new StringBuilder(); payload.append("payload={¥"channel¥":¥""); … … … // SlackのIncoming WebHookにPOST HttpClient httpClient = HttpClientBuilder.create().build(); HttpPost request = new HttpPost(this.slackWebhookUrl); … … … } … … … }
Beanの差し替え
•Bean定義を上書きするために以下の内容を custom-activity-feed-context.xml として作成し、以下の場所に配置する。 tomcat/shared/classes/alfresco/extension/subsystems/ActivitiesFeed/default/default
11
<?xml version='1.0' encoding='UTF-8'?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="feedNotifier" class="org.alfresco.repo.activities.feed.FeedNotifierImpl"> … … … <property name="searchService" ref="SearchService"/> <!-- <property name="userNotifier" ref="emailUserNotifier"/> --> <property name="userNotifier" ref="slackUserNotifier"/> <property name="numThreads" value="${activities.feedNotifier.numThreads}"/> <property name="batchSize" value="${activities.feedNotifier.batchSize}"/> </bean> <bean id="slackUserNotifier" class="jp.aegif.alfresco.repo.activities.feed.SlackUserNotifier"> <property name="activitiesFeedModelBuilderFactory" ref="feedModelBuilderFactory"/> <property name="activityService" ref="activityService"/> … … …
(補足)Beanの差し替え
•Bean定義を上書きするために以下の内容を custom-activity-feed-context.xml として作成し、以下の場所に配置する。 tomcat/shared/classes/alfresco/extension/subsystems/ActivitiesFeed/default/default
12
これは誤植ではなくdefaultを2回重ねる必要があります。けっこうハマるポイントなので要注意。 詳しくはこちらを参照してください。 https://community.alfresco.com/docs/DOC-5777-alfresco-subsystems#w_extensionclasspath
alfresco-global.properties に設定値を追記
•SlackのIncoming WebHook用のURLをプロパティとして設定し、通知を送る頻度を10秒に1回に変更する。
13
activities.feedNotifier.slackWebhookUrl=https://hooks.slack.com/services/XXXXXXXX activities.feed.notifier.cronExpression=0/10 * * * * ?
改善すべき点
•配信するメッセージのフォーマットを整える。Eメール通知やRSSフィードの仕組みを応用すれば多言語対応もできるはず。
•Eメールで1日1回送りつつ、今回のようにリアルタイムに近い形での配信も行う場合は送信済みのアクティビティの管理方法を考える必要がある。 ※デフォルトのEメール通知では一度送ったアクティビティには送信済みのフラグが付けられ、何度も送信されない仕組みがある。今回もEメールによる通知をSlackに置き換えているだけなので同じ仕組みで動いている。両方を併用する場合はSlackには送ったがEメールでは送っていないといったステータスの管理が必要になる。
•今回はAlfresco上のユーザ名とSlack上のユーザ名が同じであるという前提で作ったが、両者が異なる場合には変換する仕組みが必要。
15
(参考)
•Alfresco addons にSlack連携のアドオンがありました。 https://addons.alfresco.com/addons/alfresco-slack-plugin
•SOURCE SENSEという会社が作っているようで、設定用のUIもあるようです。興味のある方は使ってみるとよいかもしれません(紹介しておいて申し訳ありませんが動作確認はしてません・・・)。
16