Created by Shota Omori(@morix1500) 2017-10-24 GoビギナーズLT大会!「最近、Go言語始めました」の会
Goで英語ツイートを音声化するツイッターボットを作った2017.10.24Go言語LT大会!「最近、Go言語始めました」の会@morix1500
View Slide
じこしょうかい・大森翔太(@morix1500)・株式会社モブキャスト・インフラエンジニア・Go歴:2か月くらい?・技術ブログやってます! https://blog.haramishio.xyz/
きょうのテーマ・英語のツイートを音声化するツイッターボットの紹介・エラーハンドリングに悩んだ話
〇〇と学ぶ英語Botというものがある
英語学習Botのいいところ・平易な文章であること・日本語訳とポイントとなる単語の意味が載ってる・好きなアニメのセリフで学べる
英語学習Botのよくないところ・単語がコピペしづらい ⇒ ツイッタークライアントによると思う・発音がわからない
ということでBotに英語をしゃべらせた
Botの仕組みGoAppPolly1. Streaming2. Get Speech Request3. Get Speech4.EncodeVideo5. Upload Video &Tweet
Amazon Pollyとは・AWSが提供するテキストから音声化するサービス・47種類の男女の声と24の言語(日本語含む)に対応・機械学習によるなめらかな発音・SSML(Speech Sythesis Markup Language)による音声の編集・MP3などでダウンロード可能
Twitterに音声ファイルをアップロードするには・Twitterに音声ファイルをアップロードできない・じゃあどうすれば?・音声ファイルを動画化してそれをアップロード
Go言語でどう作ったか・Twitter Client ・Anaconda(https://github.com/ChimeraCoder/anaconda )・Pollyの操作 ・AWS SDK・音声の動画化 ・ffmpeg
完成したのがこちらアニメで学ぶ英語音声bot@km_eng_speechhttps://twitter.com/km_eng_speech
Botを作るときに悩んだこと・Go言語でのエラーハンドリングのやり方 ・例外がないからハンドリングどうやれば…
よくあるエラー処理func main() {if err := something(); err != nil {fmt.Println(err)}}
よくあるエラー処理(複数エラーの場合)var (Err01 = errors.New("Output Error 01")Err02 = errors.New("Output Error 02"))func main() {err := something()switch err {case Err01:fmt.Println("type is Err01")fmt.Printf("%+v\n", err)case Err02:fmt.Println("type is Err02")fmt.Printf("%+v\n", err)}}エラー定義しといて返却されたerrでハンドリングする
この方法の問題点・エラーに追加情報を付与できないfunc hoge() error {return Err01}func something() error {if err := hoge() ; err != nil {return fmt.Errorf("%+v from hoge", err)}return nil}違うエラー(Err01ではない)になってしまう!
かいけつあん・pkg/errorsを使用する https://github.com/pkg/errors
pkg/errorsとは・元のエラーを変更しない形で、追加情報を付与できる・エラーのスタックトレースも出力することができる
エラー定義と追加情報の付与・エラー定義 Err01 = errors.New(“Output Error 01”)・追加情報の付与 return errors.Wrap(Err01, “from hoge”)
エラー定義と追加情報の付与import ("fmt""github.com/pkg/errors")var (Err01 = errors.New("Output Error 01")Err02 = errors.New("Output Error 02"))func hoge() error {return Err01}func fuga() error {return Err02}func something() error {if err := hoge() ; err != nil {return errors.Wrap(err, "from hoge")}if err := fuga() ; err != nil {return errors.Wrap(err, "from fuga")}return nil}
エラー判定・エラーの根本原因の呼び出し errors.Cause(err)err := something()fmt.Println(err)fmt.Println(errors.Cause(err))---------------------------from hoge: Output Error 01Output Error 01
エラー判定func main() {err := something()switch errors.Cause(err) {case Err01:fmt.Println("type is Err01")fmt.Printfln(err)fmt.Printf("%+v\n", err)case Err02:fmt.Println("type is Err02")fmt.Println(err)fmt.Printf("%+v\n", err)}}
エラー判定(前ページの出力結果)type is Err01from hoge: Output Error 01Output Error 01main.init/home/ubuntu/go/pkg/src/github.com/morix1500/go-error-handling/04.go:9runtime.main/home/ubuntu/go/current/src/runtime/proc.go:173runtime.goexit/home/ubuntu/go/current/src/runtime/asm_amd64.s:2337from hogemain.something/home/ubuntu/go/pkg/src/github.com/morix1500/go-error-handling/04.go:23main.main/home/ubuntu/go/pkg/src/github.com/morix1500/go-error-handling/04.go:32runtime.main/home/ubuntu/go/current/src/runtime/proc.go:185runtime.goexit/home/ubuntu/go/current/src/runtime/asm_amd64.s:2337
まとめ・複雑なエラーハンドリングは「pkg/errors」がおすすめ・適切にエラーを処理してユーザに優しいエラーメッセージを!・スタックトレースで開発者にも優しいエラーメッセージを!
最後に - Go言語を使ってみた感想・作りたいと思ったものがサクッと作れる srm - 安全なrmコマンドhttps://github.com/morix1500/srmruler - csv/tsv/ltsvを表形式に表示するコマンドhttps://github.com/morix1500/ruler・パッケージが充実しており車輪の再発明をしなくていい・とにかく読みやすい/書きやすい!・ワンバイナリで配布できるのは非常に便利・どんどんGo言語の使用を進めていきたい!