Eclipse 4.7 Oxygen の 設定 - JavaScript編

今回は、Eclipse 4.7 Oxygen の JavaScript に 関する設定を行っていきます.
引き続き各種設定については、お好みがあると思います. ご参考になれば.

作業環境

  • Windows 10 64bit
  • Java SE Development Kit 1.8.0_141
  • Eclipse 4.7 Oxygen

設定

まずは、いつも通り Eclipse の メニュー から [ウィンドウ] - [設定] を クリックし、設定ウィンドウを表示します.

[JavaScript] - [エディター] - [入力]

  • セミコロン: チェック
  • 波括弧: チェック
  • 文字列リテラルへの貼り付け時にテキストをエスケープ: チェック

なるべく自動でやってもらった方が楽なので…

[JavaScript] - [エディター] - [保管アクション]

  • 保管時に選択したアクションを実行: チェック
  • 追加アクション: チェック
  • [構成] ボタンをクリックし、以下を追加
    • コード・スタイル - if/while/for/do ステートメントでブロックを使用 - 常時
    • コード・スタイル - 条件を括弧で囲む - 必要な場合のみ
    • 不要なコード - 未使用のローカル変数を除去
    • 不要なコード - 不要な ‘$NON-NLS$’ タグを除去
    • コード編成 - 末尾の空白を除去 - 全ての行

こちらも Java編 同様、処理を自動化して楽になるように設定します.

[JavaScript] - [コードスタイル]

  • 新機関数と型のコメントを自動的に追加: チェック

JSDoc の テンプレートが自動で入ってくれるので便利です.

[JavaScript] - [コードスタイル] - [フォーマッター]

[新規] ボタンをクリック

[JavaScript] - [コードスタイル] - [フォーマッター] - [新規プロファイル]

プロファイル名に任意の名称 (ここでは Formatter) を 入力し、[OK] ボタンをクリック

[JavaScript] - [コードスタイル] - [フォーマッター] - [Formatter プロファイル]

  • タブ・ポリシー: スペースのみ
  • インデント・サイズ: 2

Java エディター の タブ設定同様で、ここで設定しないとタブが入力されます. 要注意です. またインデント・サイズ は Google の JavaScript Style Guide の “Each time a new block or block-like construct is opened, the indent increases by two spaces. - 4.2 Block indentation: +2 spaces“ に 習って 2 にしました.

[JavaScript] - [バリデーター] - [JSDoc]

  • 誤った形式の Jsdoc コメント: 警告
    • タグ内のエラーをレポート: チェック
  • 未指定の Jsdoc タグ: 警告
  • 未指定の Jsdoc コメント: 警告

厳しく設定します.

[JavaScript] - [バリデーター] - [エラー/警告]

  • JavaScript セマンティクス検証を使用可能にする: チェック
  • 次の JavaScript バリデーター・オプションの問題重大度レベルを選択: 以下を除き すべて 警告
    • 外部化されていないストリング: 無視

厳しく設定します. この手のものは習慣なので、厳しく設定したとしても習慣化されれば気にもならなくなるので、むしろ設定しておいた方が楽ですね.

[JSON] - [JSON ファイル] - [エディター]

  • 行の幅: 999
  • スペースを使用したインデント: チェック
    • インデント・サイズ: 2

JSON は データの表現なので行の幅を縛るより、ありのままで表示してほしいので 行の幅 を 999 に しました. またインデント・サイズは JavaScript の コードに合わせて 2 に しています.

[JSON] - [JSON ファイル] - [検証]

  • 構文検証を使用可能にする: チェック
  • スキーマ検証を有効にする: チェック

チェックはしてもらった方が良いので、有効にします.


Eclipse の 書籍

本記事の 4.7 より古いバージョンとなりますが、Eclipse の 使い方について一通り知るにはよいでしょう. Eclipse は だいぶ枯れているので、大きな違いはないので多少のバージョン違いでも特に問題なく対応できます. (※ Eclipse や IDE を すでに使っている場合には不要です)

Java の 書籍

IDE は あくまでも道具なので、プログラミングの知識はしっかりつけておきたいところです.
Java 8 までを、しっかり身に着けるには こちらの書籍がよいです. こんな感じで Java 9 も 出してほしいですね.


Java 程ではありませんでしたが、設定項目は多めでした. だいぶ設定ができてきました.

Eclipse 4.7 Oxygen の 設定 - Java編

今回は、Eclipse 4.7 Oxygen の Java に 関する設定を行っていきます. 今回はかなり長いです. もうちょっとデフォルト設定と気が合えばよいのですが、ついつい設定したくなってしまう…
引き続き各種設定については、お好みがあると思います. ご参考になれば.

作業環境

  • Windows 10 64bit
  • Java SE Development Kit 1.8.0_141
  • Eclipse 4.7 Oxygen

設定

まずは、いつも通り Eclipse の メニュー から [ウィンドウ] - [設定] を クリックし、設定ウィンドウを表示します.

[Java] - [インストール済みの JRE]

Java SE Development Kit(JDK) の パスになっているかを確認します.
JRE の場合、Java 標準ライブラリーのソースが参照できないため開発に支障があるので、追加してチェックをつけます.

[Java] - [エディター] - [入力]

  • 訂正位置で自動的に挿入 - セミコロン: チェック

なるべく自動でやってもらった方が楽なので…

[Java] - [エディター] - [保管アクション]

  • 保管時に選択したアクションを実行: チェック
  • 追加アクション: チェック
  • [構成] ボタンをクリックし、以下を追加
    • コード・スタイル - if/while/for/do ステートメントでブロックを使用 - 常時
    • コード・スタイル - ‘for’ ループを拡張へ変換
    • コード・スタイル - 式で括弧を使用 - 必要な場合のみ
    • コード・スタイル - 関数型インターフェース・インスタンスへ変換: 可能な場合はラムダを使用
    • コード編成 - 末尾の空白を除去 - 全ての行
    • メンバー・アクセス - 宣言されているクラスを修飾子として使用: チェック
    • 不要なコード - 未使用のインポートの除去
    • 不要なコード - 不要な ‘$NON-NLS$’ タグを除去
    • 不要なコード - 冗長な型引数を除去

保管アクションは、エディタを保存するたびに実行してくれる処理になります. うまく設定することで作業を自動化させたり、チームでの開発で お作法を整えたりできるのでかなり便利です. 厳しくするなら全部チェックしてもよいぐらいですが、このぐらいがバランスが良いように感じます.
ソース・コードのフォーマットにチェックがついているチームに入ったことがありますが、ちょっと使いにくかった… (たぶん Ctrl + S を かなりの高頻度で押す私が悪い)

[Java] - [コード・スタイル] - [コード・テンプレート]

  • 新規メソッドと型のコメントを自動的に追加: チェック

Javadoc の テンプレートが自動で入ってくれるので便利です. ここのテンプレートもしっかり設定したいのですが、今回は設定項目が多いので別途.

[Java] - [コード・スタイル] - [フォーマッター]

[新規] ボタンをクリック

[Java] - [コード・スタイル] - [フォーマッター] - [新規プロファイル]

プロファイル名に任意の名称 (ここでは Formatter) を 入力し、[OK] ボタンをクリック

[Java] - [コード・スタイル] - [フォーマッター] - [Formatter プロファイル]

  • タブ・ポリシー: スペースのみ

