Slide 1

Slide 1 text

GoとLINE BOTに まとめて入門する やぎぬ(@yagi_eng) 2020/11/04 1 The Go gopher was designed by Renée French. Licensed under the Creative Common 3.0 Attributions License.

Slide 2

Slide 2 text

ゆるくやっていきましょ • 時間的に全然ごはん食べたり飲んだりしながら聞いて頂いてOKです • 堅苦しいの好きじゃないので、ゆるくやっていきましょう! 2

Slide 3

Slide 3 text

アジェンダ • 登壇者の自己紹介 • こんなの作ります • このイベントの進め方 • このイベントのゴール • レクチャ • レクチャのアジェンダはレクチャ直前にて 3

Slide 4

Slide 4 text

登壇者の自己紹介 4

Slide 5

Slide 5 text

名前 Yaginuma Kohei(あだ名:やぎぬ) 経歴 大手SIerでクラウドエンジニア⇒フリーWebエンジニア 最近興味があること 個人サービス開発、 LINEbot&ミニアプリ、Go、マネジメント、コーチング、etc… 趣味 海外旅行、ランチ巡り、水泳、ミュージカル鑑賞、ゲーム、 なんか面白そうなこと、etc… 5 やぎぬ

Slide 6

Slide 6 text

6 • 2020/9 大阪・滋賀 • 2020/3 セブ • 2020/2 台湾 • 2019/8,9 東南アジアバックパック • 2019/8 北海道 • 2018/11 東北周遊 • 2018/9 カンボジア・ベトナム • etc… Instagramにいっぱい 旅行の写真載せてます! https://www.instagram.com/yaginu_travels_around/ 旅行好きです

Slide 7

Slide 7 text

7 中目黒・渋谷あたりでよくランチ 食べてます Instagramにいっぱい ランチの写真載せてます! https://www.instagram.com/yaginu_nakame_lunch/ 食べるのも好きです

Slide 8

Slide 8 text

上田さん 8 コミュニティ活動 Google Developer Expert (Go) Go ビギナーズ Go Conference @tenntenn https://tenntenn.dev

Slide 9

Slide 9 text

こんなの作ります 9

Slide 10

Slide 10 text

10 こちらのQRコードを LINEで読み取るとお手元の 端末でお試し頂けます サンプル

Slide 11

Slide 11 text

説明 11 今回やること • 位置情報を送信すると、その周辺の飲食店を返すBOTの作成 やらないこと • お気に入り機能 • 文字検索 • LIFF 技術的な補足 • 飲食店検索にはホットペッパーAPIを使います • 先ほどのサンプルではGoogleMapsAPIを使っていますが、 ホットペッパーAPIの方がカジュアルに使えます

Slide 12

Slide 12 text

このイベントの進め方 12

Slide 13

Slide 13 text

StepByStepで解説していくスタイル • いきなり目的のBOTを作るのはハードル高いしごちゃごちゃしてしまうので、 hello worldからはじめて5ステップに分けて解説していきます 13

Slide 14

Slide 14 text

Excuse • カジュアルに参加頂けるように1時間という時間枠でやっています • Goでの開発やLINE BOT開発の流れを理解して頂きたいというのが趣旨です • 文法については体系立ててレクチャせず、かいつまんでレクチャしていきます • オンライン形式や限られた時間枠ということを踏まえ、ハンズオン形式や ライブコーディング形式ではなく、講義形式で行います 14

Slide 15

Slide 15 text

このイベントのゴール 15

Slide 16

Slide 16 text

GoとLINE BOTの初歩的なことがわかる • Goの基本事項がわかる • LINE BOT SDKの使い方がわかる • 「よし、GoやLINEBOTに触ってみよう」と思える 16

Slide 17

Slide 17 text

レクチャ 17

Slide 18

Slide 18 text

レクチャのアジェンダ • LINE BOTの概要 • Goの概要 • 実装&解説 18

Slide 19

Slide 19 text

LINE BOTの概要 19

Slide 20

Slide 20 text

