首页
/ Cal.com QR Code 应用集成指南:为事件类型链接生成可打印、可分享、可嵌入的二维码

Cal.com QR Code 应用集成指南:为事件类型链接生成可打印、可分享、可嵌入的二维码

2026-09-09 10:39:38作者:戚魁泉Nursing

导读

本文基于 cal.diy 仓库中 packages/app-store/qr_code 应用展开,讲解如何在 Cal.com 的事件类型(Event Type) 上集成 QR Code 应用,一键生成可用于打印、分享或嵌入的二维码,并支持通过附加 URL 参数定制二维码指向的链接。读者学完后,将掌握该应用的安装机制、事件类型设置界面、二维码生成原理(含三种尺寸与样式细节)、底层数据结构(Zod schema)以及把二维码用于线下物料投放的完整实战方法。

一、应用定位:为“事件类型链接”生成二维码

QR Code 应用在仓库中的官方描述只有一句话,但定位非常精准:

Easily generate a QR code for your links to print, share, or embed. (轻松为你的链接生成二维码,用于打印、分享或嵌入。)

其核心价值在于:Cal.com 的每一个事件类型(如 30 分钟咨询、60 分钟会议)都拥有一个独立的预订链接(eventType.URL)。线下场景(名片、海报、易拉宝、会议桌牌)无法直接点击链接,QR Code 应用将这一业务链接转化为物理世界可扫描的二维码,实现“线下扫码 → 在线预订”的闭环。同时通过附加参数(如 UTM 来源、渠道标记、?guest=1 等),可以追踪不同投放渠道的预订转化效果。

从元数据看(见 config.json),这是一个典型的 EventType 扩展型应用

配置项 含义
slug qr_code 应用唯一标识,不可修改
type qr_code_other 应用类型标识,供 API 层识别
variant other 应用变体分类
categories ["other"] 应用市场中的分类归属
extendsFeature EventType 核心特征:扩展的是事件类型而非全局功能
isOAuth false 无需 OAuth 授权流程
publisher Cal.com, Inc. 发布方

extendsFeature: "EventType" 是关键——它决定了该应用出现在事件类型配置页的应用卡片区域,而不是用户级或团队级设置中心。这也是后文所有安装、配置、渲染逻辑的落点。

二、安装机制:无密钥的默认安装(API 层)

QR Code 应用不依赖任何第三方凭证或 OAuth 令牌,因此其安装流程是最简化的“默认安装”。应用入口文件 index.ts 仅做了一件事:导出 api 命名空间:

export * as api from "./api";

api/index.ts 只暴露了一个 add handler(即“添加/安装”处理函数),具体实现在 api/add.ts

import type { AppDeclarativeHandler } from "@calcom/types/AppHandler";

import { createDefaultInstallation } from "../../_utils/installation";
import appConfig from "../config.json";

const handler: AppDeclarativeHandler = {
  appType: appConfig.type,
  variant: appConfig.variant,
  slug: appConfig.slug,
  supportsMultipleInstalls: false,
  handlerType: "add",
  createCredential: ({ appType, user, slug, teamId }) =>
    createDefaultInstallation({ appType, user: user, slug, key: {}, teamId }),
};

export default handler;

这段代码的几个要点值得展开:

  • handlerType: "add" 声明这是一个安装型 handler;AppDeclarativeHandler 是 Cal.com app-store 声明的通用接口(类型定义见 types/AppHandler.d.ts)。
  • createDefaultInstallation(来自 packages/app-store/_utils/installation.ts)是 Cal.com 为无凭证应用提供的标准安装函数:传入空对象 key: {} 即可建立一条 Credential 记录,表示“该事件类型已启用 QR Code 应用”。
  • supportsMultipleInstalls: false 表明每个用户/团队只能安装一次,符合“工具型”应用的特征——不需要重复安装多份。
  • 因为 key 为空、appKeysSchema 为空对象(见下文),所以整个安装过程不产生任何敏感配置或密钥,这也是它成为入门级、零门槛应用的原因。

三、事件类型设置界面:附加参数 + 三档尺寸二维码

安装后,QR Code 应用会以 AppCard 形式呈现在事件类型配置页中。外层卡片组件 EventTypeAppCardInterface.tsx 使用了 Cal.com 的标准基础设施:

  • useIsAppEnabled(app):读取/切换应用启用状态,控制卡片右上角开关;
  • useAppContextWithSchema<typeof appDataSchema>():基于 Zod schema 读写事件类型 metadata.apps 中的应用数据,disabled 状态会联动传递给内层设置组件。

真正的功能逻辑在 EventTypeAppSettingsInterface.tsx 中,其 UI 由两部分组成。

3.1 附加 URL 参数输入框

界面顶部是一个 TextField(标签为 additional_url_parameters,即“附加 URL 参数”),允许用户为二维码指向的链接追加查询参数:

const [additionalParameters, setAdditionalParameters] = useState("");
const query = additionalParameters !== "" ? `?${additionalParameters}` : "";
const eventTypeURL = eventType.URL + query;

行为逻辑为:

  • 输入为空 → query 为空字符串,二维码指向原始事件类型链接 eventType.URL
  • 输入非空 → 自动拼接 ? 前缀,得到 eventType.URL?<你的参数>

典型用法示例:在门店桌牌投放时输入 utm_source=qr-table&utm_medium=offline,即可在预订分析中区分不同渠道来源;需要携带与会者身份时也可输入如 guest=1 等平台支持的查询参数。注意参数需符合 URL 编码规范,多个参数用 & 连接。