実は Java エディター の タブ設定は、ここに隠れているのです… 前回の タブでスペースを挿入: チェック は 一般エディターで、Java エディター の 設定ではないので注意が必要です.

[Java] - [コンパイラー] - [Javadoc]

  • 誤った形式の Javadoc コメント: 警告
    • メンバーの可視性を次のように設定: Private
    • タグ引数の検証: チェック
    • 不可視参照をレポート: チェック
    • 使用すべきでない参照をレポート: チェック
    • タグ記述の欠落: すべての標準タグを検証
  • 未指定の Javadoc タグ: 警告
    • メンバーの可視性を次のように設定: Private
    • オーバーライドしたメソッドの実装を無視: チェックを外す
    • メソッド型パラメーターを無視: チェックを外す
  • 未指定の Javadoc コメント: 警告
    • メンバーの可視性を次のように設定: Protected
    • オーバーライドしたメソッドの実装を無視: チェックを外す

ひたすら厳しく設定しています. Javadoc は Protected 以上は書くようにし、書くからには厳しくチェックです.
よく「コードを見ればわかるでしょ」って言われるのですが、それはコードを見る側が言う言葉で、コードを見てもらう側がいう言葉ではないと思っています. 私の周辺だと、この違いがスキルにも大きく表れているように感じます.

[Java] - [コンパイラー] - [エラー/警告]

  • フィルター入力 へ ~無視 を 入力し、以下を除いて すべて 警告
    • インスタンス・フィールドへの限定されていないアクセス: 無視
    • 外部化されていないストリング: 無視
    • static にできるメソッド: 無視
    • 潜在的に static にできるメソッド: 無視
    • ボクシングおよびアンボクシング変換: 無視

ここも厳しく設定しています. 最初から厳しくし設定しておけば習慣化しますし、コードレビューの際に不要なチェックや雑音というか不要なノイズが減るので、ちゃんと本質を見てもらいやすくなります.

[Java] - [ビルド・パス]

  • ソース・フォルダー名: src/main/java
  • 出力フォルダー名: target/classes

Maven の パスに合わせました.

[Maven]

  • アーティファクト・ソースのダウンロード: チェック

Java 開発をする場合は、Maven/Gradle は 使うケースが多いかと思います. Eclipse の Gradle 設定はあまりないのですが、Maven は 少し設定しておきたいです.
利用するライブラリーのソースは参照できるようにしておくと便利なのでチェックしておきます. Javadoc は ソースから見れるので Javadoc の ダウンロードは設定してません.

[Maven] - [ユーザー・インターフェース]

  • デフォルトの POM エディターで XML ページを開く

GUI エディター より、XML で 見た方が早いので設定しました. GUI エディターは設定するときよりも、Jar の 依存関係を見たりするときに使ってます.

[実行/デバッグ] - [コンソール]

  • コンソールのバッファー・サイズ: 200000

少し多めに.


Eclipse の 書籍

本記事の 4.7 より古いバージョンとなりますが、Eclipse の 使い方について一通り知るにはよいでしょう. Eclipse は だいぶ枯れているので、大きな違いはないので多少のバージョン違いでも特に問題なく対応できます. (※ Eclipse や IDE を すでに使っている場合には不要です)

Java の 書籍

IDE は あくまでも道具なので、プログラミングの知識はしっかりつけておきたいところです.
Java 8 までを、しっかり身に着けるには こちらの書籍がよいです. こんな感じで Java 9 も 出してほしいですね.


結構、設定項目がありました. 手になじませて使うためにも仕方ないですね.

Eclipse 4.7 Oxygen の 設定 - 一般編

今回から、Eclipse 4.7 Oxygen の 設定を行っていきます. そのまま使い始めてもよいのですが、ちゃんと設定してあげると より手になじむのでしっかり設定していきたいところです.
各種設定については、お好みがあると思います. ご参考になれば、といったところでしょうか.

作業環境

  • Windows 10 64bit
  • Java SE Development Kit 1.8.0_141
  • Eclipse 4.7 Oxygen

設定

まずは、Eclipse の メニュー から [ウィンドウ] - [設定] を クリックし、設定ウィンドウを表示します.

[一般] - [エディター]

  • インプレース・システム・エディターの許可: チェックを外す

好みがわかれるところかと思いますが、Eclipse 内で Office ソフトが表示されたりするのは見ずらいと思うので外しています. (もちろん IDE なのだから統合すべしという観点もあるかと思います)

[一般] - [エディター] - [テキスト・エディター]

  • タブでスペースを挿入: チェック
  • 印刷マージンの表示: チェック
    • 印刷マージン: 120
  • 空白文字を表示

タブも好みがわかれるところかと思います. 私はスペース派なので設定しています.
また印刷マージンをいくつにするかも意見が割れるところですね. 最近は広く表示できるので 80 に こだわらなくてもよいかと思いますが、一方でいくつが適切なのかは、正直わからないです… なお Google の Java Style Guide は “Java code has a column limit of 100 characters. - 4.4 Column limit: 100“ と 100文字ですね… 100 だと、ちょっと足りない気がしているので 120 に しています. 水平解像度 1920 で Eclipse 内でエディターを 2枚並べられる感じです.
好みというより コーディング規約で しょっ引かれるところだと思うので、ルールに合わせましょう.

[一般] - [エディター] - [テキスト・エディター] - [空白文字を表示] - [可視性の構成]

  • 空白 - 先頭: チェックを外す
  • 空白 - 囲い: チェックを外す
  • 復帰: チェックを外す
  • 改行: チェックを外す

エディター内に表示する空白文字のパターンを選択します. OK なものは非表示、NG なものを表示にしました. 表示されていたら対処が必要との観点になるのでわかりやすいかと.

[一般] - [エディター] - [テキスト・エディター] - [スペル]

  • スペル・チェックを使用可能にする: チェックを外す

英語、苦手なんでチェックしたいところ. ですが、あまり有効に働いた思い出が無いので外しています.

[一般] - [エディター] - [構造化テキスト・エディター] - [タスク・タグ]

  • タスク・タグの検索を使用可能にする: チェック

有効にしておくと TODOFIXME XXX などを タスク・ビュー表示してくれます. 暫定実装した際などはタグをつけておくと、後で改修がしやすいので便利です. 一方で多用されすぎでリストがあふれるなどの悲しいことも…

[一般] - [ワークスペース]

  • テキスト・ファイル・エンコード: UTF-8
  • 新規テキスト・ファイルの行区切り文字: Unix

Windows を 使ってはいますが、ソースコードの観点からは UTF-8LF が よいと思います. Git の 変換もいらないし.

[一般] - [外観] - [色とフォント]

  • テキスト・フォント: Migu 1M 10

開発環境にとってフォントは大事です. 専用のフォントも作られているくらいなので自分に合ったフォントを見つけて設定したいですね.
私は M+とIPAの合成フォント さん の Migu 1M を 使わせていただいてます. 素晴らしいフォントをありがとうございます!!


Eclipse の 書籍

本記事の 4.7 より古いバージョンとなりますが、Eclipse の 使い方について一通り知るにはよいでしょう. Eclipse は だいぶ枯れているので、大きな違いはないので多少のバージョン違いでも特に問題なく対応できます. (※ Eclipse や IDE を すでに使っている場合には不要です)