Messaging API • LINE BOTっていうけど正確にはMessagingAPI • 以下公式より引用 • Messaging APIを使って、ユーザー個人に合わせた体験をLINE上で提供する ボットを作成できます。 • 作成したボットは、LINEプラットフォームのチャネルに紐づけます。 • Messaging APIを使って、ボットサーバーとLINEプラットフォームの間で データを交換できます。リクエストは、JSON形式でHTTPSを使って送信さ れます。 引用元 https://developers.line.biz/ja/docs/messaging-api/overview 20

Slide 21

Slide 21 text

Messaging APIの仕組み(公式から引用) 1. ユーザーが、LINE公式アカウントにメッセージを送信します。 2. LINEプラットフォームからボットサーバーのWebhook URLに、 Webhookイベントが送信されます。 3. Webhookイベントに応じて、ボットサーバーからユーザーに LINEプラットフォームを介して応答します。 21

Slide 22

Slide 22 text

Goの概要 22

Slide 23

Slide 23 text

Goとは? 23 Googleが開発したプログラミング言語 • 2009年11月に最初のバージョンをオープンソースで公開 • 2012年3月に正式バージョンであるGo1.0を公開 • 2020年11月現在の最新バージョンはGo1.15 • 半年毎のペースでバージョンアップ • Robert Griesemer、Rob Pike、Ken Thompsonによって設計された 特徴 • 強力でシンプルな言語設計と文法 • 並行プログラミング • 豊富な標準ライブラリ群 • 周辺ツールの充実 • シングルバイナリ・クロスコンパイル 上田さん資料 より抜粋

Slide 24

Slide 24 text

Goが開発された理由 24 Google内の課題を解決するために開発された • 開発速度の低下 • 超巨大なコードベース • 複雑な依存関係 • マルチコア時代のシステム言語 • 並行処理とガベージコレクタを同時に採用 • 軽量プログラミング言語(LL, Light weight Language)の盛り上がり • 静的型付け言語だとコンパイル時にエラーが発見できる • 動的型付け言語だと書きやすい • いいところ取りの書きやすい静的型付け言語がない • 静的解析がしやすい言語 • 言語設計のレベルで静的解析しやすい言語を目指した 上田さん資料 より抜粋

Slide 25

Slide 25 text

Goの特徴 − 周辺ツールの充実 − 25 • go toolとして標準/準標準で提供 • サードパーティ製のツールも充実 • IDEによらない独立したツールとして提供 go build ビルドを行うコマンド go test xxxx_test.goに書かれたテストコード の実行 go doc, godoc ドキュメント生成 gofmt, goimports コードフォーマッター go vet コードチェッカー gopls Language Server Protocol (LSP) の実装 上田さん資料 より抜粋

Slide 26

Slide 26 text

インストール 26 必要に応じて、以下の記事を参考にインストールしてください 【超簡単】GoのインストールとVSCode設定方法 https://qiita.com/yagi_eng/items/69cb75cd3062a24888ac

Slide 27

Slide 27 text

実装&解説 27

Slide 28

Slide 28 text

こんな感じで実装していきます! 1. まずはHello, World! 2. オウム返しのLINEBOT 3. 位置情報から緯度/経度を返すLINEBOT 4. 位置情報から周辺の飲食店を返すLINEBOT 5. 位置情報から周辺の飲食店を見やすく返すLINEBOT 28

Slide 29

Slide 29 text

リポジトリはこちら https://github.com/yagi-eng/go-linebot-start ⇒ステップ毎にブランチを作成しています、インデント下がりがブランチ名 1. まずはHello, World! • hello-world 2. オウム返しのLINEBOT • parrot 3. 位置情報から緯度/経度を返すLINEBOT • latlng 4. 位置情報から周辺の飲食店を返すLINEBOT • resto 5. 位置情報から周辺の飲食店を見やすく返すLINEBOT • carousel 29

Slide 30

Slide 30 text

このレクチャで出てくるけど触れない要素 Goに興味を持って独学される際には以下も参考にしてみてください あまり一度に情報詰め込み過ぎるとパンクするので。。 • パッケージ管理・インポート • exported・unexported宣言 • エラー処理 • 変数宣言における_(ブランク変数) • 配列とスライス • ポインタ 30

Slide 31

Slide 31 text

1.まずはHello, World! 31

