はじめに
Qiita APIを使って記事を自動で取得する方法についてまとめます。
今回はLaravelを使って実装しました。
Qiita認証
まずはQiitaの設定からアプリケーションを登録してClient IDとClient Secretを入手します。
次に設定ファイルに先ほど入手して情報を追加します。
QIITA_CLIENT_ID=
QIITA_CLIENT_SECRET=
QIITA_REDIRECT_URI=
QiitaControllerを使ってトークンを保存します
Qiitaトークンとは、Qiita APIで本人認証を行うための鍵です。
ルーティングの設定
Route::get('/qiita/auth', [QiitaController::class, 'redirectToQiita'])->name('qiita.auth');
コントローラーの作成
public function redirectToQiita()
{
$query = http_build_query([
'client_id' => env('QIITA_CLIENT_ID'),
'scope' => 'read_qiita',
'state' => csrf_token(),
]);
return redirect("https://qiita.com/api/v2/oauth/authorize?$query");
}
ビューの作成
<a href="{{ route('qiita.auth') }}">Qiitaアカウントを連携する</a> |
これでボタンを押すとQiitaの認証ページに飛ばすことができます。
次はトークンを保存する処理を実装します。
認証した後に設定したURLへリダイレクトされます
Route::get('/qiita/callback', [QiitaController::class, 'handleCallback'])->name('qiita.callback');
トークン情報を保存します
codeはURLに入っている
public function handleCallback(Request $request)
{
$response = Http::withHeaders([
'Content-Type' => 'application/json',
])->post('https://qiita.com/api/v2/access_tokens', [
'client_id' => env('QIITA_CLIENT_ID'),
'client_secret' => env('QIITA_CLIENT_SECRET'),
'code' => $request->code,
]);
$data = $response->json();
$user = \App\Models\User::find(1);
$user->qiita_token = $data['token'] ?? null;
$user->save();
return redirect()->route('mypage');
}
記事の取得と保存
ルーティング
Route::get('/qiita/sync', [QiitaController::class, 'syncQiitaArticles'])->name('qiita.sync');
コントローラー
updateOrCreateとはLaravel標準のORMの機能で短くまとめることができます
public function syncQiitaArticles()
{
$user = \App\Models\User::find(1);
$token = $user->qiita_token;
$response = Http::withHeaders([
'Authorization' => "Bearer {$token}",
])->get('https://qiita.com/api/v2/authenticated_user/items');
$articles = $response->json();
foreach ($articles as $item) {
\App\Models\Article::updateOrCreate(
[
'url' => $item['url'],
'user_id' => $user->id,
],
[
'title' => $item['title'],
'created_at' => $item['created_at'],
]
);
}
return redirect()->route('mypage');
}
ビュー
記事一覧表示
ルーティング
Route::get('/mypage', function () {
$articles = Article::all();
return view('mypage', compact('articles'));
})->name('mypage');
ビュー
issetでarticlesがコントローラーから渡されているかチェックして、あればforeachで一つづつ表示します。
@isset($articles)
<h2>あなたのQiita記事一覧</h2>
<ul>
@foreach ($articles as $article)
<div class="article-card">
<h3>{{ $article['title'] }}</h3>
@if($article['image_path'])
<img src="{{ asset('storage/' . $article['image_path']) }}" width="200">
@endif
<p>
<a href="{{ $article['url'] }}" target="_blank">Qiita記事を見る</a><br>
@if($article['github_url'])
<a href="{{ $article['github_url'] }}" target="_blank">GitHubを見る</a>
@endif
</p>
<a href="{{ route('articles.edit', $article->id) }}">編集</a>
</div>
@endforeach
</ul>
@endisset
画像とGitHub URLを追加
ルーティング
Route::get('/articles/{id}/edit', [ArticleController::class, 'edit'])->name('articles.edit');
コントローラー
findOrFailは記事をDBから取得(なければ404エラーを返す)
public function edit($id)
{
$article = Article::findOrFail($id);
return view('edit', compact('article'));
}
ビュー
画像とGitHub URLを追加できます
@extends('layout')
@section('content')
<h1>{{ $article->title }} の編集</h1>
<form action="{{ route('articles.update', $article->id) }}" method="POST" enctype="multipart/form-data">
@csrf
<div>
<label>GitHub URL:</label>
<input type="text" name="github_url" value="{{ $article->github_url }}">
</div>
<div>
<label>画像:</label>
@if($article->image_path)
<img src="{{ asset('storage/' . $article->image_path) }}" width="200"><br>
@endif
<input type="file" name="image">
</div>
<button type="submit">更新</button>
</form>
@endsection
編集した内容を更新します
ルーティング
Route::post('/articles/{id}', [ArticleController::class, 'update'])->name('articles.update');
コントローラー
public function update(Request $request, $id)
{
$article = Article::findOrFail($id);
$article->github_url = $request->github_url;
if ($request->hasFile('image')) {
$path = $request->file('image')->store('articles', 'public');
$article->image_path = $path;
}
$article->save();
return redirect()->route('mypage');
}
マイページで更新された内容が表示されます。
まとめ
今回はQiita APIを使って記事を取得する方法をやりました。
また、取得した記事情報に画像とGitHub URLを追加しました。
参考文献