Skip to content

Commit 4559dac

Browse files
authored
Merge pull request #24 from teesofttech/feature/3-sender-id-apis
Implement Sender ID APIs
2 parents c8c732c + 93ae6c7 commit 4559dac

12 files changed

Lines changed: 291 additions & 2 deletions

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ var response = await client.Messaging.SendAsync(new SendMessageRequest
5656
});
5757
```
5858

59+
Fetch sender IDs:
60+
61+
```csharp
62+
var senderIds = await client.SenderIds.GetAsync();
63+
```
64+
5965
## Examples
6066

6167
Run the examples project after setting your Termii API key:

docs/API_COVERAGE.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ The Termii docs describe a REST/JSON API and state that each account has its own
4040

4141
| Area | Capability | Method | Path | Auth placement | SDK surface | SDK status | Tracking | Test status |
4242
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
43-
| Messaging | Fetch sender IDs | GET | `/api/sender-id` | Query | `TermiiClient.SenderIds` | Planned | #3 | Planned unit + optional integration |
44-
| Messaging | Request sender ID | POST | `/api/sender-id/request` | JSON body | `TermiiClient.SenderIds` | Planned | #3 | Planned unit + optional integration |
43+
| Messaging | Fetch sender IDs | GET | `/api/sender-id` | Query | `TermiiClient.SenderIds` | In progress | #3 | Unit tests added |
44+
| Messaging | Request sender ID | POST | `/api/sender-id/request` | JSON body | `TermiiClient.SenderIds` | In progress | #3 | Unit tests added |
4545
| Messaging | Send SMS/channel message | POST | `/api/sms/send` | JSON body | `TermiiClient.Messaging` | Implemented | #7, PR #21 | Unit tests added |
4646
| Messaging | Send WhatsApp conversational message | POST | `/api/sms/send` | JSON body | `TermiiClient.Messaging` | Implemented | #7, PR #21 | Unit tests added |
4747
| Messaging | Send bulk message | POST | `/api/sms/send/bulk` | JSON body | `TermiiClient.Messaging` | Implemented | #7, PR #21 | Unit tests added |
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
namespace Termii;
2+
3+
public sealed class GetSenderIdsRequest
4+
{
5+
public string? SenderId { get; set; }
6+
7+
public string? Status { get; set; }
8+
9+
internal string ToPath()
10+
{
11+
var query = new List<string>();
12+
13+
if (!string.IsNullOrWhiteSpace(SenderId))
14+
{
15+
query.Add($"sender_id={Uri.EscapeDataString(SenderId)}");
16+
}
17+
18+
if (!string.IsNullOrWhiteSpace(Status))
19+
{
20+
query.Add($"status={Uri.EscapeDataString(Status)}");
21+
}
22+
23+
return query.Count == 0
24+
? "/api/sender-id"
25+
: $"/api/sender-id?{string.Join("&", query)}";
26+
}
27+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace Termii;
2+
3+
public interface ITermiiSenderIdClient
4+
{
5+
Task<SenderIdListResponse> GetAsync(
6+
GetSenderIdsRequest? request = null,
7+
CancellationToken cancellationToken = default);
8+
9+
Task<RequestSenderIdResponse> RequestAsync(
10+
RequestSenderIdRequest request,
11+
CancellationToken cancellationToken = default);
12+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace Termii;
4+
5+
public sealed class RequestSenderIdRequest
6+
{
7+
[JsonPropertyName("sender_id")]
8+
public string SenderId { get; set; } = string.Empty;
9+
10+
[JsonPropertyName("use_case")]
11+
public string UseCase { get; set; } = string.Empty;
12+
13+
[JsonPropertyName("company")]
14+
public string Company { get; set; } = string.Empty;
15+
16+
internal void Validate()
17+
{
18+
TermiiRequestValidation.Required(SenderId, nameof(SenderId));
19+
TermiiRequestValidation.Required(UseCase, nameof(UseCase));
20+
TermiiRequestValidation.Required(Company, nameof(Company));
21+
}
22+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace Termii;
4+
5+
public sealed class RequestSenderIdResponse
6+
{
7+
[JsonPropertyName("code")]
8+
public string? Code { get; set; }
9+
10+
[JsonPropertyName("message")]
11+
public string? Message { get; set; }
12+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace Termii;
4+
5+
public sealed class SenderIdListResponse
6+
{
7+
[JsonPropertyName("content")]
8+
public IReadOnlyCollection<SenderIdRecord> Content { get; set; } = Array.Empty<SenderIdRecord>();
9+
10+
[JsonPropertyName("totalElements")]
11+
public int? TotalElements { get; set; }
12+
13+
[JsonPropertyName("totalPages")]
14+
public int? TotalPages { get; set; }
15+
16+
[JsonPropertyName("size")]
17+
public int? Size { get; set; }
18+
19+
[JsonPropertyName("number")]
20+
public int? Number { get; set; }
21+
22+
[JsonPropertyName("first")]
23+
public bool? First { get; set; }
24+
25+
[JsonPropertyName("last")]
26+
public bool? Last { get; set; }
27+
28+
[JsonPropertyName("empty")]
29+
public bool? Empty { get; set; }
30+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace Termii;
4+
5+
public sealed class SenderIdRecord
6+
{
7+
[JsonPropertyName("sender_id")]
8+
public string? SenderId { get; set; }
9+
10+
[JsonPropertyName("status")]
11+
public string? Status { get; set; }
12+
13+
[JsonPropertyName("country")]
14+
public string? Country { get; set; }
15+
16+
[JsonPropertyName("company")]
17+
public string? Company { get; set; }
18+
19+
[JsonPropertyName("usecase")]
20+
public string? UseCase { get; set; }
21+
22+
[JsonPropertyName("createdAt")]
23+
public string? CreatedAt { get; set; }
24+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
namespace Termii;
2+
3+
internal sealed class TermiiSenderIdClient : ITermiiSenderIdClient
4+
{
5+
private readonly TermiiJsonHttpPipeline _pipeline;
6+
7+
public TermiiSenderIdClient(TermiiJsonHttpPipeline pipeline)
8+
{
9+
_pipeline = pipeline ?? throw new ArgumentNullException(nameof(pipeline));
10+
}
11+
12+
public Task<SenderIdListResponse> GetAsync(
13+
GetSenderIdsRequest? request = null,
14+
CancellationToken cancellationToken = default)
15+
{
16+
return _pipeline.SendJsonAsync<SenderIdListResponse>(
17+
HttpMethod.Get,
18+
(request ?? new GetSenderIdsRequest()).ToPath(),
19+
body: null,
20+
TermiiAuthenticationLocation.Query,
21+
cancellationToken);
22+
}
23+
24+
public Task<RequestSenderIdResponse> RequestAsync(
25+
RequestSenderIdRequest request,
26+
CancellationToken cancellationToken = default)
27+
{
28+
if (request is null)
29+
{
30+
throw new ArgumentNullException(nameof(request));
31+
}
32+
33+
request.Validate();
34+
35+
return _pipeline.SendJsonAsync<RequestSenderIdResponse>(
36+
HttpMethod.Post,
37+
"/api/sender-id/request",
38+
request,
39+
TermiiAuthenticationLocation.Body,
40+
cancellationToken);
41+
}
42+
}

src/Termii/TermiiClient.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,15 @@ private TermiiClient(HttpClient httpClient, TermiiOptions options, bool ownsHttp
3535

3636
_pipeline = new TermiiJsonHttpPipeline(_httpClient, Options);
3737
Messaging = new TermiiMessagingClient(_pipeline);
38+
SenderIds = new TermiiSenderIdClient(_pipeline);
3839
}
3940

4041
public TermiiOptions Options { get; }
4142

4243
public ITermiiMessagingClient Messaging { get; }
4344

45+
public ITermiiSenderIdClient SenderIds { get; }
46+
4447
public void Dispose()
4548
{
4649
if (_ownsHttpClient)

0 commit comments

Comments
 (0)