Java の 書籍

IDE は あくまでも道具なので、プログラミングの知識はしっかりつけておきたいところです.
Java 8 までを、しっかり身に着けるには こちらの書籍がよいです. こんな感じで Java 9 も 出してほしいですね.


以上、Eclipse の 一般設定でした. 設定は好みがわかれるので難しいですよね.
より良い設定があったら教えていただければと.

Eclipse 4.7 Oxygen に Eclipse Foundation から Plug-in を 追加

前回 Eclipse 4.7 Oxygen を インストール しました. インストールしたのは Eclipse IDE for Java Developers の パッケージになり、HTML や CSS などの Web 開発を行うには Plug-in を 追加する必要があります. 今回は Web 開発系 の Plug-in 他、Eclipse Foundation が 提供している Plug-in を 追加します. (3rd Party の Plug-in は 別途)

作業環境

  • Windows 10 64bit
  • Java SE Development Kit 1.8.0_141
  • Eclipse 4.7 Oxygen

Plug-in の 追加手順

Eclipse の メニューから [ヘルプ] - [新規ソフトウェアのインストール] を クリックします.

インストールする Plug-in の 選択画面が表示されるので、[作業対象] に [–すべての使用可能なサイト–] を 選択します.

少しするとインストールできる Plug-in の 一覧が表示されるので、インストールする Plug-in に チェックします.
今回は以下の Plug-in を 選択しました.

  • [コラボレーション] - [動的言語ツールキット - Mylyn 統合]
  • [コラボレーション] - [Eclipse GitHub 統合 (タスク・フォーカス・インターフェース)]
  • [Web, XML, Java EE および OSGi エンタープライズ開発] - [Eclipse Web 開発者ツール]
  • [Web, XML, Java EE および OSGi エンタープライズ開発] - [JavaScript 開発ツール]

インストールする Plug-in の 確認画面が表示されるので、[次へ] ボタンをクリックして進めます.

ライセンスの確認画面が表示されます. 内容を確認し同意できたら [使用条件の条項に同意します] を 選択し、[完了] ボタンをクリックします. 同意できなかったら、残念ながら終了です…

Plug-in の ダウンロード と インストールが行われます. インストールが完了すると再起動の確認ダイアログが表示されます. 特に問題なければ [今すぐ再起動] ボタンをクリックします.

[いいえ] を 選んで Eclipse を自分で終了した場合は、次回 eclipse.exe -clean.cmd で 起動します. 日本語化 Plug-in の Pleiades を 正しく機能させるためには Plug-in を 追加した後はクリーンアップ起動する必要があります.

いずれにしても Plug-in 追加後の起動で、下図のような「キャッシュのクリーンアップ中」の スプラッシュが表示されないで起動した場合は Plug-in の 機能 および 日本語化が正しく行えていない場合があるので、 eclipse.exe -clean.cmd で 起動しなおします.


Eclipse の 書籍

本記事の 4.7 より古いバージョンとなりますが、Eclipse の 使い方について一通り知るにはよいでしょう. Eclipse は だいぶ枯れているので、大きな違いはないので多少のバージョン違いでも特に問題なく対応できます. (※ Eclipse や IDE を すでに使っている場合には不要です)

Java の 書籍

IDE は あくまでも道具なので、プログラミングの知識はしっかりつけておきたいところです.
Java 8 までを、しっかり身に着けるには こちらの書籍がよいです. こんな感じで Java 9 も 出してほしいですね.


HTML や CSS、JavaScript などは Atom や Visual Studio Code といった高機能エディタで開発する流れもあり、また サーバサイドは Web API に することも多く、Eclipse で HTML/CSS/JavaScript を コーディングするシーンが減ってくるのかなとも思いますが、Plug-in を 入れておくとハイライトしてくれたりと、何かと便利なので入れています. 設定については次回にて.

Eclipse 4.7 Oxygen リリース! & インストール

Eclipse Oxygen Now Available - 2017/06/28 ということで、統合開発環境 Eclipse の 新バージョンがリリースされました! 毎年6月末ごろのお楽しみですね♪ 色々あって出遅れてしまいましたが、新バージョンを試してみたいと思います.

作業環境

  • Windows 10 64bit
  • Java SE Development Kit 1.8.0_141
  • Eclipse 4.7 Oxygen

Eclipse とは

改めて書くほどのことではないかもしれませんが、本ブログで取り扱うのは初なので、一応ざっくりと.
当初 IBM が 開発し、現在は Eclipse Foundation が 開発・提供をしていフリー&オープンソースの統合開発環境(IDE)です. Java の 流行に合わせて発展・普及してきた感じがあります. Java だけではなく、HTML, CSS, JavaScrip, C/C++, PHP や XML などの言語に対応しているほか、モデリング や リッチクライアント といった多様な開発が行えます. また Plug-in で 機能拡張もでき Python なども Plug-in で 対応できます. (基本的には全部 Plug-in で対応しているので、公式にパッケージングされているかの違いですね)
Android アプリ の 開発は、残念ながら Android Studio へと移行してしまいました…
無料で使える IDE としては、かなり高機能で Eclipse だけでかなりのことができます. とはいえ、最近は AtomVisual Studio Code といった高機能エディタの流れもあり、軽量プログラミング言語と呼ばれる領域の開発はエディタに変わり、重量級の開発が Eclipse に 残る感じでしょうか.

今回のリリース 4.7 Oxygen では、たくさんの修正が入っているものの、さすがに 15年を超える歴史を持つソフトウェアとなると大きな新機能は無いようです. Java 9 対応がありますが、Java 9 自体が 2017年9月リリース予定なので early access preview となっています.

詳細なリリースは Eclipse IDE, Oxygen Edition New and Noteworthy になります. また こちらの Eclipse 4.7 Oxygen 新機能 30+ / Java 9 を試そう! - Eclipse Oxygen 新機能・変更点 が 詳細にまとめてくださっています.

インストール手順

Java は インストールされている前提とします.

Eclipse の ダウンロード・サイト http://www.eclipse.org/downloads/ へ アクセスします.
環境を自動判別して [DOWNLOAD 64 BIT] ボタンが用意されていますが、今回は ZIP ファイルから入れるので、ボタンの下 [Download Packages] を クリックします. (インストーラーを使うと簡単なのですが、インストール・パスが思うようにいかなかったので ZIP ファイル に しました)

今回は Java の 開発で使うので、Eclipse IDE for Java Developers の パッケージを選択しました. Eclipse IDE for Java Developers の 行の、[64 bit] リンク を クリックします.

ダウンロード画面が表示されます. ダウンロードする前に [SHA-512] アイコンをクリックしてファイルのチェックサムをコピーしておきます. 準備ができたら [DOWNLOAD] ボタンをクリックしてダウンロードを開始します.

ファイルがダウンロードできたら Windows PowerShell 4.0 以降の Get-FileHash コマンドを使い、ダウンロード前にコピーしたチェックサムを確認します. eclipse-java-oxygen-R-win32-x86_64.zip の チェックサムは aa41bced7699b933fac9b254de1609edfec7f2baac89a5a262e92d9119561a6b19fb367a65946ced7ab718f640b74b51f753ed685aeeb45b50f533e6131ac85a でした.

