TwitterAPI使って自動でTweetするGoのプログラムを作る with Docker
今回はTwitterAPIを使ってGoで書かれたプログラムからツイートしてみます
環境
- Docker Version 20.10.2
- docker-compose version 1.27.4, build 40524192
前準備
Twitterのアカウントを取得して以下の4つを発行します
ソースコード
TwitterAPIを有効にするためOAuth認証を通します
keys.go
package keys import ( //Twitter APIに必要なimportになります。なければインストールしましょう。 "github.com/ChimeraCoder/anaconda" "os" ) func GetTwitterApi() *anaconda.TwitterApi { anaconda.SetConsumerKey(os.Getenv("TFC_API_KEY")) anaconda.SetConsumerSecret(os.Getenv("TFC_API_SECRET_KEY")) api := anaconda.NewTwitterApi(os.Getenv("TFC_ACCESS_TOKEN"), os.Getenv("TFC_ACCESS_SECRET")) return api }
ツイートするための
main.go
package main import ( "fmt" . "fmt" "local.packages/keys" // go modulus環境でローカルパッケージをインポート ) func main() { api := keys.GetTwitterApi() tweet_text := fmt.Sprintf("テストツイート") tweet, err := api.PostTweet(tweet_text, nil) if err != nil { panic(err) } Print(tweet.Text) fmt.Println("posting!") }
import
でローカルにあるkeysパッケージをもってくるのですがこの書き方がベストプラクティスかどうかは微妙です。
mainパッケージとkeysパッケージ両方にgo.modを配置してmainのほうのgo.modファイルをこうします↓
module main.go go 1.14 replace local.packages/keys => ./keys // modules名を相対パスに置き換えている require ( // ry )
なんでこれでうまくいってるのかよくわかってないです
ディレクトリ構成はこうなります↓ keysパッケージのほうのmodファイルには何も書いてません
> tree . ├── Dockerfile ├── README.md ├── docker-compose.yml ├── go.mod ├── go.sum ├── keys │ ├── go.mod │ └── keys.go ├── main.go
Dockerfileを修正
Dockerfileにアナコンダをとってくる文を追加します
FROM golang:1.14.0-alpine3.11 # ビルド時にashを使う SHELL ["/bin/ash", "-c"] WORKDIR /go/src/app COPY ./ ./ # Go Modulesを使うと明言する ENV GO111MODULE=on # apkはalpine linux(超軽量なLinux)の独自のパッケージ管理システム RUN apk add --no-cache alpine-sdk # Golang 環境構築 # (追加)TwitterAPIを捌くのにアナコンダを使用します RUN go get github.com/ChimeraCoder/anaconda
環境変数受け渡しのためにdocker-compose.ymlを修正
ホスト(コンテナの外)のシェルに環境変数をセット
私はFishシェラーをなのでset -x
で環境変数をセットします
TFCは今回のプロジェクトの名前なので気にしないでください
set -x TFC_ACCESS_TOKEN xxxxxxxxxxxxxxxxxxxxxxxxxxxxx set -x TFC_ACCESS_SECRET xxxxxxxxxxxxxxxxxxxxxxxxxxxx set -x TFC_API_KEY xxxxxxxxxxxxxxxxxxxxx set -x TFC_API_SECRET_KEY xxxxxxxxxxxxxxxxxxxxx
docker-composeでコンテナ起動時に環境変数を設定するようにする
こちらの記事を参考にして .ymlファイルを書きました。↓
version: '3' # composeファイルのバーション指定 services: app: # service名 build: . # ビルドに使用するDockerfileがあるディレクトリ指定 tty: true # コンテナの起動永続化 volumes: - .:/go/src/app # マウントディレクトリ指定 environment: TFC_API_KEY: ${TFC_API_KEY?err} # composeが起動しているシェルの環境変数を利用 TFC_API_SECRET_KEY: ${TFC_API_SECRET_KEY?err} # 未設定またはempty値の場合にエラ〜メッセージを表示して終了する TFC_ACCESS_TOKEN: ${TFC_ACCESS_TOKEN?err} TFC_ACCESS_SECRET: ${TFC_ACCESS_SECRET?err}
コンテナの中に入って環境変数を確認
$ docker-compose up -d $ docker-compose exec app /bin/ash $ set 省略
set
コマンドで先ほどセットしたKEYやTOKENが表示されたら成功です
ツイートしてみる
コンテナの中に入ってgo run
します
> docker-compose exec app /bin/sh /go/src/app # go run main.go テストツイートposting!
自分のツイッターアカウントを見にいってみたら成功してました
ちなみに2連続で同じ内容を呟くと以下のようなエラーが返ってきました
panic: Get https://api.twitter.com/1.1/statuses/update.json returned status 403, {"errors":[{"code":187,"message":"Status is a duplicate."}]}
おつかれさまです。次回はツイートの取得をやります。
参考サイト
案外知られてないdocker-composeの環境変数定義の記法