RoBoHoNからSlackに投稿してみました

RoBoHoNの開発メモです。
今回Slackに投稿する機能を作ってみました。
RoBoHoNとお出かけの際にお役に立てれば幸いです。

#はじめに
SlackのWebAPIを使用します。Slackのチーム登録、tokenの取得方法等は省略します。

#参考
こちらの記事を参考にさせていただきました。
[OkHttp調べてみた](http://qiita.com/hymmr/items/5d87277b44892e7b690b)
[OkHttp 2.0 を使ってみた](http://qiita.com/ryugoo/items/478ba23cda0f57bd21e8)
[Android から Slack にメッセージ送信](http://haraki.jp/blog/blog.cgi?id=155)

#環境です
使用した環境です。
MacOS Sierria 10.12.1
AndroidStudio 2.1.2
RoBoHoN SDK 1.0.1
~~（なぜかAndroidStudio2.2.2+SDK1.0.2はプラグインから作成したアプリがうまく動きませんでした）~~
(追記 2017/4/7)
AndroidStudio 2.3 + RoBoHoN SDK 1.1.0 で問題なく動きます。

#OkHttp使いました
SlackのWebAPIとの通信は、OkHttpを使用しました。バージョンは、3.4.2です。
http://square.github.io/okhttp/
okhttpのサイトをよく読まなかったので（[ちゃんと書いてある](http://square.github.io/okhttp/#download)）ハマったのですが、[Okio](https://github.com/square/okio)も必要です。

```:gradle(app)
dependencies {
　　　　　　　　　：
    compile 'com.squareup.okhttp3:okhttp:3.4.2'
    compile 'com.squareup.okio:okio:1.11.0'
}
```

(追記 2017/4/7 現在のバージョンです)

```:gradle(app)
dependencies {
　　　　　　　　：
    compile 'com.squareup.okhttp3:okhttp:3.6.0'
    compile 'com.squareup.okio:okio:1.11.0'
}
```

#おまじない
```:AndroidManifast.xml
<uses-permission android:name="android.permission.INTERNET"/>
```

#サンプルその１
doInBackground()でSlackのWebAPIをpostし、onPostExecute()で結果のJSONを解析します。
OKとNGでそれぞれ別々のaccostを呼び出して、RoBoHoNから発話します。

```java:AsyncSlack.java
package jp.co.robohon.sample;

import android.os.AsyncTask;
import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;

import jp.co.sharp.android.voiceui.VoiceUIManager;
import jp.co.robohon.sample.customize.ScenarioDefinitions;
import jp.co.robohon.sample.util.VoiceUIManagerUtil;
import jp.co.robohon.sample.util.VoiceUIVariableUtil;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * Slackへの投稿
 */
public class AsyncSlack extends AsyncTask<String, Void, String > {

    public static final String TAG = AsyncSlack.class.getSimpleName();

    /**
     * Slack WebAPI Token
     */
    private static final String SLACK_TOKEN = "＊ここにトークンを書いてね＊";
    /**
     * Slack URL
     */
    private static final String SLACK_URL = "https://slack.com/api/chat.postMessage";
    /**
     * 音声UI制御.
     */
    private VoiceUIManager mainVoiceUIManager = null;

    /**
     * コンストラクタ
     */
    public AsyncSlack(VoiceUIManager mVoiceUIManager) {
        super();
        mainVoiceUIManager = mVoiceUIManager;
    }

    /**
     * 同一スレッドではエラーになるため、バックグランドでSlackに投稿する
     */
    @Override
    protected String doInBackground(String... params) {
        Log.v(TAG, "doInBackground()");

        String message = params[0];     // Message
        String username = params[1];    // Bot name
        String channel = param[2];      // channel

        String result = "";

        FormBody.Builder formBodyBuilder = new FormBody.Builder()
            .add("token", SLACK_TOKEN)  // Token
            .add("channel",channel)     // channel
            .add("text", message)       // Message
            .add("username", username); // Bot name

        RequestBody requestBody = formBodyBuilder.build();

        Request request = new Request.Builder()
                .url(SLACK_URL)
                .post(requestBody)
                .build();

        OkHttpClient client = new OkHttpClient();

        try{
            Response response = client.newCall(request).execute();
            result = response.body().string();
        } catch (IOException ex){
            Log.e(TAG, "OkHttpClient ["+ex.getMessage()+"]");
        }

        return result;
    }

    /**
     * 実行後の結果解析.ロボホン発話.
     */
    @Override
    protected void onPostExecute(String result) {
        Log.v(TAG, "onPostExecute()");

        boolean isOk = false;

        try {
            if (result.length() > 0) {
                JSONObject json = new JSONObject(result);
                String tagOk = json.getString("ok");
                if (tagOk.equals("true")){
                    isOk = true;
                }else{
                    Log.e(TAG, "SlackResultError:" + result);
                }
            }
        } catch (JSONException ex){
            Log.e(TAG, "Failed JSONObject[" + ex.getMessage() + "]");
        }

        // ロボホン発話
        if (isOk){
            if (mainVoiceUIManager != null) {
                VoiceUIVariableUtil.VoiceUIVariableListHelper helper = new VoiceUIVariableUtil.VoiceUIVariableListHelper().addAccost(ScenarioDefinitions.ACC_SLACK_SUCCESS);
                VoiceUIManagerUtil.updateAppInfo(mainVoiceUIManager, helper.getVariableList(), true);
            }
        }else{
            if (mainVoiceUIManager != null) {
                VoiceUIVariableUtil.VoiceUIVariableListHelper helper = new VoiceUIVariableUtil.VoiceUIVariableListHelper().addAccost(ScenarioDefinitions.ACC_SLACK_ERROR);
                VoiceUIManagerUtil.updateAppInfo(mainVoiceUIManager, helper.getVariableList(), true);
            }
        }

    }
}
```

#サンプルその２
RoBoHoNのシナリオ側で聞き取りを行い、コマンドに聞き取ったメッセージをデータとして渡して、そのままSlackに投稿します。（シナリオは省略します）

```java:MainActivity.java
    /**
     * VoiceUIListenerクラスからのコールバックを実装する.
     */
    @Override
    public void onExecCommand(String command, List<VoiceUIVariable> variables) {
        Log.v(TAG, "onExecCommand() : " + command);
        switch (command) {
            case ScenarioDefinitions.FUNC_END_APP:
                finish();
                break;
            case ScenarioDefinitions.FUNC_POST_SLACK:
                //シナリオデータの取得
                final String m_message = VoiceUIVariableUtil.getVariableData(variables, ScenarioDefinitions.KEY_M_MESSAGE);
                // Slackに投稿を行う
                AsyncSlack task = new AsyncSlack(mVoiceUIManager);
                String params[] = {m_message, mOwnerName, "testchannel"};
                task.execute(params);
                break;
            :
```