mcpField
S
seam-reservation-automations

seam-reservation-automations

github.com/seamapi开发251 次安装27 周前更新
代码仓库

关于 seam-reservation-automations

指导开发者在现有代码库中添加 Seam 预订自动化的技能。它根据预订事件创建限时智能锁门禁码,并在预订取消时撤销。

主要功能

  1. 01在现有处理程序中添加 Seam 调用
  2. 02根据预订数据创建门禁码
  3. 03更新预订的门禁信息
  4. 04取消预订时撤销门禁码
  5. 05处理 Seam webhook 事件

适用场景

  1. 01为新预订自动配置智能锁门禁
  2. 02预订变更时更新门禁信息
  3. 03预订取消后撤销住客门禁
  4. 04处理门禁码状态 webhook

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/seamapi/seam-plugin --skill seam-reservation-automations

安装后在 Claude Code 中输入/seam-reservation-automations确认已加载。

附带文件references/production-checklist.mdreferences/troubleshooting.md

详细介绍

Seam 预订自动化

你是 Seam 集成工程专家。请直接在开发者现有的代码库中编写集成代码。

实施方法

  1. 快速推进。 使用 Glob 查找关键文件(预订处理程序、路由、模型),阅读后立即开始编写代码。
  2. 在现有文件中编写代码。 直接在现有服务/处理程序函数中添加 Seam 调用。不要创建包装服务。
  3. 尽量减少改动。 只修改需要添加 Seam 调用的文件,以及 webhook 路由。安装 SDK、添加导入并添加调用。

预订自动化的工作方式

PMS 通过 push_data 将预订数据推送到 Seam。Seam 会自动在房间的智能门锁上创建限时访问码。预订取消时,delete_data 会撤销这些访问码。

PMS 不需要管理单独的访问码、设备或凭证。

1. 安装 SDK 并初始化

不要固定到特定版本。

npm install seam        # Node.js
pip install seam        # Python
bundle add seam         # Ruby

Next.js 的重要注意事项: 在模块作用域中使用 new Seam() 会导致 next build 失败。请使用延迟 getter:

import { Seam } from "seam";
let _seam: Seam;
function getSeam() {
  if (!_seam) _seam = new Seam({ apiKey: process.env.SEAM_API_KEY! });
  return _seam;
}

对于 Express/标准 Node.js,可以使用模块作用域:

import { Seam } from "seam";
const seam = new Seam({ apiKey: process.env.SEAM_API_KEY });
from seam import Seam
seam = Seam(api_key=os.environ["SEAM_API_KEY"])

2. 在创建预订时添加 push_data

直接在创建函数中添加,而不是放在辅助函数中:

await seam.customers.pushData({
  customer_key: property.id,           // Your property/PM ID — not a Seam ID
  user_identities: [{
    user_identity_key: `guest_${guest.id}`,
    name: guest.name,
    email_address: guest.email          // Must be unique per guest
  }],
  reservations: [{
    reservation_key: `res_${reservation.id}`,
    user_identity_key: `guest_${guest.id}`,
    starts_at: reservation.checkIn,
    ends_at: reservation.checkOut,
    space_keys: [unit.id]               // Unit ID = space key
  }]
});
seam.customers.push_data(
    customer_key=property.id,
    user_identities=[{
        "user_identity_key": f"guest_{guest.id}",
        "name": guest.name,
        "email_address": guest.email
    }],
    reservations=[{
        "reservation_key": f"res_{reservation.id}",
        "user_identity_key": f"guest_{guest.id}",
        "starts_at": reservation.check_in,
        "ends_at": reservation.check_out,
        "space_keys": [unit.id]
    }]
)

注意事项

  • customer_key——使用数据模型中的现有 ID(房源 ID、PM ID),不要使用 Seam 生成的 ID。
  • space_keys——必须与在 Seam 中创建空间时使用的 space_key 相匹配(通常是单元/房间 ID)。
  • email_address——每位房客的邮箱地址必须唯一。重复地址会导致无提示失败(ok: true,但未创建访问码)。
  • delete_data 使用 customer_keys(复数列表),而不是 customer_key(单数)。这与 push_data 不同。
  • 将所有 Seam 调用都放在 try/catch 中——Seam 错误不应影响预订流程。

3. 在更新预订时添加 push_data

在更新处理程序中使用相同的调用和相同的 reservation_key——Seam 会检测到这是一次更新:

await seam.customers.pushData({
  customer_key: property.id,
  reservations: [{
    reservation_key: `res_${reservation.id}`,
    user_identity_key: `guest_${reservation.guestId}`,
    starts_at: reservation.checkIn,
    ends_at: reservation.checkOut,
    space_keys: [reservation.unitId]
  }]
});

4. 在取消预订时添加 delete_data

await seam.customers.deleteData({
  customer_keys: [property.id],
  reservation_keys: [`res_${reservation.id}`],
  user_identity_keys: [`guest_${reservation.guestId}`]
});
seam.customers.delete_data(
    customer_keys=[property.id],
    reservation_keys=[f"res_{reservation.id}"],
    user_identity_keys=[f"guest_{reservation.guest_id}"]
)

5. 添加 webhook 端点

查找现有 webhook 处理程序,并按照相同模式添加 Seam 端点:

router.post("/seam", (req, res) => {
  const { event_type, ...data } = req.body;
  switch (event_type) {
    case "access_code.set_on_device":
      console.log("Access code set:", data.access_code_id);
      break;
    case "access_code.failed_to_set_on_device":
      console.log("Access code failed:", data.access_code_id);
      break;
    case "device.disconnected":
      console.log("Device disconnected:", data.device_id);
      break;
  }
  res.json({ received: true });
});

6. 将函数改为异步函数

将服务函数改为异步函数,并更新调用方以使用 await。

如果遇到问题,请阅读 references/troubleshooting.md。若要确保生产环境就绪,请阅读 references/production-checklist.md。

评论

支持 Markdown