AWSを使って外部サイトからkintoneにレコードを追加

#やりたいこと#
外部サイトで入力したデータをマスタ（kintone）に登録

#動作確認環境#
作業端末：windows10
マスタデータ：kintone

#テストの流れ#
1. kintoneアプリ作成
2. AWS Lambda関数の作成
3. AWS Lambda環境構築
4. AWS API Gateway環境構築
5. 外部ページの作成

#1．kintoneアプリ作成#
####1-1．テスト用のアプリを作成####
○アプリ名：テストアプリ
○項目１：レコード番号
○項目２：文字列（1行）
　　➤フィールド名：テキスト
　　➤フィールドコード：text　
![kintone1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2225708/ee62981b-ce81-9739-9a01-0cbc7426f32d.png)

####1-2．APIトークンの生成####
アプリの設定＞設定＞APIトークンからレコード閲覧アクセス権有りのAPIトークンを生成し保存（APIトークンを控える）
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2225708/a09ad4a8-4612-051d-842e-585ddeb587c9.png)

#2．AWS Lambda関数の作成#

※node.jsのインストールは[こちら](https://qiita.com/sefoo0104/items/0653c935ea4a4db9dc2b)を参考にしました。

####2-1．作業フォルダ作成####
コマンドプロンプトからnpmを実行し作業フォルダを作成

``` 
$mkdir <作業フォルダを作成> (例：c:\temp\kintone_postなど)

$cd <作業フォルダのパスを指定>

$npm init --yes

$npm config set strict-ssl false

$npm install express ejs request

$npm install axios --save
```
※「npm config set strict-ssl false」は証明書エラー回避のため

####2-2．index.jsを編集####
2-1で作成した作業フォルダにindex.jsを作成し編集

```index.js
var aws = require('aws-sdk');
const axios = require('axios');
var request = require('request');

/* kintone用のパラメータ（変更が必要） */
var DOMAIN = '<サブドメイン名>.cybozu.com'; //kintone環境のドメイン
var APP_ID = <kintoneアプリのID>;   //アプリID

/* 変更は不要 */
var BASE_URL = "https://" + DOMAIN + '/k/v1/';
var headers = {'X-Cybozu-API-Token': '<kintoneのAPIトークン>'};

exports.handler = function(event, context, callback) {
    /* リクエスト本文取得 */
    const body = JSON.parse(JSON.stringify(event.body));
    var body_postrecords = {
        app: APP_ID,
        record:{
            text:{value:body.text}
            }
        }
    }

    //レコードの作成
    var options_postrecords = {
        url: BASE_URL + 'record.json',
        method: 'POST',
        headers: headers,
        'Content-Type': 'application/json',
        data: body_postrecords
    }

    //レコードを送信
    axios.request(options_postrecords).then((res) => {
      callback(null, res.data["id"]);
    }).catch((err) => {
      console.log(err);
    });
    
};
```

####2-3．ZIPファイルに圧縮####

```
$zip -r kintonepost.zip index.js node_modules/
```

#3．AWS Lambda環境構築#
####3-1．関数の作成####

関数名のみ入力し、後はデフォルトのまま関数を作成
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2225708/af26aaf2-a719-44ab-43fe-3dfd7fdc5bc4.png)
![kintone5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2225708/5e7a2ead-9be8-e987-abb6-8aad5c4be758.png)

####3-2．ZIPファイルをアップロード####
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2225708/9562a322-30b2-44ac-89f7-c3a5062e4f96.png)

####3-3．関数の動作確認####
テストを実行し、エラーのレスポンスがないことを確認
エラーが出た場合は、index.jsの内容やLambda関数の設定のタイムアウト値などを見直してみる…
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2225708/7946d907-d90f-e70a-a419-af5434fd24e3.png)
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2225708/aa339875-2477-426d-6a0b-63d9dac803c3.png)

#4．AWS API Gateway環境構築#
####4-1．APIの作成①####
APIを作成からREST APIの構築を選択
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2225708/5958be21-276e-1110-f3ac-d9678ab7c191.png)

####4-2．APIの作成➁####
API名を入力し、APIを作成
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2225708/86ffb71a-750e-7202-2884-1d4b46656f00.png)


####4-3．APIの作成③####
APIにメソッドを追加
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2225708/f8aa6ed5-c886-5876-1675-aa0fa6c3e652.png)

####4-4．APIの作成④####
POSTを選択し、Lambda関数を入力し保存
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2225708/a0cde11c-e1e8-f036-ff16-ffecfdfb3c25.png)

####4-5．CORSの有効化####
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2225708/d4fdb3bb-b70f-e419-5683-6b45659e74b8.png)

####4-6．メソッドリクエストの設定####
メソッドリクエストのリクエスト本文にコンテンツタイプを追加
コンテンツタイプ：application/json
モデル名：Empty
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2225708/50514cb3-8ee7-5993-fcd5-185ed5b4c831.png)

####4-7．統合リクエストの設定####
統合リクエストのマッピングテンプレートを追加し、テンプレートを「メソッドリクエストのパススルー」で生成しbody-jsonをbodyにしてから保存する
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2225708/8acb3570-68ef-5384-f527-0c1ecafe22e8.png)

####4-8．統合レスポンスの設定####
統合レスポンスにもマッピングテンプレートを「メソッドリクエストのパススルー」で生成し保存する
さっきもbody-jsonを変更した場合はこちらも直す
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2225708/f4583310-c88a-8cd7-cf5b-92f294ab118b.png)

####4-9．テスト####
APIの動作確認を行い、レスポンス本文にkintoneに追加したレコード番号が返ってきたらOK
エラーが発生するようならLambda関数のタイムアウトやAPIのLambdaプロキシ統合の使用にチェックが入っていないかなどを疑う
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2225708/b417749e-14ac-881a-bb60-adc90a185274.png)

####4-10．APIのデプロイ####
アクションからAPIのデプロイを実行
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2225708/c5c0088b-087c-75a4-a85e-44f0c8da5dd9.png)

####4-11．URIのチェック####
APIのURIを控えて、APIの構築が完了です。
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2225708/4d42a602-2e44-c064-37d8-3a473260cdf8.png)

#5．外部サイト側の設定#
####5-1．APIの送信####
PHPの場合…

```index.php
// APIのURI
$url = '<APIのURI>';

// リクエストヘッダ: パラメータを json で渡す
$content = json_encode(array(
                 'text' => 'hogehoge3'
                 ));

$context = array(
  'http' => array(
    'method' => 'POST',
    'header' => "Content-Type: application/json\r\n"
              // APIキーの設定がある場合はコメント外す
              // . "x-api-key:<APIキー>\r\n"
              . "Content-Length: " . strlen($content) . "\r\n" ,
    'content' => $content
  )
);

// APIのコール
$resultJson = file_get_contents($url, false, stream_context_create($context));

// レスポンス確認
$json = mb_convert_encoding($resultJson, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
$arr = json_decode($json);
$record_no = $arr->body;
```

#参考サイト#
https://qiita.com/RyBB/items/648388cbcf296d5e1371

https://developer.cybozu.io/hc/ja/articles/210014653-Slack%E3%81%8B%E3%82%89kintone%E3%81%B8%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E7%99%BB%E9%8C%B2%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95-AWS-Lambda-%E3%81%A7%E3%81%A4%E3%81%AA%E3%81%90-%E5%BE%8C%E7%B7%A8

参考にさせていただき、ありがとうございました。