ただし SHA-512 の チェックサムは長い文字列のため、コマンド プロンプト からの実行では出力が切れてしまいます.

1
2
3
4
5
c:\>powershell Get-FileHash -Algorithm SHA512 %USERPROFILE%\Downloads\eclipse-java-oxygen-R-win32-x86_64.zip

Algorithm Hash
--------- ----
SHA512 AA41BCED7699B933FAC9B254DE1609EDFEC7F2BAAC89A5A262E92D9119561A6B19F...

そのため PowerShell を 起動して、Get-FileHash から Format-List へ パイプします.

1
2
3
4
5
6
c:\> powershell

PS C:\> Get-FileHash -Algorithm SHA512 $ENV:UserProfile\Downloads\eclipse-java-oxygen-R-win32-x86_64.zip | Format-List

Algorithm : SHA512
Hash : AA41BCED7699B933FAC9B254DE1609EDFEC7F2BAAC89A5A262E92D9119561A6B19FB367A65946CED7AB718F640B74B51F753ED685AEEB45B50F533E6131AC85A

ZIP ファイル を 任意の場所に解凍します. 今回は C:\Develop\tool\eclipse-4.7-oxygen-install に 解凍しました.
※ 解凍ツールは Windows 10 の エクスプローラー で 右クリック から [すべて展開] を 使いました. 解凍する場所によっては Windows の パスの長さ(ドライブ・レター、フォルダ、ファイル名) が 260文字に制限されている 件にかかりエラーとなる場合があります. その場合は、パスが短くなる場所で解凍します. こちら Pleiades - 日本語化プラグイン Eclipse、Android Studio、PhpStorm さん の ページ下部「Windows 上で zip を解凍するときの注意」に 詳細があります.

日本語化

続いて Eclipse を 日本語化します. Pleiades - 日本語化プラグイン Eclipse、Android Studio、PhpStorm さん の サイトから Pleiades プラグイン を ダウンロードします. 今回は [最新版] を 利用させていただきました.
英語が苦手なので日本語化プラグインにはいつも助けていただいています. 素晴らしいプラグインをありがとうございます!

ダウンロードしたら、チェックサム… は わからなかったので確認できないです. (Subversion に コミットされているファイルのチェックサムってどうやってとるんだろう)

Eclipse を インストールした場所に解凍します.

続いて、 eclipse.ini に 以下の 2行を追記します. その際に改行コードが LF を 扱えるエディタで編集する必要があります. 改行コードを CRLF で 保存すると Eclipse が 起動しないことがあるので注意が必要です. 今回は Visual Studio Code を 使いました. (Eclipse を 一度起動すると CRLF に なるので、一度起動して終了し、編集するのも手かもしれません)
併せて -Duser.name=Your Name の 行も追加しておくと便利です. これを設定しておくと Eclipse の Javadoc コード保管で Your Name に 指定した文字列を入れてくれます.

1
2
-Xverify:none
-javaagent:plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar

eclipse.exe -clean.cmd を ダブルクリックして Eclipse を 起動します.
普段は eclipse.exe を 使いますが、初回起動 と Plug-in の 追加を行った場合は、 eclipse.exe -clean.cmd を 使ってクリーンアップした起動を行います.

ワークスペースのディレクトリーを選択するダイアログが表示されます. 任意の場所を指定し、[この選択をデフォルト…] に チェックします. (今回は C:\Develop\workspace に しました)

日本語化した Eclipse が 無事に起動しました!
「ようこそ」画面が表示されています. 必要なくなりましたら、右下の [始動時に常に「ようこそ」を表示] の チェックを外して、「ようこそ」タブ の 右にある [×] を クリックしてエディタを閉じます.


Eclipse の 書籍

本記事の 4.7 より古いバージョンとなりますが、Eclipse の 使い方について一通り知るにはよいでしょう. Eclipse は だいぶ枯れているので、大きな違いはないので多少のバージョン違いでも特に問題なく対応できます. (※ Eclipse や IDE を すでに使っている場合には不要です)

Java の 書籍

IDE は あくまでも道具なので、プログラミングの知識はしっかりつけておきたいところです.
Java 8 までを、しっかり身に着けるには こちらの書籍がよいです. こんな感じで Java 9 も 出してほしいですね.


Eclipse の インストーラー が できたとはいえ 日本語化の手順など、年1回の新バージョン・リリースでインストールしているので手慣れてはいますが、やはり整理しておかないとですね. 今もあるのかわかりませんが eclipse.iniCRLF トラブルはかなりはまった記憶があります…
インストール後の各種設定もいろいろあし、Python や Visual Studio Code などにも手を出し始めたので、しばらくは初期設定話が続きそう orz

Python 3.6 64bit の インストール

Python を 使うことになり、初めてなので インストール・メモ. ちょっとしたメモでも仲間が増えたときに、こんな感じで~って説明できるので残しておくことにしたことはないですね.

作業環境

  • Windows 10 64bit
  • Python 3.6 64bit

バージョン と インストールする環境について検討

今回は Windows 10 に Python を インストールします. Windows 10 だと、Bash on Ubuntu on Windows で Linux 環境に Python を 入れられるはずですが、いきなり複雑なことをするとトラブル時に対応できなくなりそうなので、まずは Windows 10 に 直接インストールし、Python に 慣れてきたら Bash on Ubuntu on Windows を 使ったりとアレンジしたいと思います.

Pyhton は 2.x と 3.x があります. 今回はまったく新しく使い始めるため、ありがたいことに過去のしがらみなし、ということで 2017年7月現在 最新 の 3.6.2 を 使いたいと思います. また、開発・実行環境の Windows 10 が 64bit なので、Python も 64bit を 選択したいと思います. Pyhton の ライブラリ によっては 32bit しか用意がないなど、64bit を 使うと困ることもあるみたいですが、これは切り替えが簡単なので、困るまでは 64bit で 行ってみます.

インストール手順

Python の トップページ や Downloads の メニュー、Downloads ページ にある [Download Python 3.6.2] は、OS を 自動判定して適切なインストーラーをダウンロードさせてくれるのですが、こちらからだと 32bit 版 が ダウンロードされます. そのため こちらからはダウンロードはせず、Windows 版のダウンロード・ページから 64bit 版 を 選択してダウンロードします.

Windwos 版 の ダウンロード・ページ Python Releases for Windows | Python.org https://www.python.org/downloads/windows/ へ アクセスします.
こちらから Windows x86-64 executable installer を ダウンロードします.

チェックサムの確認は Python 3.6.2 - 2017-07-17 リンクから Python Release Python 3.6.2 | Python.org 画面へ行き、画面中段の Files に MD5 Sum が 記載されています. 今回ダウンロードした Windows x86-64 executable installer4377e7d4e6877c248446f7cd6a1430cf です.
確認方法は Windows PowerShell 4.0 以降の Get-FileHash コマンドを使います.

1
2
3
4
5
c:\> powershell Get-FileHash -Algorithm MD5 c:\python-3.6.2-amd64.exe

Algorithm Hash
--------- ----
MD5 4377E7D4E6877C248446F7CD6A1430CF

ダウンロードした python-3.6.2-amd64.exe を ダブルクリックして、インストーラーを起動します.