Slide 32

Slide 32 text

できあがり 32 localhost:8080にアクセスしたら Hello, Worldと表示されるように実装します

Slide 33

Slide 33 text

実装 33 main関数 • 最初に実行される関数 • 厳密には初期化後に実行される 関数宣言 • 18-21行目参照(返り値なし) • 返り値ありは後述 変数宣言 • 19行目参照 • 他にも色んな宣言の仕方がある • 型推論がある • 右辺から判断して自動で型付け

Slide 34

Slide 34 text

実装 34 ハンドラ登録 • 11行目参照 • 「このURLにアクセスしたら、この関数を 実行しますよ」の登録 • 11行目ではルートドメインにアクセスした らhelloHandlerが実行されるように登録 • localhost:8080/helloとしたければ、 http.HandleFunc(“/hello”, helloHandler) とする HTTPサーバの起動 • 15行目参照

Slide 35

Slide 35 text

35 サーバ立てるのめっちゃ楽

Slide 36

Slide 36 text

実行 36 以下のコマンドを実行する $ go run (実行するGoファイルのパス) または $ go run (実行するGoファイルのディレクトリパス) e.g. $ ls main.go $ go run main.go または $ go run .

Slide 37

Slide 37 text

【再掲】できあがり 37 localhost:8080にアクセスしたら Hello, Worldと表示されるように実装します

Slide 38

Slide 38 text

2.オウム返しのLINEBOT 38

Slide 39

Slide 39 text

できあがり 39 送信した内容をそのままオウム返しする LINE BOTを作成します

Slide 40

Slide 40 text

差分 40 https://github.com/yagi-eng/go-linebot-start/compare/hello-world...parrot

Slide 41

Slide 41 text

LINE Developersに登録 41 以下の公式サイトを参考にアカウントやチャネルを作成する ・Messaging APIを始めよう ⇒LINE Developersコンソールでチャネルを作成する https://developers.line.biz/ja/docs/messaging-api/getting-started/ ・ボットを作成する ⇒LINE Developersコンソールでボットを設定する https://developers.line.biz/ja/docs/messaging-api/building-bot/ ※チャネル: 「BOTを管理するもの」くらいの認識でOKです

Slide 42

Slide 42 text

LINE Developersでシークレットを取得 42 LINE Developersの各チャネル画面のBasic settingsの下の方にあります

Slide 43

Slide 43 text

LINE Developersでアクセストークンを取得 43 LINE Developersの各チャネル画面のMessaging APIの下の方にあります

Slide 44

Slide 44 text

実装(Handlerを1つ増やす) 44 ※緑塗りが追加部分 localhost:8080/callbackにアクセスしたら lineHandler関数が実行されるうように 実装します

Slide 45

Slide 45 text

実装(lineHandler関数) 45 LINEBOT SDKのexampleをほぼそのままコピペです 少しごちゃっとするので、雰囲気をつかむだけでOKです (自分も最初は雰囲気だけでやってました) • LINEBOT SDK • https://github.com/line/line-bot-sdk-go • 参考にしたexampleファイル • https://github.com/line/line-bot-sdk- go/blob/master/examples/echo_bot/server.go

Slide 46

Slide 46 text

実装(lineHandler関数 前半) 46 LINEBOT初期化 • 28-31行目参照 • linebotパッケージを使うとLINEBOTで 色々できる • 29, 30行目ではLINE Developersで取得した 認証情報※を記述 ※ 認証情報を載せたままGitHubでソースコード を公開しないように注意 通常は環境変数から取得したりします

Slide 47

Slide 47 text

実装(lineHandler関数 前半) 47 変数宣言(複数) • 28行目参照 • Goでは複数の変数(ここではbotとerr)を 宣言できる • 同様に、関数も複数の値を返せる if文 • 32行目参照 • 条件文に()はいらない

Slide 48

Slide 48 text

実装(lineHandler関数 後半) 48 おおまかな処理の流れ • 37-45行目 • リクエストの内容チェック • 46-60行目 • どのようなイベント※が起こったかを 確認して個別に処理する • 具体的な内容は次スライド ※イベント メッセージ受信、 ポストバック受信など

