プログラミング

プログラミング未経験者がAPI勉強会を経て自作webアプリを作った話(#xhack勉強会レポート)

33歳、未経験から学習を始めて約3ヶ月になります。(2019年9月現在)
XHACK主催の勉強会に参加しひじょーーーーーに良い刺激を受け、
Twitter APIを用いた自作Webアプリをリリースできてしまったのでレポートを書きます!
※この記事はnoteに掲載したものを一部修正したものです

※2019年11月 追記
xhack勉強会主催者の松田さん@xhack20にお誉めいただきました

このレポートの内容

勉強会でWebAPIの仕組みを学んだ結果、自作Webアプリリリースまで自走できたことのお話です。
勉強会の内容を応用すればこんなことができる!という一例としてレポートします。

勉強会の内容について細かくレポートしているものではありません。
それはこちら(note記事)に別レポートがあるのでぜひご参照ください。

今回参加した勉強会はこちら
JavaScriptと無料APIを駆使してウェブアプリ開発ハンズオン

xHack勉強会についてはこちら(connpass)

勉強会の目的

「ぐるなびAPI」を題材とし、このようなWebサイトを作成します。

ぐるなびAPI

その中で以下のことを理解することが目的です。

– WebAPIの概要がわかる

– WebAPIの使い方、利用方法、作り方がわかる

– データフォーマットについて理解する(JSON、XML、CSV)

(勉強会資料から引用)

…正直、そんな簡単に作れちゃうの?って疑問を持ちながらのスタートでした。

APIとは?

– アプリケーション プログラミング インターフェース

– 別のソフトウェアの機能を利用する仕組み

– 要求と応答を事前に取り決めておく

(勉強会資料から引用)

つまり、あるソフトウェアのデータを他のソフトウェアから呼び出したい時
「データを要求する方法」「データを受け渡す方法」
これを定めておくことで扱いやすくするもの! と僕は理解しました!

WebAPIとは?

「ネットワークで使えるAPI」ただそれだけ!!!
もっと詳しく知りたい方はGoogle先生に聞いてみてください。
今回の題材でいう「ぐるなびAPI」は、

ぐるなび(ネットワーク上) ⇄ PC

というネットワーク越しでのやりとりをしているので、WebAPIですね。
他にもAmazon・Facebook・Twitterなど、様々なWebAPIが存在します。
これらの多くは無料で使用できるとのこと!!!
無料で有用なデータを自分のwebサイトに用いることができる…太っ腹…

要求(リクエスト)方法

ぐるなびAPIのデータ要求(リクエスト)方法は、URLパラメータにて行うと取り決められています。GET送信とかのあれです。

https://gakisan8273.com/blog/how_to_use_get/

ざっくりの流れはこうなります。

1. ぐるなびAPIのアカウント登録をし「API key」を発行してもらう

2. 使いたいAPIを選ぶ

3. APIのURLにパラメータを付与してリクエスト

もうちょい細かく見ていきましょう。

API keyの発行

ぐるなびAPIの場合はアカウント登録をして「ぐるなびAPI key」をぐるなびから発行してもらい、APIを使うときにAPI keyで認証をとる必要があります。(他のAPIでも、なんらかの認証が必要です。)

といっても簡単で、↓ここ↓から単純に登録するだけ。その辺のサービスの会員登録と変わりありません。

https://ssl.gnavi.co.jp/api/regist/?p=input

4-2. 使いたいAPIを選ぶ

APIって、同じサービスの中に複数あるんです。知らんかった…

今回は「レストランを検索する」ことをするとし、「レストラン検索API」を使うことにしましょう。

URLパラメータでリクエスト

「レストラン検索API」のURLはこちらです。
https://api.gnavi.co.jp/RestSearchAPI/v3/
これにパラメータを付与してリクエストすればOK。
パラメータは以下のように取り決められています。

・keyid(自分のAPI key)認証のため必須
・他は任意

「焼肉」でフリーワード検索した結果が欲しいとしましょう。
実際のリクエスト方法はこうなります。

(例:ぐるなびAPI リクエスト方法)

https://api.gnavi.co.jp/RestSearchAPI/v3/?keyid=(自分のAPI key)&freeword=焼肉

keyid=(自分のAPI key) :
API key を送信することで「認証されたアカウントからAPIを利用している」ことをぐるなび側へ認識させています。
(API keyが間違っているとエラーになり結果を受信できない)

freeword=焼肉 :
パラメータ「freeword」はフリーワード検索するときのパラメータ名
「焼肉」はフリーワード検索に使うワード

他にも店舗名で検索したり、住所で検索するパラメータが用意されています。

リクエストの方法は、ぐるなびAPI公式に詳しく公開されています。

https://api.gnavi.co.jp/api/manual/restsearch/?_ga=2.102019073.1876674989.1567524198-988801239.1566098548

このようにすると、ぐるなびAPIから返答(レスポンス)として検索結果が返ってきます。
次はレスポンスの方法を見ていきましょう!

返答(レスポンス)方法

ぐるなびAPIのリクエストはURLパラメータで送信することが分かりました。
対してレスポンスは、いくつかのデータ形式で返されます。

データ形式とは?

一定のルールのもとデータを記述するとし、そのルールをデータ形式と呼びます。

例えば「データの区切りはカンマとする」というルールでデータを記述するとこうなります。

店舗名, 住所, 電話番号1, 電話番号2

牛角, 前橋市六供町, 027-xxx-xxxx , 0120-xxx-xxxx

「データの区切りはカンマとする」ルールは「CSV形式」(comma-separated-values)と呼ばれています。これはエクセルを使っているとたまに見ますね。

WebAPIで代表的なのは「JSON」形式です。
どんな形式なのか、確認してみましょう!

JSON

JSON (JavaScript Object Notation)です。なんのこっちゃ・・・
JavaScriptのオブジェクトみたいなデータ形式のことらしいです。
正確でないかもしれないけど簡単に言うと、
・{}で囲う
・”key” と”value” を対応させる
・配列も使える

つまり、こう。

{

 ”店舗名” : “牛角”,

 ”住所” : “前橋市六供町”,

 ”電話番号” : [“027-xxx-xxxx”, “0120-xxx-xxxx”]

}

連想配列のように、keyとvalueが対応してますね。
電話番号が複数ある場合、valueを配列として表しています。

実際のぐるなびAPIのレスポンスはこうなります。
(「静岡県」で検索した結果)

ここから必要なデータを抽出して変数に格納してしまえば、あとは自分のプログラムで自由に使えるってことになりますね!!

ただし、JSONを操作できるようにするため、以下の関数で変換(デコード)する必要があることに注意!!!!
・JavaScript なら JSON.perse()
・PHP なら json_decode()

【まとめ】WebAPIの使い方

1. URLパラメータでリクエストする

2. JSON形式でレスポンスされる

3. JSONを変換し、必要なデータを取り出す

たったこれだけ!簡単!!

勉強会で学んだことを応用してみよう!

実際の勉強会ではそのあと、
・DOMの動的追加によるHTML構築
・検索フォームの実装
などなどを実施してWebサイトを作ったんですが…このレポートでは省略します。

この勉強会でもっとも有益だったのは「APIいけるやん!!」という感覚を持てたことです。
勉強会で得た知識を応用し、APIを使って自分なりに何かアウトプットをしようと思い立ちました!!

PHPとTwitterAPIで学習報告ツイート支援ツールを作る

僕はTwitterで毎日の学習進捗をツイートしています。こんな風に。
プログラミング学習者は同じように報告ツイートしている人が多く見受けられます。

これを毎回ツイートするのに、以下のステップを踏んでいます。

1. 自分のプロフィールを開く

2. 最新の報告ツイートまでさかのぼる

3. 報告ツイートを開く

4. 本文をコピーする

5. 新規ツイート欄を開いてペースト

6. 日数・時間を更新する

7. 内容を編集する

8. ツイートする

んー・・・生産性のない行動が多いような・・・
これを改善したいとつねづね考えていました…KAIZEN!!

APIの仕組みを理解した今、Twitter APIを使えば1〜4が自動でできちゃうんじゃね?と思い、勉強会で得たことのアウトプットも兼ねて
Twitter APIを使ったツールを作ってみることにしました!!

勉強会ではJavaScriptでAPIを使いましたが、API keyの漏洩防止のためサーバサイド言語のPHPで開発します。

そしてせっかくツールを作るのだから、
自分だけじゃなく他の人も使えるものを作ろう!!と考えました。

設計構想

QCストーリーを利用して設計構想を練りました。
製造業ではよく使われる手法なのですが、考えを整理するのにおすすめ。

QCストーリー(wikipedia)

以下の流れで進めていきます。

現状把握 ・・・ 今どうなっているか

要因分析 ・・・ 何が原因か

対策の立案 ・・・ どうすれば改善できるか

対策の実施 ・・・ 対策を実行する

効果の確認 ・・・ 対策がどれだけ効果があったかチェック

現状把握

「今どうなっているか」を把握します。先ほどのコピペ。
僕のフォロワーさんにアンケートを取った結果、大多数の人がこのように報告ツイートを作っていることが分かりました。

1. 自分のプロフィールを開く

2. 最新の報告ツイートまでさかのぼる

3. 報告ツイートを開く 

4. 本文をコピーする 

5. 新規ツイート欄を開いてペースト

6. 日数・時間を更新する

7. 内容を編集する

8. ツイートする

要因分析

「なぜ面倒くさいか?」を分析します。
先ほどのアンケートの中で、何が面倒かを聞いた結果をまとめました。

1. 自分のプロフィールを開く    

 ・・・ 自分のプロフなんて滅多に見ないし、他の画面を開いていたい

2. 最新の報告ツイートまでさかのぼる

 ・・・ 普通のツイートに紛れて報告ツイがどこにあるか見つけにくい

3. 報告ツイートを開く

 ・・・ たかがワンタップ、されどワンタップ

4. 本文をコピーする

 ・・・ 範囲を選択してコピー、地味に面倒

5. 新規ツイート欄を開いてペースト

 ・・・ はいはいペーストペースト

6. 日数・時間を更新する

 ・・・ 日数と時間の場所にカーソルを移動するのが地味に手間

     日数のカウント間違いがよくある

7. 内容を編集する

 ・・・ 不要な本文は消して、必要なとこは残して、大抵毎回同じ作業

8. ツイートする

 ・・・ さすがに面倒ではないとする

対策の立案

「どうすれば改善できるか」を示す。

1. 自分のプロフィールを開く    

2. 最新の報告ツイートまでさかのぼる

3. 報告ツイートを開く

4. 本文をコピーする

5. 新規ツイート欄を開いてペースト

 → Twitter APIで最新の報告ツイート本文を取得しすることで自動化する

  ※ 本レポートはこの部分を詳細に記載します

6. 日数・時間を更新する

 → 「日数入力欄」「時間入力欄」を設け、カーソル移動の手間をなくす

    学習日数は自動で更新されるようにする

7. 内容を編集する

 → 報告フォーマットを規定し不要な行は自動削除

  「前回ツイートからコピペする行」を決めておき、自動コピペ

8. ツイートする

 → ツールからワンボタンでツイート画面に遷移

対策の実施

それでは立案した対策を実装していきます!
今回はAPI勉強会のレポなので、
Twitter APIを使った所のみ細かく書きます!

・ Twitter APIで最新の報告ツイート本文を取得しすることで自動化する

・ 「日数入力欄」「時間入力欄」を設け、カーソル移動の手間をなくす

・ 学習日数は自動で更新されるようにする

・ 報告フォーマットを規定し不要な行は自動削除

・ 「前回ツイートからコピペする行」を決めておき、自動コピペ

・ ツールからワンボタンでツイート画面に遷移

Twitter APIの使い方

ざーっくり以下の通りです。ぐるなびとあまり変わらず。

1. Twitter Developer に登録する

2. ベアラートークン(ぐるなびでいうAPI keyみたいなもん)を発行する

3. 使いたいAPIを選ぶ

4. URLパラメータでリクエスト

5. レスポンスのJSONから必要な情報を抽出

Twitter Developer に登録する

まずこちらから登録してくださーい。

https://developer.twitter.com/en.html

英語のサイトかつ登録方法もややこしいので、以下のサイトを参考にしました。

https://syncer.jp/Web/API/Twitter/REST_API/

ぶっちゃけこのサイト見ればこの先の方法全て書いてあります!
でも僕がより初心者にわかるように噛み砕きますので、このまま読んであげてください。

ベアラートークンを発行する

ベアラートークン(笑)いきなり知らない単語が出てきて困惑しました。

ぐるなびAPIでのAPI keyに相当する、Twitter APIを使うための認証キーみたいなもんです。
(もっと強い権限を持ったアクセストークンというものもあります)

ぐるなびAPIと違うのは、登録をするだけでは発行できないということ。
Twitter Developerに登録が終わったら、ここに
「API key」と「API secret key」が表示されているはずです。
これらを用いて、ベアラートークンを発行する手続きを取ります。

まず以下に従い、API keyとAPI key secretをBase64エンコードします。
(Base64は64進数のエンコード方式です。なんか便利らしい)

ざっくりと要約するとこうなります。

2つを コロン( : ) で繋いだ

「”API key” : “API secret」を Base64エンコードする

それを「クレデンシャル」と呼ぶ

コードはこう。上記のクレデンシャルを作成します。

// クレデンシャルを作成
$credential = base64_encode( $api_key . “:” . $api_secret ) ;

次にベアラートークンを発行しにいきます。
以下によるとPOSTリクエストが必要。ぐるなびAPIと違う!

頑張って読み解いていくと・・・こうすればいいみたい

◾️HTTPリクエストのヘッダー:

・Authorizationの値を

Basic +クレデンシャル(さっきBase64エンコードして作ったやつ)にする

・Content-Typeの値を

”application/x-www-form-urlencoded;charset=UTF-8”にする

◾️HTTPリクエストのボディ:

・grant_type=client_credentials にする

そのリクエストのサンプルがこちら。

レスポンスはこう。JSON形式で返ってくるようです。

レスポンスの以下の部分がJSONですね。
“access_token” のvalueがベアラートークンを表しています。

{

“token_type”:”bearer”,

“access_token”:”AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2FAAAAAAAAAAAAAAAAAAAA%3DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA”

}

実際にリクエストしてレスポンスを取得する方法として、
file_get_contents 関数を使う必要があります。

https://www.php.net/manual/ja/function.file-get-contents.php

この関数はHTTPリクエストを実行し、レスポンスを返してくれるものです。(僕はそう理解しました)

パラメータは以下。filename はリクエスト先のURLとします。

contextはHTTPリクエストの中身を指定するストリームコンテキストとします。
まずリファレンスの通りにストリームを作成し、stream_context_create関数でストリームコンテキストを生成します。
(正直ストリームコンテキストがいまだに理解ができてません。こうすればできる、ということだけ把握しました)

メソッドはPOST、ヘッダーにはAuthorizationとContent-Typeを指定します。そしてボディにはgrant_typeを指定。

ようやくベアラートークンを発行する準備が整いました。
(まだAPI使えません!!!)
ベアラートークンを発行するコードをまとめるとこのようになります。
これで、POSTでのリクエストが実行されます。

$arr にはJSONをデコードして配列に変換されたものが格納されています。

なので、以下のようにすればベアラートークンの値が取得できます。

はいお疲れ様です。
ベアラートークンが取得できたので、Twitter APIを使う準備が整いました!!!!

あとは実際にAPIを使うとき、HTTPヘッダーにベアラートークンを入れてあげればOK。

使いたいAPIを選ぶ

Twitter APIを使う目的は、「最新の報告ツイート本文を取得する」でした。
言い換えれば「指定ユーザのプロフィールのタイムラインから報告ツイート本文を取得する」となります。

それに相当するAPIはこれです。

https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-user_timeline

URLパラメータ(GET)でリクエストします。URLは以下。
レスポンスはJSONです。ぐるなびと同じで一安心。

パラメータはこちら。ここから必要なものをURLに付与していきます。

やっっっっとこれでリクエストできる・・・!!!!!

やっとリクエスト!!!!レスポンス!!!!!

リクエストのパラメータを指定する必要があります。
今回はこのように指定しました。

screen_name = (Twitter ユーザ名) // ツイートを取得する対象ユーザ名

count = 100      // 最新100件を取得する

include_rts = false // リツイートを除外する

exclude_replies = true // リプライを除外する

tweet_mode = extended // ツイートを省略せず全文取得する

このAPIを使う目的は「指定ユーザのプロフィールのタイムラインから報告ツイート本文を取得する」でした。
その流れはこんな感じ。

1. 過去ツイートを100件取得する(多すぎると処理遅くなりそうなので制限

2. 100件の中から報告ツイートを抽出する(ロジックは後述)

3. 報告ツイートの本文を取得する

過去100件の中にさすがに報告ツイートがあると想定しています。

学習進捗報告ツイートはリツイートやリプライではないことが想定されるため、リクエスト段階で除外しました。

実際のリクエストはこうです。

$tweets にデコードされたJSON形式のレスポンスが格納されています。
つまり100件の過去ツイートを取得できたということです。

レスポンスで取得したJSONの中身はこうなります。

過去ツイートから進捗報告ツイートを抽出

無事APIで自分の過去ツイートを取得できましたが、このままではどれが報告ツイートかわかりません。
進捗報告ツイートは毎回同じフォーマットで作られていますので、
「フォーマットの文字列が含まれるツイート」を抽出することで、それを進捗報告ツイートと判定することができます。

文字列を特定するため、まずフォーマットを登録します。
そこから「英字・ひらがな・カタカナ・漢字」を抽出し、これを検索パターンとします。
抽出した文字列をセッションに詰めておきます。(2回目以降のアクセスで再登録が不要なように)

抽出した文字列を全て含むものを「進捗報告ツイート」とします。

これで、APIを用いて
「指定ユーザの過去ツイートから進捗報告ツイートを抽出する」
が実現できました!

あとは最新の報告ツイートから日数や時間を読み取ったり、新しい報告ツイート生成のため入力フォームをつくったりなんやかんやすると…
こんなツールが出来上がりました!!

学習進捗報告ツイート支援Webアプリ 「Report Supporter」

こうして出来上がったものがこちらになります。

https://gakisan8273.com/reportsupporter/

学習進捗報告ツイートの作成の、改善前後の比較は以下。

◾️改善前

1. 自分のプロフィールを開く

2. 最新の報告ツイートまでさかのぼる

3. 報告ツイートを開く

4. 本文をコピーする

5. 新規ツイート欄を開いてペースト

6. 日数・時間を更新する

7. 内容を編集する

8. ツイートする

◾️改善後

1. webアプリを開く

2. 日数・時間を更新する

3. 内容を編集する

4. ツイートする

工程が大幅に短縮され時短になっていることがわかります。

これをweb上に公開し、自分以外のプログラミング学習者が実際に使用してくれています。うれしい。

まとめ / 勉強会への所感

勉強会で学ぶことは、google先生がいれば自力でも学ぶことができます。
でもこの勉強会のおかげでこんなツールを作れるくらいに成長しました。

僕にとって勉強会は「知識を教えてくれる場所」であることはもちろん、
それに加えて「知識を得るきっかけを作る場所」です。

勉強会の内容を応用し、自ら何かを作り出す(アウトプット)することで本当の意味でインプットする。

これから勉強会に参加される方に、
僕の経験が少しでも参考になれば幸いです。

また(群馬から)勉強会参加するぞー!!!