目次

【Hugo】NetlifyのFunctionsで楽天市場のAPIから商品リンクを作成する


このブログは2年ほど前からWordpressからHugoに移行していて、細かなところを自分の勉強や暇つぶしを兼ねていじっています。CDNはNetlifyを利用していますが、Functionsで楽天APIを利用できるようにしてみたので軽くまとめます。

楽天APIはアイデア次第で何だか色々なことができそうですが、今のところ何ができそうかは見えていません。

バイバイ、WordPress。ハロー Hugo

WordPressをやめてHugoに移行した。

Hugoとは?

Hugoとは、静的サイトジェネレータの1つで、Go言語で開発されています。特徴としては、高速かつ軽量、ビルドが非常に早いことです。このサイトもローカル環境はDockerにして、コンテナの中にはビルドキャッシュを含めないようにしていますが、全ページのビルドに20秒程。1ページを新規更新するのには20msほどしかかかりません。一般に、静的サイトジェネレータは、動的なサーバーが必要ないため、セキュリティが向上し、ホスティングやデプロイも簡単とされています。

ホスティングはNetlifyにお任せですが、自分たちでフロントページも作るなら、読み込み専用にすることが簡単そうですね。

Netlify Functionsとは?

Netlify Functionsは、小規模なAPIやバックエンド処理を簡単かつ効果的に作成・デプロイできます。これにより、静的サイトに動的な機能を追加することができます。裏側の仕組みは、AWSのLamdaを利用1しているそうです。

無料枠でも1ヶ月あたり 125万回の実行が可能です。多分ですが、AWSのサポート期限に沿う形になると思うので、Node.js 16を利用している場合は、今年の6月までにアップデートしないと行けなさそう2です。

実装手順

Netlifyのアカウントは作成済み、Hugoでのデプロイも済ませている前提となりますが、Functionsを作成することは結構簡単です。ローカル環境も用意するとなると一手間必要ですがそう大きな問題はないでしょう。

ショートコードの作成

楽天APIを呼び出すためのショートコードを作成します。今回はAmazonリンクと一緒に楽天の商品リンクを出すようにしてみました。

こういうのですね↓

Anker Charging Station (7-in-1, 100W) …

最大100Wの急速充電:USB-Cポートは最大100W出力に対応し、MacBook Proなどのノー …

仕組みとしては、ショートコードでまず第一引数をAmazonで取得するAPIを実行するFunctions、次に第二引数を楽天のAPIを実行するショートコードとしています。

1
2
3


{{/*  hoge B0CHFNYC7L "Anker Charging Station (7-in-1, 100W)" */}}
1
2
3
4
5
{{ $asin := .Get 0 }}
{{ $jsonData := getJSON $.Page.Site.Params.AmazonApiEndpoint $asin }}
{{ with .Get 1 }}
 {{ $jsonData := getJSON $.Page.Site.Params.RakutenApiEndpoint . }}
{{ end }}

こんな感じですね。

肝心の楽天のAPIの中身はFunctionsで作成していて

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
const apiEndpoint = "https://app.rakuten.co.jp/services/api/IchibaItem/Search/20220601"
const APPKey = process.env.RAKUTEN_APPID
const AFFIKey = process.env.RAKUTEN_AFFIID
const axios = require('axios');

exports.handler = async (event, _context, callback) => {

    if ('keyword' in event.queryStringParameters === false) {
        console.error("empty 'keyword' !");
        return;
    }
    try {
        const response = await axios.get(apiEndpoint, {
            setTimeout: 2000,
            params: {
                format: 'json',
                applicationId: APPKey,
                affiliateId: AFFIKey,
                keyword: event.queryStringParameters.keyword,
                elements: "affiliateUrl"
            },
        })
        const responseData = response.data;
        callback(null, {
            statusCode: 200,
            body: JSON.stringify(responseData),
        });
    } catch (error) {
        callback(error, {
            statusCode: 500,
            body: JSON.stringify({ error: 'Internal Server Error' }),
        });
    }
};

と、こんな感じにしています。エラーハンドリングをするならもっと細かくするべきでしょうが、とりあえずはやっつけです。 process.env.は、NetlifyのEnviromentsを利用しています。ローカル環境では、Docker-composeに以下のように、持たせています。ホスト側のAPIトークンはdirenv3で管理しましょう。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
version: '3'
services:
    hugo:
        platform: linux/amd64
        build: .
        volumes:
            - "../:/src"
        entrypoint: bash
        ports:
            - "1313:1313"
        tty: true
        working_dir: /src/site
        depends_on:
            - "npm"
        command:
            - hugo server
            - --bind=0.0.0.0
            - --buildDrafts
            - --environment=development
    npm:
        build:
            context: .
            dockerfile: npm/Dockerfile
        volumes:
            - "../:/src"
        working_dir: /src/site/
        command:
            - -c
            - "netlify dev --port=9999"
        environment:
          ${AMAZON_PARTNER}: AMAZON_PARTNER
          ${AMAZON_ACCESSKEY}: AMAZON_ACCESSKEY
          ${AMAZON_SECRETKEY}: AMAZON_SECRETKEY
          ${RAKUTEN_APPID}: RAKUTEN_APPID
          ${RAKUTEN_AFFIID}: RAKUTEN_AFFIID

さて、これで(楽天が一番おすすめする店舗ですが)任意のプロダクトを自動発生させることができるようになりました。思っていたよりも楽天のAPIはシンプルなのでアイデアさえあれば活用の幅は広いかもしれません。

ただ、自分がやりたかったのは、「楽天市場での特定商品の検索結果へのリンク」なんですよねぇ。今のAPIのDocsを見るとどうもそこに辿り着くことができない気がする・・・

Anker Charging Station (7-in-1, 100W) …

最大100Wの急速充電:USB-Cポートは最大100W出力に対応し、MacBook Proなどのノー …