Slide 49

Slide 49 text

実装(lineHandler関数 後半) 49 拡張for文 • 46行目参照 switch文 • 49行目参照

Slide 50

Slide 50 text

実装(lineHandler関数 後半) 50 51行目 • 受信したメッセージがテキスト形式の場合 52行目 • 受信したメッセージを取得 53行目 • メッセージを送信

Slide 51

Slide 51 text

【再掲】Messaging APIの仕組み(公式から引用) 1. ユーザーが、LINE公式アカウントにメッセージを送信します。 2. LINEプラットフォームからボットサーバーのWebhook URLに、 Webhookイベントが送信されます。 3. Webhookイベントに応じて、ボットサーバーからユーザーに LINEプラットフォームを介して応答します。 51

Slide 52

Slide 52 text

実行 52 • ngrokというサービスを使い、外部からローカル環境へのアクセスを可能にする • ngrokが発行するURLをLINE DevelopersのWebhook URLに登録する • BOTを自分のLINEアプリに友だち追加して、メッセージを送信する 【参考】ngrokの利用方法 https://qiita.com/hirokisoccer/items/7033c1bb9c85bf6789bd

Slide 53

Slide 53 text

実行(ローカル環境を外部公開) 53 以下のコマンドを実行する # 8080番を公開したい時は以下の通り $ ngrok http 8080 ngrok by @inconshreveable Session Status online Session Expires 7 hours, 59 minutes Version 2.3.35 Region United States (us) Web Interface http://127.0.0.1:4040 Forwarding http://xxxxxx.ngrok.io -> http://localhost:8080 Forwarding https:// xxxxxx.ngrok.io -> http://localhost:8080 httpsのアドレスを Webhookに登録する

Slide 54

Slide 54 text

実行(Webhook登録) 54 LINE Developersの各チャネル画面のMessaging APIの下の方にあります

Slide 55

Slide 55 text

実行(友だち追加して会話) 55 LINE Developersの各チャネル画面の Messaging APIにQRコードがあるので、 友だち追加して試す

Slide 56

Slide 56 text

【再掲】できあがり 56 送信した内容をそのままオウム返しする LINE BOTを作成します

Slide 57

Slide 57 text

3.位置情報から 緯度/経度を返すLINEBOT 57

Slide 58

Slide 58 text

できあがり 58 位置情報を送ったら その位置の緯度と経度を返すよう実装します

Slide 59

Slide 59 text

差分 59 https://github.com/yagi-eng/go-linebot-start/compare/parrot...latlng

Slide 60

Slide 60 text

実装 60 59-60行目 • 送信されたメッセージが位置情報であれば、 sendRestoInfo関数を実行 • sendRestoInfo関数の実装は次スライド ※このステップでは位置情報を返すだけです が、次ステップでレストラン情報を返すよう にするので、関数名にはレストランを入れ ちゃってます

Slide 61

Slide 61 text

実装(sendRestoInfo関数) 61 68行目 • イベントから位置情報メッセージを取得 70-71行目 • 緯度と経度を取得 • float型で取得されるので、 strconv.FormatFloatで文字列に置換

Slide 62

Slide 62 text

実装(sendRestoInfo関数) 62 73行目 • 返信するメッセージを生成 • “”中の1つ目に%sにlatが、2つ目の%sにlng が代入される 75行目 • メッセージを送信

Slide 63

Slide 63 text

【再掲】できあがり 63 位置情報を送ったら その位置の経度と緯度を返すよう実装します

Slide 64

Slide 64 text

4.位置情報から 周辺の飲食店を返すLINEBOT 64

Slide 65

Slide 65 text

できあがり 65 位置情報を送ったら、その周辺の レストラン一覧を返すよう実装します

Slide 66

Slide 66 text

差分 66 https://github.com/yagi-eng/go-linebot-start/compare/latlng...resto

Slide 67

Slide 67 text

ホットペッパーAPI 67 飲食店検索などいろいろできて、かつ気軽に使えるAPI ホットペッパーAPIリファレンス https://webservice.recruit.co.jp/doc/hotpepper/reference.html

Slide 68

Slide 68 text

