2
1

More than 3 years have passed since last update.

kintone Webhook と AWS Lambda の連携で kintoneにコメントを書き込む

Last updated at Posted at 2019-10-22

kintoneとAWS Lambda を連携させて、
[kintoneレコード追加] → [Webhook発火] → [API Gateway] → [AWS Lambda] → [AWS Lambda] → [kintoneレコードコメント書き込み] をやってみました。

仕組みイメージ

kintoneWebhookAwsLambda.png

実行環境

  • macOS 10
  • AWS Cloud9
  • kintone

前提条件

  • kintoneでWebhookを設定済み
  • AWSアカウント取得済み
  • API Gateway設定出来る
  • AWS Lambda作成出来る
  • AWS CloudWatch利用出来る
  • JavaScript, Node.js書ける
  • 何らかのSDKを使った経験がある
  • AWSで課金されることを理解している

どんなことが出来るか

Webhookを設定したkintoneアプリにレコードを追加します。
スクリーンショット 2019-10-22 16.29.09.png

Webhookが発火して、[AWS API Gateway]経由で1つ目のLambdaを実行します。1つ目のLambdaは直ぐにkintoneへレスポンスを返して、2つ目のLambdaを実行します。2つ目のLambdaでWebhook通知を発火したkintoneアプリのレコードにコメントを書き込みます。
スクリーンショット 2019-10-22 16.29.29.png
レコード詳細画面をリロードするとコメントを使う設定になっていれば、追加したレコードのコメントに書き込みがあるはずです。

事前準備

下記拙稿をご覧下さい。

処理内容の説明

処理の流れに沿って、処理の中の重要な点を説明します。

kintoneのレコードを追加したことをWebhookで通知する

kintoneにはWebhook機能があります。

以下参照(kintoneヘルプより

Webhookは、複数のWebサービスを連携するための仕組みです。
kintoneでWebhookを設定すると、次の操作が行われたときに、そのことを外部のWebサービスに通知できます。

レコードの追加
レコードの編集
レコードの削除
コメントの書き込み
レコードのステータスの変更

今回このWebhookの仕組みを利用して、通知の内容を AWS Lambda でログに出力して、受信が成功したことを再度kintoneのレコードコメントに書き込みしています。
ただし、コメントの書き込みに対する処理はループしてしまうので、操作種類を見てコメント書き込みの時は、再度kintoneのレコードに書き込む処理を省いています。

Webhook通知を [AWS API Gateway] で受信する

API Gateway は AWS が提供する Web API 作成のサービスです。
REST API サービスを簡単に用意することが出来ます。

今回は最初のLambda関数を実行させる入り口として利用しています。
Webhookの設定で、API Gateway の API エンドポイント(URL) を登録することで、作成した API と紐づけた Lambda関数が実行されます。

最初のLambda関数が実行される

Lambda関数でWebhook通知内の操作の種類を判別して、レコードコメント書き込み以外の場合は、次のLambda関数を実行して、そうで無い場合はそのまま成功ステータスを返しています。

const aws = require('aws-sdk');

"use strict";
let sc;
let result;
let response;

exports.handler = async (event, context, callback) => {
  try {
    const kintonePost = JSON.parse(event.body);
    console.log(kintonePost);
    const operationType = kintonePost.type;
    console.log(operationType);

    if (operationType !== 'ADD_RECORD_COMMENT') {

      sc = 200;
      result = "kintone comment POST success!";
      response = {
        statusCode: sc,
        headers: { "Content-type": "application/json" },
        body: JSON.stringify( result )
      };

      let lambda = new aws.Lambda({apiVersion: '2015-03-31'});
      const params = {
        FunctionName: "<arn>",
        InvocationType: "RequestResponse",
        Payload: JSON.stringify(event)
      };
      console.log(params);
      lambda.invoke(params, (err, data) => {
        let res = data;
        if (err) {
          console.log("invoke error.");
          console.log(err);
          context.done(err, err);        
        } else {
          console.log("invoke success.");
          console.log("response:", res);
          context.done(null, res);
        }
      });
    } else {
      sc = 200;
      result = "kintone Record POST success!";
      response = {
        statusCode: sc,
        headers: { "Content-type": "application/json" },
        body: JSON.stringify( result )
      };
    }
  } catch(err) {
    sc = 400;
    result = err.message;
    response = {
      statusCode: sc,
      headers: { "Content-type": "application/json" },
      body: JSON.stringify( result )
    };
  }
  callback(null, response);
};

2つ目のLambdaでkintoneのレコードコメントに書き込み

2つ目のLambda関数に処理が渡った際に、Webhookが発火したkintoneアプリの同じレコードのレコードコメントに kintoneのREST APIを叩いてコメントを書き込んでいます。

let requestPromise = require('request-promise');
"use strict";
const env = process.env;
const url = 'https://' + env.SUBDOMAIN + '/k/v1/';
const headers = {'X-Cybozu-API-Token': env.APITOKEN, 'Content-Type': 'application/json'};
let sc; // status code
let result; // Response payload

exports.handler = async (event, context, callback) => {
    console.log(event);
    const kintonePost = JSON.parse(event.body);
    console.log(kintonePost);
    const operationType = kintonePost.type;

    const kintonePostComment = (kintonePost) => {
        const req_body = {
            "app": kintonePost.app.id,
            "record": kintonePost.record['$id'].value,
            "comment": {
                "text": "操作種類:" + operationType + "\nAWS Lambdaからのコメント書き込みです。\nご確認をお願いします。"
            }
        };
        const option = {
            url: url + 'record/comment.json',
            method: 'POST',
            headers: headers,
            json: req_body
        };
        return requestPromise(option)
        .then((response)=>{
            context.done(null, {text: "kintone comment POST success!"});
            sc = 200;
            result = "kintone comment POST success!";
            let callback = {
              statusCode: sc,
              headers: { "Content-type": "application/json" },
              body: JSON.stringify( result )
            };
            return callback;
        })
        .catch((error)=>{
            console.error('kintone Post Comment failed:', error);
            sc = 400;
            result = error;
            let callback = {
              statusCode: sc,
              headers: { "Content-type": "application/json" },
              body: JSON.stringify( result )
            };
            return callback;
        });
    };

    let kintonePostResponse;
    if (operationType !== 'ADD_RECORD_COMMENT') {
        kintonePostResponse = await kintonePostComment(kintonePost);
        console.log(kintonePostResponse);
    } else {
        sc = 200;
        result = "kintone Record POST success!";
        let callback = {
          statusCode: sc,
          headers: { "Content-type": "application/json" },
          body: JSON.stringify( result )
        };
        kintonePostResponse = callback;
    }
    callback(null, kintonePostResponse);
};

あとがき

普段 VS Code を利用してコードを書きますが、
Lambdaの開発については、Cloud9を利用した方が捗るような気がしました。
Cloud9についてはもう少し調べて、出来ればチームで使えるようにしていきたい。


参考リンク

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

AWS関連

Node関連

kintone関連

Cloud9

その他

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1