Skip to content

Commit a641311

Browse files
committed
Bootstrap .NET SDK solution
1 parent 4b3eff8 commit a641311

15 files changed

Lines changed: 412 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- main
8+
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v4
16+
17+
- name: Setup .NET
18+
uses: actions/setup-dotnet@v4
19+
with:
20+
dotnet-version: 8.0.x
21+
22+
- name: Restore
23+
run: dotnet restore
24+
25+
- name: Build
26+
run: dotnet build --configuration Release --no-restore
27+
28+
- name: Test
29+
run: dotnet test --configuration Release --no-build

.gitignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
bin/
2+
obj/
3+
.vs/
4+
.vscode/
5+
.idea/
6+
TestResults/
7+
coverage/
8+
*.user
9+
*.suo
10+
*.nupkg
11+
*.snupkg
12+
artifacts/

Directory.Build.props

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project>
2+
<PropertyGroup>
3+
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
4+
<Nullable>enable</Nullable>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<LangVersion>latest</LangVersion>
7+
<RepositoryUrl>https://github.com/teesofttech/Termii.SDK</RepositoryUrl>
8+
<RepositoryType>git</RepositoryType>
9+
<PackageProjectUrl>https://github.com/teesofttech/Termii.SDK</PackageProjectUrl>
10+
<PackageLicenseExpression>MIT</PackageLicenseExpression>
11+
<Authors>Teesoft Tech</Authors>
12+
<Company>Teesoft Tech</Company>
13+
</PropertyGroup>
14+
</Project>

README.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Termii .NET SDK
2+
3+
A .NET SDK for the Termii messaging, token, and insights APIs.
4+
5+
> This SDK is in early development. The first milestones establish the client, tests, examples, API coverage matrix, and package structure before endpoint support is added feature by feature.
6+
7+
## Current Status
8+
9+
The initial repository setup includes:
10+
11+
- A `Termii` SDK project targeting `netstandard2.0` and `net8.0`.
12+
- A lightweight unit test project.
13+
- An examples project for developer-facing usage.
14+
- An API coverage matrix in `docs/API_COVERAGE.md`.
15+
16+
## Usage
17+
18+
```csharp
19+
using Termii;
20+
21+
var client = new TermiiClient(new TermiiOptions
22+
{
23+
ApiKey = "your-termii-api-key"
24+
});
25+
```
26+
27+
The default base URL is `https://api.ng.termii.com`.
28+
29+
## Examples
30+
31+
Run the examples project after setting your Termii API key:
32+
33+
```bash
34+
export TERMII_API_KEY="your-termii-api-key"
35+
dotnet run --project examples/Termii.Examples
36+
```
37+
38+
## Tests
39+
40+
Run the local test suite:
41+
42+
```bash
43+
dotnet test
44+
```
45+
46+
Integration tests are opt-in and must not call live Termii endpoints unless the required environment variables are present:
47+
48+
```bash
49+
export TERMII_API_KEY="your-termii-api-key"
50+
export TERMII_BASE_URL="https://api.ng.termii.com"
51+
dotnet test tests/Termii.IntegrationTests
52+
```
53+
54+
As endpoint support is added, integration tests should remain credential-gated so normal CI can run without network access or Termii credits.
55+
56+
## Roadmap
57+
58+
Development is tracked through GitHub issues:
59+
60+
- SDK foundation and HTTP pipeline.
61+
- Messaging APIs.
62+
- Sender ID and number APIs.
63+
- Token/OTP APIs.
64+
- Insights APIs.
65+
- CI, documentation, NuGet packaging, and GitHub Releases.
66+
67+
Official Termii documentation: https://developer.termii.com/