APIKEYを発行 68 公式サイトの新規登録より流れで登録できます メアド登録だけなので簡単に使える!

Slide 69

Slide 69 text

使用するAPIのレスポンス例 69 https://webservice.recruit.co.jp/hotpepper/gourmet/v1/?key=(YOURKEY)&format =json&large_area=Z011

Slide 70

Slide 70 text

実装 70 ※赤塗りが削除部分 75行目 • getRestoInfo関数を作成して、それでメッ セージ返すように変更

Slide 71

Slide 71 text

実装(構造体の定義) 71 構造体 • 84, 89, 94行目参照 • 型の異なるデータ型を集めたデータ型 • type (構造体の名前) struct{} で定義できる JSONパース • Goでは構造体とJSONの構造を紐づけて パースするのが一般的 • その際は、フィールドの先頭は大文字で 始める必要あり • フィールドの右に`json:”xxx”`と記述する 必要あり

Slide 72

Slide 72 text

実装(構造体の定義) 72 見切れてた

Slide 73

Slide 73 text

実装(getRestoInfo関数 前半) 73 関数宣言(返り値あり) • 99行目参照 • 引数の後に返り値の型を定義

Slide 74

Slide 74 text

実装(getRestoInfo関数 前半) 74 100-104行目 • 実行するAPIのURL生成 107-120行目 • APIを実行し、レスポンスのJSONを Goで扱える形にして117行目の response型のdataに格納 • おまじない程度に思ってOK

Slide 75

Slide 75 text

実装(getRestoInfo関数 後半) 75 122-126行目 • dataに格納したJSONのデータのうち、お店 の名前と住所を抽出してinfoに格納してい き、それを呼び出し元に返却

Slide 76

Slide 76 text

【再掲】できあがり 76 位置情報を送ったら、その周辺の レストラン一覧を返すよう実装します

Slide 77

Slide 77 text

5.位置情報から周辺の飲食店を 見やすく返すLINEBOT 77

Slide 78

Slide 78 text

できあがり 78 位置情報を送ったら、 その周辺のレストラン一覧を 見やすく返すよう実装します この表示形式をカルーセルと言います

Slide 79

Slide 79 text

差分 79 https://github.com/yagi-eng/go-linebot-start/compare/resto...carousel

Slide 80

Slide 80 text

実装(メッセージ形式を変更) 80 83行目 • bot.ReplyMessage()の第2引数を変更 • before: linebot.NewTextMessage() • after: linebot.NewTemplateMessage() split形式の方が diff見やすかったので

Slide 81

Slide 81 text

実装(構造体の定義) 81 カルーセル表示用に以下の要素をJSONパース の際に取得するように構造体を定義 • 写真のURL • ホットペッパーのURL

Slide 82

Slide 82 text

実装(getRestoInfo関数) 82 スライス宣言 • 143行目参照 • ここでは*linebot.CarouselColumn型の スライスを生成 スライス追加 • 156行目参照 これ

Slide 83

Slide 83 text

実装(getRestoInfo関数) 83 145-148行目 • 住所を定義 • 60字以内に収める必要があるので、 61文字以上ある場合はそれ以降をカット ※runeでは絵文字などは1文字分以上としてカ ウントされます

Slide 84

Slide 84 text

実装(getRestoInfo関数) 84 150-155行目 • 1つ1つのカルーセルの実装と実体は以下の ように対応

Slide 85

Slide 85 text

【再掲】できあがり 85 位置情報を送ったら、 その周辺のレストラン一覧を 見やすく返すよう実装します この表示形式をカルーセルと言います

Slide 86

Slide 86 text

86 以上です!

Slide 87

Slide 87 text

おまけ 87

Slide 88

Slide 88 text

私のGoの独学の進め方 88 https://twitter.com/yagi_eng/status/1277551601167679490

Slide 89

Slide 89 text

各種アカウント ・Twitter https://twitter.com/yagi_eng ・Qiita https://qiita.com/yagi_eng ・Wantedly https://www.wantedly.com/users/135658076 ・Instagram https://www.instagram.com/yaginu_travels_around/ https://www.instagram.com/yaginu_nakame_lunch/ だいだい yagi_eng の アカウント名でやってます 89

