Slackにファイルをアップロードする

# はじめに
とある理由(いずれ記事を書きます)で、Slack にファイルをアップロードしようと思ったのですが、アップロードに関しては意外とやっている方が少なく苦労しました。
なんとか、画像をアップロードすることが出来たので、やり方をまとめておきます。

Web HookやCommandなら、以前に「[SlackクローンのMattermostのWindows版を動かす](https://qiita.com/yaju/items/de94de6d8d8476d47454)」という記事で簡単なものを作成したことがあります。
この時、Slackに自分だけのチーム「YajuAlone」を作成しました。

# アプリ作成
ファイルのアップロードをするには`file.upload API`を使用するため、Slack Appを作成する必要があります。
参照：[Slack API 推奨Tokenについて](https://qiita.com/ykhirao/items/3b19ee6a1458cfb4ba21)

ここにアクセスします。
https://api.slack.com/apps

1. `Create New App` をクリックします。
2. `App Name` でアプリケーション名を入力します。
3. `Development Slack Workspace` でワークスペースを選択します。
4. `Create App` をクリックします。

![2019-06-30_10h53_45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/e3efe312-a816-2426-d3ed-abd88424dfe7.png)

## スコープ設定
`Permissions`ボタンをクリックします。
![2019-06-30_10h58_21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/6685305e-3422-1edb-ae4b-8353d46539fe.png)

スコープ (Scopes) にはファイル書き込みのため `files:write:user` が必要です。
一覧から`files:write:user`を選択します。
![2019-06-30_11h05_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/48402073-f850-408b-25ab-db5b30b55970.png)

またメッセージ投稿のため `chat:write:user` も付与しておきます。
一覧から`chat:write:user`を選択します。
![2019-06-30_11h06_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/9c335002-b78f-fdcd-720a-6ea1a8ac5778.png)

`Save Changes`ボタンをクリックして保存します。
![2019-06-30_11h11_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/31997b64-a444-4089-0b24-952441ecb402.png)

## Slackにアプリをインストール
`Install App to Workspace`ボタンをクリックします。
![2019-06-30_11h22_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/e07d7156-105e-2a6b-0f6e-b9d53ad29d68.png)

内容を確認したら、インストールボタンをクリックします。
![2019-06-30_11h31_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/067003ce-a2a4-f601-c2ee-8aa012f26341.png)

## Tokenをコピー
トークンが表示されるので、`Copy`ボタンでクリップボードにコピーします。
このトークンを後で使用します。
![2019-06-30_11h38_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/34bbc717-15bb-a4c8-8466-84361cfbf9ca.png)

# アプリ動作確認
"Hello"がSlackに表示されるか、httpを直接叩いてみます。

下記コードの`xoxp-xxx-xx-xx-xxxx`の部分を、コピーしたトークンに書き換えてください。

```
https://slack.com/api/chat.postMessage?token=xoxp-xxx-xx-xx-xxxx&channel=general&text=%22Hello%22
```

## 実行結果
```
{"ok":true,"channel":"C4WVA6B5Z","ts":"1561862556.001000","message":{"bot_id":"BKP0Q999Q","type":"message","text":"\"Hello\"","user":"U4XMXT42J","ts":"1561862556.001000","team":"T4XMXT3SA"}}
```

![SlackAppResult.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/10a247f8-6a8f-e9b8-1d04-7b128f80be3f.png)

# ファイルアップロード動作確認

```php:upload.php
<?php
$slacktoken = "xoxp-xxx-xx-xx-xxxx";
$channelId = 'general';

$header = array();
$header[] = 'Content-Type: multipart/form-data';
$file = new CurlFile(dirname(__FILE__)."/logo3D.jpg", 'image/jpg');

$postitems =  array(
    'token' => $slacktoken,
    'channels' => $channelId,
    'file' =>  $file,
    'text' => "コミットしました",
    'title' => "コミットしました",
    'filename' => "logo3D.jpg"
);
    
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_FAILONERROR, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_URL, "https://slack.com/api/files.upload");
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS,$postitems);

$body = curl_exec($curl);
$errno = curl_errno($curl);
$error = curl_error($curl);
curl_close($curl);

echo $body;
echo $errno;
echo $error;
```

## 参照
* [PHP で Slack のチャンネルにファイルをアップロードする](https://mseeeen.msen.jp/upload-files-to-slack-channel-by-php/)
* [commitしたら写真を撮られてSlackにアップされるスクリプトを作った](http://c5meru.hatenablog.jp/entry/2017/06/02/223104)
* [PHPの最後の終了タグ ?> は付けないでおこうねというお話](https://thesaibase.com/php/end-tag)
* [Slack APIでファイルをアップロードする方法](https://www.utali.io/entry/2016/10/07/172806)
* [file file types](https://api.slack.com/types/file#file_types)

## 実行結果
![SlackAppResult2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/da00ff6a-d2df-d16f-fba0-a3b66930346c.png)

## 嵌ったこと
最初、実行しても画像が表示されなかったんですよね。PHPは滅多に触らないのでエラー情報を出す方法も分かってなくて原因が分からず、次の休日になるまで放置してました。

files.uploadのExampleにて、Curlコマンドを実行すると画像が表示されました。
https://api.slack.com/methods/files.upload

```
curl -F file=@logo3D.jpg -F "initial_comment=logo" -F channels=general -H "Authorization: Bearer xoxp-xxx-xx-xx-xxxx" https://slack.com/api/files.upload
```

PHP側で問題がありそうです。
PHPのエラーを出せるように修正したら、下記のエラーが出ていました。

```
60: SSL certificate problem: unable to get local issuer certificate
```
* [‘cURL error 60’エラーが出たときの対処法 ‘cURL error 60: SSL certificate problem: unable to get local issuer certificate’](http://nanoappli.com/blog/archives/7992)
* [Windows で PHP の curl が証明書のエラーを出したら](https://michinobu.jp/tec/dialy/phpcurlcertificateproblem)

https://curl.haxx.se/ca/cacert.pem から curl 用の証明書をダウンロードして、`C:\xampp\php\extras\ssl` フォルダに置きました。
そして、php.ini で修正して、Apacheを再起動します。

```ini:php.ini
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo = C:\xampp\php\extras\ssl\cacert.pem
```

# 最後に
Slackにファイルをアップロードする記事を書いてみたものの、自分がやろうとしていることでは使わないかも知れません。なので、今度のためですね。

スクリーンキャプチャにはフランスの会社Learnpulse SASが開発、提供するデスクトップ画面を画像、動画として保存する支援ツール「[Screenpresso](https://www.screenpresso.com/ja/)」を使用しています。見た目が綺麗に編集できるのが気に入ってます。