#xhack勉強会 レポート -API勉強会を経て自作webアプリを作った話- 「JavaScriptと無料APIを駆使してウェブアプリ開発ハンズオン」(2019年8月18日)

33歳、未経験から学習を始めて約3ヶ月になります。
XHACK主催の勉強会に参加しひじょーーーーーに良い刺激を受け、
Twitter APIを用いた自作Webアプリをリリースできてしまったのでレポートを書きます!

0. このレポートの内容

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

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


1. 勉強会の目的

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


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

- WebAPIの概要がわかる
- WebAPIの使い方、利用方法、作り方がわかる
- データフォーマットについて理解する(JSON、XML、CSV)

(勉強会資料から引用)

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

2. APIとは?

- アプリケーション プログラミング インターフェース
- 別のソフトウェアの機能を利用する仕組み
- 要求と応答を事前に取り決めておく

(勉強会資料から引用)

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

3. WebAPIとは?

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

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

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

4. 要求(リクエスト)方法

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

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

1. ぐるなびAPIのアカウント登録をし「API key」を発行してもらう
2. 使いたいAPIを選ぶ
3. APIのURLにパラメータを付与してリクエスト

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

4-1. API keyの発行

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

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


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

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

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

4-3. 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公式に詳しく公開されています。


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


5. 返答(レスポンス)方法

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

5-1. データ形式とは?

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

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

店舗名, 住所, 電話番号1, 電話番号2
牛角, 前橋市六供町, 027-xxx-xxxx , 0120-xxx-xxxx 

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

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

5-1-1. 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()

6. 【まとめ】WebAPIの使い方

1. URLパラメータでリクエストする
2. JSON形式でレスポンスされる
3. JSONを変換し、必要なデータを取り出す

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

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

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

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

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

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

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

1. 自分のプロフィールを開く
2. 最新の報告ツイートまでさかのぼる 
3. 報告ツイートを開く       
4. 本文をコピーする        
5. 新規ツイート欄を開いてペースト
6. 日数・時間を更新する  
7. 内容を編集する
8. ツイートする

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

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

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

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


8-1. 設計構想

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

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

現状把握 ・・・ 今どうなっているか
要因分析 ・・・ 何が原因か
対策の立案 ・・・ どうすれば改善できるか
対策の実施 ・・・ 対策を実行する
効果の確認 ・・・ 対策がどれだけ効果があったかチェック


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

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で最新の報告ツイート本文を取得しすることで自動化する
・ 「日数入力欄」「時間入力欄」を設け、カーソル移動の手間をなくす
・ 学習日数は自動で更新されるようにする
・ 報告フォーマットを規定し不要な行は自動削除
・ 「前回ツイートからコピペする行」を決めておき、自動コピペ
・ ツールからワンボタンでツイート画面に遷移


8-2. Twitter APIの使い方

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

1. Twitter Developer に登録する
2. ベアラートークン(ぐるなびでいうAPI keyみたいなもん)を発行する
3. 使いたいAPIを選ぶ
4. URLパラメータでリクエスト
5. レスポンスのJSONから必要な情報を抽出


8-2-1. Twitter Developer に登録する

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


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

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


8-2-2. ベアラートークンを発行する

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

ぐるなび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エンコードする
それを「クレデンシャル」と呼ぶ

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

$api_key = '*********************';// APIキー (隠してます)
$api_secret = '************************';// APIシークレット(隠してます)

// クレデンシャルを作成
$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%3DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
}


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

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

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


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


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



// リクエスト用のコンテキストを作成する
$context = array(
	"http" => array(
		"method" => "POST" , // リクエストメソッド
		"header" => array(	// ヘッダー
			"Authorization: Basic " . $credential ,
			"Content-Type: application/x-www-form-urlencoded;charset=UTF-8" ,
		) ,
		"content" => http_build_query(	// ボディ
			array(
				"grant_type" => "client_credentials" ,
			)
		) ,
	) ,
) ;

// ストリームコンテキストを生成する
$streamContext = stream_context_create( $context );


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

<?php
// 設定項目
$api_key = '****************'; // APIキー (隠してます)
$api_secret = '***************'; // APIシークレット (隠してます)

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

// リクエストURL
$request_url = "https://api.twitter.com/oauth2/token" ;

// リクエスト用のコンテキストを作成する
$context = array(
	"http" => array(
		"method" => "POST" , // リクエストメソッド
		"header" => array(			  // ヘッダー
			"Authorization: Basic " . $credential ,
			"Content-Type: application/x-www-form-urlencoded;charset=UTF-8" ,
		) ,
		"content" => http_build_query(	// ボディ
			array(
				"grant_type" => "client_credentials" ,
			)
		) ,
	) ,
) ;

// ストリームコンテキストを生成する
$streamContext = stream_context_create( $context );

// HTTPリクエストを実行 (レスポンスとしてベアラートークン入りのJSONが返ってくる)
$response = file_get_contents( $request_url , false , $streamContext ) ;

