スマレジのAPIを使うのに何度かハマった


## スマレジのハマりポイント
1. スマレジのアカウントの種類が二種類ある。
1. スマレジのAPIが二種類ある


## スマレジのアカウント
- スマレジショップアカウント (勝手に名前つけてる。普通のスマレジアカウント)
- スマレジデベロッパーズアカウント

### スマレジショップアカウント
ショップの方のアカウント、アイテムの追加とか行う飲食店のオーナーさんがいじってそうなイメージのもの。

https://smaregi.jp/

### スマレジデベロッパーズアカウント
Qiitaに記事を読みに来るような人が作るべきであろう開発者用アカウント。

https://developers.smaregi.jp/

## スマレジのAPI
まず最初のハマりポイントはAPIが二種類あることを知っていなければならない。
- スマレジAPI
- スマレジプラットフォームAPI

### スマレジAPI
こっちのAPIはEOLを迎えてこれからサポートされなくなっていくらしい。
そのためスマレジプラットフォームAPIに移行することを推奨されている。
今回はこちらは使わないので割愛。

### スマレジプラットフォームAPI
新しい方のAPI (つまり未熟でリソースが少ない)
これを使ってスマレジアプリを開発し、ショップの方に売っていくような仕組みらしい。
開発者とショップが完全に分かれて、開発者だけでもスマレジアプリを作って稼げるようになっている。
この辺りはShopifyも同じようなことをしているのでShopifyから拝借したアイデアなのだろう。
基本的にはこちらでの開発が推奨される。(出来ることも多いので)

## トークン取得まで
スマレジプラットフォームAPIを使うためのステップとして
1. contractId / clientId / clientSecretをスマレジデベロッパーズアカウントから取得
1. アクセストークンを取得
1. アクセストークンを使用して何らかのアクションを行う。


### Firebase / Nodejs / axios

``` Typescript
import * as functions from "firebase-functions";
import axios from "axios";
import * as qs from "qs";

const clientId: string | undefined = functions.config().smaregi.client_id;
const clientSecret: string | undefined = functions.config().smaregi.client_secret;
const contractId: string | undefined = functions.config().smaregi.contract_id;
const idEndpoint: string = "https://id.smaregi.dev"; // Change dev -> jp for production
const basicToken: string | undefined = btoa(`${clientId}:${clientSecret}`);

// String => Base64 encoding
const btoa = (inputString: string) => {
  return Buffer.from(inputString).toString("base64");
};

export const getToken = async (_data: any, _context: any) => {
  // https://id.smaregi.dev/app/{contractId}/token
  const path = `${idEndpoint}/app/${contractId}/token`;
  try {
    const res = await axios.post(
      path,
      qs.stringify({ // type: x-www-form-urlencoded requires this part
        grant_type: "client_credentials",
        scope: "waiter.stores:read", // or anything listed in doc
      }),
      {
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
          Authorization: `Basic ${basicToken}`,
        },
      }
    );
    // Just take out the token part from here and set it to some variable. 
    functions.logger.info(res, { structuredData: true });
    return res;
  } catch (e) {
    functions.logger.error(e, { structuredData: true });
    return null;
  }
};

```

returnの辺りは適当に書いてありますが、随時更新していこうと思います。 (2021/08/12)

## ハマりポイント1: queryString
bodyのほうがqueryStringタイプじゃないと行けなかったので、`qs(body)`を入れる必要がありました。
axiosを初めて使ったのでもしかしたらaxios使いからは当たり前のことだったのかもしれません。

https://axios-http.com/docs/urlencoded

## ハマりポイント2: APIトークン
一番ハマったのがここ。
デベロッパーズアカウントの
アプリ -> アプリ名 -> 環境設定タブ の中にあります。

個人的に一番参考になったのはこちらのQ&A

https://community.smaregi.dev/discussion/53/%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%81%8C%E5%8F%96%E5%BE%97%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%9B%E3%82%93

仕様書はこちら

https://developers.smaregi.dev/apidoc/common/

https://waiter1.smaregi.dev/apidoc/#section/%E6%A6%82%E8%A6%81/%E3%83%9A%E3%83%BC%E3%82%B8%E3%83%8D%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3


流れ的には、アクセスしたいリソースのトークンを取得　=> リソースの取得

一旦トークンを取得するところまで。
ここまで来ればこの先の開発は進めやすいかと思うので、少しでも同じようにハマったひとの助けになれば良いなと思います。

この後もまだまだ開発途中のアプリで実機確認したいとか、試さないと行けないけど情報が足りなくて出来ないなんてことが山ほどあるので、随時追記していきます。