RAKUS Developers Blog | ラクス エンジニアブログ

株式会社ラクスのITエンジニアによる技術ブログです。

APIの基本から実践

f:id:tech-rakus:20210205111610p:plain

今回はAPIについて解説します。エンジニア/プログラマの方はよく聞く単語だと思いますが、 私自身、他の人にうまく説明できるかと考えた時にあまり自信がなかったのでまとめてみることにしました。

APIとは

APIは「Application Programming Interface」の略で、ざっくりいうとあるプログラムから別のソフトウェアを操作するための仕組みのことです。 企業などがアプリケーションの一部の機能を外部に向けて公開することで、第三者は開発したアプリで機能を利用することができます。

APIを使うメリット

開発コストの削減

基本的にWeb APIAPI自体の仕様が変更になる以外に、バグ修正等の運用コストも必要ありません。また、Web APIは無料で公開されているものが多いので、開発時間の削減も可能です。

開発の効率化

アプリケーション開発で、ある機能を実装したいとなった時、一部の機能は他社がAPIとして公開している場合があります。 例として、駅情報が必要になった時には既に駅情報を取得できるAPIが存在していますので、1から機能を実装する必要はありません。 1から作成する場合は、路線データ、地図データ、料金データ、アップデートなどを考慮する必要がありますが、 APIを利用することでこれらの考慮が不要となり、効率よく開発を進めることができます。

セキュリティの向上

ログイン機能実装時には、FacebookTwitterGoogleAPIを活用することで該当アカウントを利用したログインができます。 大手企業の高いセキュリティ機能を利用することでセキュリティ面の担保ができます。

APIの種類

ごく一部ですが、例として以下のようなものがあります。
Twitter:アカウントと利用者や、ツイート、ダイレクトメッセージといったTwitterデータの利用ができる
Amazon:商品情報、在庫情報、注文情報などを呼び出すことができる
Google:画像の分析やテキストの読み取り、手書き文字の読み取り、人や建造物の特定など、画像認識に関するさまざまな機能が使える
・LINE:BOTを作成して、応答メッセージの送受信を行ったりすることができる
・Slack:チャンネルや DM からのメッセージなど、イベントを送信したり、Slack チャンネルとユーザーグループを作成、変更したりできる

実践

作ったもの

APIを使って飲食店検索BOTを作成しました。
仕様としては、位置情報を送った際に日本酒のある近くの居酒屋を検索しています。 f:id:taku_76:20210204045807p:plain

使用するAPI

ぐるなびAPI

ぐるなびに掲載されている飲食店の基本情報を取得することができますので、飲食店を検索するようなアプリ作成時に使用するといいです。

LINE Messaging API

Messaging APIを使うことでBOTを作成することができます。ユーザーの反応によって何かしらの処理を行うことができますので、例えばオウム返しなどといったユーザーの送ったメッセージと同じメッセージを返すBOTが簡単に作れたりします。

構成

f:id:taku_76:20210203180415p:plain

作成手順

ぐるなびAPI登録

まず、アクセスキーを発行するために以下のサイトでアカウントを作成します。

ぐるなび Web Service - トップページ

どのようなAPIがあるかは以下のサイトで確認できます。

ぐるなび Web Service - API一覧

次に受け取るデータの確認を行うのですが、ぐるなびAPIはテストツールが用意されているため簡単にどのようなデータが返ってくるか確認することができます。 方法は、以下のサイトで使用するAPI名とパラメータを指定して「クエリを送信ボタン」を押下するだけです。

ぐるなび Web Service - API テストツール

今回はヒット件数を制限するhit_per_pageと、フリーワード検索を行うfreewordを指定しています。

f:id:taku_76:20210203152335p:plain

画像の下部にJSON形式でデータが返ってきていることが分かりますね。こちらからどのようなデータが返ってきているか確認します。 アプリに組み込むときは、URLをコピペすればとりあえずは動きます。あとは、必要に応じて検索パラメータを変更するように実装すればOKです。

LINEBOT登録

以下からLINE Developersにログインします。それからプロバイダーを作成して、Messaging APIを選択してのチャネルを作成します。
※LINE Developersへの登録にはLINE個人アカウントが必要になります。

LINE Developers

Node.jsなどの環境構築

こちらについて今回は割愛させていただきます。

実装

今回実装したコードは以下となります。

'use strict';

const fetch = require('node-fetch');
const express = require('express');
const line = require('@line/bot-sdk');
var request = require('request');
const PORT = process.env.PORT || 3000;

const config = {
    channelSecret: 'チャネルシークレット',
    channelAccessToken: 'チャネルアクセストークン'
};

const app = express();
app.set('port', (process.env.PORT || 3000));