PATH は 追加しておいた方が便利なので、[Add Python 3.6 to PATH] に チェックをつけます.
インストール・オプションを指定したいので [Customize installation] を クリックしてインストールを進めます.

Optional Features では、特に変更せず [Next] ボタンをクリックして進みます.

Advanced Options では、以下を設定し、[Install] ボタンをクリックします.

  • [Install for all users] を チェック
  • [Precompile standard library] を チェック (Install for all users チェックすると自動で付く)
  • [Customize install location] を 必要に応じて設定 (私は C:\Develop 以下にまとめるのが好きなので設定)

インストールが完了しました.
[Disable path length limit] を すると、Windows の パスの長さ(ドライブ・レター、フォルダ、ファイル名) が 260文字に制限されている のを解除できます. Windows 10 で、この MAX_PATH が 解除できるようになったため Python 3.6 で 追加された機能(Issue 27731: Opt-out of MAX_PATH on Windows 10 - Python tracker) になります.
パスが長くなるようでしたら設定します. 今回は長くなる想定が無いので選択しませんでした.

動作確認

コマンド プロンプト で バージョンを出力してみます. コマンドは python --version もしくは python -V です. 大文字で -V であることに注意です. インストール・オプションで [Add Python 3.6 to PATH] に チェックしたので、パスが通っているため、直接 python コマンドが実行できます.

1
2
3
4
5
6
7
8
c:\> echo %PATH%
C:\Develop\sdk\Python36\;C:\Develop\sdk\Python36\Scripts\; ...(省略)

c:\> python --version
Python 3.6.2

c:\> python -V
Python 3.6.2

小文字の場合は 詳細報告 (verbose) モード の オプション指定になり、インタプリタに入ります. 突然大量の出力があり、その後は プロンプトが c:\ のような Windows から >>> に 変わり、Python 命令を受け付ける状態になります.
1 + 1 のような命令を入力すると、実行結果が返ってきます.
一方で命令にないことをすると、エラーが返ります.
終了するには Ctrl + Z キーを押す、もしくは exit() を 実行します. exit で 実行すると Use exit() or Ctrl-Z plus Return to exit と返ってきます.
なお、Ctrl + CKeyboardInterrupt です.
突然の出力とインタプリタの起動で思わぬ動きをしてビックリしますが、落ち着いて exit() しましょう.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
c:\> python -v
import _frozen_importlib # frozen
import _imp # builtin
import sys # builtin
... (省略)
>>>
>>> 1 + 1
2
>>>
>>> python -V
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'python' is not defined
>>>
>>> (※ Ctrl+C)
KeyboardInterrupt
>>>
>>> exit()


主にクロール系の処理になるので、こちらで勉強しています.
最初の言語として勉強するための本には向いていませんが、Python の 言語使用の話もあるので他の言語を知ってる場合には、これ1冊でも十分ではないでしょうか.
またクローラーを作るという観点では、Python の 基本機能だけではなく Shell や Python の 外部ライブラリを使ったりと、バリエーションを持たせて解説があるので とても分かりやすいほか、法律に関する話などもあるのが素晴らしいです!


