markdown で書いたテキストを Medium に投稿する を iPad だけで完結させた話

Medium に投稿した記事の流用です。
なぜこんな事をしでかしたのかは[こちら](https://t.co/5KrJXRhk1i)をご覧ください。

少しステップがいりますがタイトル通り iPad ですべて完結させるやり方です。
Github に上げています。

[Github - post-md-medium](https://github.com/tick-taku/post-md-medium)

以下、解説と使い方です。


## 使用環境


- iPad Air 第4世代
- iPadOS 14.5
- Python 3.9 (後述の a-shell のデフォルトがそうでした)


## 事前準備


Medium の Integration を使う事前準備をします。


### Integration token


まず Medium の Settings から integration token を発行します。
description には任意ですが何に使うトークンかわかる説明を入れて Get を押すと下にトークンが発光されます。
トークンの画面は Web 版にしか現れない様なので注意です。

![integration_token](http://drive.google.com/uc?export=view&id=15-YpJO7R7V-jRqpCUZilwG1decwNhUbL)


このトークンは後で使用するのでコピーしておきましょう。


### Download apps


次に使用するアプリをダウンロードします。

[a-shell](https://holzschu.github.io/a-Shell_iOS/) と [Working Copy](https://workingcopyapp.com/) を使いますのでダウンロードしてください。（App Store で検索しても出てきます。）

a-shell は iPad で使えるターミナルです。後で触れますが Python が触れる環境が整っています。普通に Python のプログラミングの勉強に持ってこいなめちゃつよアプリです。

Working Copy は iPad の Git クライアントアプリです。push が有料ですが、pull は無料でできます。とても使いやすいめちゃつよアプリです。

ちなみに自分はマークダウンエディタは [Joplin](https://joplinapp.org/) を使っています。（今まで Boostnote を使っていたのですが、方向性の不一致から最近乗り換えようとしています😭）
なので本ツールは Joplin がはきだすテキストファイルの形式に合わせて作成しているので、もしこだわりのエディタが無ければ合わせてダウンロードしておくと少しだけ幸せになれるかもしれません。



## How to use


### Git clone


それでは本題に入っていきます。一応使い方を Github の README に書いてあるので、わかる方はここからはそっちを見ていただいても大丈夫だと思います。

まず a-shell を起動して `mkdir medium` としてディレクトリを作成してください。名前はなんでも大丈夫です。

次に Working Copy を立ち上げ以下のリポジトリを clone してください。Repository とある横の + を押すとリポジトリが追加できます。URL を以下の様にして DONE するとクローンされます。
ssh キーは Github のアカウントにログインすると自動で登録してくれているので SSH に切り替えて URL 指定するといけます。

[Github - post-md-medium](https://github.com/tick-taku/post-md-medium)

![git clone](http://drive.google.com/uc?export=view&id=1777nKKJEgRezSM71hppid_Do78hq8Vkr)

もしできそうになければ普通に zip をダウンロードしてきても大丈夫です。


クローンできたら右上のシェアから Setup folder sync を選択してください。リポジトリと同期するディレクトリを選ぶ事になるので、先ほど作成したディレクトリが a-shell の下にあるので選択して DONE です。
同期しなくても Save to file するだけでも問題はありません。

![folder sync](http://drive.google.com/uc?export=view&id=1T8IufgAqpt9vyB1pOhOqnPnOGBqkD0vg)

最終的に a-shell に戻って `cd medium` して `ls` した時に以下の様になっていると成功です。

![sync success](http://drive.google.com/uc?export=view&id=1e08HeKcO4K7sOhb1V9sSvGiXIjCIbqav)


### Setup


↑の状態から

```
python etc/init.py
```

を実行してください。Integration token を入力させられますので一番最初に準備したトークンをコピペして Enter 。トークンデータが入ったファイルが作成されます。

ここまででセットアップは完了です。


### Post

だいたいのエディタにはテキストファイルのエクスポート機能が付いているはずなので、右上のシェアから Save to file で ↑ で準備したディレクトリにエクスポートしましょう。

エクスポートした時にタグの設定がどこにもなかったので、もしタグも合わせてポストしたい場合は本文の先頭に `#Medium` みたいに入力してみてください。

テキストファイルが用意できたら

```
python post_medium.py
```

を実行してください。ポストするファイルの名前を入力させられるので用意したファイル名を入力してください。

ここで draft か public か選択できます。デフォルトで draft 	にしているので何も入力しなければ draft になります。public と入力すれば直で公開されます。
posted nantara~~ 	みたいに表示されれば完了です。

お疲れ様でした！これで iPad からマークダウンで書いたテキストをそのまま Medium に投稿できる様になりました！
オシャなカフェでドヤり放題です👏


## 実装について


init も全て Python にしているのは、一応 PC からでも使える様に init.sh を置いていますが、これが a-shell で実行できなかったからです。
ここが一番試行錯誤しました。subprocess で無理やり run しても一度にやりすぎみたいな感じでターミナルに怒られてクラッシュする始末...😇

最終的に Python なら実行できたので妥協しました。ちなみに PC なら pipenv で実行できる様になっています。たぶん。

コンテンツタイプのお話ですが、最初は HTML ならみたいな話を見かけたので markdown を HTML にコンバートしてから投げるつもりでしたが、 [Medium API のドキュメント](https://github.com/Medium/medium-api-docs#readme) によると markdown が指定できるので最強かよ...となった次第です。
まぁ独自スタイルにコンバートされるので思ったレイアウトではないですが...

タグの扱いだけまだ悩んでいます。使っていくうちにアップデートしていくかもしれません。

とりあえず動く、を優先したので今後色々整備していくかもしれません。

少しだけ API の解説を。

まず Integration token から json のポストに必要な User ID の取得です。

```
user_id_res = requests.get('https://api.medium.com/v1/me', headers={ 'Authorization': f'Bearer {integration_token}' })
user_id = user_id_res.json()['data']['id']
```

このユーザ ID がリクエスト URL に必要です。
実際のリクエストは以下。contentFormat に本文のフォーマットが指定できます。今回はマークダウンですが、HTML も指定できます。

```
post_url = f'https://api.medium.com/v1/users/{user_id}/posts'

headers = {
  'Authorization': f'Bearer {integration_token}',
  'Content-Type': 'application/json'
}

json = {
  "title": title,
  "contentFormat": 'markdown',
  "content": content,
  "tags": tags,
  "publishStatus": publish_status
}

requests.post(post_url, headers=headers, json=json)
```

レスポンスで投稿した記事の URL なんかも取れるのでハンドリングするといいかもしれませんね。


## Conclusion


普通にはてブとかにしとけばよかったんじゃ？？🤔


僕の GW はこれに費やされました。。。つらみ。。。
誰がこんなニッチな事やりたがるんや。。。

こだわりが強いのも考えものですね...


でも上手くいった時の達成感はクルものがあるので楽しくやれました。
普段仕事で Python 触らないのでこうやってたまに何か書くと楽しいです🤗

やっぱり Integration が用意されてるサービスは僕みたいな人にはいいですね！用途に合わせて自動化したり便利に使えるので。

ただまぁ、Note が公式でサポートされたらそっちに移行するかもしれません。


少し長くなってしまいましたが同じ悩みを持つ人がいれば（いるのか...?）手助けになれば幸いです。
もし上手くいかないとかよく分からないとなればサポートしますのでコメントください。


それではみなさん、よい iPad ライフを✋


## 参考

https://matsubara0507.github.io/posts/2018-11-04-create-mdium.html

https://github.com/icyphox/mdium