モスクワの天気に詳しい彼女botが欲しい


# はじめに

モスクワの天気に精通した**彼女風LINE BOT**を作成しました

[![Image from Gyazo](https://i.gyazo.com/c78a840ad1fe0201b3b649766a4e7a04.png)](https://gyazo.com/c78a840ad1fe0201b3b649766a4e7a04)

#### QRコード

[![Image from Gyazo](https://i.gyazo.com/f22a26304e7bc0755cd4f4a95b1d2cd2.png)](https://gyazo.com/f22a26304e7bc0755cd4f4a95b1d2cd2)

#### 使用技術
 - Go
 - line-bot-sdk
 - heroku
 - [openWeather API](https://openweathermap.org/)

# 事前準備
LINE BOT 作成手順は、以下記事にまとめましたので、参考にして頂けますと幸いです。
[LINE BOTで彼女botを作りたい](https://qiita.com/umaibou1126/items/f1a00c1311f6f2dc0114)

# リッチメニュー 作成

#### [LINE Official Account Manager](https://account.line.biz/login?redirectUri=https%3A%2F%2Fmanager.line.biz%2F%3Fstatus%3Dsuccess) ログイン

#### 「アカウント名選択」 > 「トークルーム管理」 > 「リッチメニュー」 選択

[![Image from Gyazo](https://i.gyazo.com/2e0075892f6e13d93ab03534a44b0add.png)](https://gyazo.com/2e0075892f6e13d93ab03534a44b0add)

#### 「作成」 > 「コンテンツ設定」 > 「テンプレート選択」 > 「画像を作成」

[![Image from Gyazo](https://i.gyazo.com/128c0a3297fad8a8cf0b24e00d8e4b9e.png)](https://gyazo.com/128c0a3297fad8a8cf0b24e00d8e4b9e)

#### 任意の画像・テキストを設定し、右上の「適用」をクリック

[![Image from Gyazo](https://i.gyazo.com/b7ecaee4b1c98d4dbf7674664ff67e7f.png)](https://gyazo.com/b7ecaee4b1c98d4dbf7674664ff67e7f)

#### 「アクション」 で「テキスト」を選択し、任意の文字を設定 > 右上の「保存」で完了

[![Image from Gyazo](https://i.gyazo.com/11322d60079be878e42e612a77ea6703.png)](https://gyazo.com/11322d60079be878e42e612a77ea6703)


# openWeather API 設定

#### [openWeather API](https://openweathermap.org/) > API Key 取得

[![Image from Gyazo](https://i.gyazo.com/cea6f6f9adb5007a454c111898d14c3b.png)](https://gyazo.com/cea6f6f9adb5007a454c111898d14c3b)

# Bot作成

#### Goプロジェクト準備

```
$ mkdir sample-bot && cd sample-bot
$ go mod init github.com/GitHubユーザ名/GitHubリポジトリ名
```

#### Goライブラリインストール

```
$ go get github.com/line/line-bot-sdk-go/linebot
$ go get github.com/gin-gonic/gin
```

#### コーディング

```main.go
package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/line/line-bot-sdk-go/linebot"
)

type Wdata struct {
	Weather []Weather `json:"weather"`
	Info    Info      `json:"main"`
}

type Weather struct {
	Main string `json:"main"`
	Icon string `json:"icon"`
}

type Info struct {
	Temp     float32 `json:"temp"`
	Humidity float32 `json:"humidity"`
}

func main() {
	port := os.Getenv("PORT")

	if port == "" {
		log.Fatal("$PORT must be set")
	}
	bot, err := linebot.New(
		"LINE シークレット",
		"LINE アクセストークン",
	)
	if err != nil {
		log.Fatal(err)
	}

	router := gin.New()
	router.Use(gin.Logger())

	// LINE Messaging API ルーティング
	router.POST("/callback", func(c *gin.Context) {
		events, err := bot.ParseRequest(c.Request)
		if err != nil {
			if err == linebot.ErrInvalidSignature {
				log.Print(err)
			}
			return
		}

		// モスクワ
		var moskwaWeather string
		moskwaWeather = "モスクワ"

		for _, event := range events {
			// イベントがメッセージの受信だった場合
			if event.Type == linebot.EventTypeMessage {
				switch message := event.Message.(type) {
				// メッセージがテキスト形式の場合
				case *linebot.TextMessage:
					replyMessage := message.Text
					// モスクワ
					if strings.Contains(replyMessage, moskwaWeather) {
						moskwasWeather(bot, event)
					}
					// 上記意外は、おうむ返しで返信
					_, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(replyMessage)).Do()
					if err != nil {
						log.Print(err)
					}
				}
			}
		}
	})
	router.Run(":" + port)
}

// モスクワ
func moskwasWeather(bot *linebot.Client, e *linebot.Event) {
	lat := "55.755826" // モスクワの緯度
	lon := "37.6173" // モスクワの経度
	url := "http://api.openweathermap.org/data/2.5/weather?lat=" + lat + "&lon=" + lon + "&APPID=XXXXXXXXXX" // openWeather：API Keyを設定
	//天気情報を取得
	resp, err := http.Get(url)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	byteArray, _ := ioutil.ReadAll(resp.Body)
	jsonBytes := ([]byte)(string(byteArray[:]))
	if err != nil {
		log.Fatal(err)
	}

	wdata := new(Wdata)
	if err := json.Unmarshal(jsonBytes, wdata); err != nil {
		fmt.Println("JSON Unmarshal error:", err)
		return
	}
	var resWeather string
	resWeather = fmt.Sprintf(wdata.Weather[0].Main)

	// 日本語変換
	if resWeather == "Clouds" {
		resWeather = "曇り"
	} else if resWeather == "Clear" {
		resWeather = "晴れ"
	} else if resWeather == "Rain" {
		resWeather = "雨"
	} else if resWeather == "Drizzle" {
		resWeather = "霧雨"
	} else if resWeather == "Thunderstorm" {
		resWeather = "雷雨"
	} else if resWeather == "Snow" {
		resWeather = "雪"
	}

	var temp string
	temp = fmt.Sprintf("%.2f", (wdata.Info.Temp - 273.15))
	var humidity string
	humidity = fmt.Sprintf("%.2f", wdata.Info.Humidity)
	var res string
	res = fmt.Sprintf("天気：%s\n気温：%s℃\n湿度：%s％", resWeather, temp, humidity)

	_, err = bot.ReplyMessage(e.ReplyToken, linebot.NewTextMessage(res)).Do()
	if err != nil {
		log.Fatal(err)
	}
}
```

# 参考文献

 - [LINE BOT APIで簡単BOT作成](https://ceblog.mediba.jp/post/150169029917/line-bot-api%E3%81%A7%E7%B0%A1%E5%8D%98bot%E8%A3%BD%E4%BD%9C)
 - [【初学者向け】Go,LINEBot,AWSLambdaで天気予報のボットを作成！](https://qiita.com/shinya_1004/items/fb73172feb693b57605c)
 - [毎朝 天気を通知する LINE Bot を作ってみました。](http://takagusu.hateblo.jp/entry/2017/01/24/200453)
 - [無料天気予報APIのOpenWeatherMapを使ってみる](https://qiita.com/nownabe/items/aeac1ce0977be963a740)
 - [モスクワの基本情報](https://tentsuki.jp/information/russian/1632/)