インストーラーのダウンロードで 32bit が 自動選択されるという現象がありましたが、それ以外は特に難しいことなくインストールができますね. 後はバージョン情報を出力させる際に、つい python -v と 小文字を使う癖があるようで、いきなりの詳細報告モードのインタプリタで毎回焦ります (;^_^A
何はともあれインストールができたので、バリバリ開発にいそしみ、面白いものができたらアップしていけたらと思います.

Slack の ボット で 2FA(Two-Factor Authentication / 2要素認証) 未設定ユーザ を 監視する - Slack ボット 実装編

Slack の Free Plan でも、API から 2FA の 設定状況が見れることが分かりました. それを使ってボットが 2FA の 設定状況を監視しレポートするようにしたいと思います.

作業環境

  • Slack
  • Node.js 6.11.0 LTS
  • Botkit 0.5.2

通知方法の検討

セキュリティに関することなのでキッチリ警告していきたいものの、あまり頻度が高いのも考え物. 加減が難しいところです…
今回は、未設定者に DM で 週1回 月曜日 の 14時 に 通知し、Slack の チーム管理者 向けに #sandbox へ 未設定者一覧の支援依頼のメッセージを出力します. (未設定者を公開で晒すのも微妙なので、実際には管理者用チャンネルとかにした方が良いかもしれないですね)

Slack ボット の 実装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
const Botkit = require('botkit');
const cron = require('cron');

const controller = Botkit.slackbot();

const channel = '#sandbox';
const url = 'https://get.slack.help/hc/ja/articles/204509068-2%E8%A6%81%E7%B4%A0%E8%AA%8D%E8%A8%BC%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B';

controller.spawn({
token: process.env.bot_access_token
}).startRTM((err, bot, payload) => {

new cron.CronJob({ cronTime: '00 00 14 * * 1', timeZone: 'Asia/Tokyo', start: true, onTick: () => {

let admins = [];
let reports = [];
bot.api.users.list({ token: process.env.access_token }, (err, response) => {
for (let member of response.members) {
if (member.deleted || member.is_bot || member.name == 'slackbot') {
continue;
}

if (member.is_admin) {
admins.push(member.id)
}

if (!member.has_2fa) {
reports.push(member.id)
}
}

if (reports.length != 0) {
bot.say({
channel: channel,
text: `2FA の 未設定 ${reports.length} 人、み~つけた! ` +
'管理者の人~、設定の仕方を助けてくださいませ. ' +
`設定の説明は <${url}|こっち> に あるよ. \n` +
`未設定者: ${createMentions(reports)}`
});
}

for (let report of reports) {
bot.startPrivateConversation({ user: report }, (response, convo) => {
convo.say('Slack の 2FA(Two Factor Authentication / 二要素認証) 設定をしてくださいな. ' +
`設定の説明は <${url}|こっち> に あるよ. \n` +
`あとは ${bot.team_info.name} Slack チーム の 管理者 ${createMentions(admins)} に 聞くのもありだね.`
);
});
}
});
}});

function createMentions(userIds) {
let mentions = [];
for (let userId of userIds) {
mentions.push(` <@${userId}>`);
}
return mentions;
}
});

まずは、cron モジュールを使ったボットにするため controller.spawn().startRTM() 内で処理を実装するボットを作ります. この辺りは Slack の ボット で 定時アクション で 作ったものになります.

続いて定期処理を作るために new cron.CronJob()cronTime: '00 00 14 * * 1' と 処理、その他オプションを渡します. cronTime は 秒 分 時 日 月 曜日 なので、'00 00 14 * * 1' は 左3つで14時ちょうど、右3つで毎週月曜日となります.

14行目からメインのコードになります. チーム管理ユーザ と レポート対象ユーザ を 保持するための配列を用意します.
続いてユーザー一覧を取得する Slack API を 前回の通り bot.api.users.list()token に OAuth で 権限を与えられている方のトークンを渡します.

API から取得した ユーザー一覧を for-of で 回しながら adminsreports の 配列を作成していきます. 削除済み と ボット と “slackbot” は チェック不要なので continue します. “slackbot” さん は、なぜかボット判定が効かないので名前で判別しています.
続いて、is_admin で チーム管理者の判定をします. オーナーも is_admintrue で 管理者に入ります. (もし外すなら is_primary_owneris_owner で オーナー判定できます)
最後に今回の肝である has_2fa で レポート対象ユーザーの判定をします. 通常は無いはずですが、管理者が 2FA 未設定のケースを想定して is_adminhas_2faelse if ではなく if で 分けてます.

32行目から、管理者向けの通知になります.
レポート対象ユーザー reports が 空でなければ bot.say() で 指定チャンネルへ未設定者のリストを通知します.
※ 今回 const channel = '#sandbox'; と チャンネル名指定してますが、正式には https://slack.com/api/channels.list?token=[API_TOKEN] で 調べた ID を 使うべきです

42行目から、未設定者に対する DM になります.
未設定者の配列 は for-of で 回し、DM を 送る bot.startPrivateConversation() を 呼び出します.
bot.say() のように、直接メッセージを出せず、Conversation の 形式で送ります. そのため bot.startPrivateConversation() の 第2引数で渡すコールバック関数で受け取る 第2引数 convo に対して say() を 呼び出します.

通知!

まずは管理者向けにチャンネルへポストされた方になります. 今回は実験用なので #sandbox に 晒されてます.

続いて DM を 受けている側になります. ちゃんと相談先のチーム管理者へのメンションも出ています. 安心ですね.



これで、2FA 未設定者を ×炙り出して晒す ◎検出して通知 できるようになりました.
有料プランのように強制はできないものの、毎週通知されることと、管理者へもフォローするよう通知が行くので、おのずと設定されることに期待したいと思います.

もし強化するとしたら、全チャンネルから BAN して、チャンネル参加を拒否する鬼ボットにするとかですかね… なんか面白そうだなぁ. 作ってみたくなってきた.

Slack の ボット で 2FA(Two-Factor Authentication / 2要素認証) 未設定ユーザ を 監視する - API 確認編

Slack には Free Plan でも 2FA の 機能が用意されています. アカウントの安全性から 2FA は 設定しておくべきですが、2FA の 必須化は 有料 の Standard Plan からになります. 目の届く範囲での利用でしたら、声がけしていくことで全員に設定してもらうことはできそうですが、ある程度の規模になると難しくなってきます. そんな時こそ、有料プラン! と 行きたいところですが、この手の話は往々にして時間がかかるもの. その間 ボットに 2FA の 状態を監視、レポートしてもらいたいと思います.

作業環境

  • Slack
  • Node.js 6.11.0 LTS
  • Botkit 0.5.2

まずは 2FA 設定状況 の 確認

管理者権限のユーザで https://my.slack.com/admin へ アクセスすると、チーム・メンバーの一覧 と 2FA の 設定状況を確認することができます.
下図の例では [Team Admin] は 2FA が 設定されているため、2FA アイコンがついています. 一方で [You] は アイコンがついていないので、2FA が 設定されていません. 2FA を 設定するよう指導が必要です!って、自分ですが…
なお、2FA の 設定方法は こちら 2要素認証を設定する – Slack に ヘルプがあります.

毎度ウェブから確認するのは手間なので、2FA を 必須化したいところです. Slack には 2FA 必須化オプションが 有料 の Standard Plan から用意されているので、こちらを使うことで 2FA の 設定を強制することができます. 価格情報は https://my.slack.com/pricing から参照でき、2017年6月現在 “850円/月/アクティブ・ユーザー” です.

お金の話になると途端に進捗が悪くなる、なんてことは よくある話でして、何とかボットでうまく警告したいところで、ボットでチェックする方法を考えていきます.

API で ユーザー情報 の 取得

まずは API で ユーザー情報を取得し、どのような情報があるのか確認してみます. ユーザー情報取得 の API は users.listusers.info が あります.

それぞれのデータを確認するために、ボットを起動した際に API 呼び出しを行ってみます.
※ 11行目 の U01CAXXXX は 調べたいユーザ の ID に なります. bot.api.users.list() の データ出力を確認してから、表示したいユーザ の ID を 設定します.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const Botkit = require('botkit');

const controller = Botkit.slackbot();

controller.spawn({
token: process.env.bot_access_token
}).startRTM((err, bot, payload) => {
bot.api.users.list({}, (err, response) => {
console.log(response)
});
bot.api.users.info({ user: 'U01CAXXXX' }, (err, response) => {
console.log(response)
});
});

実行すると、以下のような情報がコンソールに出力されます. (順不同、整形済み、name: ‘username’ のみ抽出)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
info: ** API CALL: https://slack.com/api/users.list
{ ok: true,
members:
[ { id: 'U01CACXXXX',
team_id: 'T10ADAXXXX',
name: 'username',
deleted: false,
color: '9f69e7',
real_name: '',
tz: 'Asia/Tokyo',
tz_label: 'Japan Standard Time',
tz_offset: 32400,
profile: [Object],
is_admin: false,
is_owner: false,
is_primary_owner: false,
is_restricted: false,
is_ultra_restricted: false,
is_bot: false,
updated: 1487291465 } ],
cache_ts: 1497847517 }

info: ** API CALL: https://slack.com/api/users.info
{ ok: true,
user:
{ id: 'U01CACXXXX',
team_id: 'T10ADAXXXX',
name: 'username',
deleted: false,
color: '9f69e7',
real_name: '',
tz: 'Asia/Tokyo',
tz_label: 'Japan Standard Time',
tz_offset: 32400,
profile: [Object],
is_admin: false,
is_owner: false,
is_primary_owner: false,
is_restricted: false,
is_ultra_restricted: false,
is_bot: false,
updated: 1487291465 } }

残念ながら 2FA に 関する情報は取得できないようです…

OAuth で 取得した トークン を 使う

ところで API リファレンス を よく見ると、引数 token の Description は “Authentication token. Requires scope: users:read“ と なっています. 先ほどのプログラムでは token を 渡していないので、ボット の トークン で アクセスしていたことになります.
では OAuth で users:read を 取得しているトークン を API 呼び出しに使ってみます. Slack の API 呼び出し関数 の 引数 に 環境変数で渡されたトークンを token: process.env.access_token として渡します. (以下、API 呼び出し部分を抜粋)

1
2
3
4
5
6
bot.api.users.list({ token: process.env.access_token }, (err, response) => {
console.log(response)
});
bot.api.users.info({ token: process.env.bot_access_token, user: 'U01CAXXXX' }, (err, response) => {
console.log(response)
});

実行結果を確認します. (順不同、整形済み、name: ‘username’ のみ抽出)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
info: ** API CALL: https://slack.com/api/users.list
{ ok: true,
members:
[ { id: 'U01CACXXXX',
team_id: 'T10ADAXXXX',
name: 'username',
deleted: false,
color: '9f69e7',
real_name: '',
tz: 'Asia/Tokyo',
tz_label: 'Japan Standard Time',
tz_offset: 32400,
profile: [Object],
is_admin: false,
is_owner: false,
is_primary_owner: false,
is_restricted: false,
is_ultra_restricted: false,
is_bot: false,
updated: 1487291465,
has_2fa: false } ],
cache_ts: 1497850133 }

info: ** API CALL: https://slack.com/api/users.info
{ ok: true,
user:
{ id: 'U01CACXXXX',
team_id: 'T10ADAXXXX',
name: 'username',
deleted: false,
color: '9f69e7',
real_name: '',
tz: 'Asia/Tokyo',
tz_label: 'Japan Standard Time',
tz_offset: 32400,
profile: [Object],
is_admin: false,
is_owner: false,
is_primary_owner: false,
is_restricted: false,
is_ultra_restricted: false,
is_bot: false,
updated: 1487291465 } }

21行目に has_2fa: false が あります! users.list では has_2fa が あり、users.info には無いようですが、ユーザーを一覧で取得できる users.list に あるのは助かります. これを使えば、2FA を 設定していないユーザーを抽出し、連絡することができそうです.



とりあえず、2FA 設定の有無が API から取得できることが確認できました. ここまでくれば ボット実装は、これまでの組み合わせなので簡単にできそうですね. 使いやすい API が あるってことは、偉大だ.

Hexo に 関連する記事のリストを追加する

WordPress などでよく見る「関連記事」の リンク、設置してみたいです. Hexo は 静的サイト・ジェネレーターなので、あらかじめサイトが作られていて訪問いただいた際にデータを蓄積して、それを活用するような仕組みは作れません. JavaScript で 制御できる範囲までです. と、あきらめていたら素晴らしいプラグインを作ってくださっている方がいらっしゃりました! ということで、さっそく設置してみます.

作業環境

  • Windows 10
  • Hexo 3.3
  • Hexo Theme Landscape
  • hexo-related-popular-posts

その素晴らしいプラグインは hexo-related-popular-posts! 関連する記事だけでなく、人気の切りリストも作れてしまう優れものです. 素敵なプラグインをありがとうございます!

設置方法については、作者さん の 記事 ブログで関連記事や人気記事を生成するプラグインを作った(node.js製hexo) | TPB が すべてを語ってくださっているので、このまま! という感じですが、機能がたくさんあるので、まずは関連する記事のリストだけに絞って設置しましたので、その記録.

npm で インストールを実行するだけになります.

1
2
3
4
C:\Develop\repos\[username].github.io> npm install hexo-related-popular-posts --save
`-- hexo-related-popular-posts@2.0.0
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules\chokidar\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

Hexo Theme Landscape に 関連する記事 の リスト を 表示

Hexo の デフォルト・テーマ Landscape を カスタマイズします.
テーマ の レイアウト・ファイル /themes/landscape/layout/_partial/article.ejs の 表示したい場所に popular_posts() を 追加します.
今回は記事の後の [NEWER/OLDER ナビゲーション] と [コメント欄] の 間に配置するため、以下のようにしました.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
</article>

<nav id="related-posts" class="article-inner" style="font-size: smaller">
<div class="article-entry">
<h2>関連記事</h2>
<%-
popular_posts({ PPMixingRate: 0.0 })
%>
</div>
</nav>

<% if (!index && post.comments && config.disqus_shortname){ %>
<section id="comments">
<div id="disqus_thread">
<noscript>Please enable JavaScript to view the <a href="//disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
</div>
</section>
<% } %>

4行目 ~ 11行目 の <nav> タグで 囲まれている部分が追加したものになります.
popular_posts() は、関連する記事を <ul><li> の HTML で 出力してくれます. 「関連記事」のようなタイトルは自前で記述する必要があります.

今回は記事やコメントの枠と合わせたかったので、<nav class="article-inner"><div class="article-entry"> で 囲むようにしました. この辺はお好みで自由にできるのがいいですね.

続いて 本体の popular_posts({ PPMixingRate: 0.0 })PPMixingRate: 0.0 ですが、関連記事のみを表示するオプションになります.
hexo-related-popular-posts は 関連記事 と 人気記事 の 両方が扱えます. すごい! この混合具合を指定することができ、0.0 が 関連記事のみ、1.0 が 人気記事のみ と なります.
人気記事の機能を使うには、Google Analytics API の 設定が必要とのことで、今回は関連記事のみとしました. いずれちゃんと設定して、人気記事を表示するか、ブレンドするようにしてみたいと思います.

そのほかのオプションについては、ヘルパータグの表示オプション に 詳細が書かれています.

いざ確認!

hexo generate して ローカルサーバで動作確認すると、<head> に Google Analytics のためのコードが追加されています.


無事、関連記事が表示されるようになりました. Slack ボット の 記事などは、ボットを いろいろなパターンで作っていたりするので、ご紹介できたらなぁと思っていたので、とても助かります.

静的サイト・ジェネレーターを使っているので関連記事などは難しいかなぁと思っていましたが、素晴らしいプラグインのおかげでつけられました. 作者さま ありがとうございます!

Slack の ボット で ランダムなカスタム絵文字リアクション を する

Slack の ボット に OAuth で 権限を与えられたので、その権限を使って Slack API を 実行するボットを作成してみます.
今回は emoji:read の 権限を使い、チームに追加されているカスタム絵文字をランダムで選択してリアクションするボットにしたいと思います.

作業環境

  • Slack
  • Node.js 6.10.2 LTS
  • Botkit 0.5.2

ボット で 絵文字リアクション を 使う

例によって Basic Usage をもとにカスタマイズしたいと思います. Basic Usage そのままに、hello と DM や メンションされたら、返事をした後に 元のメッセージに raised_hand の リアクションをつけるようにします.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const Botkit = require('botkit');

const controller = Botkit.slackbot();

controller.spawn({
token: process.env.bot_access_token
}).startRTM();

controller.hears('hello', [ 'direct_message', 'direct_mention', 'mention' ], (bot, message) => {
bot.reply(message, 'Hello yourself.');

bot.api.reactions.add({
name: 'raised_hand',
channel: message.channel,
timestamp: message.ts
});
});

起動する際に、環境変数 bot_access_tokenaccess_token に、それぞれ ボットのトークン と OAuth で 権限取得したトークンを設定しておくことを忘れないように注意します.

Slack の リアクション は API 呼び出しになります. bot.api 以下に Slack API に 対応したメソッドiが用意されています. 今回は reactions.add の API を 呼び出したいので、bot.api.reactions.add() に なります.

reactions.add の Slack API リファレンス を 参考に、引数 を オブジェクトで渡します.
token は Botkit の 起動時に渡しているので不要で、name が 必須です. ここでは raised_hand を 設定しました. 文章中に絵文字として使う場合は :raised_hand:: で 囲みますが、リアクション API で 指定する場合は : なしで指定します.
channeltimestamp は オプションなのですが、これはファイルへのリアクションとメッセージへのリアクションで引数が異なるだけで、メッセージへのリアクションは channeltimestamp が 必要となります.
message が 元のメッセージのオブジェクトなので、message.channelmessage.ts で リアクションをつける元のメッセージ指定ができます.
また、第2引数で コールバック関数 を 渡して API の 戻りを受けられますが、今回は特に処理がないので省略しました. たいしたリアクションではないのでエラー処理も省略していますが、重要な場合はエラー・ハンドルしておいたほうがよいいでしょう.

あとはボットを起動して “@BOTNAME hello” と メンションすれば、自分のメッセージにリアクションを付けてくれ、”Hello yourself.” と 返事をしてくれます.

カスタム絵文字でも、設定したカスタム絵文字の名前を : 無しで指定することで利用できます.

利用できる カスタム絵文字 の 一覧 を 取得する

ここまでは API 呼び出しはしたものの、OAuth で 取得した権限とトークンは必要ありませんでした. ここからが本題 “カスタム絵文字をランダムで選択してリアクションするボット” を 作ります.

ランダムで選択するということは、ランダムで選ぶための候補が必要となります. そのために、まずは 利用できるカスタム絵文字 の 一覧 を 取得したいと思います.

カスタム絵文字の一覧取得は emoji.list の Slack API に なります. リファレンス の Description に “Authentication token. Requires scope: emoji:read” と あるように、emoji:read の 権限が必要となります.

とりあえず実験で、先のリアクション・プログラムに以下を追加します. 特別な引数はないので空オブジェクトを渡し、第2引数 で API の 戻りを受けてコンソールへ出力しています.

1
2
3
4
bot.api.emoji.list({}, (err, response) => {
console.log(err);
console.log(response);
});

hello メンションをすると、以下のようなログが返ってくるかと思います. 権限がないと言われています.

1
2
3
4
5
6
info: ** API CALL: https://slack.com/api/emoji.list
missing_scope
{ ok: false,
error: 'missing_scope',
needed: 'emoji:read',
provided: 'identify,bot:basic' }

プログラムを修正し、bot.api.emoji.list() の 第1引数 の オブジェクト に token: process.env.access_token を 与えます. これまでは token を 与えていなかったので、Botkit が 内部的に、起動時の controller.spawn() で 渡されていた process.env.bot_access_token を 使ってくれていました. これはボット用のトークンなので、identify,bot:basic の 権限しかありません. 今回は、それに代わって token: process.env.bot_access_token と 明示的に利用するトークンを指定することで、OAuth で 与えられた権限を利用できるようにします.

1
2
3
4
5
6
bot.api.emoji.list({
token: process.env.access_token
}, (err, response) => {
console.log(err);
console.log(response);
});

起動しなおして、hello メンションすると、以下のように errnullresponse に 値が入ってきます.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
info: ** API CALL: https://slack.com/api/emoji.list
null
{ ok: true,
emoji:
{ bowtie: 'https://emoji.slack-edge.com/T13A2XXXX/bowtie/f3ec6f2bb0.png',
squirrel: 'https://emoji.slack-edge.com/T13A2XXXX/squirrel/465f40c0e0.png',
glitch_crab: 'https://emoji.slack-edge.com/T13A2XXXX/glitch_crab/db049f1f9c.png',
piggy: 'https://emoji.slack-edge.com/T13A2XXXX/piggy/b7762ee8cd.png',
cubimal_chick: 'https://emoji.slack-edge.com/T13A2XXXX/cubimal_chick/85961c43d7.png',
dusty_stick: 'https://emoji.slack-edge.com/T13A2XXXX/dusty_stick/6177a62312.png',
slack: 'https://emoji.slack-edge.com/T13A2XXXX/slack/5ee0c9bea3.png',
pride: 'https://emoji.slack-edge.com/T13A2XXXX/pride/56b1bd3388.png',
thumbsup_all: 'https://emoji.slack-edge.com/T13A2XXXX/thumbsup_all/50096a1020.gif',
slack_call: 'https://emoji.slack-edge.com/T13A2XXXX/slack_call/b81fffd6dd.png',
shipit: 'alias:squirrel',
white_square: 'alias:white_large_square',
black_square: 'alias:black_large_square',
simple_smile: 'https://a.slack-edge.com/0e8da/img/emoji_2016_06_08/apple/simple_smile.png',
bot_aloha_01: 'https://emoji.slack-edge.com/T13A2XXXX/bot_aloha_01/8ca07cf9170a82c1.png',
bot_aloha_02: 'https://emoji.slack-edge.com/T13A2XXXX/bot_aloha_02/cbed400e1d85041f.png',
bot_aloha_03: 'https://emoji.slack-edge.com/T13A2XXXX/bot_aloha_03/4f9440ce2931a3df.png',
bot_aloha_04: 'https://emoji.slack-edge.com/T13A2XXXX/bot_aloha_04/4c4ccb4999b129e0.png' },
cache_ts: '1497403802.153746' }

前半は Slack の サービス側が追加したカスタム絵文字のようです. 後半に自分で追加したものがありました.
(Slack の サービス側追加のカスタム絵文字は Customize Your Team の Emoji には無いのですが、なんだろう…)

今回は bot_aloha_01~04 までを、こちらの Shaka Hand Sign Vectors - Download Free Vector Art, Stock Graphics & Images 素材を利用させていただき、アロハの挨拶で使われる Shaka sign の カスタム絵文字を追加させていただきました. 素敵なアイコン素材 を ありがとうございます!
(この ジェスチャー? ハンド・サイン? も、”アロハ“ と 思ってましたが、Shaka sign って いうんですね. 知らなかった.)

カスタム絵文字 を ランダムで選び、リアクションする

カスタム絵文字の一覧が取れるようになったので、あとは使いたいカスタム絵文字のセットからランダムで取得するだけになります. API 呼び出しのコールバック関数を以下のように実装しました.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
bot.api.emoji.list({
token: process.env.access_token
}, (err, response) => {
let emojis = [];
for (let emoji in response.emoji) {
if (emoji.startsWith('bot_aloha_')) {
emojis.push(emoji)
}
}

bot.api.reactions.add({
name: emojis[Math.floor(Math.random() * emojis.length)],
channel: message.channel,
timestamp: message.ts
});
});

emoji.list API の 戻り response.emojifor-in で 回し、bot_aloha_ で 始まる カスタム絵文字を使う候補の配列に追加します.

候補配列ができたら、使うものをランダムで取得して bot.api.reactions.add() の 呼び出しに使います. リアクションはボットの権限で実行できるので、token は 渡しません.

emoji.list を キャッシュしておいたり、emoji.list を ハードコーディングしておくこともできますが、命名ルール(今回は bot_aloha_ で 始まる) に応じて動くようにしておくことで、命名ルールに則ってカスタム絵文字を追加するだけで拡張できるので、毎回 emoji.list を 呼び出すようにしました.

プログラム最終系

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const Botkit = require('botkit');

const controller = Botkit.slackbot();

controller.spawn({
token: process.env.bot_access_token
}).startRTM();

controller.hears('hello', [ 'direct_message', 'direct_mention', 'mention' ], (bot, message) => {
bot.reply(message, 'Hello yourself.');

bot.api.emoji.list({
token: process.env.access_token
}, (err, response) => {
let emojis = [];
for (let emoji in response.emoji) {
if (emoji.startsWith('bot_aloha_')) {
emojis.push(emoji)
}
}

bot.api.reactions.add({
name: emojis[Math.floor(Math.random() * emojis.length)],
channel: message.channel,
timestamp: message.ts
});
});
});


OAuth で 取得した権限を実際に使ってみました.
Botkit の API 呼び出し bot.api.[SLACK_API_NAME]() の 第1引数のオブジェクトに token: process.env.access_token を 追加するだけで利用できるので簡単ですね. 権限が不要な場合は token: を つけなくてよいのも簡単で助かります. 多くの場合 token: 無しで使ってたりするので、必要な時にうっかり付け忘れて missing_scope で 怒られるというケースもありますが…
とはいえ、Slack API が 使いやすくなっていることと、Botkit が 便利にしてくれているおかげで、簡単に利用することができました!ありがたいです.