JPでmastodon.elを使う

<!---


--->

mastodon.elまEmacs用のマストドンクライアントです。私が使っているEmacsクライアントは自作ですが、こちらは他の方が作成されたもので、Melpaからインストールもできます。(mstdn.jpは現在v2.1.0のようです)

https://github.com/jdenen/mastodon.el

package-install などでインストールできるパッケージはこちらになります。


```
M-x mastodon
```


## インストール

package-installを使ってインストールします。

```
M-x package-install RET mastodon RET
```

他のインストール方法も[README.org](https://github.com/jdenen/mastodon.el/blob/master/README.org)に説明されています。

## インスタンスの選択

`mastodon-instance-url` でインスタンスのURLを設定します。

```
(setq mastodon-instance-url "https://mstdn.jp")
```

通常だとEmailとパスワードを入力すると認証とtoken発行をやりますが、現状発行できない状態になっていたのでtokenを手動で設定してしまいます。

```
(setq mastodon-auth--token "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx")
```

## 起動

```
M-x mastodon
```

![timeline.png](https://qiita-image-store.s3.amazonaws.com/0/36261/19156031-8b76-5ae7-0004-2ca6ec70a7ab.png)


## tootする

tootするときはTL上でnを押すとトゥート編集バッファに移動します。

![toot-buffer.png](https://qiita-image-store.s3.amazonaws.com/0/36261/1e6c5c52-fb66-03c1-5ec5-4e01543c4804.png)

トゥートを編集してC-c C-cでトゥートします。


## Fav

使ってみたらJPではファボとBTができなくなっていました。多分クライアントが新しいAPIに対応していないようです。
原因はここです。

```
(defun mastodon-toot--action (action callback)
  "Take ACTION on toot at point, then execute CALLBACK."
  (let* ((id (mastodon-tl--property 'toot-id))
         (url (mastodon-http--api (concat "statuses/"
                                         (number-to-string id)
                                         "/"
                                         action))))
    (let ((response (mastodon-http--post url nil nil)))
      (mastodon-http--triage response callback))))
```

`(number-to-string id)` のidがすでにstringになっているのでnumber-to-stringでエラーしてしまいますのでそのまま使うように変更します。


```
(defun mastodon-toot--action (action callback)
  "Take ACTION on toot at point, then execute CALLBACK."
  (message action)
  (let* ((id (mastodon-tl--property 'toot-id))
         (url (mastodon-http--api (concat "statuses/"
                                         id
                                         "/"
                                         action))))
    (let ((response (mastodon-http--post url nil nil)))
      (mastodon-http--triage response callback))))
```

## BT

BTもできなくなっていました。原因はboostedの判定が正しく行えていないことです。

```
(defun mastodon-toot--toggle-boost ()
  "Boost/unboost toot at `point'."
  (interactive)
  (let* ((id (mastodon-tl--property 'toot-id))
         (boosted (get-text-property (point) 'boosted-p))
         (action (if boosted "unreblog" "reblog"))
         (msg (if boosted "unboosted" "boosted"))
         (remove (when boosted t)))
    (mastodon-toot--action action
                           (lambda ()
                             (mastodon-toot--action-success "B" remove)
                             (message (format "%s #%d" msg id))))))
```

`(boosted (get-text-property (point) 'boosted-p))` でboosted-pのtext属性を取得していますがここが正しく取れていませんでした。


```
(defun mastodon-tl--byline (toot)
  "Generate byline for TOOT."
  (let ((id (cdr (assoc 'id toot)))
        (timestamp (mastodon-tl--field 'created_at toot))
        (faved (mastodon-tl--field 'favourited toot))
        (boosted (mastodon-tl--field 'reblogged toot)))
    (propertize
     (concat (propertize "\n | " 'face 'default)
             (when boosted
               (format "(%s) "
                       (propertize "B" 'face 'mastodon-boost-fave-face)))
             (when faved
               (format "(%s) "
                       (propertize "F" 'face 'mastodon-boost-fave-face)))
             (mastodon-tl--byline-author toot)
             (mastodon-tl--byline-boosted toot)
             " "
             (format-time-string mastodon-toot-timestamp-format (date-to-time timestamp))
             (propertize "\n  ------------" 'face 'default))
     'favourited-p faved
     'boosted-p    boosted
     'toot-id      id
     'toot-json    toot)))
```

## リプライ

リプライも手をいれないといけないようになってました。

```
(defun mastodon-toot--reply ()
  "Reply to toot at `point'."
  (interactive)
  (let* ((toot (mastodon-tl--property 'toot-json))
         (id (number-to-string (mastodon-tl--field 'id toot)))
         (account (mastodon-tl--field 'account toot))
         (user (cdr (assoc 'username account))))
    (mastodon-toot user id)))
```

これもnumber-to-stringを修正する必要がありました。

```
(defun mastodon-toot--reply ()
  "Reply to toot at `point'."
  (interactive)
  (let* ((toot (mastodon-tl--property 'toot-json))
         (id (mastodon-tl--field 'id toot))
         (account (mastodon-tl--field 'account toot))
         (user (cdr (assoc 'username account))))
    (mastodon-toot user id)))
```

これをevalするとJP向きにもリプライできます。


## その他

| キーバインド| 用途|
|:-:|:-:|
| ? | メニュー  |
| b | ブースト |
| f | ファボ |
| F | FTL表示 |
| H | HTL表示 |
| j | 下のトゥートに移動 |
| k | 上のトゥートに移動 |
| L | LTL表示 |
| n | トゥート編集バッファに移動 |
| q | 終了 |
| Q | マストドンバッファを閉じてウィンドウをkill |
| r | リプライ |
| t | スレッドを開く |
| T | Prompt for tag and open its timeline |

全部ためしてみようかなあと思ったのですが、わりとちゃんと動かないところがあったのでちょっとやりきれなかったです。
先々月あたりにAPIの仕様変更があったのでその影響で動作しなくなっているものと思われます。