kintone-Zoom連携自習4日目

自習4日目。
Zoomミーティングの作成をLambdaに実装する。
Lambdaの作成には、AWS SAMを利用。
SAM CLI, version 1.58.0

Lambdaの作成

雛形作成

sam init でLambdaの雛形を作成する。

$ sam init
Which template source would you like to use?
	1 - AWS Quick Start Templates
	2 - Custom Template Location
Choice: 1
What package type would you like to use?
	1 - Zip (artifact is a zip uploaded to S3)
	2 - Image (artifact is an image uploaded to an ECR image repository)
Package type: 1

Which runtime would you like to use?
	1 - nodejs14.x
	2 - python3.8
	3 - ruby2.7
	4 - go1.x
	5 - java11
	6 - dotnetcore3.1
	7 - nodejs12.x
	8 - nodejs10.x
	9 - python3.7
	10 - python3.6
	11 - python2.7
	12 - ruby2.5
	13 - java8.al2
	14 - java8
	15 - dotnetcore2.1
Runtime: 1

Project name [sam-app]: zoom-integration

Cloning app templates from https://github.com/aws/aws-sam-cli-app-templates

AWS quick start application templates:
	1 - Hello World Example
	2 - Hello World Example TypeScript
	3 - Step Functions Sample App (Stock Trader)
	4 - Quick Start: From Scratch
	5 - Quick Start: Scheduled Events
	6 - Quick Start: S3
	7 - Quick Start: SNS
	8 - Quick Start: SQS
	9 - Quick Start: Web Backend
Template selection: 2

    -----------------------
    Generating application:
    -----------------------
    Name: zoom-integration
    Runtime: nodejs14.x
    Dependency Manager: npm
    Application Template: hello-world-typescript
    Output Directory: .

    Next steps can be found in the README file at ./zoom-integration/README.md


SAM CLI update available (1.58.0); (1.18.2 installed)
To download: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html

ビルド

sam buildします。

$ sam build
Your template contains a resource with logical ID "ServerlessRestApi", which is a reserved logical ID in AWS SAM. It could result in unexpected behaviors and is not recommended.
Building codeuri: /Users/kazoo/local/kintone/zoom/zoom-create/zoom-integration/zoom-integration runtime: nodejs14.x metadata: {'BuildMethod': 'esbuild', 'BuildProperties': {'Minify': True, 'Target': 'es2020', 'EntryPoints': ['app.ts']}} architecture: x86_64 functions: ZoomIntegrationFunction
Running NodejsNpmEsbuildBuilder:CopySource
Running NodejsNpmEsbuildBuilder:NpmInstall
Running NodejsNpmEsbuildBuilder:EsbuildBundle

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {stack-name} --watch
[*] Deploy: sam deploy --guided

TypeScriptを選択してビルドエラーになる時はSAM CLIのバージョンを最新版にすること。

ローカル実行

`sam local start-api` でローカル実行します。

$ sam local start-api
Mounting ZoomIntegrationFunction at http://127.0.0.1:3000/zoom [GET]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2022-10-03 20:07:17  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
Invoking app.lambdaHandler (nodejs14.x)
Image was not found.
Removing rapid images for repo public.ecr.aws/sam/emulation-nodejs14.x
Building image...............................................................................................................................................................................................................................................................................................
Skip pulling image and use local one: public.ecr.aws/sam/emulation-nodejs14.x:rapid-1.58.0-x86_64.

Mounting /zoom/zoom-create/zoom-integration/.aws-sam/build/ZoomIntegrationFunction as /var/task:ro,delegated inside runtime container
START RequestId: b9957aa8-e000-402e-99a4-449932d82e49 Version: $LATEST
END RequestId: b9957aa8-e000-402e-99a4-449932d82e49
REPORT RequestId: b9957aa8-e000-402e-99a4-449932d82e49	Init Duration: 1.42 ms	Duration: 258.03 ms	Billed Duration: 259 ms	Memory Size: 128 MB	Max Memory Used: 128 MB
No Content-Type given. Defaulting to 'application/json'.
2022-10-03 20:09:00 127.0.0.1 - - [03/Oct/2022 20:09:00] "GET /zoom HTTP/1.1" 200

curl でapiにアクセスして確認します。

$ curl http://127.0.0.1:3000/zoom
{"message":"hello world"}

kintone Webhookの利用

kintone Webhookから作成したLambdaを呼び出してみます。
アプリを作成して、WebhookにAPI GatewayのURLを入力します。

