公開日:2025-03-07
システム開発グループ テクニカルマネージャーの浅利です。
今日は前回の続きで、大量の同時登録がある場合に Amazon SQS を使って kintone にまとめて登録する方法の、実際の実装についてです。
- 1. 対象:
- 2. 前回のおさらい
- 3. お題: フォーム上で入力して、kintoneにまとめて登録する Webアプリを、実際に作ってみる
- 3.1. 1. Webページ
- 3.2. 2. 登録ボタンで呼び出されるLambda
- 3.3. 3. SQSトピックを用意し、2のLambdaから送れるようにする
- 3.4. 4. メッセージ重複チェック用のDynamoDBテーブル
- 3.5. 5. SQSから起動しkintoneへの登録を行うLambda
- 3.6. 6. kintoneアプリ
- 4. 実際に試してみる
- 5. まとめ
- 6. アールスリーが業務改善・システム開発を支援する「キミノマホロ for kintone」
対象:
kintone と AWS の知識が多少ある方🙇♂️
前回のおさらい
前回の記事では、Amazon SQS を利用してデータを複数件まとめてから、いっぺんにkintoneに登録する方法を説明しました。
今回は、そのWebアプリを実際に作ってみましょう、という話です。
- フォーム送信時に呼ばれるLambdaではSQSに登録する
- SQSのメッセージ複数件で別のLambdaがトリガー起動されるようにし、kintoneへ複数レコード登録を行う
- 重複メッセージ除去のため、DynamoDBを使う

お題: フォーム上で入力して、kintoneにまとめて登録する Webアプリを、実際に作ってみる
今回は簡単なWebアプリを作成し、AWSのサービスを活用してデータをkintoneにまとめて登録してみます。
JavaScript や Lambda のコード例も記載していますが、簡単のためエラー処理等は省略していますので、ご注意ください。
1. Webページ
簡単な問合せページのWeb画面を、HTMLで用意しました。
タイトル・メールアドレス・問合せ内容の入力エリアと、登録ボタンがあるだけの画面です。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="main.css">
<script src="main.js"></script>
<title>問い合わせ</title>
</head>
<body>
<form id="myform">
<h1>問合せフォーム</h1>
<div>
<h2>タイトル</h2>
<input type="text" name="title"></input>
<h2>メールアドレス</h2>
<input type="email" name="mail"></input>
<h2>問合せ内容</h2>
<textarea name="detail"></textarea>
</div>
<button type="button" onclick="callApi()">登録</input>
</form>
</body>
</html>
さらに、登録ボタンを押した時に実行されるJavaScriptのコードも用意しました。
後で説明する関数URLにフォームの入力内容を送って、成功なら「登録しました」とダイアログが出るだけのスクリプトです。
const URL = "登録Lambdaの関数URLをここに書く(後で説明)";
async function callApi() {
const form = document.getElementById("myform");
const title = form.elements["title"].value;
const mail = form.elements["mail"].value;
const detail = form.elements["detail"].value;
const data = JSON.stringify({title, mail, detail});
console.log(data);
try {
const response = await fetch(URL, {
method: "POST",
cache: "no-cache",
body: data,
headers: {"Content-Type": "application/json; charset=utf-8"}
});
console.log(response);
alert("登録しました");
} catch(err) {
console.log(err);
alert("登録失敗しました");
}
}
これともう一つ、ここでは説明しませんがスタイルシートのファイル main.css も作って、この3つをS3バケットにアップロードします。
そして、大量にアクセスがあることを考慮して、Amazon CloudFront 経由でこのS3上のWebページが表示できるよう設定しました。
(その設定内容についてはここでは詳しくは説明しません)

