PythonでSlackに気圧情報(BeautifulSoupで取得)をグラフ付きで送りたい(＋Google Spread Sheetで管理したい)2

## 第一話

[PythonでSlackに気圧情報(BeautifulSoupで取得)をグラフ付きで送りたい(＋Google Spread Sheetで管理したい)](https://qiita.com/hungrykirby/items/a4b945ed5770aea223c0)

## 今回やること

- [直近の気圧を取得](https://qiita.com/hungrykirby/items/a4b945ed5770aea223c0)
- Slackに通知 <= この記事
- Google Spread Sheetに保存

## 気圧をSlackに送信する

`Slack API` の導入の記事はたくさんあるので割愛しますが、なんかけっこうUIが変わっていてしばらくはまったので、メモしておきます。くだらないのでQiitaの記事にはしていません…。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Slack Api、botをワークスペースに参加させてなくて、2時間くらい溶かした</p>&mdash; キャリーラーメン (@hungrykirby) <a href="https://twitter.com/hungrykirby/status/1220988392126599169?ref_src=twsrc%5Etfw">January 25, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

あと投稿に失敗してもいい感じにエラーが出ずになんか苦戦した。

---
```py
import os
import requests
from os.path import join, dirname
from dotenv import load_dotenv

load_dotenv(verbose=True)
dotenv_path = join(dirname(__file__), '.env')
load_dotenv(dotenv_path)

class SlackItem:
  token = None
  channel = None
  SLACK_API_BASE = "https://slack.com/api/"
  rootdir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))

  def __init__(self, channel = 'imgs'):
    self.token = os.environ.get("TOKEN")
    self.channel = channel

  def post_with_img(self, file_name, file_title, initial_comment):
    token = self.token
    channel = self.channel
    url = self.SLACK_API_BASE + "files.upload"
    data = {
      'token': token,
      'channels': '#' + channel,
      'title': file_title,
      'initial_comment': initial_comment
    }
    img_file = {'file': open(join(self.rootdir, 'imgs', file_name), 'rb')}
    if token:
      requests.post(url, data=data, files=img_file)
  
  def post_text(self, text):
    url = self.SLACK_API_BASE + 'chat.postMessage'
    token = self.token

    post_json = {
      'token': token,
      'text': text,
      'channel': '#' + self.channel,
      'link_names': 1
    }
    if token:
      requests.post(url, data = post_json)
```

雰囲気でコードを書いています。
単純に `requests` で投げているだけです。

特別なモジュールは今回使用しませんでした。

---
```py
from dotenv import load_dotenv

load_dotenv(verbose=True)
dotenv_path = join(dirname(__file__), '.env')
load_dotenv(dotenv_path)
```

[python-dotenvを使って環境変数を設定する](https://qiita.com/harukikaneko/items/b004048f8d1eca44cba9)

環境変数は `.env` ファイルにまとめましょう。また儀礼として `.env.sample` というファイルを作るのがしきたりのようです。

`.env` は絶対に `git push` など世界に公開しちゃだめです・ 

```envファイルの中身.env
TOKEN=Slackのkey
SPREADSHEET_KEY=Google Spread SheetのKey(本番用)
JSON_FILE_NAME=Google Spread Sheetを読み書きする用のJSONファイル
SPREADSHEET_KEY_DEV=Google Spread SheetのKey(テスト用)
```

`.env.sample` は公開してもいいです。どういうKeyが必要なのか知るためにもこれは出しておいた方がいいです。

```env.sampleファイルの中身.env.sample
TOKEN=
SPREADSHEET_KEY=
JSON_FILE_NAME=
SPREADSHEET_KEY_DEV=
```

windowsで `echo` みたいなことやるとなぜかエラーで臨む挙動をしませんでした。

参考に書いておくと `pip freeze` と `echo` の `cmd` ( `PowerShell` )からファイルに書き込みする系はなぜか落ちました。
原因も対処もわかっていませんが `PowwerShell` なら

```shell
$ ni .env
```

でファイルを作成できます。 `NewItem` の略らしいです。MacやLinuxの `touch` より名前的には直感的な気がします。

---
```py
  def __init__(self, channel = 'imgs'):
    self.token = os.environ.get("TOKEN")
    self.channel = channel
```
デフォルトで `imgs` というチャンネルに投稿するようにしています。


```py
    post_json = {
      'token': token,
      'text': text,
      'channel': '#' + self.channel,
      'link_names': 1
    }
```
`channel` の引数は割と直感的に取れます。
個人でやる分にはこれで十分ですが、だれかが `channel` の名前を変更すると動かなくなるため、本来はチャンネルの `ID` を指定する必要があります。

[Slack — APIに使う「チャンネルID」を取得する方法](https://qiita.com/YumaInaura/items/0c4f4adb33eb21032c08)

`link_names` がどういう意味合いを持っているのかわかっていませんが、今回はあまり気にしないことにします。

---

`https://slack.com/api/files.upload`
で画像投稿

`https://slack.com/api/chat.postMessage`
でテキスト投稿ができます。

```py
data = {...} # チャンネル情報やらテキストやら
img_file = {'file': open(join(self.rootdir, 'imgs', file_name), 'rb')}
requests.post(url, data = data, files = img_file)
```

ちょっと混乱を招く表記で申し訳ないのですが、 `imgs` というディレクトリ直下の画像をアップロードの対象としています。

## 動かす

とりあえず、この `Class` を呼べば、適当に投稿できます。

## 続き

第三話