はじめに
Slackbotでの天気予報をお知らせするbotを作成しました。以下、コード。
このbot作成時につまづいた、GoでのAPIをここに記します。
※botに関しての記事ではないので、注意。
API
今回使用した天気予報を持ってくるAPIは、OpenWeatherAPIです。
また、Slackbotを作成したため、もしよければSlackapiを使用してbotを作成してください。
登録方法は、以下のサイト参考。
無料天気予報APIのOpenWeatherMapを使ってみる
API Get
GoogleChromeのアプリ等で実際に、OpenWeatherMapのAPIを叩いてみます。
以下のURLを叩けば、JSONで返ってきます。
http://api.openweathermap.org/data/2.5/weather?lat=緯度&lon=経度&appid=apikey
例:石川県野々市市
{
"coord": {
"lon": 136.63,
"lat": 36.53
},
"weather": [
{
"id": 801,
"main": "Clouds",
"description": "few clouds",
"icon": "02n"
}
],
"base": "stations",
"main": {
"temp": 278.32,
"feels_like": 275.8,
"temp_min": 277.59,
"temp_max": 279.15,
"pressure": 1023,
"humidity": 75
},
"visibility": 10000,
"wind": {
"speed": 1
},
"clouds": {
"all": 20
},
"dt": 1576494007,
"sys": {
"type": 1,
"id": 8017,
"country": "JP",
"sunrise": 1576447105,
"sunset": 1576481950
},
"timezone": 32400,
"id": 1854979,
"name": "Nonoichi",
"cod": 200
}
このJSONをGo言語で扱うには、構造体をしようしなくてはいけません。
JSONをGoの構造体で表すと以下のようになります。
JSON-to-Goを使用すれば一発です。
type WeatherResult struct {
Coord struct {
Lon float64 `json:"lon"`
Lat float64 `json:"lat"`
} `json:"coord"`
Weather []struct {
ID int `json:"id"`
Main string `json:"main"`
Description string `json:"description"`
Icon string `json:"icon"`
} `json:"weather"`
Base string `json:"base"`
Main struct {
Temp float64 `json:"temp"`
FeelsLike float64 `json:"feels_like"`
TempMin float64 `json:"temp_min"`
TempMax float64 `json:"temp_max"`
Pressure int `json:"pressure"`
Humidity int `json:"humidity"`
} `json:"main"`
Visibility int `json:"visibility"`
Wind struct {
Speed int `json:"speed"`
} `json:"wind"`
Clouds struct {
All int `json:"all"`
} `json:"clouds"`
Dt int `json:"dt"`
Sys struct {
Type int `json:"type"`
ID int `json:"id"`
Country string `json:"country"`
Sunrise int `json:"sunrise"`
Sunset int `json:"sunset"`
} `json:"sys"`
Timezone int `json:"timezone"`
ID int `json:"id"`
Name string `json:"name"`
Cod json.Number `json:"cod"`
}
botを作成する際には、必要なものだけでも大丈夫です。(例えば、Weatherとか)
準備ができたので、main.go
で実際に持ってきましょう。
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
)
// 中略 ここに先ほどの構造体を入れる。
func main() {
result := GetWeather()
fmt.Println(result)
}
// APIを叩く関数
func GetWeather() string {
values := url.Values{}
baseUrl := "http://api.openweathermap.org/data/2.5/weather?"
// query
values.Add("appid", "APIKEY") // OpenWeatherのAPIKey
values.Add("lat", "36.5286") // 緯度(石川県野々市市)
values.Add("lon", "136.6283") // 経度(石川県野々市市)
weather := ParseJson(baseUrl + values.Encode())
return weather
}
// ここでパースします。
func ParseJson(url string) string {
weather := ""
response, err := http.Get(url)
if err != nil { // エラーハンドリング
log.Fatalf("Connection Error: %v", err)
return "取得できませんでした"
}
// 遅延
defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatalf("Connection Error: %v", err)
return "取得できませんでした"
}
jsonBytes := ([]byte)(body)
data := new(WeatherResult)
if err := json.Unmarshal(jsonBytes, data); err != nil {
log.Fatalf("Connection Error: %v", err)
}
if data.Weather != nil {
weather = data.Weather[0].Main
}
return weather
}
やっていることは、簡単。
GetAPI
は、ベースとなるURLを変数に、必要なqueryを構造体に保管します。それらを組み合わせて
ParseJson
に渡します。
http
パッケージでのGetメソッドでGETし、持ってきたBodyをioutil
パッケージで読み込みます。
それをbyte型で格納し、データを表示します。
ターミナルで、go run main.go
を走らせると、設定した都市の気候が表示されます。
これで、APIを持ってくることができました。
終わりに
他の言語は、ライブラリーや標準で実装できるのに、goはできないのがかなり不便ですね。
多分、あると思いますが、データの流れがわかるので自分で書くのもありかな。