Sveve 1.0.0

dotnet add package Sveve --version 1.0.0
                    
NuGet\Install-Package Sveve -Version 1.0.0
                    
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="Sveve" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Sveve" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Sveve" />
                    
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 Sveve --version 1.0.0
                    
#r "nuget: Sveve, 1.0.0"
                    
#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 Sveve@1.0.0
                    
#: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=Sveve&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Sveve&version=1.0.0
                    
Install as a Cake Tool

Sveve logo

This is unofficial packages and not made by or supported by Sveve.

This repository contains two packages:

  • Sveve A .NET client for the Sveve sms REST API.
  • Sveve.AspNetCore Receive sms and delivery reports from Sveve in a .NET API.

Sveve

The Sveve package contains a client for the Sveve REST API.
It is built on netstandard2.0 and therefore supports most .NET environments.

SveveClient

To communicate with Sveve, create a SveveClient:

var client = new SveveClient(new SveveClientOptions
{
    Username = "username",
    Password = "password"
});

Send sms

await client.SendAsync(new Sms("99999999", "Drink water!"));

Sveve limits each account to 5 concurrent requests.
To send multiple messages in a single request, pass an IEnumerable<Sms> instead of a single Sms to SendAsync:

await client.SendAsync([
    new Sms("44444444", "Drink water!"), 
    new Sms("99999999", "You too!")]);

Schedule sms

var sms = new Sms("+47 949 49 494", "A friendly reminder to drink water")
{
    SendTime = DateTimeOffset.Now.AddDays(1);
};
await client.SendAsync(sms);

Repeat sms

Sveve supports repeating messages, but be careful with this one.
Use the SendRepeat class to specify a repetition:

var sms = new Sms("+47 999 99 999", "Am I annoying now?");

// Never repeat the sms. This is the default behaviour.
sms.Repeat = SendRepeat.Never;

// Send the sms once every hour and NEVER stop. ( Please dont )
sms.Repeat = SendRepeat.Hourly();

// Send the sms every two days until the sms has been sent three times.
sms.Repeat = SendRepeat.Daily(days:2).Times(3);

// Send the sms once every month for a year.
sms.Repeat = SendRepeat.Monthly().Until(DateTime.Now.AddYears(1));

await client.SendAsync(sms);

Be very careful when making repetitions that never end.

Sender

If the receivers phone supports it and Sender is specified, it will be used as display name for the sender.

To set the default Sender for all messages sent by client:

var client = new SveveClient(new SveveClientOptions
{
    Username = "...",
    Password = "...",
    Sender = "MyCompany"
});

You can also specify a sender on the individual sms:

var sms = new Sms("44444444", "Badabing badabom")
{
    Sender = "MyCompany"
};

When Sender is specified on both SveveClientOptions and Sms, Sms.Sender wins.

Replies

await client.SendAsync(new Sms("444 44 444", "Hello, how are you?")
{
    ReplyAllowed = true
});

This allows the receiver to reply to the sms.
To handle the replies, see Sveve.AspNetCore.

If ReplyAllowed is true Sveve sends the sms from a randomly generated 14-digit phone number. This means that the display-senders configured in either SveveClientOptions.Sender or Sms.Sender are ignored.

If you have already sent a sms and want to send another to the same thread on the users phone:

// Send the first sms and keep the id.
var response = await client.SendAsync(new Sms("444 44 444", "Hello, how are you?")
{
    ReplyAllowed = true
});

// remember the sms id.
int messageId = response.MessageId("44  44444 4");

// Send another sms to the same conversation/thread on the users phone.
await client.SendAsync(new Sms("44444444", "Pleace don't ignore me :(")
{
    ReplyTo = messageId
});

To receive messages, see Sveve.AspNetCore.

Testing

Test sms are sent to Sveve but not delivered to the receiver.

Test-mode can be enabled for a single sms:

var sms = new Sms("99999999", "Not actually sent") { Test = true };

or for the entire SveveClient:

var client = new SveveClient(new SveveClientOption
{
    Username = "username",
    Password = "password",
    Test = true
});

When sending messages in bulk, all messages must agree on Sms.Test.
Otherwise an ArgumentException is thrown.

If SveveClientOptions.Test is true, Sms.Test is ignored.
All messages become test messages.

Groups

Sveve allows you to manage named collections of recipients called groups.
All the groups on your account can be listed with

List<string> groupNames = await client.GroupsAsync();

To work with an individual group, use

SveveGroup group = client.Group("my-group");

// AddMemberAsync creates the group if it does not
// already exist.
await group.AddMemberAsync("99999999", name:"Some Member");