// JSONを配列に変換する
$arr = json_decode( $response, true ) ;


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

//$arr の中身
{
    "token_type"    => "bearer", 
    "access_token"  => "(ベアラートークン)"


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

$bearerToken = $arr["access_token"];

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

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

// APIを使うときのリクエスト用のコンテキスト
$context = array(
	'http' => array(
		'method' => 'GET' , // リクエストメソッド
		'header' => array(  // ヘッダー
			'Authorization: Bearer '. $bearerToken, //ベアラートークン
		) ,
	) ,
) ;


8-2-3. 使いたいAPIを選ぶ

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

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


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


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


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


8-2-4. やっとリクエスト!!!!レスポンス!!!!!

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

screen_name = (Twitter ユーザ名) // ツイートを取得する対象ユーザ名
count = 100      // 最新100件を取得する
include_rts = false           // リツイートを除外する
exclude_replies = true     // リプライを除外する
tweet_mode = extended  // ツイートを省略せず全文取得する


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

1. 過去ツイートを100件取得する(多すぎると処理遅くなりそうなので制限
2. 100件の中から報告ツイートを抽出する(ロジックは後述)
3. 報告ツイートの本文を取得する

過去100件の中にさすがに報告ツイートがあると想定しています。
学習進捗報告ツイートはリツイートやリプライではないことが想定されるため、リクエスト段階で除外しました。

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

$count = 100;

// パラメータ指定
$params = array(
	    'screen_name' => (Twitter ユーザID),
	    'count' => $count ,
	    'include_rts' => false,
	    'exclude_replies' => true,
	    'tweet_mode' => 'extended',//ツイート全文が表示されるようにする 
                        //jsonがtextでなくfull_textになることに注意
	) ;

// リクエストURL
$requestUrl ='https://api.twitter.com/1.1/statuses/user_timeline.json';

// クエリ形式に変換
if($params){
       	$Qparams = http_build_query($params);
	$requestUrl .= '?'.$Qparams;
}

// リクエスト用のコンテキスト
$context = array(
	'http' => array(
		'method' => 'GET' , // リクエストメソッド
		'header' => array(  // ヘッダー
			'Authorization: Bearer '. $bearerToken,
		) ,
	) ,
) ;

// ストリームコンテキストを作成
$Scontext = stream_context_create($context);

// HTTPリクエストを実行 (レスポンスとして過去ツイート情報がJSONで返ってくる)
$json = file_get_contents($requestUrl, false, $Scontext);
$tweets = json_decode($json, true); //jsonを連想配列に変換 falseだとオブジェクトに変換

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


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

// $tweets の中身 デコードされたJSON
Array
(
   [0] => Array //1件目のツイート 
       (
           [created_at] => Sun Sep 08 04:16:26 +0000 2019
           [id] => 1170551442907643905
           [id_str] => 1170551442907643905
           [full_text] => ちょっとした隙間時間にスマホから作業しようとするんだけど、ぜんぜん集中できず時間終わってしまう😇
           [truncated] => 
           [display_text_range] => Array
               (
                   [0] => 0
                   [1] => 48
               )

           [entities] => Array
               (
                   [hashtags] => Array
                       (
                       )

                   [symbols] => Array
                       (
                       )

                   [user_mentions] => Array
                       (
                       )

                   [urls] => Array
                       (
                       )

               )

           [source] => <a href="http://twitter.com/download/iphone" rel="nofollow">Twitter for iPhone</a>
           [in_reply_to_status_id] => 
           [in_reply_to_status_id_str] => 
           [in_reply_to_user_id] => 
           [in_reply_to_user_id_str] => 
           [in_reply_to_screen_name] => 
           [user] => Array
               (
                   [id] => 1130503281271222272
                   [id_str] => 1130503281271222272
                   [name] => がき@地方で強く生きていく
                   [screen_name] => gakisan8273
                   [location] => グンマー
                   [description] => 【楽しく生きる】ためお金の勉強をしている30代勤め人 / 収入源を増やすべく未経験からプログラミングを勉強中 / まずは副業で月5万稼ぐ! / 効率化・システム化が大好物 / 2児の父 / 現職はメカエンジニア兼マネージャー / 転職3回出戻り有/

学習進捗報告ツイート支援ツールを作成しました⬇︎
                   [url] => https://t.co/yE0kDdw15y
                   [entities] => Array
                       (
                           [url] => Array
                               (
                                   [urls] => Array
                                       (
                                           [0] => Array
                                               (
                                                   [url] => https://t.co/yE0kDdw15y
                                                   [expanded_url] => http://gakisan8273.com/reportsupporter/
                                                   [display_url] => gakisan8273.com/reportsupporte…
                                                   [indices] => Array
                                                       (
                                                           [0] => 0
                                                           [1] => 23
                                                       )

                                               )

                                       )

                               )

                           [description] => Array
                               (
                                   [urls] => Array
                                       (
                                       )

                               )

                       )

                   [protected] => 
                   [followers_count] => 873
                   [friends_count] => 972
                   [listed_count] => 8
                   [created_at] => Mon May 20 15:59:20 +0000 2019
                   [favourites_count] => 8599
                   [utc_offset] => 
                   [time_zone] => 
                   [geo_enabled] => 
                   [verified] => 
                   [statuses_count] => 708
                   [lang] => 
                   [contributors_enabled] => 
                   [is_translator] => 
                   [is_translation_enabled] => 
                   [profile_background_color] => F5F8FA
                   [profile_background_image_url] => 
                   [profile_background_image_url_https] => 
                   [profile_background_tile] => 
                   [profile_image_url] => http://pbs.twimg.com/profile_images/1132304176694812673/0Zx6ddK9_normal.jpg
                   [profile_image_url_https] => https://pbs.twimg.com/profile_images/1132304176694812673/0Zx6ddK9_normal.jpg
                   [profile_banner_url] => https://pbs.twimg.com/profile_banners/1130503281271222272/1558797437
                   [profile_link_color] => 1DA1F2
                   [profile_sidebar_border_color] => C0DEED
                   [profile_sidebar_fill_color] => DDEEF6
                   [profile_text_color] => 333333
                   [profile_use_background_image] => 1
                   [has_extended_profile] => 1
                   [default_profile] => 1
                   [default_profile_image] => 
                   [following] => 
                   [follow_request_sent] => 
                   [notifications] => 
                   [translator_type] => none
               )

           [geo] => 
           [coordinates] => 
           [place] => 
           [contributors] => 
           [is_quote_status] => 
           [retweet_count] => 0
           [favorite_count] => 3
           [favorited] => 
           [retweeted] => 
           [lang] => ja
       )
[1] = Array( ... // 2件目のツイート [99]まで続く


8-3. 過去ツイートから進捗報告ツイートを抽出

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

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

$tweetFormat = <<<EOT   //実際は入力フォームからPOSTして登録する
Day : 80          
Today : 2h / 補足 1.5h   
Total : 150h / 補足 75h

EOT;

// 連続した英字、ひらがな、カタカナ、漢字を検索 半角・全角スペースは含まれない
$pattern = '/[a-zA-Zぁ-んァ-ヶー一-龠]+/u'; 
    // フォーマットから正規表現で該当するパターンを全て検索
    // 該当結果が第三引数 $searchWordsArray に多次元配列で格納される
    preg_match_all($pattern, $tweetFormat, $searchWordsArray );
    
    // 多次元配列を1次元配列に修正
    foreach($searchWordsArray[0] as $val){
      $searchWords[] = $val; // これが検索パターンの配列
    }

// セッションに検索パターンを格納
$_SESSION['pattern'] = $searchWords;     


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

// 過去ツイート1件目から100件目までループする
for($i = 0; $i < $count; $i++){
    if (!empty($tweets[$i])){

        // $tweet はAPIのレスポンスが格納
        // ツイート本文を取得
	$tweetText = $tweets[$i]['full_text']; 
        // ツイート日を取得
	$created_at = date('Y-m-d H:i', strtotime($tweets[$i]['created_at']));
	$flg1 = array(); //ツイートが各検索ワードにマッチすれば立たせる
	$flg2 = 0; // flg1がfalseならインクリメントする
                  // 全部のワード検索が終わった後、flg2が0なら=全部Trueなら
                  // それが報告ツイート
	
        // 全ての検索ワードで判定 マッチしなかったら flg2 が立つ
        foreach ($_SESSION['pattern'] as $val){
	    $flg1 = preg_match('/'.$val.'/i', $tweets[$i]['full_text']);
	    if(!$flg1){
	    	$flg2++;
	    }
	}
        // flg2が立っていない → 全ての検索ワードにマッチした → 報告ツイート
	if($flg2 === 0){
            // 報告ツイートのインスタンスを生成
	    $tweet[] = new PreviousTweets($tweetText,$created_at);
	}
    }
}


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

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


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

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


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

◾️改善前

1. 自分のプロフィールを開く
2. 最新の報告ツイートまでさかのぼる
3. 報告ツイートを開く   
4. 本文をコピーする 
5. 新規ツイート欄を開いてペースト
6. 日数・時間を更新する
7. 内容を編集する
8. ツイートする


◾️改善後

1. webアプリを開く
2. 日数・時間を更新する
3. 内容を編集する
4. ツイートする


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

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

9. まとめ / 勉強会への所感

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

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


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


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

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

2020年10月 追記
勉強会の成果もあり、2020年1月からITエンジニアに転身を果たしました!
33歳からの新しい挑戦です。

僕は4回の転職経験となり、累計で書類通過率約90%・内定率約75%ほどでした。 転職や職務経歴書のノウハウをここで公開してますので、是非参考にしてください。


この記事が気に入ったらサポートをしてみませんか?