2. 登録ボタンで呼び出されるLambda
先ほどのWebページの登録ボタンで呼び出されるLambdaを用意します。
簡単のため、エラー等を考慮せずに書きました。
import json
import boto3
SQS_URL = "SQSのURLをここに書く"
sqs_client = boto3.client("sqs")
def lambda_handler(event, context):
body = event.get("body")
sqs_response = sqs_client.send_message(QueueUrl=SQS_URL, MessageBody=body)
print(sqs_response)
return {
"statusCode": 200,
"body": "SUCCESS!"
}
このLambdaに対して、(API Gatewayでもいいのですが) 今回は「関数URL」を設定します。
さらに関数URL設定時に、「その他の設定」の項目の CORSを有効にし、許可ヘッダーを「content-type」、許可メソッドを「POST」としました。
関数URLの設定が完了すると発行されるURLを、1 の main.js の const URL = "~";
へ記載し、ボタンを押したときにこのLambdaが動くようにします。
※ 1つ注意点といて、(ここでは簡単のため処理を特に入れていませんが、)
例えば「問合せ内容」欄に非常に長いテキストを入れてしまうと、SQSのメッセージの上限サイズ(256KB)を超えエラーになってしまいます。
もし大きいデータを扱いたい場合は、データはSQS以外に入れ、SQSにはそのIDだけを送る、といった工夫が必要になってくると思います。
3. SQSトピックを用意し、2のLambdaから送れるようにする
次は、SQSトピック用意します。 前回書いたように「標準キュー」にする必要があります。
SQSトピックが用意できたら、そのURLを 2のLambdaの SQS_URL = "~"
へ記載します。 さらに、LambdaのIAMロールにて、このSQSトピックに SendMessage ができるようポリシーを設定する必要があります。
こうすることで、2のLambdaからこのSQSトピックへメッセージが登録できるようになります。
4. メッセージ重複チェック用のDynamoDBテーブル
前回の記事でも説明した重複メッセージの除去のため、DynamoDB にテーブルを1つ用意します。
ここでは、テーブル名「MessageIds」、プライマリキー「messageId」としました。
次のLambdaで、このテーブルに条件付き書き込みをすることで、すでに登録済みならスキップするという判定に使用します。
なお今回はやりませんが、古いデータは必要ないためTTLを設定しても良いと思います。
5. SQSから起動しkintoneへの登録を行うLambda
3のSQSからトリガー起動されるLambdaを用意します。
こちらも、簡単のため、エラー等を考慮せずに書いています。
また、kintoneへ登録する処理は皆さんご存知だと思いますので、省略しています。
import json
import boto3
from botocore.exceptions import ClientError
dynamodb_client = boto3.client("dynamodb")
def lambda_handler(event, context):
sqs_records = event.get("Records")
if sqs_records:
kintone_records = []
for record in sqs_records:
messageId = record["messageId"]
data = json.loads(record["body"])
# すでに登録済みでないか、messageId をチェック
not_duplicated = register_messageId(messageId)
if not_duplicated:
# kintoneへ登録用の形式へ変換
new_record = {
"title": { "value": data.get("title") },
"mail": { "value": data.get("mail") },
"detail": { "value": data.get("detail") }
}
kintone_records.append(new_record)
print(f"まとめて登録: {len(kintone_records)}件")
if kintone_records:
★(省略) kintone REST API の、POST /k/v1/records.json を使って、kintone_records をいっぺんに登録する★
return {}
def register_messageId(messageId: str) -> bool:
# messageIdの重複チェックを行うために、DynamoDB に登録済みか確認し、
# 登録されてないなら登録して true を返す
try:
dynamodb_client.put_item(
TableName="MessageIds",
Item={"messageId": {"S": messageId}},
ConditionExpression="attribute_not_exists(messageId)"
return True
except ClientError as client_error:
if client_error.response['Error']['Code'] == "ConditionalCheckFailedException":
# 条件エラー → False
return False
else:
raise Exception("エラー")
また、先ほどと同じようにLambdaのIAMロールの権限設定も必要です。
このLambdaはSQSからトリガー起動されてないといけないため、ReceiveMessage、DeleteMessage、GetQueueAttributes を許可するようポリシーを設定してください。
そのあと、トリガーの設定にて、3のSQSトピックから起動できるように設定します。
その際の設定は、前回お話ししたように、「バッチサイズ:100」「バッチウィンドウ:例 60秒」等と複数のメッセージをまとめて実行されるようにします。必要なら「最大実行数」を2以上に設定してもいいかもしれません。
※ このように「バッチサイズ:100」「バッチウィンドウ:60秒」と設定したとしても、必ず100個もしくは60秒経ったらまとめてLambdaが起動するというわけではなく、最大ここまで、という設定のようです。
タイミングによってはもっと少ないメッセージ数でLambdaが起動します。
6. kintoneアプリ
Webフォームから入力した内容が最終的に反映されるkintoneアプリを用意します。
今回の「タイトル」「メールアドレス」「内容」のそれぞれのフィールドを用意するだけです。

kintoneアプリが用意できたら、5のLambdaの、kintoneへ登録する部分のアプリID等をこのアプリに登録されるよう書き換えてください。
以上で、ひととおり仕組みが出来上がりました。
実際に試してみる
実際にWebフォームから登録してみましょう。
(試す前に、まとめて登録されるさまの確認のために、バッチウィンドウを300秒(5分)のように伸ばしておくと確認がしやすいと思います)
連続して登録できるように、ブラウザのウィンドウをたくさん開いて今回のWebフォームをそれぞれで表示します。 それぞれのウィンドウでタイトル・メールアドレス・問合せ内容をあらかじめ入力した状態にしてから、「登録」ボタンをダダダッと連続で押します。
すると、5のLambdaのCloudWatch Logにて、複数個のレコードがいっぺんに登録されることを確認できました。
(1個になるときもあります)
まとめ
以上、前回の記事の内容を、実際に実装してみるという話でした。
前回もお伝えしましたが、この仕組みを応用したものが、 サイボウズ株式会社様 事例紹介 の kintone AWARD グランプリの投票システムとなっていますので、 ぜひそちらの記事もご覧ください。
アールスリーが業務改善・システム開発を支援する「キミノマホロ for kintone」
アールスリーでは業務改善・システム開発を行うサービスを「キミノマホロ for kintone」として提供しています。
今回書かせていただいた内容も、そのシステム開発のノウハウをもとにしています。
また キミノマホロ for kintone では、以下のようなワークショップを無料で開催していますので、ぜひ詳細をご覧ください。

ワークショップ開催中!
詳細はワークショップの各ページからご覧ください。
投稿者プロフィール

- Webとか.NETとかスマホとかマイコンとかシーケンサーとか、いろいろやってるエンジニアです