// Does nothing if the group does not exist
// or the member is not in the group.
await group.RemoveMemberAsync("44444444");

// Send sms to Some Member and every other member of my-group.
await client.SendAsync("my-group", "Hello!");

When you are done with a group, you can delete it using

// Does nothing if the group does not exist.
await group.DeleteAsync();

or move all the members from the original group to another group.

SveveGroup myGroup = client.Group("my-group");

// another-group is created if it does not already exist.
await myGroup.MoveToAsync("another-group");

// my-group is now empty.

Admin

To send messages from Sveve, you need sms units. Sms units are bought in advance. To check the remaining amount of sms units on your account call

int remaining = await client.RemainingSmsUnitsAsync();

If you need more sms units, you can buy them in fixed size bulks like this:

await client.PurchaseSmsUnitsAsync(SmsUnitOrder.Bulk500);

Calls to PurchaseSmsUnitsAsync will cost you real money billed to your account.

Bigger purchases cost you less per sms unit.

Logs and metrics

The client produces logs and metrics all of which are prefixed by Sveve.

Sveve.AspNetCore

The Sveve.AspNetCore package contains everything you need to receive incoming sms and delivery reports from Sveve in a .NET API.

To receive sms and reports, first configure your API, then configure Sveve.

Configure your API

In Program.cs register your consumers on the IServiceCollection. Consumers are registered using

// Consume delivery reports
builder.Services.AddSveveDeliveryConsumer<MyDeliveryConsumer>();

// Consume incoming messages
builder.Services.AddSveveSmsConsumer<MySmsConsumer>();

// Consume all Sveve notifications
builder.Services.AddSveveConsumer<MyConsumer>();

Consumers are transient by default.

You can add multiple consumers to the same notification.

After the app has been build, add an endpoint Sveve can call with notifications:

app.MapSveveConsumerEndpoint("api/sveve");

If no consumers are registered for a notification or any consumer throws during handling,
your API will return 500 Internal Server Error and Sveve will try again later.

Configure Sveve

Once your API is configured to consume notifications from Sveve, you need to tell Sveve where to deliver the reports.

Grab the full URL to your Sveve consumer endpoint and head over to Sveve and sign in.
Once there, add the consumer URL to all callbacks:
The endpoint works for both GET and POST
Sveve Dashboard

You can also add the URL to callbacks for messages to dedicated phone numbers and code words.

Delivery reports

When a sms sent by you has been delivered or failed to deliver, Sveve will notify you and all the registered ISveveDeliveryConsumers will be invoked with the appropriate callback.

Here is an example delivery report consumer.

class MyConsumer(ILogger logger) : ISveveDeliveryConsumer
{
    public Task SmsDelivered(
        OutgoingSms sms, 
        CancellationToken cancellationToken)
        => Task.CompletedTask;

    public Task SmsFailed(
        OutgoingSms sms, 
        SmsDeliveryError error, 
        CancellationToken cancellationToken)
    {
        logger.LogWarning(
            "Failed to deliver sms to {PhoneNumber}. Reason: {Reason}",
            sms.ReceiverPhoneNumber, error.Description);
        return Task.CompletedTask;
    }
}

Incoming messages

When someone sends you a message, Sveve will notify you and all the registered ISveveSmsConsumers will be invoked with the appropriate callback.

Here is an example sms consumer.
When a user replies to a sms, we reply to them with a joke made by some gpt model.

class MyConsumer(GptModel gpt, SveveClient sveve) : ISveveSmsConsumer
{
    public async Task SmsReceived(
        IncomingSmsReply sms, 
        CancellationToken cancellationToken)
    {
        var joke = await gpt.PromptAsync(
            "You are a very funny comedian who loves to make people laugh." +
            "Make a joke about this: " + sms.Message);
            
        var reply = new Sms(sms.SenderPhoneNumber, "Joke: " + joke)
        {
            // Ensure SMS is added to the same thread
            // as the message the user replied to:
            ReplyTo = sms.MessageId
        };
        
        await sveve.SendAsync(reply, cancellationToken);
    }
    
    public Task SmsReceived(
        IncomingSmsToCode sms,
        CancellationToken cancellationToken)
        => Task.CompletedTask;
    
    public Task SmsReceived(
        IncomingSmsToDedicatedPhoneNumber sms,
        CancellationToken cancellationToken)
        => Task.CompletedTask;
}

Logs and metrics

The consumers produces logs and metrics all of which are prefixed by Sveve.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos 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
1.0.0 144 11/23/2024
1.0.0-preview1 93 11/16/2024