AWS Lambda にPOSTしたkintoneのレコードからThinreportsを利用してPDFファイルを生成する

[これまでの記事](https://qiita.com/sy250f/items/0f2aaf17fd670bf82c84#%E3%81%93%E3%82%8C%E3%81%BE%E3%81%A7%E3%81%AE%E8%A8%98%E4%BA%8B)でRubyのインストールからLambda・API Gatewayの利用、ThinreportsによるPDF生成までテストしてきましたが、最後にこれまでのまとめとして、LambdaにPOSTしたkintoneレコードを利用してPDFを生成してみたいと思います。
![kintonePostAwsLambda.png](https://qiita-image-store.s3.amazonaws.com/0/214523/9706eb0c-09a5-3939-837f-2778eddd0dc4.png)

# 今回のゴール
Thinreportsで生成したPDFファイルです。
<img width="452" alt="スクリーンショット 2019-01-13 13.24.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/214523/29ff5dfe-70c5-7db8-5165-803b47c9cf8e.png">

# 処理の流れ
kintoneアプリの詳細画面に設置したボタンを押下して、AWSのAPI Gateway経由でLambdaを実行し、PDFファイルをAWS S3に出力します。

 - kintoneアプリ作成
 - kintoneカスタマイズJavaScriptファイル作成
 - [Thinreportsレイアウトファイルを作成](http://www.thinreports.org/documentation/ja/getting-started/quickstart.html)
 - Lambdaファンクションの作成
 - S3,API Gatewayの設定
 - kintoneアプリから実行
 - S3にPDFファイルが生成されていることを確認

# kintoneアプリ作成
kintoneアプリを新規に作成します。
文字列１行フィールドを追加して次のように設定します。

| フィールド名      |    フィールドタイプ  |  フィールドコード   |
|:-----------------|:------------------:|:------------------:|
| text             |    文字列１行       |    text            |

アプリを作成したらレコードを登録しておきます。
<img width="752" alt="スクリーンショット 2019-01-13 9.16.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/214523/88759ba7-13d3-7768-d0d1-b7ee3c1be770.png">

# kintoneカスタマイズJavaScriptファイル作成
kintone.proxyを利用して、レコードをAWSへPOSTします。

```customer.js
const url = kintoneEnv.props.url;
console.log(url);
const method = 'POST';
const headers = {'Content-Type' : 'application/json'};

kintone.events.on('app.record.detail.show', event => {
  let myButton = document.createElement('button');
  myButton.id = 'myButton';
  myButton.innerHTML = 'Hello Ruby!!';
  myButton.onclick = () => {
      console.log(event);
      let data = event;
      kintone.proxy(url, method, headers, data, (body, status, headers) => {
          console.log(status, body);            
          if(status >= 200 && status < 300) {
              console.log("Success");
          }else{
              console.log("Error");
          }
      });
      return event;
  };
  kintone.app.record.getHeaderMenuSpaceElement().appendChild(myButton);
})
```
[kintoneアプリ開発ベース〜ビルド、デプロイ、環境切り替え〜](https://qiita.com/hiroyasu55/items/c7bbabfcbf2412570215)の記事を参考にして、ビルド・デプロイをしました。
API GatewayのURLは設定ファイルから読み込みます。

# Thinreportsレイアウトファイルを作成
[Thinreports](http://www.thinreports.org/)はRubyでPDFファイルを生成するソフトウェアです。rubyのライブラリとデザイナが提供されています。詳しくはhttp://www.thinreports.org/を参照してください。

<img width="991" alt="スクリーンショット 2019-01-13 13.09.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/214523/b0efa471-c3dd-ede9-42e1-5664ccaff443.png">

今回は[クイックスタートガイド](http://www.thinreports.org/documentation/ja/getting-started/quickstart.html)のレイアウトファイルをそのまま利用します。
尚、サンプルコードとレイアウトファイルはリンク先の下の方からダウンロード出来ます。

# Lambdaファンクションの作成
LambdaにはRubyとRubyのgemライブラリを利用しています。

手順は次の通りです。詳細はこれまでの記事を参考にしてください。

 1. thinreportsインストール
 2. Rubyスクリプト作成
 3. zip圧縮
 4. S3アップロード
 5. Lambdaにアップロード

```hello_world.rb
# coding: utf-8
require 'thinreports'
require 'json'
require 'base64'
require 'aws-sdk-s3'

def lambda_handler(event:, context:)
    begin
        print 'JSON.parse event.body => '
        pp JSON.parse(event["body"])
        event_body = JSON.parse(event["body"])
        record = event_body["record"]
        print 'record => '
        pp record
        puts '$id => ', record["$id"]["value"]
        puts 'text => ', record["text"]["value"]
    rescue => e
        puts "#{e.class}: #{e.message}"
        puts e.backtrace
    end

    begin
        region = 'S3バケットのリージョン'
        bucket_name = 'バケット名'
        key = 'put-hello-ruby.pdf'
        # S3 Backet Object init
        s3 = Aws::S3::Resource.new(region: region)
        obj = s3.bucket(bucket_name).object(key)
        # Thinreports Object init
        report = Thinreports::Report.new layout: 'hello_world'
        # 1st page
        report.start_new_page
        report.page.item(:world).value(record["$id"]["value"])
        report.page.item(:thinreports).value(record["text"]["value"])
        obj.put(body: report.generate)
    rescue => e
        puts "#{e.class}: #{e.message}"
        puts e.backtrace
    end

    { statusCode: 200, body: JSON.generate('Hello Lambda! Thinreports for Ruby') }
end
```
### 補足説明
kintoneからPOSTしたデータは、event["body"]にセットされているので、それをJSON.parseしてRubyオブジェクトに変換します。さらに、kintoneのレコードのみを取り出してrecord変数にセットしています。

```ruby
    event_body = JSON.parse(event["body"])
    record = event_body["record"]
```

":world"と":thinreports"がThinreportsのレイアウトファイルに設定したブロックツールのIDと対応しています。ここでセットした値がレイアウトファイルに差し込まれます。
最後にreport.generateでPDFを出力します。

```ruby
    report.page.item(:world).value(record["$id"]["value"])
    report.page.item(:thinreports).value(record["text"]["value"])
    obj.put(body: report.generate)
```

# S3,API Gatewayの設定
S3に書き込み権限を付与します。API GatewayはLambdaファンクションの作成時にLambdaのコンソール画面から設定します。詳細はこれまでの記事を参考にしてください。


# kintoneアプリから実行
kintoneアプリの詳細画面のボタンを押下します。
実行後にログを確認します。

# S3にPDFファイルが生成されていることを確認
S3のコンソールからバケットを選択してPDFファイルが生成されていることを確認します。
<img width="865" alt="スクリーンショット 2019-01-13 13.38.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/214523/8862b103-f704-4af2-5416-eb8cb596a600.png">

ファイルをダウンロードしてPDFファイルを確認します。

# まとめ
kintoneで帳票出力が必要なものに関しては、外部のレポートサービスを利用することが多いと聞きますが、今回AWS Lambda、Thinreports を利用して、kintoneの帳票出力をある程度自前でサポートできる可能性があると感じました。

生成したPDFファイルをセキュリティを保った上で、ユーザーにどのようにダウンロードさせるか？やLambdaのデバッグやテスト、デプロイ等は今後試していきたいと思います。

# これまでの記事

 1. [AWS Lambda の Ruby サポート を受けてRubyのインストールからデプロイまでやってみたメモ](https://qiita.com/sy250f/items/a3cfab59b51a5b2f7f7a)
 2. [AWS Lambda for Ruby を使って Lambda から Thinreports ライブラリで生成したPDFをS3に保存してみるメモ](https://qiita.com/sy250f/items/a49c64a6bc1d594ca4a8)
 3. [kintone から AWS API Gateway 経由で Lambda for Ruby ファンクションにリクエストを投げてみるテスト](https://qiita.com/sy250f/items/c342600af7c4d660af79)
 4. [kintone のレコードを kintone.proxyでAWS LambdaへPOSTリクエストしてログに吐き出してみるテスト](https://qiita.com/sy250f/items/62706bc1fa47b8d08a53)

# 参考リンク
参考にさせて頂きました。この場をお借りして感謝致します。

 - [kintoneアプリ開発ベース〜ビルド、デプロイ、環境切り替え〜](https://qiita.com/hiroyasu55/items/c7bbabfcbf2412570215)
 - [http://www.thinreports.org/](http://www.thinreports.org/)
 - [kintoneでフォームのフィールドコード一覧を表示させる（サブテーブル含む）](https://qiita.com/the_red/items/8f16938f7c8229d34970)