Termii.SDK.sln

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.0.31903.59
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{827E0CD3-B72D-47B6-A68D-7590B98EB39B}"
7+
EndProject
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Termii", "src\Termii\Termii.csproj", "{2C2E40AF-504E-4A61-B46A-84A1BC352ED5}"
9+
EndProject
10+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{0AB3BF05-4346-4AA6-1389-037BE0695223}"
11+
EndProject
12+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Termii.Tests", "tests\Termii.Tests\Termii.Tests.csproj", "{6AE7CBA2-1987-477E-B14D-C34F50A5DD48}"
13+
EndProject
14+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Termii.IntegrationTests", "tests\Termii.IntegrationTests\Termii.IntegrationTests.csproj", "{73C4DC47-8035-4F23-8C46-1AAFE5E7D449}"
15+
EndProject
16+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{B36A84DF-456D-A817-6EDD-3EC3E7F6E11F}"
17+
EndProject
18+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Termii.Examples", "examples\Termii.Examples\Termii.Examples.csproj", "{063DC3E1-23F8-4D66-918D-8FB1C61B648D}"
19+
EndProject
20+
Global
21+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
22+
Debug|Any CPU = Debug|Any CPU
23+
Debug|x64 = Debug|x64
24+
Debug|x86 = Debug|x86
25+
Release|Any CPU = Release|Any CPU
26+
Release|x64 = Release|x64
27+
Release|x86 = Release|x86
28+
EndGlobalSection
29+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
30+
{2C2E40AF-504E-4A61-B46A-84A1BC352ED5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
31+
{2C2E40AF-504E-4A61-B46A-84A1BC352ED5}.Debug|Any CPU.Build.0 = Debug|Any CPU
32+
{2C2E40AF-504E-4A61-B46A-84A1BC352ED5}.Debug|x64.ActiveCfg = Debug|Any CPU
33+
{2C2E40AF-504E-4A61-B46A-84A1BC352ED5}.Debug|x64.Build.0 = Debug|Any CPU
34+
{2C2E40AF-504E-4A61-B46A-84A1BC352ED5}.Debug|x86.ActiveCfg = Debug|Any CPU
35+
{2C2E40AF-504E-4A61-B46A-84A1BC352ED5}.Debug|x86.Build.0 = Debug|Any CPU
36+
{2C2E40AF-504E-4A61-B46A-84A1BC352ED5}.Release|Any CPU.ActiveCfg = Release|Any CPU
37+
{2C2E40AF-504E-4A61-B46A-84A1BC352ED5}.Release|Any CPU.Build.0 = Release|Any CPU
38+
{2C2E40AF-504E-4A61-B46A-84A1BC352ED5}.Release|x64.ActiveCfg = Release|Any CPU
39+
{2C2E40AF-504E-4A61-B46A-84A1BC352ED5}.Release|x64.Build.0 = Release|Any CPU
40+
{2C2E40AF-504E-4A61-B46A-84A1BC352ED5}.Release|x86.ActiveCfg = Release|Any CPU
41+
{2C2E40AF-504E-4A61-B46A-84A1BC352ED5}.Release|x86.Build.0 = Release|Any CPU
42+
{6AE7CBA2-1987-477E-B14D-C34F50A5DD48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
43+
{6AE7CBA2-1987-477E-B14D-C34F50A5DD48}.Debug|Any CPU.Build.0 = Debug|Any CPU
44+
{6AE7CBA2-1987-477E-B14D-C34F50A5DD48}.Debug|x64.ActiveCfg = Debug|Any CPU
45+
{6AE7CBA2-1987-477E-B14D-C34F50A5DD48}.Debug|x64.Build.0 = Debug|Any CPU
46+
{6AE7CBA2-1987-477E-B14D-C34F50A5DD48}.Debug|x86.ActiveCfg = Debug|Any CPU
47+
{6AE7CBA2-1987-477E-B14D-C34F50A5DD48}.Debug|x86.Build.0 = Debug|Any CPU
48+
{6AE7CBA2-1987-477E-B14D-C34F50A5DD48}.Release|Any CPU.ActiveCfg = Release|Any CPU
49+
{6AE7CBA2-1987-477E-B14D-C34F50A5DD48}.Release|Any CPU.Build.0 = Release|Any CPU
50+
{6AE7CBA2-1987-477E-B14D-C34F50A5DD48}.Release|x64.ActiveCfg = Release|Any CPU
51+
{6AE7CBA2-1987-477E-B14D-C34F50A5DD48}.Release|x64.Build.0 = Release|Any CPU
52+
{6AE7CBA2-1987-477E-B14D-C34F50A5DD48}.Release|x86.ActiveCfg = Release|Any CPU
53+
{6AE7CBA2-1987-477E-B14D-C34F50A5DD48}.Release|x86.Build.0 = Release|Any CPU
54+
{73C4DC47-8035-4F23-8C46-1AAFE5E7D449}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
55+
{73C4DC47-8035-4F23-8C46-1AAFE5E7D449}.Debug|Any CPU.Build.0 = Debug|Any CPU
56+
{73C4DC47-8035-4F23-8C46-1AAFE5E7D449}.Debug|x64.ActiveCfg = Debug|Any CPU
57+
{73C4DC47-8035-4F23-8C46-1AAFE5E7D449}.Debug|x64.Build.0 = Debug|Any CPU
58+
{73C4DC47-8035-4F23-8C46-1AAFE5E7D449}.Debug|x86.ActiveCfg = Debug|Any CPU
59+
{73C4DC47-8035-4F23-8C46-1AAFE5E7D449}.Debug|x86.Build.0 = Debug|Any CPU
60+
{73C4DC47-8035-4F23-8C46-1AAFE5E7D449}.Release|Any CPU.ActiveCfg = Release|Any CPU
61+
{73C4DC47-8035-4F23-8C46-1AAFE5E7D449}.Release|Any CPU.Build.0 = Release|Any CPU
62+
{73C4DC47-8035-4F23-8C46-1AAFE5E7D449}.Release|x64.ActiveCfg = Release|Any CPU
63+
{73C4DC47-8035-4F23-8C46-1AAFE5E7D449}.Release|x64.Build.0 = Release|Any CPU
64+
{73C4DC47-8035-4F23-8C46-1AAFE5E7D449}.Release|x86.ActiveCfg = Release|Any CPU
65+
{73C4DC47-8035-4F23-8C46-1AAFE5E7D449}.Release|x86.Build.0 = Release|Any CPU
66+
{063DC3E1-23F8-4D66-918D-8FB1C61B648D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
67+
{063DC3E1-23F8-4D66-918D-8FB1C61B648D}.Debug|Any CPU.Build.0 = Debug|Any CPU
68+
{063DC3E1-23F8-4D66-918D-8FB1C61B648D}.Debug|x64.ActiveCfg = Debug|Any CPU
69+
{063DC3E1-23F8-4D66-918D-8FB1C61B648D}.Debug|x64.Build.0 = Debug|Any CPU
70+
{063DC3E1-23F8-4D66-918D-8FB1C61B648D}.Debug|x86.ActiveCfg = Debug|Any CPU
71+
{063DC3E1-23F8-4D66-918D-8FB1C61B648D}.Debug|x86.Build.0 = Debug|Any CPU
72+
{063DC3E1-23F8-4D66-918D-8FB1C61B648D}.Release|Any CPU.ActiveCfg = Release|Any CPU
73+
{063DC3E1-23F8-4D66-918D-8FB1C61B648D}.Release|Any CPU.Build.0 = Release|Any CPU
74+
{063DC3E1-23F8-4D66-918D-8FB1C61B648D}.Release|x64.ActiveCfg = Release|Any CPU
75+
{063DC3E1-23F8-4D66-918D-8FB1C61B648D}.Release|x64.Build.0 = Release|Any CPU
76+
{063DC3E1-23F8-4D66-918D-8FB1C61B648D}.Release|x86.ActiveCfg = Release|Any CPU
77+
{063DC3E1-23F8-4D66-918D-8FB1C61B648D}.Release|x86.Build.0 = Release|Any CPU
78+
EndGlobalSection
79+
GlobalSection(SolutionProperties) = preSolution
80+
HideSolutionNode = FALSE
81+
EndGlobalSection
82+
GlobalSection(NestedProjects) = preSolution
83+
{2C2E40AF-504E-4A61-B46A-84A1BC352ED5} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
84+
{6AE7CBA2-1987-477E-B14D-C34F50A5DD48} = {0AB3BF05-4346-4AA6-1389-037BE0695223}
85+
{73C4DC47-8035-4F23-8C46-1AAFE5E7D449} = {0AB3BF05-4346-4AA6-1389-037BE0695223}
86+
{063DC3E1-23F8-4D66-918D-8FB1C61B648D} = {B36A84DF-456D-A817-6EDD-3EC3E7F6E11F}
87+
EndGlobalSection
88+
EndGlobal

docs/API_COVERAGE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Termii API Coverage
2+
3+
This matrix tracks the Termii API surface against SDK implementation work.
4+
5+
| Area | Capability | SDK status | Issue |
6+
| --- | --- | --- | --- |
7+
| Foundation | Solution, projects, examples, basic tests | In progress | #1 |
8+
| Foundation | Client configuration, authentication, HTTP pipeline | Planned | #2 |
9+
| Foundation | Error handling and validation | Planned | #6 |
10+
| Messaging | Send SMS and channel messages | Planned | #7 |
11+
| Messaging | Sender ID APIs | Planned | #3 |
12+
| Messaging | Number API messaging | Planned | #5 |
13+
| Token | Send, verify, and generate OTP | Planned | #4 |
14+
| Insights | Balance, DND, number status, message history | Planned | #9 |
15+
| Release | NuGet package metadata and publishing workflow | Planned | #8 |
16+
| Release | GitHub Release and NuGet publication | Planned | #13 |
17+
18+
References:
19+
20+
- Termii developer docs: https://developer.termii.com/
21+
- Postman collection: https://termii.s3.us-west-1.amazonaws.com/upload/files/UozvGXj5czYEeY4OmE2f.json
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using Termii;
2+
3+
var apiKey = Environment.GetEnvironmentVariable("TERMII_API_KEY");
4+
5+
if (string.IsNullOrWhiteSpace(apiKey))
6+
{
7+
Console.WriteLine("Set TERMII_API_KEY to run the Termii examples.");
8+
return;
9+
}
10+
11+
var client = new TermiiClient(new TermiiOptions
12+
{
13+
ApiKey = apiKey,
14+
});
15+
16+
Console.WriteLine($"Termii client configured for {client.Options.BaseUrl}.");
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<IsPackable>false</IsPackable>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<ProjectReference Include="../../src/Termii/Termii.csproj" />
10+
</ItemGroup>
11+
</Project>

src/Termii/Termii.csproj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
4+
<AssemblyName>Termii</AssemblyName>
5+
<RootNamespace>Termii</RootNamespace>
6+
<PackageId>Termii</PackageId>
7+
<Description>A .NET SDK for the Termii messaging, token, and insights APIs.</Description>
8+
<PackageTags>termii;sms;otp;messaging;dotnet;sdk</PackageTags>
9+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
10+
<NoWarn>$(NoWarn);1591</NoWarn>
11+
</PropertyGroup>
12+
</Project>

src/Termii/TermiiClient.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
namespace Termii;
2+
3+
/// <summary>
4+
/// Main entry point for the Termii SDK.
5+
/// </summary>
6+
public sealed class TermiiClient
7+
{
8+
public TermiiClient(TermiiOptions options)
9+
{
10+
Options = options ?? throw new ArgumentNullException(nameof(options));
11+
Options.Validate();
12+
}
13+
14+
public TermiiOptions Options { get; }
15+
}

0 commit comments

Comments
 (0)