TL;DR
-
オレ プログラム ウゴカス オマエ ゲンシジン ナル - Qiita
- アリガト トモダチ
* ぼくも原始人くんとなかよくなりたいになったアリガト トモダチ https://t.co/58aOE2P9g4
— 70_10 (@70_10) 2019年2月15日
まずはcliで作った
- そもそもmasotodonのAPI叩いたりしたことなかったので勉強がてらcliで作った
- goでmastodonのクライアントあるんだっけって思ったけど速攻で mattnさんのやつ 見つけた
- 以下原始人くんが最新のトゥートを拾ってきて翻訳してトゥートするとても簡単なコード
package main
import (
"context"
"fmt"
"github.com/mattn/genshijin"
"github.com/mattn/go-mastodon"
"log"
)
func main() {
c := mastodon.NewClient(&mastodon.Config{
Server: "https://example.com",
ClientID: "",
ClientSecret: "",
})
err := c.Authenticate(context.Background(), "", "")
if err != nil {
log.Fatal(err)
}
s, err := c.GetAccountStatuses(context.Background(), mastodon.ID("2"), &mastodon.Pagination{})
if err != nil {
log.Fatal(err)
}
fmt.Println(s[0].Content)
_, err = c.PostStatus(context.Background(), &mastodon.Toot{
Status: genshijin.Shaberu(s[0].Content),
})
if err != nil {
log.Fatal(err)
}
}
RSSを取得してtootさせるようにしてみた
- 自身がtootしたらすぐ原始人くんがtootするようにしたかった
- 「自身がtootした」っていうeventにhookさせる簡単な方法が思いつかなかったのでzapierでRSS取得して自鯖にPOSTするってZAP設置してみた
- mastodon本体に手を入れたくなかった
- サーバー側に新着かどうか判定するために保存するcache等もつくりたくなかった
- FTLには出したくなかったので未収載にした
package main
import (
"context"
"fmt"
"github.com/mattn/genshijin"
"github.com/mattn/go-mastodon"
"log"
"net/http"
"strings"
)
func handler(w http.ResponseWriter, r *http.Request) {
c := mastodon.NewClient(&mastodon.Config{
Server: "",
ClientID: "",
ClientSecret: "",
})
err := c.Authenticate(context.Background(), "", "")
if err != nil {
log.Fatal(err)
}
r.ParseForm()
toot := genshijin.Shaberu(strings.Join(r.Form["toot"], ","))
_, err = c.PostStatus(context.Background(), &mastodon.Toot{
Status: toot,
Visibility: "unlisted",
})
if err != nil {
log.Fatal(err)
}
fmt.Fprintf(w, "Hello, World")
fmt.Println(toot)
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8888", nil)
}
- 作ったはいいけど15分に一度ぐらいの周期っぽいので全然おもしろくなかった
原始人くん自ら取りに行かせるようにしてみた
- 今現在動いてるのがこれ
- 最後のtootを last_toot に入れておいて同じであれば5秒スリープして再取得とか言うぶん投げっぷり
- 実装中なんどかHttp Status Code 429 が帰ってきてこまりました
- CPUが回りすぎているのでなんとかせねばならん
- boostを弾きたいのでboostかどうかを
Status.Reblog != nil
で判定してるのだけど行儀が良いのかよくわからんになってる
package main
import (
"context"
"fmt"
"github.com/mattn/genshijin"
"github.com/mattn/go-mastodon"
"log"
"time"
)
func main() {
c := mastodon.NewClient(&mastodon.Config{
Server: "",
ClientID: "",
ClientSecret: "",
})
err := c.Authenticate(context.Background(), "", "")
if err != nil {
log.Fatal(err)
}
last_toot := ""
for {
s, err := c.GetAccountStatuses(context.Background(), mastodon.ID("2"), &mastodon.Pagination{})
if err != nil {
fmt.Println(err)
time.Sleep(60 * time.Second)
continue
}
if s[0].Reblog != nil {
time.Sleep(5 * time.Second)
continue
}
toot := genshijin.Shaberu(s[0].Content)
if last_toot != toot {
c.PostStatus(context.Background(), &mastodon.Toot{
Status: toot,
Visibility: "unlisted",
})
fmt.Println(toot)
last_toot = toot
}
time.Sleep(5 * time.Second)
}
}
[追記]StreamingAPIでやった
- そういえばStreamingAPIあったなってなってマストドンのタイムラインをgo-mastodon のWebSocketを使用し取得する - Qiita を参考にサクッと実装したら無茶がなくなった。
- 公開のLTLのトゥートを拾うのでユーザ参加させれば誰でも原始人くんはつぶやくはず
package main
import (
"context"
"fmt"
"github.com/mattn/genshijin"
"github.com/mattn/go-mastodon"
"log"
)
func main() {
c := mastodon.NewClient(&mastodon.Config{
Server: "",
ClientID: "",
ClientSecret: "",
})
err := c.Authenticate(context.Background(), "", "")
if err != nil {
log.Fatal(err)
}
wsc := c.NewWSClient()
q, err := wsc.StreamingWSPublic(context.Background(), true)
if err != nil {
log.Fatal(err)
}
for e := range q {
if t, ok := e.(*mastodon.UpdateEvent); ok {
if t.Status.Sensitive {
continue
}
fmt.Printf("\x1b[37m[%s] \x1b[35m%-20s: \x1b[33m%s\n", t.Status.CreatedAt.Local().Format("15:04:05"), t.Status.Account..Acct, t.Status.Content)
c.PostStatus(context.Background(), &mastodon.Toot{
Status: genshijin.Shaberu(t.Status.Content),
Visibility: "unlisted",
})
}
}
}