kintoneのWebhookでLambdaを呼び出した時に、kintoneから渡される値を確認するために、app.tsに`console.log(event)`を追加します。
また、Webhookからのリクエストを受付するため、API Gateway のメソッドをgetからpostに変更します。

app.ts

export const lambdaHandler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
    let response: APIGatewayProxyResult;
    try {
        console.log(event);
        response = {
            statusCode: 200,
            body: JSON.stringify({
                message: 'hello world',
            }),
        };
    } catch (err: unknown) {
        console.log(err);
        response = {
            statusCode: 500,
            body: JSON.stringify({
                message: err instanceof Error ? err.message : 'some error happened',
            }),
        };
    }

    return response;
};

template.yaml

Resources:
  ZoomIntegrationFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: zoom-integration/
      Handler: app.lambdaHandler
      Runtime: nodejs14.x
      Events:
        ZoomIntegration:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /zoom
            Method: post

ビルドしてデプロイします。
初回のデプロイでは質問が多いので主な点だけ記載します。
今回は検証用なのでauthorizationは設定していませんが、プロダクションで利用する場合は何かしらの設定をする必要があります。

$ sam deploy --guided

Configuring SAM deploy
======================

	Looking for config file [samconfig.toml] :  Not found

	Setting default arguments for 'sam deploy'
	=========================================
	Stack Name [sam-app]: sam-app-zoom
	AWS Region [ap-northeast-1]:
	#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
	Confirm changes before deploy [y/N]:
	 #SAM needs permission to be able to create roles to connect to the resources in your template
	Allow SAM CLI IAM role creation [Y/n]:
	#Preserves the state of previously provisioned resources when an operation fails
	Disable rollback [y/N]:
	ZoomIntegrationFunction may not have authorization defined, Is this okay? [y/N]: y
	Save arguments to configuration file [Y/n]:
	SAM configuration file [samconfig.toml]:
	SAM configuration environment [default]:

	Looking for resources needed for deployment:
	 Managed S3 bucket: <S3 bucket>
	 A different default S3 bucket can be set in samconfig.toml

	Saved arguments to config file
	Running 'sam deploy' for future deployments will use the parameters saved above.
	The above parameters can be changed by modifying samconfig.toml
	Learn more about samconfig.toml syntax at
	https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html

kintoneアプリ作成

最低限のフィールドですが、Zoomミーティング作成に必要なフィールドを持つアプリを作成します。Webhookには前段で作成したAPI GatewayのエンドポイントURLを設定します。

kintoneアプリ
Webhook設定

アプリを作成して、Webhookを設定したらアプリにレコードを作成します。Webhookの設定とAPIの作成に問題なければ、Cloudwatchログにkintoneのレコードの情報が表示されます。

2022-10-03T23:10:04.287Z	13b6e1a8-3328-456a-9bf7-d572c27daf11	INFO	{
  resource: '/zoom',
  path: '/zoom/',
  httpMethod: 'POST',
  headers: {
・・・
    'Content-Type': 'application/json',
    Host: 'xxxxx.amazonaws.com',
    'User-Agent': 'kintone-Webhook/0.1',
・・・
  },
・・・
  },
  body: '{"id":"7f414809-5261-4ad3-9883-349cdae7366a","type":"ADD_RECORD","app":{"id":"330","name":"Zoomミーティング予約"},"record":{"duration":{"type":"NUMBER","value":"60"},"start_time":{"type":"DATETIME","value":"2022-10-03T23:09:00Z"},"レコード番号":{"type":"RECORD_NUMBER","value":"2"},"更新者":{"type":"MODIFIER","value":{"code":"AdminUser","name":"AdminUser"}},"作成者":{"type":"CREATOR","value":{"code":"AdminUser","name":"AdminUser"}},"topic":{"type":"SINGLE_LINE_TEXT","value":"kintone-zoom-integration-topic"},"$revision":{"type":"__REVISION__","value":"1"},"更新日時":{"type":"UPDATED_TIME","value":"2022-10-03T23:10:00Z"},"作成日時":{"type":"CREATED_TIME","value":"2022-10-03T23:10:00Z"},"$id":{"type":"__ID__","value":"2"}},"recordTitle":"kintone-zoom-integration-topic","url":"https://luck-gk.cybozu.com/k/330/show#record=2"}',
  isBase64Encoded: false
}

あとは、Lambda内でbody.typeで分岐させて処理すれば良いです。

参考:


この記事が気に入ったらサポートをしてみませんか?