Hello Slack. Incoming Webhook スニペット集

アドホックにSlackへのメッセージ送信を行うとき、毎回調べてるのでよく使う言語のスニペットをメモ(要はPOSTリクエスト集)。

* 原則的に組み込みモジュールのみ利用
* メッセージの構造体を受け取り、Incoming Webhookに送信する関数`slack`を定義
* Webhook呼び出しは`application/json`でも`application/x-www-form-urlencoded`(payload=JSON)でも可
* 関数の戻り値はIncoming Webhookのレスポンスボディ(通常`ok`)
* その戻り値を標準出力する呼び出しサンプル

よかったら他の言語のもコメントに追記ください。


# Ruby

```ruby:hello-slack.sh
require 'json'
require 'uri'
require 'net/http'

def slack(payload)
  webhook_url = 'https://hooks.slack.com/services/~~~~~/~~~~~/~~~~~~~~~~~'
  res = Net::HTTP.post_form(URI.parse(webhook_url), payload: JSON.dump(payload))
  res.body
end

puts slack(
  username: "hello-slack.rb",
  channel: "the-chennal",
  text: "hello by ruby",
)
```

# シェルスクリプト

規約違反ですが関数の引数はJSON文字列で。

```bash:hello-slack.sh
slack() {
  WEBHOOK_URL="https://hooks.slack.com/services/~~~~~/~~~~~/~~~~~~~~~~~"

  curl -s -X POST \
    -H 'Content-Type: application/json' \
    -d "$1" \
    "$WEBHOOK_URL"
}

echo $(slack '{"username":"hello-slack.sh","channel":"the-channel","text":"hello by sh"}')
```

# JavaScript

## NodeJS

意外と記述量が多い。

```javascript:hello-slack-node.js
const https = require('https')

async function slack(payload) {
  const webhookUrl = 'https://hooks.slack.com/services/~~~~~/~~~~~/~~~~~~~~~~~'

  return new Promise((resolve, reject) => {
    const options = {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      }
    }

    https.request(webhookUrl, options, res => {
      res.on('data', res => resolve(res.toString()))
    })
      .on('error', reject)
      .end(JSON.stringify(payload))
  })
}

slack({
  username: 'hello-slack.js',
  channel: 'the-channel',
  text: 'hello by nodejs'
}).then(console.log)
```

ライブラリを使うと楽。

```javascript:hello-slack-axios.js
const axios = require('axios')

async function slack(payload) {
  const webhookUrl = 'https://hooks.slack.com/services/~~~~~/~~~~~/~~~~~~~~~~~'
  const res = await axios.post(webhookUrl, JSON.stringify(payload))
  return res.data
}

slack({
  username: 'hello-slack-axios.js',
  channel: 'the-channel',
  text: 'hello by js with axios'
}).then(console.log)
```

## GAS

```javascript:hello-slack.gs
function slack(payload) {
  var webhookUrl = "https://hooks.slack.com/services/~~~~~/~~~~~/~~~~~~~~~~~"

  var options = {
    method: "post",
    contentType: "application/json",
    payload: JSON.stringify(payload),
    muteHttpExceptions: true
  }

  var res = UrlFetchApp.fetch(webhookUrl, options)
  return res.getContentText()
}

function test() {
  slack({
    username: "hello-slack.gs",
    channel: 'the-channel',
    text: 'hello by gas'
  })
}
```

# PHP

`curl`を使う方法と`file_get_contents`を使う方法あり。

## curl

```php:hello-slack-curl.php
<?php

function slack($payload) {
  $webhook_url = 'https://hooks.slack.com/services/~~~~~/~~~~~/~~~~~~~~~~~';

  $ch = curl_init($webhook_url);
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
  $res = curl_exec($ch);
  curl_close($ch);

  return $res;
}

echo slack(array(
  'username' => 'hello-slack-php.php',
  'channel' => 'the-channel',
  'text' => 'hello by php with curl'
));
```

## file_get_contents

```php:hello-slack-file_get_contents.php
<?php

function slack($payload) {
  $webhook_url = 'https://hooks.slack.com/services/~~~~~/~~~~~/~~~~~~~~~~~';

  $stream_opts = array(
    'http' => array(
      'method' => 'POST',
      'header' => "Content-Type: application/json",
      'content' => json_encode($payload),
    )
  );

  return file_get_contents($webhook_url, false, stream_context_create($stream_opts));
}

echo slack(array(
  'username' => 'hello-slack-file_get_contents.php',
  'channel' => 'the-channel',
  'text' => 'hello by php with file_get_contents'
));
```

# Python

あまり得意ではないですがこんな感じ？

```python:hello-slack.py
import json
import urllib.request

def slack(payload):
  webhook_url = "https://hooks.slack.com/services/~~~~~/~~~~~/~~~~~~~~~~~"

  post_data = "payload=" + json.dumps(payload)

  request = urllib.request.Request(webhook_url, method="POST", data=post_data.encode())
  with urllib.request.urlopen(request) as response:
    return response.read().decode()

print(slack({
  "username": "hello-slack.py",
  "channel": "the-channel",
  "text": "hello by python",
}))
```