自分のインスタグラムの投稿が多くなり何を投稿したか探すのが億劫になってきたのでキーワードで投稿を検索できるサイトを勉強がてら簡単に作成しました。
使用技術はNext.js13系(SSG) + Chakra ui + Vercelです
作った投稿一覧サイト↓
https://saunabouya-search.vercel.app/
Contents
インスタグラムのapiを取得できるようにする
これがなかなか面倒でした。。。
必要な手順を以下に列挙していきます。
- Instagramをプロアカウントを切り替える
- PCでFacebookにログイン
- Facebookページを作成
- FacebookページとInstagramプロアカウントの紐づける
- Facebook for DevelopersからFacebook アプリを作成
- Instagram Graph APIを追加
- InstagramグラフAPIエクスプローラーからアクセストークンを取得
- 無期限トークンとビジネスアカウントIDを取得
詳しくは以下のリンクを参考にしてください。。
https://www.teijitaisya.com/instagram-graph-api/#index_id4
Next.jsの環境構築
以下のコマンドでNext.jsを立ち上げます。
npx create-next-app insta-post --ts
cd insta-post
npm run dev
環境変数
先ほど取得した無期限トークンとビジネスアカウントIDを.envに記載します。
NEXT_PUBLIC_INSTAGRAM_ACCESS_TOKEN=無期限トークンを入力
NEXT_PUBLIC_INSTAGRAM_BUSINESS_ID=インスタグラムのビジネスアカウントIDを入力
インスタグラムの投稿apiを取得する
インスタグラムの投稿は一度のリクエストで最大25件までしか取れません。
今回SSGで一度に全ての投稿を取得したかったので26件目以降も一度に取得するようにする必要がありました。
インスタグラムのapiではリクエストの結果に以下のようなページングのパラメーターが含まれているのでこちらを使用して26件目以降の投稿を取得します。
以下は公式ドキュメントに記載されているパラメータの例です
{
"data": [
... Endpoint data is here
],
"paging": {
"cursors": {
"after": "MTAxNTExOTQ1MjAwNzI5NDE=",
"before": "NDMyNzQyODI3OTQw"
},
"previous": "https://graph.facebook.com/{your-user-id}/albums?limit=25&before=NDMyNzQyODI3OTQw"
"next": "https://graph.facebook.com/{your-user-id}/albums?limit=25&after=MTAxNTExOTQ1MjAwNzI5NDE="
}
}
https://developers.facebook.com/docs/graph-api/results?locale=ja_JP
https://developers.facebook.com/docs/instagram-api/guides/content-publishing?locale=ja_JP
pages/api/instagram.tsにインスタグラムの投稿apiを取得するメソッドを作成します。
getInstagramPostsメソッドにはデフォルト引数を渡しておき
リクエストのパラメーターにafterのキーがある場合のみGETパラメーターを末尾に追加するようにします。
import axios from "axios";
const accessToken = process.env.NEXT_PUBLIC_INSTAGRAM_ACCESS_TOKEN;
const businessId = process.env.NEXT_PUBLIC_INSTAGRAM_BUSINESS_ID;
export async function getInstagramPosts(param = '') {
let after = ''
if(param !== '') {
after = `&after=${param}`
}
const response = await axios.get(
`https://graph.facebook.com/v16.0/${businessId}/media?access_token=${accessToken}&fields=caption%2Clike_count%2Cmedia_url%2Cmedia_type%2Cvideo_url%2Cpermalink%2Ctimestamp%2Cusername${after}`
);
return response.data;
}
getStaticPropsで投稿データを取得
先ほども書きましたがインスタグラムの投稿は一度のリクエストで最大25件までしか取れません。
なのでページ送りのパラメータが存在する限りリクエストを続けてすべての投稿を取得し、concatメソッドで一つの配列として結合します。
import { getInstagramPosts } from "@/pages/api/instagram";
export const getStaticProps = async () => {
let data:any = []; //妥協...
let after = '';
let hasNextPage = true;
while (hasNextPage) {
try {
const response = await getInstagramPosts(after);
data = data.concat(response.data);
after = "after" in response.paging.cursors ? response.paging.cursors.after : '',
hasNextPage = !!after;
} catch (error) {
console.error('Error fetching data:', error);
hasNextPage = false;
}
}
return {
props: {
data: data
}
};
};
余談なのですが最初objectのキーがない場合以下のようにundefinedを代入しておりビルド時に怒られてしまいました。。
なのでキーが存在しない場合は空文字を代入します。
after = "after" in response.paging.cursors ? response.paging.cursors.after : undefined,
`undefined` cannot be serialized as json. please use `null` or omit this value.
まとめ
今回はSSG + vercelでインスタグラムの投稿一覧ページを作成しました。
SSGなので新規でインスタグラムのフィードを投稿した際、最新の投稿が一覧には反映されていないというデメリットはありますが個人的にはなかなか使い勝手がいいのではと思っています。
結局インスタグラムのapiを取得できるようにデベロッパーアカウントを作るところが一番苦労しました。笑