この記事はFusic Advent Calendar15日目の記事です。
こばんは。お久しぶりです。まっさんです。
アドベントカレンダー何を書こうか迷っていたら、こんな時間になっていまいました。良い子はちゃんと事前に準備しときましょう。
とくに何も閃かなかったので、弊社の一部のメンバーで行っている朝の15分輪読会で、絶賛勉強中のgo言語について書いてみようと思います。(golang初学者ですので、誤り等ありました。ご指摘いただければ幸いです)
社内のニコニコカレンダーのcliツールを作ってみる
弊社には、@Y_uuu が作成した、nicoleというニコニコカレンダーがあります。
社員の20〜50%が日々投稿する人気ツールです。
そんなニコニコカレンダーのcliツールを作ってみました。リファクタリングとか、してないので、色々ツッコミどころ満載ですが、こんな感じです。
package main
import (
"bufio"
"bytes"
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"net/http"
"os"
"time"
)
type PostData struct {
Mood string `json:"mood"`
Message string `json:"message"`
Date string `json:"date"`
}
func main() {
postJson := createJson()
if postJson == nil {
return
}
key := getEnvKey()
req, err := http.NewRequest("POST", "{{ ニコニコカレンダーのAPIのURL }}", bytes.NewBuffer(postJson))
req.Header.Set("API-KEY", key)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Sprintf("req err: %s", err)
}
defer resp.Body.Close()
respBody, err := ioutil.ReadAll(resp.Body)
if err == nil {
fmt.Sprintf("resp err: %s", err)
}
fmt.Println(string(respBody))
}
func createJson() []byte {
t := time.Now()
defaultMood := "normal"
defaultMessage := "普通"
mood := flag.String("mood", defaultMood, "気分")
key := flag.String("api_key", "", "あなたのApiキーを入力して下さい。")
message := flag.String("message", defaultMessage, "今日の一言")
date := flag.String("date", t.Format("2006-01-02"), "日時")
flag.Parse()
if *key != "" {
setEnvKey(*key)
return nil
}
postData := PostData{*mood, *message, *date}
outputJSON, err := json.Marshal(&postData)
if err != nil {
fmt.Sprintf("json err: %s", err)
}
return outputJSON
}
func setEnvKey(key string) {
file, err := os.Create(`./.env`)
if err != nil {
fmt.Sprintf("create file err: %s", err)
}
defer file.Close()
output := key
file.Write(([]byte)(output))
}
func getEnvKey() string {
file, err := os.Open("./.env")
if err != nil {
fmt.Sprintf("open file err: %s", err)
}
defer file.Close()
var envKey string
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
envKey = line
}
if err := scanner.Err(); err != nil {
fmt.Sprintf("read file err: %s", err)
}
return envKey
}
躓いたポイント
社内のニコニコカレンダーのAPIを叩くために、マイページで作成した API_KEY
が必要になります。
ファイルに書き出すよりも、環境変数にセットしたかったので、ググったところ、os
パッケージをインポートすると、いい感じに環境変数の読み取り、書き込みができるとのこと。
こんな感じ。
読み取り
package main
import (
"fmt"
"os"
)
func main() {
val := os.Getenv("HOGE")
fmt.Println(val)
}
設定されてない場合は、空文字が返ります。
書き込み
package main
import (
"fmt"
"os"
)
func main() {
os.Setenv("HOGE", "hoge_value")
}
とても、簡単ですね。しかし、いざ使ってみると、上手くAPI_KEY
が取得できない。
どうも、Goの動いているプロセスに対して、環境変数がセットされるようで、そのプロセスが死ぬの環境変数も消えてしまう?っぽい。(間違っていたらすみません。)
外部コマンドに頼る
os
パッケージを使って環境変数にセットしよう作戦はあえなく、失敗したので、Go
からexport HOGE=hoge
のようにos
のコマンドを呼び出して無理やり環境変数を設定したいと思います。
os/exec
パッケージを使用して外部コマンドを実行できるようです。こんな感じ。
package main
import (
"fmt"
"os/exec"
)
func main() {
out, err := exec.Command("ls", "-la").Output()
if err != nil {
fmt.Println(err)
}
fmt.Printf(string(out))
}
exec.Command
で環境変数をセットしようとしたのですが、こちらは
exec: "export": executable file not found in $PATH
とエラーになり上手く行かず。(理由もまだわかって何ので、わかったら追記します。。。)
おとなしくドットファイルに書き込む
環境変数にセットするのは、上手く行かなかったので、おとなしくドットファイルを作成して、そこで書き込みと読み取りを行うことにしました。
終わりに
まだまだ、Go
っぽい書き方とかGo
の良さが活かせていないので、日々の輪読をとして精進しようと思います。
明日は、 @yoshitake_1201 の投稿ですので、皆様お楽しみにー!!!