Getting Started with Sinch Functions
Getting Started with Sinch Functions
Sinch Functions 入门指南
I’ve built a lot of voice integrations. Every single one needed a deployment whose only job was to talk to the Sinch API: receive the callback, translate it into SVAML or a Conversation API call, hand off to the rest of the application. Not the interesting part. Just the piece that has to exist because your code and Sinch’s network live in different places, with a round trip between them on every call event.
我构建过许多语音集成项目。每一个项目都需要一个部署环境,其唯一的工作就是与 Sinch API 通信:接收回调、将其转换为 SVAML 或 Conversation API 调用,然后将其移交给应用程序的其余部分。这并不是核心部分,它仅仅是因为你的代码和 Sinch 的网络位于不同位置而必须存在的“胶水”代码,且每次呼叫事件都会在两者之间产生往返延迟。
Sinch Functions moves that piece into the network itself. Your voice and messaging handlers run on the same infrastructure that’s already carrying your calls and messages, right where the callbacks originate. This isn’t a general-purpose Lambda replacement: the rest of your application, and any compute that isn’t glue against Sinch’s APIs, stays exactly where it is, whether that’s AWS, Azure, or your own infrastructure. Your order lookup, your database writes, your actual business logic: still on Lambda or wherever you already have it. Functions is specifically for the code that exists only to bridge your app and the Sinch network, not a place to run your whole system.
Sinch Functions 将这部分逻辑直接移入网络内部。你的语音和消息处理程序运行在承载呼叫和消息的同一基础设施上,即回调产生的源头。这不是通用的 Lambda 替代品:你的应用程序其余部分,以及任何非 Sinch API 胶水代码的计算任务,都保持在原位,无论是 AWS、Azure 还是你自己的基础设施。你的订单查询、数据库写入、实际业务逻辑:依然保留在 Lambda 或你现有的任何地方。Functions 专门用于那些仅作为应用程序与 Sinch 网络桥梁的代码,而不是运行整个系统的平台。
I’ve been trying it out and this post walks through getting set up, writing a basic voice function, and deploying it.
我一直在试用它,这篇文章将带你了解如何进行设置、编写基本的语音函数并将其部署。
Pricing is usage-based and separate from your Voice and Conversation usage: $0.10 per compute-hour (first hour free each month), $0.05 per GB-month of storage (first 0.1 GB free), $0.05 to $0.15 per GB-month for the database depending on tier (first 0.1 GB free), and $5.00 per month per function if you want it kept always-on instead of scaling to zero. These are the current Standard rates from your project’s Billing Overview in the Sinch dashboard; treat them as a snapshot, not a guarantee, given the Alpha status below.
定价基于使用量,与你的语音和对话使用量分开计算:每计算小时 0.10 美元(每月首小时免费),每 GB-月存储空间 0.05 美元(首 0.1 GB 免费),数据库根据层级每 GB-月 0.05 至 0.15 美元(首 0.1 GB 免费),如果你希望函数保持常驻而不缩减至零,则每个函数每月 5.00 美元。这些是 Sinch 仪表板中项目账单概览里的当前标准费率;鉴于下文提到的 Alpha 状态,请将其视为快照而非保证。
Sinch Functions is listed as Alpha in the Sinch Build dashboard. Expect the CLI, runtime APIs, pricing, and this walkthrough itself to change before general availability. Treat it as something to experiment with, not something to put in front of production traffic yet.
Sinch Functions 在 Sinch Build 仪表板中被列为 Alpha 版本。预计在正式发布之前,CLI、运行时 API、定价以及本指南本身都可能会发生变化。请将其视为实验性工具,不要将其用于生产环境流量。
Prerequisites
前置条件
-
You’ll need Node.js 20 (the other supported runtime is C#, but this walkthrough uses Node.js)
-
A Sinch account with a phone number assigned to a Voice App, ideally a Voice App you don’t use for anything real yet; more on why under Running Locally below
-
Project ID, Key ID, and Key Secret from the Sinch dashboard
-
你需要 Node.js 20(另一种支持的运行时是 C#,但本指南使用 Node.js)
-
一个拥有已分配电话号码的语音应用(Voice App)的 Sinch 账户,最好是一个尚未用于实际业务的语音应用;原因详见下文“本地运行”部分
-
来自 Sinch 仪表板的项目 ID (Project ID)、密钥 ID (Key ID) 和密钥密文 (Key Secret)
Installing the CLI
安装 CLI
npm install -g @sinch/cli
Then authenticate: 然后进行身份验证:
sinch auth login
The CLI prompts for your Project ID, Key ID, and Key Secret, then two follow-up questions. Say yes when it asks to add Voice application credentials (Key and Secret from your Voice App); this walkthrough builds a voice function and won’t work without them. It’ll also offer to install Sinch’s developer skills for AI coding assistants like Claude Code and Cursor; that’s a genuinely interesting feature but a big enough topic (it installs globally across every agent it finds on your machine) that it deserves its own post rather than a detour here. Everything from this step is stored locally and injected automatically when you run or deploy. You don’t reference any of it in code.
CLI 会提示你输入项目 ID、密钥 ID 和密钥密文,然后是两个后续问题。当它询问是否添加语音应用凭据(来自你的语音应用的 Key 和 Secret)时,请选择“是”;本指南构建的是语音函数,没有这些凭据将无法工作。它还会提议为 Claude Code 和 Cursor 等 AI 编码助手安装 Sinch 开发技能;这是一个非常有趣的功能,但话题较大(它会全局安装到你机器上找到的每个代理中),因此值得单独写一篇文章,而不是在这里绕道。此步骤之后的所有内容都存储在本地,并在你运行或部署时自动注入。你无需在代码中引用它们。
Confirm the connection before moving on: 在继续之前确认连接:
sinch health
✔ API is healthy 🏥 Health Status: Status: healthy API URL: https://functions.api.sinch.com Project ID: <your-project-id>
Creating your first function
创建你的第一个函数
Initialize a project from a template: 从模板初始化项目:
sinch functions init simple-voice-ivr --name my-simple-voice-ivr
This template is also available for C#; pass --runtime csharp if you’d rather use that. The command walks you through a few prompts: a company name used in the voice prompts, whether to auto-configure voice integration on deploy (say yes, it’s what wires up the callback URL automatically), and whether to enable a database (pick “No database” for this one, since a basic IVR greeting doesn’t need persistence). It then installs dependencies for you, so there’s no separate npm install step. Once it’s done:
该模板也支持 C#;如果你更喜欢使用 C#,请传入 --runtime csharp。该命令会引导你完成几个提示:语音提示中使用的公司名称、是否在部署时自动配置语音集成(选择“是”,它会自动连接回调 URL),以及是否启用数据库(此例选择“无数据库”,因为基本的 IVR 问候语不需要持久化)。它随后会自动为你安装依赖项,因此无需单独执行 npm install。完成后:
cd my-simple-voice-ivr
Here’s what the template generates: 模板生成的内容如下:
my-simple-voice-ivr/
├── .github/
├── .vscode/
├── node_modules/
├── .env
├── AGENTS.md
├── CLAUDE.md
├── README.md
├── function.ts
├── package.json
├── package-lock.json
├── runtime.json
├── sinch.json
├── test.http
└── tsconfig.json
function.ts is the only file you need to touch for this walkthrough. AGENTS.md and CLAUDE.md are instructions for AI coding assistants working in this project, test.http is a set of ready-made requests if your editor supports the REST Client format, and runtime.json and sinch.json are metadata the CLI manages for you.
在本指南中,你只需要修改 function.ts 文件。AGENTS.md 和 CLAUDE.md 是针对在该项目中工作的 AI 编码助手的说明,test.http 是一组现成的请求(如果你的编辑器支持 REST Client 格式),而 runtime.json 和 sinch.json 是 CLI 为你管理的元数据。
function.ts is where your logic lives. Named exports become HTTP endpoints. The runtime maps them automatically based on the export name. Open it before changing anything. The template already generated a complete, working Yes/No IVR: an ice handler that plays a menu, a pie handler that responds to the key press and retries on bad input, a dice handler that logs when the call ends, and a default handler for a base HTTP endpoint. It’s worth reading through once to see the full shape of a real voice function.
function.ts 是存放逻辑的地方。具名导出(Named exports)会成为 HTTP 端点。运行时会根据导出名称自动映射它们。在进行任何更改之前先打开它。模板已经生成了一个完整、可用的“是/否” IVR:一个播放菜单的 ice 处理程序,一个响应按键并处理错误输入的 pie 处理程序,一个在呼叫结束时记录日志的 dice 处理程序,以及一个用于基础 HTTP 端点的默认处理程序。值得通读一遍,以了解真实语音函数的完整形态。
I’m about to replace most of it with a simpler version to build it back up in stages, not because anything is wrong with what’s there. Before touching the generated menu logic, replace it with the simplest possible ice handler, just answering the call:
我打算将其大部分内容替换为一个更简单的版本,以便分阶段构建,这并不是因为原有的代码有什么问题。在修改生成的菜单逻辑之前,先将其替换为最简单的 ice 处理程序,仅用于接听电话:
import type { VoiceFunction, FunctionContext } from '@sinch/functions-runtime';
import type { Voice } from '@sinch/voice';
import { createIceBuilder, createUniversalConfig } from '@sinch/functions-runtime';
export default {
async ice(context: FunctionContext, callbackData: Voice.IceRequest) {
const config = createUniversalConfig(context);
const companyName = config.getVariable('COMPANY_NAME', 'Your Company');
return createIceBuilder()
.say(`Hello! Thanks for calling ${companyName}.`)
.hangup()
.build();
},
} satisfies VoiceFunction;
ice is the Incoming Call Event, the first callback Sinch sends when a call arrives, and it’s one of four voice callbacks, each firing at a different point in a call’s lifecycle: the ca…
ice 是“呼入呼叫事件”(Incoming Call Event),是呼叫到达时 Sinch 发送的第一个回调。它是四个语音回调之一,每个回调在呼叫生命周期的不同阶段触发:ca…