3.2 三档尺寸二维码生成

设置界面底部一次性渲染三个不同尺寸的二维码,供不同投放场景选用:

function QRCode({ size, data }: { size: number; data: string }) {
  const QR_URL = `https://api.qrserver.com/v1/create-qr-code/?size=${size}&data=${data}`;
  return (
    <Tooltip content={eventTypeURL}>
      <a download href={QR_URL} target="_blank" rel="noreferrer">
        <img
          className={classNames(
            "hover:bg-cal-muted border-default border transition hover:shadow-sm",
            size >= 256 && "min-h-32"
          )}
          style={{ padding: size / 16, borderRadius: size / 20 }}
          width={size}
          src={QR_URL}
          alt={eventTypeURL}
        />
      </a>
    </Tooltip>
  );
}
// 渲染处
<QRCode size={256} data={eventTypeURL} />
<QRCode size={128} data={eventTypeURL} />
<QRCode size={64} data={eventTypeURL} />

从源码可以提炼出该实现的几个关键设计:

  • 生成方式:二维码图由 api.qrserver.comcreate-qr-code 接口按需生成,sizedata 直接作为查询参数传给该服务,<img>src 即指向生成的图片地址——这是一个无需后端、纯前端的二维码方案,部署成本为零。
  • 尺寸档位256px(适合海报、易拉宝等远距离扫描)、128px(适合名片、宣传单页)、64px(适合屏幕嵌入、邮件签名等近距离小场景)。
  • 下载与提示:整个 <img> 包裹在带 download 属性的 <a> 标签内,用户点击即可直接下载 PNG 图片用于印刷;鼠标悬停时通过 Tooltip 显示二维码指向的完整事件类型 URL,方便校对。
  • 视觉样式:内边距为 size / 16(如 256px 时为 16px),圆角为 size / 20,保证二维码留白符合规范且观感统一;size >= 256 时追加 min-h-32 类避免大图在布局中塌陷。
  • 语义化alt={eventTypeURL} 使二维码的可访问性与 SEO 语义都指向目标预订链接。

四、数据结构:极简的 Zod Schema 与事件类型元数据

QR Code 应用的数据层非常干净,见 zod.ts

import { z } from "zod";

import { eventTypeAppCardZod } from "../eventTypeAppCardZod";

export const appDataSchema = eventTypeAppCardZod;

export const appKeysSchema = z.object({});

其中 appDataSchema 直接复用所有 EventType 应用共享的 eventTypeAppCardZod.ts

export const eventTypeAppCardZod = z.object({
  enabled: z.boolean().optional(),
  credentialId: z.number().optional(),
  appCategories: z.array(z.string()).optional(),
});

这意味着该应用在事件类型 metadata.apps 中存储的数据只有三个可选字段enabled(开关状态)、credentialId(安装凭证 ID)、appCategories(所属分类)。附加参数输入框中的内容仅存在于组件本地 useState不会持久化到数据库——每次进入配置页都从空字符串开始,这是该实现的一个值得注意的行为(若希望跨会话保留参数,需要二次开发)。

appKeysSchema(应用级密钥 Schema)为空对象,从数据结构层面再次印证:QR Code 应用不持有任何密钥、Token 或敏感配置,是一个完全公开、零权限要求的轻量应用。

五、应用市场的注册与分发位置

作为 app-store 生态的一员,QR Code 应用通过 packages/app-store/apps.metadata.generated.ts 等生成文件被注册进应用市场列表;其扩展了事件类型,因此遵循 extendsFeature: "EventType" 的通用注册规则。对该应用的源码进行二次开发或本地调试时,可参考 packages/app-store/CONTRIBUTING.md 了解 app-store 目录的组织约定,以及同目录下其他 EventType 扩展类应用(如 giphy、hitpay、qr_code 等)作为对照样本。

六、适用场景与限制总结

综合 DESCRIPTION.md 与源码实现,QR Code 应用最适合以下场景:

  1. 线下物料投放:打印 256px 二维码到海报/桌牌/易拉宝,客人扫码直达预订页;
  2. 内容分享:在邮件签名、即时通讯、社交平台分享 128px 或 64px 二维码;
  3. 嵌入第三方页面:将 <img> 形式的二维码嵌入官网、活动页、PPT 等任意支持图片的载体;
  4. 渠道归因:利用附加 URL 参数区分不同投放渠道的预订来源。

使用时需注意的边界:

  • 二维码渲染依赖外部 api.qrserver.com 服务,离线或该服务不可达时无法出图(从源码结构可以推断这是当前实现的固有限制);
  • 附加参数仅存于前端状态,不持久化;
  • 应用无密钥、无 OAuth,因此也没有权限配置或企业级管控能力,适合轻量使用而非复杂场景。

七、结语

QR Code 应用是 Cal.com app-store 中“小而完整”的典型样本:一条安装 handler、一张事件类型卡片、一个设置界面,即完成了“事件类型链接 → 可打印/分享/嵌入二维码”的完整闭环。它既是一个开箱即用的功能,也为开发者理解 EventType 扩展型应用(extendsFeature: "EventType"、共享 eventTypeAppCardZodcreateDefaultInstallation 安装范式)提供了极佳的参考实现。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
docsdocs
暂无描述
Markdown
899
5.83 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
925
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.84 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
601
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.03 K
525
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
395