Slide 90

Slide 90 text

とりあえず手元で動かしたい方向け 90 • 以下のリポジトリをclone(またはfolk) • https://github.com/yagi-eng/go-linebot-start/tree/master • LINE DevelopersとホットペッパーAPIに登録して、 BOT作成&各種キーなどを発行 • ngrok(外部へローカルホストを公開するツール)をインストール • cloneしたmain.goに発行した各種キーを埋め込む • 33, 34, 122行目 • 以下の順にコマンドを実行 • $ ngrok http 8080 #ngrok実行 • $ cd go-linebot-start/answer • $ go run main.go #Go実行 • ngrokが生成したURLをLINE DevelopersのBOTページでWebhookURLに登録 • 作成したボットに位置情報を送信してみる

Slide 91

Slide 91 text

91 以下再掲

Slide 92

Slide 92 text

リポジトリはこちら https://github.com/yagi-eng/go-linebot-start ⇒以下のステップ毎にブランチを作成しています、インデント下がりがブランチ名 • まずはHello, World! • hello-world • オウム返しのLINEBOT • parrot • 位置情報から経度/緯度を返すLINEBOT • latlng • 位置情報から周辺の飲食店を返すLINEBOT • resto • 位置情報から周辺の飲食店を見やすく返すLINEBOT • carousel 92

Slide 93

Slide 93 text

LINE Developersに登録 93 公式サイトを参考にアカウントを作成する ・Messaging APIを始めよう ⇒LINE Developersコンソールでチャネルを作成する https://developers.line.biz/ja/docs/messaging-api/getting-started/ ・ボットを作成する ⇒LINE Developersコンソールでボットを設定する https://developers.line.biz/ja/docs/messaging-api/building-bot/

Slide 94

Slide 94 text

LINE Developersでシークレットを取得 94 LINE Developersの各チャネル画面のBasic settingsの下の方にあります

Slide 95

Slide 95 text

LINE Developersでアクセストークンを取得 95 LINE Developersの各チャネル画面のMessaging APIの下の方にあります

Slide 96

Slide 96 text

ホットペッパーAPI 96 飲食店検索などいろいろできて、かつ気軽に使えるAPI ホットペッパーAPIリファレンス https://webservice.recruit.co.jp/doc/hotpepper/reference.html

Slide 97

Slide 97 text

APIKEYを発行 97 公式サイトの新規登録より流れで登録できます メアド登録だけなので簡単に使える!

Slide 98

Slide 98 text

実行 98 • ngrokというサービスを使い、外部からローカル環境へのアクセスを可能にする • ngrokが発行するURLをLINE DevelopersのWebhookに登録する • BOTを自分のLINEアプリに友だち追加して、メッセージを送信する 【参考】ngrokの利用方法 https://qiita.com/hirokisoccer/items/7033c1bb9c85bf6789bd

Slide 99

Slide 99 text

【再掲】Messaging APIの仕組み(公式から引用) 1. ユーザーが、LINE公式アカウントにメッセージを送信します。 2. LINEプラットフォームからボットサーバーのWebhook URLに、 Webhookイベントが送信されます。 3. Webhookイベントに応じて、ボットサーバーからユーザーに LINEプラットフォームを介して応答します。 99

Slide 100

Slide 100 text

実行(ローカル環境を外部公開) 100 以下のコマンドを実行する # 8080番を公開したい時は以下の通り $ ngrok http 8080 ngrok by @inconshreveable Session Status online Session Expires 7 hours, 59 minutes Version 2.3.35 Region United States (us) Web Interface http://127.0.0.1:4040 Forwarding http://xxxxxx.ngrok.io -> http://localhost:8080 Forwarding https:// xxxxxx.ngrok.io -> http://localhost:8080 このアドレスを Webhookに登録する ※httpsであることに注意

Slide 101

Slide 101 text

実行(Webhook登録) 101 LINE Developersの各チャネル画面のMessaging APIの下の方にあります

Slide 102

Slide 102 text

実行(友だち追加して会話) 102 LINE Developersの各チャネル画面の Messaging APIにQRコードがあるので、 友だち追加して試す