はじめに
皆さんこんにちは!
いきなりですが、登録されたレコード情報をただ配信するだけでなく事前に集計したり、登録状況を示した情報をTeamsなどのチャットへ送信したいと思ったことはありますか?
今回の記事ではSPIRALとTeamsを連携したTeamsへの登録レコードの集計データやレコード登録情報の配信、またDBのバックアップ方法等を紹介します!
記載したPHPを張り付けてご自身の設定値やフィールド名に変換するだけの、とっても簡単な実装となっているので、ぜひお試しください!
連携の仕方について
PHPを用いて、DBに登録された内容をTeamsへ定期配信します。
基本的な連携の仕方はこちらの記事をご覧ください。
▷【簡単30分】 teamsへの定期配信設定
今回はSPIRAL®ver2を使用します。
SPIRAL®ver2を使用する際の参考にしていただければ幸いです。
SPIRALについて▷【簡単プログラミング!】SPIRALってなあに?
SPIRAL SPIRAL®ver2について▷ https://spiral.pi-pe.co.jp/
定期配信でできること
集計データの配信
一つ目にDBに登録された情報を,集計しTeamsへ定期配信します。
例として、下記図のような希望日数と希望日程アンケートを用意し、これらのアンケート結果から,解答された情報の合計希望日数と各日程の合計値を計算しTeamsへ配信することができます。
ご自身の集計したい項目をDBに作成しフォームなどからレコード登録を行った後,スケジュールトリガを作成しPHP実行に下記PHPを張り付けることで,設定した時間に設定したフィールドの集計情報をTeamsへ送信します!
この際ご自身の設定値やフィールド名に変換する箇所がございますので、適宜変更してお試しください!
<?php
// スパイラル設定値
define("API_URL", "https://api.spiral-platform.com/v1");
define("API_KEY", " ご自身のAPIキーを入力してください ");
define("APP_ID", " 使用するアプリのIDを入力してください ");
define("DB_ID", " 使用するDBのIDを入力してください ");
// 集計したいDBのフィールド
define("definition1", "集計したいフィールド名1");
define("definition2", "集計したいフィールド名2");
// Teams Webhook URL
define("TEAMS_WEBHOOK_URL", " 取得したwebhookのURLを入力してください ");
// スパイラルAPI URL
$spiralApiUrl = API_URL."/apps/".APP_ID."/dbs/".DB_ID."/records";
$records = SPIRAL_API_send($spiralApiUrl);
$total = 0;
// APIからレコード取得
// 日数合計値計算
if (!empty($records["items"]) && is_array($records["items"])) {
foreach ($records["items"] as $item) {
if (isset($item[definition1]) && is_numeric($item[definition1])) {
$total += $item[definition1];
}
}
} else {
echo "レコードが取得できませんでした。\n";
}
$message = "合計値は {$total} です。";
// 選択肢ごとの合計値
$dateCounts = [];
// optionsでID→ラベルの対応を取得
$definition2Options = $records['options']['集計したいフィールド名2'] ?? [];
if (!empty($records['items']) && is_array($records['items'])) {
foreach ($records['items'] as $item) {
if (isset($item['集計したいフィールド名2']) && is_array($item['schedule'])) {
foreach ($item['集計したいフィールド名2'] as $definition2Id) {
// IDからラベル取得
$label = $ definition2Options[$definition2Id] ?? '不明な日付';
// カウントアップ
if (!isset($dateCounts[$label])) {
$dateCounts[$label] = 0;
}
$dateCounts[$label]++;
}
}
}
} else {
echo "レコードが取得できませんでした。\n";
exit;
}
// メッセージ整形
$messageLines = [];
foreach ($dateCounts as $date => $count) {
$messageLines[] = "{$date}: {$count}件";
}
$message2 = implode("\n", $messageLines);
// Teamsへ通知
$teamsData = [
"type" => "message",
"attachments" => [
[
"contentType" => "application/vnd.microsoft.card.adaptive",
"content" => [
"type" => "AdaptiveCard",
"version" => "1.4",
"body" => [
[
"type" => "TextBlock",
"text" => $message,
"wrap" => true
],
[
"type" => "TextBlock",
"text" => $message2,
"wrap" => true
]
]
]
]
]
];
TEAMS_WEBHOOK_send($teamsData);
function SPIRAL_API_send($spiralApiUrl) {
$header = [
"Authorization:Bearer " . API_KEY,
"Content-Type:application/json",
"X-Spiral-Api-Version: 1.1",
];
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, $spiralApiUrl);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
$response = curl_exec($curl);
if (curl_errno($curl)) echo curl_error($curl);
curl_close($curl);
return json_decode($response, true);
}
function TEAMS_WEBHOOK_send($data) {
$header = array(
"Content-Type:application/json",
);
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, TEAMS_WEBHOOK_URL);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
$response = curl_exec($curl);
if (curl_errno($curl)) echo curl_error($curl);
curl_close($curl);
return json_decode($response, true);
}
▽SPIRALのトライアルはこちらから!
新規レコードお知らせ配信
2つめは登録されたレコードのお知らせ配信を行います。
具体的に、登録、更新、削除されたレコードIDをTeamsに配信します。
この機能については基本的な連携作業に加えて下記2点の事前準備が必要になります。
①バックアップDBの作成
②DBとバックアップDBのレコードID連携
バックアップDBの作成
始めに,お知らせ配信したい項目を設定したDBを作成します。(DB①)
次に,先ほど作成したDBと同じ項目に加えてdb1_idを追加したDBを作成します。(DB②)
db1_idフィールドはDB①のレコードとDB②のレコードを紐づける際に使用します。
DBとバックアップDBのレコードID連携
スケジュールアクションに以下のPHPをPHP実行に張り付けることで,実行した時刻にDB①にある内容をDB②に保存することができ,DB②がDB①のバックアップとしての役割を持つことができます。
この際ご自身の設定値やフィールド名に変換する箇所がございますので、適宜変更してお試しください!
<?php
// スパイラル設定値
define("API_URL", https://api.spiral-platform.com/v1);
define("API_KEY", " ご自身のAPIキーを入力してください ");
define("APP_ID", " 使用するアプリのIDを入力してください ");
define("DB1_ID", " 使用するDBのIDを入力してください ");
define("DB2_ID", " DB1のバックアップDBのIDを入力してください");
// Spiral API呼び出し
function apiCall($method, $path, $data = null) {
$headers = [
"Authorization:Bearer " . API_KEY,
"Content-Type:application/json",
];
$url = API_URL . "/apps/" . APP_ID . $path;
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
if ($method === 'POST' || $method === 'PUT') {
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
}
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
$resp = curl_exec($curl);
curl_close($curl);
return json_decode($resp, true);
}
// DB1からレコード取得
$db1Resp = apiCall('GET', '/dbs/' . DB1_ID . '/records');
$db1Items = $db1Resp['items'] ?? [];
// DB2から全レコード取得
$db2Resp = apiCall('GET', '/dbs/' . DB2_ID . '/records');
$db2Items = $db2Resp['items'] ?? [];
// DB2レコードを db1_id でマップ
$db2Map = [];
foreach ($db2Items as $item) {
if (!empty($item['db1_id']) && is_scalar($item['db1_id'])) {
$key = (string)$item['db1_id'];
$db2Map[$key] = $item;
}
}
// DB1→DB2への同期処理
foreach ($db1Items as $record) {
$db1_id = (string)$record['_id'];
// 登録・更新用データ作成
$data = [
"DB2のフィールド名1" => isset($record['対応するDB1のフィールド名1']) ? (string)$record['対応するDB1のフィールド名1] : "",
" DB2のフィールド名2" => isset($record['対応するDB1のフィールド名2']) ? array_map('strval', $record['対応するDB1のフィールド名2']) : [],
"db1_id" => $db1_id,
];
if (isset($db2Map[$db1_id])) {
// すでにDB2に登録されている → 更新
$db2_id = $db2Map[$db1_id]['_id'];
echo "Updating DB2 record linked to DB1 ID {$db1_id}\n";
$resp = apiCall('PUT', '/dbs/' . DB2_ID . '/records/' . $db2_id, $data);
$action = 'Updated';
} else {
// 存在しない → 新規登録
echo "Adding new DB2 record linked to DB1 ID {$db1_id}\n";
$resp = apiCall('POST', '/dbs/' . DB2_ID . '/records', $data);
$action = 'Added';
}
if (isset($resp['errors'])) {
echo "Error: " . json_encode($resp['errors']) . "\n";
} else {
echo "{$action} record successfully.\n";
}
}
// DB1のID一覧を取得(文字列化して比較用)
$db1Ids = array_map(fn($rec) => (string)($rec['_id'] ?? ''), $db1Items);
$db1IdMap = array_flip($db1Ids);
// DB1に存在しないdb1_idを持つDB2レコードを削除
foreach ($db2Map as $db1_id => $db2Record) {
if ($db1_id === '' || !isset($db2Record['_id'])) {
// 無効なdb1_idや_idがないレコードはスキップ
continue;
}
if (!isset($db1IdMap[$db1_id])) {
$db2_id = $db2Record['_id'];
// ログ表示
echo "Deleting DB2 record not found in DB1 (db1_id={$db1_id})\n";
// 削除実行
$resp = apiCall('DELETE', '/dbs/' . DB2_ID . '/records/' . $db2_id);
if (isset($resp['errors'])) {
echo " Error deleting record: " . json_encode($resp['errors']) . "\n";
} else {
echo " Deleted DB2 record with db1_id: {$db1_id}\n";
}
}
}
レコード比較によるレコード情報の配信
最後にスケジュールトリガのPHP実行に下記PHPを張り付けることで、バックアップDBとDB①での紐づけたレコード同士の比較を行い、レコードが新規登録・更新・削除されたかを確認し,結果をTeamsへ送信します。
この際ご自身の設定値やフィールド名に変換する箇所がございますので、適宜変更してお試しください!
<?php
// スパイラル設定値
define("API_URL", "https://api.spiral-platform.com/v1");
define("API_KEY", " ご自身のAPIキーを入力してください ");
define("APP_ID", " 使用するアプリのIDを入力してください ");
define("DB1_ID", " 使用するDBのIDを入力してください ");
define("DB2_ID", " DB1のバックアップDBのIDを入力してください");
// Teams Webhook URL
define("TEAMS_WEBHOOK_URL", " 取得したwebhookのURLを入力してください ");
$current = SPIRAL_API_send(API_URL."/apps/".APP_ID."/dbs/".DB1_ID."/records");
$backup = SPIRAL_API_send(API_URL."/apps/".APP_ID."/dbs/".DB2_ID."/records");
$currentMap = [];
foreach ($current['items'] ?? [] as $item) {
$currentMap[$item['_id']] = $item;
}
$backupMap = [];
foreach ($backup['items'] ?? [] as $item) {
$backupMap[$item['db1_id'] ?? $item['_id']] = $item;
}
// 差分チェック
$added = [];
$deleted = [];
$updated = [];
$unchanged = [];
// 追加 or 更新
foreach ($currentMap as $db1_id => $rec) {
if (!isset($backupMap[$db1_id])) {
$added[$db1_id] = $rec;
} else {
$backupRec = $backupMap[$db1_id];
// 比較対象フィールドだけ抽出してマッピング
$currentFields = [
'schedule' => $rec['schedule'] ?? null,
'num_days' => $rec['num_days'] ?? null,
];
$backupFields = [
'schedule' => $backupRec['sche'] ?? null, // フィールド名対応
'num_days' => $backupRec['num'] ?? null,
];
// 比較
if ($currentFields !== $backupFields) {
$updated[$db1_id] = $rec;
}
else {
$unchanged[$db1_id] = $rec;
}
}
}
// 削除
foreach ($backupMap as $db1_id => $rec) {
if (!isset($currentMap[$db1_id])) {
$deleted[$db1_id] = $rec;
}
}
// ③ Teams通知
$messages = [];
if ($added) $messages[] = "🟢 追加: " . implode(', ', array_keys($added));
if ($deleted) $messages[] = "🔴 削除: " . implode(', ', array_keys($deleted));
if ($updated) $messages[] = "🟡 更新: " . implode(', ', array_keys($updated));
if ($unchanged) $messages[] = "✅ 差分無し: " . implode(', ', array_keys($unchanged));
sendToTeams($messages);
// ===== 関数定義 =====
function SPIRAL_API_send($url) {
$header = [
"Authorization:Bearer " . API_KEY,
"Content-Type:application/json",
"X-Spiral-Api-Version: 1.1",
];
$curl = curl_init($url);
curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $header,
]);
$resp = curl_exec($curl);
curl_close($curl);
return json_decode($resp, true);
}
function sendToTeams($messages) {
$payload = [
"type" => "message",
"attachments" => [[
"contentType" => "application/vnd.microsoft.card.adaptive",
"content" => [
"type" => "AdaptiveCard",
"version" => "1.4",
"body" => [[
"type" => "TextBlock",
"text" => implode("\n\n", $messages),
"wrap" => true
]]
]
]]
];
$curl = curl_init(TEAMS_WEBHOOK_URL);
curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
CURLOPT_CUSTOMREQUEST => "POST",
]);
curl_exec($curl);
curl_close($curl);
}
まとめ
今回はSPIRAL®ver2とteamを連携した、レコード情報を集計したり、比較した情報を定期配信するPHPの紹介をしました。
作成するのにはかなり時間がかかり大変でした。。。
皆さんは少し値を変更するだけでできるので、ぜひ試してみてください!
私がインターンしているスパイラル株式会社は、ローコードプラットフォーム、SPIRAL ver.1のトライアルアカウントを無償提供しています。このアカウントの記事でも紹介するように、たくさんの機能がございます。
▶︎ フォーム
▶︎ 認証エリア
▶︎ ログイン
▶︎ メール送信
▶︎ カスタムプログラム
などの作成ができますので、ぜひ試してみてください!!
そして、今チームでトライアル登録者向けに、オンボーディングコンテンツを作成しています。SPIRAL ver.1にご興味のある方、ぜひこちらもご覧ください👇





