Sinch.Functions.Runtime 0.1.38-beta

This is a prerelease version of Sinch.Functions.Runtime.
dotnet add package Sinch.Functions.Runtime --version 0.1.38-beta
                    
NuGet\Install-Package Sinch.Functions.Runtime -Version 0.1.38-beta
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Sinch.Functions.Runtime" Version="0.1.38-beta" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Sinch.Functions.Runtime" Version="0.1.38-beta" />
                    
Directory.Packages.props
<PackageReference Include="Sinch.Functions.Runtime" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Sinch.Functions.Runtime --version 0.1.38-beta
                    
#r "nuget: Sinch.Functions.Runtime, 0.1.38-beta"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Sinch.Functions.Runtime@0.1.38-beta
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Sinch.Functions.Runtime&version=0.1.38-beta&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Sinch.Functions.Runtime&version=0.1.38-beta&prerelease
                    
Install as a Cake Tool

Sinch.Functions.Runtime

Development runtime for Sinch Functions - build serverless communication workflows with ease.

Getting Started

The easiest way to get started is using the Sinch CLI:

# Install the CLI
npm install -g @sinch/cli

# Create a new function (interactive)
sinch functions init

The interactive prompt will guide you through:

  1. Selecting a runtime (Node.js, C#, etc.)
  2. Choosing a template (simple-voice-ivr recommended for first project)
  3. Setting up your project

Then start the local development server:

sinch functions dev

Your function is now running locally with hot reload!

Deploy to Production

When you're ready to deploy:

sinch functions deploy

Your function will be built and deployed to the Sinch Functions platform.

Features

Voice API

  • SinchVoiceController - Base controller for voice callbacks (ICE, PIE, ACE, DICE)
  • SVAML Builders - Fluent API for building voice responses (IceSvamletBuilder, PieSvamletBuilder)
  • Menu Utilities - IVR menu builders (MenuFactory.CreateMenu())
  • Voice Helpers - TTS, audio playback, and call control utilities
  • Webhook Validation - HMAC signature validation for Voice API callbacks

Conversation API

  • SinchConversationController - Base controller for omnichannel messaging (SMS, WhatsApp, Messenger, Viber)
  • Message Builders - Static helpers and fluent builder for messages
  • Extension Methods - Easy access to inbound message properties
  • Multi-Channel Support - Automatic SMS_SENDER handling, channel-specific configurations
  • Webhook Routing - Automatic routing to typed handlers

Infrastructure

  • FunctionContext - Pre-configured SDK clients, caching, logging
  • Local Development - In-memory caching, tunnel support for local debugging
  • SDK Integration - Pre-configured Sinch SDK clients for Voice and Conversation APIs

Voice IVR Example

using SinchFunctions.Utils;

public class FunctionController : SinchVoiceController
{
    public FunctionController(FunctionContext context, IConfiguration configuration, ILogger<FunctionController> logger)
        : base(context, configuration, logger) { }

    public override async Task<IActionResult> Ice([FromBody] IceCallbackModel callbackData)
    {
        // Create a voice menu
        var menu = MenuFactory.CreateMenu()
            .Prompt("Welcome to Sinch! Press 1 for sales, 2 for support.")
            .Option("1", "return(sales)")
            .Option("2", "return(support)")
            .Build();

        // Return SVAML response
        return Ok(new IceSvamletBuilder()
            .Action.RunMenu(menu)
            .Build());
    }

    public override async Task<IActionResult> Pie([FromBody] PieCallbackModel callbackData)
    {
        var selection = callbackData.MenuResult?.Value;

        return selection switch
        {
            "sales" => Ok(new PieSvamletBuilder().Action.ConnectPstn("+15551234567").Build()),
            "support" => Ok(new PieSvamletBuilder().Action.ConnectPstn("+15559876543").Build()),
            _ => Ok(new PieSvamletBuilder().Action.Hangup().Build())
        };
    }
}

Conversation API Chatbot Example

using Sinch.Conversation.Hooks;
using SinchFunctions.Utils;

public class FunctionController : SinchConversationController
{
    public FunctionController(FunctionContext context, IConfiguration config, ILogger<FunctionController> logger)
        : base(context, config, logger) { }

    public override async Task<IActionResult> MessageInbound(MessageInboundEvent inbound)
    {
        // Use extension methods for easy property access
        var text = inbound.GetText();
        var channel = inbound.GetChannel();
        var contactId = inbound.GetContactId();

        if (string.IsNullOrEmpty(text))
        {
            Logger.LogDebug("Ignoring non-text message from {ContactId}", contactId);
            return Ok();
        }

        Logger.LogInformation("Message from {ContactId} via {Channel}: {Text}", contactId, channel, text);

        // Reply using helper method (auto-sets SMS_SENDER from config for SMS)
        await Context.Conversation!.Messages.Send(Reply(inbound, "Thanks for your message!"));

        return Ok(new { status = "ok" });
    }

    public override Task<IActionResult> MessageDelivery(MessageDeliveryReceiptEvent callback)
    {
        var status = callback.MessageDeliveryReport?.Status?.Value;
        Logger.LogInformation("Delivery status: {Status}", status);
        return Task.FromResult<IActionResult>(Ok());
    }
}

Conversation API Extension Methods

// Easy access to inbound message properties
var text = inbound.GetText();           // Message text content
var channel = inbound.GetChannel();     // SMS, WHATSAPP, MESSENGER, etc.
var identity = inbound.GetIdentity();   // Sender's channel identity (phone/PSID)
var contactId = inbound.GetContactId(); // Sinch contact ID
var to = inbound.GetTo();               // Number the message was sent TO

// Check message types
if (inbound.IsTextMessage()) { /* handle text */ }
if (inbound.IsMediaMessage()) { /* handle media */ }
if (inbound.IsPostback()) { /* handle button click */ }

Conversation API Message Builders

// Simple reply - uses channel from inbound message
await Context.Conversation!.Messages.Send(Reply(inbound, "Hello!"));

// Static helper for SMS
var msg = ConversationMessage.CreateSms(appId, "+15551234567", "Hello!", smsSender);
await Context.Conversation!.Messages.Send(msg);

// Static helper for WhatsApp
var msg = ConversationMessage.CreateWhatsApp(appId, "+15551234567", "Hello!");
await Context.Conversation!.Messages.Send(msg);

// Fluent builder for complex cases
var msg = CreateMessage(inbound)
    .Text("Custom reply")
    .Build();
await Context.Conversation!.Messages.Send(msg);

Conversation API Webhook Events

Trigger Method Description
MESSAGE_INBOUND MessageInbound() User sends a message
MESSAGE_DELIVERY MessageDelivery() Delivery status update
EVENT_INBOUND EventInbound() Typing indicators, read receipts
CONVERSATION_START ConversationStart() Conversation begins
CONVERSATION_STOP ConversationStop() Conversation ends

Conversation API Configuration

Variable Description Required
CONVERSATION_APP_ID Your Conversation API app ID Yes
FROM_NUMBER Your SMS sender number (E.164) For SMS only
CONVERSATION_REGION API region (US, EU, BR) No (default: US)

Documentation

License

MIT License - see LICENSE file for details

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.38-beta 223 12/17/2025
0.1.37-beta 235 12/16/2025
0.1.36-beta 219 12/16/2025

See Sinch.Functions.Runtime for release notes