Skip to content

Commit 235b15a

Browse files
committed
Throw on failed HTTP requests to WhatsApp
This makes it easier to detect issues and handle abnormal execution (i.e. including Polly).
1 parent 4892934 commit 235b15a

File tree

6 files changed

+33
-27
lines changed

6 files changed

+33
-27
lines changed

src/Tests/WhatsAppClientTests.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@ public async Task SendsMessageAsync()
3131
{
3232
var (configuration, client) = Initialize();
3333

34-
var result = await client.SendTextAync(configuration["SendFrom"]!, configuration["SendTo"]!, "Hi there!");
35-
36-
Assert.True(result);
34+
await client.SendTextAync(configuration["SendFrom"]!, configuration["SendTo"]!, "Hi there!");
3735
}
3836

3937
[SecretsFact("Meta:VerifyToken", "SendFrom", "SendTo")]
@@ -43,7 +41,7 @@ public async Task SendsButtonAsync()
4341

4442
// Send an interactive message with three buttons showcasing the payload/value
4543
// being different than the button text
46-
var result = await client.SendAync(configuration["SendFrom"]!, new
44+
await client.SendAync(configuration["SendFrom"]!, new
4745
{
4846
messaging_product = "whatsapp",
4947
recipient_type = "individual",
@@ -66,8 +64,6 @@ public async Task SendsButtonAsync()
6664
}
6765
}
6866
});
69-
70-
Assert.True(result);
7167
}
7268

7369
(IConfiguration configuration, WhatsAppClient client) Initialize()

src/WhatsApp/AzureFunctions.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,18 @@ public async Task<HttpResponseMessage> Message([HttpTrigger(AuthorizationLevel.A
7171
await queue.CreateIfNotExistsAsync();
7272
await queue.SendMessageAsync(json);
7373
if (message.Type == MessageType.Content)
74-
await whatsapp.MarkReadAsync(message.To.Id, message.Id);
74+
{
75+
try
76+
{
77+
// Best-effort to mark as read. This might be an old message callback,
78+
// or the message might have been deleted.
79+
await whatsapp.MarkReadAsync(message.To.Id, message.Id);
80+
}
81+
catch (HttpRequestException e)
82+
{
83+
logger.LogWarning("Failed to mark message as read: {Id}\r\n{Payload}", message.Id, e.Message);
84+
}
85+
}
7586
}
7687
else
7788
{

src/WhatsApp/AzureFunctionsExtensions.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,9 @@ namespace Microsoft.Azure.Functions.Worker.Builder;
1515
/// </summary>
1616
public static class AzureFunctionsExtensions
1717
{
18-
/// <summary>
19-
/// Configure the WhatsApp handler for Azure Functions.
20-
/// </summary>
21-
public static IFunctionsWorkerApplicationBuilder UseWhatsApp(this IFunctionsWorkerApplicationBuilder builder, Func<IServiceProvider, Message, Task> handler)
22-
{
23-
builder.Services.AddSingleton<IWhatsAppHandler>(services => new AnonymousWhatsAppHandler(services, handler));
24-
ConfigureServices(builder.Services);
25-
return builder;
26-
}
27-
2818
static void ConfigureServices(IServiceCollection services)
2919
{
30-
services.AddHttpClient().ConfigureHttpClientDefaults(http => http.AddStandardResilienceHandler());
20+
services.AddHttpClient("whatsapp").AddStandardResilienceHandler();
3121
services.AddSingleton<IWhatsAppClient, WhatsAppClient>();
3222

3323
if (services.FirstOrDefault(x => x.ServiceType == typeof(QueueServiceClient)) == null)
@@ -68,6 +58,16 @@ static void ConfigureServices(IServiceCollection services)
6858
.ValidateDataAnnotations();
6959
}
7060

61+
/// <summary>
62+
/// Configure the WhatsApp handler for Azure Functions.
63+
/// </summary>
64+
public static IFunctionsWorkerApplicationBuilder UseWhatsApp(this IFunctionsWorkerApplicationBuilder builder, Func<IServiceProvider, Message, Task> handler)
65+
{
66+
builder.Services.AddSingleton<IWhatsAppHandler>(services => new AnonymousWhatsAppHandler(services, handler));
67+
ConfigureServices(builder.Services);
68+
return builder;
69+
}
70+
7171
/// <summary>
7272
/// Configure the WhatsApp handler for Azure Functions.
7373
/// </summary>

src/WhatsApp/IWhatsAppClient.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,7 @@ public interface IWhatsAppClient
1414
/// <param name="payload">The message payload.</param>
1515
/// <returns>Whether the message was successfully sent.</returns>
1616
/// <see cref="https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages"/>
17-
Task<bool> SendAync(string from, object payload);
17+
/// <exception cref="ArgumentException">The number <paramref name="from"/> is not registered in <see cref="MetaOptions"/>.</exception>
18+
/// <exception cref="HttpRequestException">The HTTP request failed. Exception message contains the error response body from WhatsApp.</exception>
19+
Task SendAync(string from, object payload);
1820
}

src/WhatsApp/WhatsAppClient.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ public static IWhatsAppClient Create(IHttpClientFactory httpFactory, MetaOptions
3030
=> new WhatsAppClient(httpFactory, Options.Create(options), logger);
3131

3232
/// <inheritdoc />
33-
/// <exception cref="ArgumentException"></exception>
34-
public async Task<bool> SendAync(string from, object payload)
33+
public async Task SendAync(string from, object payload)
3534
{
3635
if (!options.Numbers.TryGetValue(from, out var token))
3736
throw new ArgumentException($"The number '{from}' is not registered in the options.", nameof(from));
@@ -46,10 +45,8 @@ public async Task<bool> SendAync(string from, object payload)
4645
if (!result.IsSuccessStatusCode)
4746
{
4847
var error = JsonNode.Parse(await result.Content.ReadAsStringAsync())?.ToJsonString(new() { WriteIndented = true });
49-
logger.LogError("Failed to send WhatsApp message: {error}", error);
50-
return false;
48+
logger.LogError("Failed to send WhatsApp message from {From}: {Error}", from, error);
49+
throw new HttpRequestException(error, null, result.StatusCode);
5150
}
52-
53-
return true;
5451
}
5552
}

src/WhatsApp/WhatsAppClientExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public static Task MarkReadAsync(this IWhatsAppClient client, string from, strin
1414
});
1515

1616

17-
public static Task<bool> ReactAsync(this IWhatsAppClient client, string from, string to, string messageId, string reaction)
17+
public static Task ReactAsync(this IWhatsAppClient client, string from, string to, string messageId, string reaction)
1818
=> client.SendAync(from, new
1919
{
2020
messaging_product = "whatsapp",
@@ -28,7 +28,7 @@ public static Task<bool> ReactAsync(this IWhatsAppClient client, string from, st
2828
}
2929
});
3030

31-
public static Task<bool> SendTextAync(this IWhatsAppClient client, string from, string to, string message)
31+
public static Task SendTextAync(this IWhatsAppClient client, string from, string to, string message)
3232
=> client.SendAync(from, new
3333
{
3434
messaging_product = "whatsapp",

0 commit comments

Comments
 (0)