app.get('/', (req, res) => res.send('Hello LINE BOT!(GET)')); //ブラウザ確認用(無くても問題ない)
app.post('/webhook', line.middleware(config), (req, res) => {
    //console.log(req.body.events);

    //ここのif分はdeveloper consoleの"接続確認"用なので削除して問題ないです。
    if(req.body.events[0].replyToken === '00000000000000000000000000000000' && req.body.events[1].replyToken === 'ffffffffffffffffffffffffffffffff'){
        res.send('Hello LINE BOT!(POST)');
        console.log('疎通確認用');
        return; 
    }

    Promise
      .all(req.body.events.map(handleEvent),)
      .then((result) => res.json(result));
});

const client = new line.Client(config);

async function handleEvent(event) {
  if (event.type !== 'message') {
    return Promise.resolve(null);
  }

  //位置情報が送られた場合
  if(event.message.type == 'location') {
    //検索に必要なパラメータを定義
    var query = {
      "keyid":"アクセスキー",
      "latitude": event.message.latitude,
      "longitude": event.message.longitude,
      "range": 3,
      "freeword": "日本酒",
      "hit_per_page": 10,
    };
    //リクエストに必要なオプションを設定
    var options = {
      url: "https://api.gnavi.co.jp/RestSearchAPI/v3/",
      qs: query,
      json: true
    };
  }
  //ぐるなびAPIを叩く
  request.get(options, function(error, response, body){
    if (!error && response.statusCode == 200 || body.rest == undefined) {
      if('error' in body){
          console.log("検索エラー" + JSON.stringify(body));
          return client.replyMessage(event.replyToken, {
            type: 'text',
            text: '検索結果が0件、または検索エラーです。' //実際に返信の言葉を入れる箇所
        });
      }
    }
    var random = Math.floor(Math.random() * (body.rest.length));
    var message = {  
      "type": "flex",
      "altText": "this is a flex message",
      "contents": { //中身記載
        }
    };
    return client.replyMessage(event.replyToken, message);
  });
}

app.listen(PORT);
console.log(`Server running at ${PORT}`);

上記のコードでポイントとなるところのみ解説します。

const config = {
    channelSecret: 'チャネルシークレット',
    channelAccessToken: 'チャネルアクセストークン'
};

configにはLINE Developersで作成したチャネルの秘密鍵とアクセストークンを設定しておきます。

//位置情報が送られた場合
  if(event.message.type == 'location') {
    var query = {
      "keyid":"アクセスキー",
      "latitude": event.message.latitude,
      "longitude": event.message.longitude,
      "range": 3,
      "freeword": "日本酒",
      "hit_per_page": 10,
    };

Webhookイベントオブジェクトに送信されたメッセージが含まれており、messageプロパティに格納されています。 今回は位置情報が送られた際に処理を行いたいので、event.message.typeがlocationの時に処理します。 ちなみに位置情報が送られた際のメッセージオブジェクトは以下のようになります。
・ID:メッセージID
・type:location
・title:タイトル
・address:住所
・latitude:緯度
・longitude:経度
また、queryにはぐるなびAPIを叩く際のリクエストパラメータを設定しています。今回は以下となります。
・keyId:アクセスキー
・latitude:緯度
・longitude:経度
・range:検索範囲
・freeword:フリーワード検索
・hit_per_page:検索件数
これで送った位置から半径1km以内の、日本酒のある飲食店を検索することができます。

request.get(options, function(error, response, body){
    (中略)
    var message = {  
      "type": "flex",
      "altText": "this is a flex message",
      "contents": { 
       // Flex Message Simulatorで取得したJSONデータ
        }
    };
    return client.replyMessage(event.replyToken, message);
  });

初めはテキストで検索結果を返すようにしていたのですが、少し見た目を良くしたいと思いMessaging APIFlex Messageで返すようにしました。 そのためにtypeをflexとしています。 またFlex Message Simulatorを使うことでメッセージを送信しなくてもレイアウトを確認することができます。

Flex Message Simulator

表示されるJSONデータをコピペして必要に応じて修正し、contentsに設定します。今回は以下のレスポンスデータを使用して表示しています。
・rest.name:店名
・rest.url_mobile:携帯サイトURL
・rest.image_url.shop_image1:店の画像
・rest.address:住所
・rest.opentime:営業時間
※店によっては画像が空だったりするので注意が必要です。

おわりに

今回APIを使って飲食店検索BOTを作ってみましたが、ぐるなびAPIはテストツールでレスポンスを確認できるので使いやすさを感じました。
また、LINE Messaging APIは送受信が簡単で、レイアウトはFlex Message Simulatorを使うことでわりとすぐ実装ができました。
記事作成時にいろいろな種類のAPIを見ていましたが使ってみたいものがありましたので、どのように利用するかを考え、また実践してみたいです。

Copyright © RAKUS Co., Ltd. All rights reserved.