Configuración
Cada opción del cliente, lo que lee del entorno y lo que rechaza.
Opciones
using var http = new HttpClient(); var client = new OpenEmailClient(new OpenEmailOptions{ ApiKey = Environment.GetEnvironmentVariable("OPENEMAIL_API_KEY"), BaseUrl = "https://api.openemail.uk", Timeout = TimeSpan.FromSeconds(30), MaxRetries = 2, HttpClient = http, Headers = { ["X-Team"] = "billing" },}); Console.WriteLine($"{client.Mode} {client.Raw.BaseUrl}");| Opción | Qué hace |
|---|---|
| ApiKey | La clave de API del espacio de trabajo, que empieza por oe_live_ o oe_test_. |
| AccessToken | Un token de acceso de OAuth, para una aplicación que una persona conectó. Pasa una clave o un token, no ambos. |
| AccessTokenProvider | Una función que devuelve el token de acceso. Se ejecuta antes de cada petición, así que es el lugar donde renovar un token. |
| BaseUrl | El origen de la API. A un host sin esquema, como localhost:2222, se le añade el esquema. |
| HttpClient | El HttpClient que tu aplicación ya tiene, como uno de IHttpClientFactory o uno con un manejador de pruebas. El cliente nunca lo libera. |
| Timeout | Cuánto puede tardar un intento. El valor por defecto es 30 segundos, TimeSpan.Zero lo desactiva y las subidas esperan al menos diez minutos. |
| MaxRetries | Cuántas veces se reintenta una petición fallida. El valor por defecto es 2, y 0 envía una sola vez. |
| UserAgent | Sustituye la cabecera User-Agent, que es openemail-dotnet/ y la versión. |
| Headers | Cabeceras que se añaden a cada petición. |
Todo lo que omitas se lee del entorno: OPENEMAIL_API_KEY, después OPENEMAIL_ACCESS_TOKEN, y OPENEMAIL_BASE_URL. client.Mode indica si la clave es una clave live o test.
Cancelación y tiempos de espera
Cada método recibe un CancellationToken al final. Cancelarlo detiene la llamada al instante, reintentos incluidos, y lanza OperationCanceledException, mientras que Timeout limita cada intento.
using var deadline = new CancellationTokenSource(TimeSpan.FromSeconds(10)); var thread = await client.Threads.GetAsync("CAHk7pQ2x9LmZ4-mail.example.com", cancellationToken: deadline.Token); Console.WriteLine(thread["messageCount"]);Opciones de una llamada
Los parámetros de consulta y los ajustes de la llamada son argumentos nombrados con los nombres de la API, como limit:, cursor: e idempotencyKey:. Cada método acepta apiKey: para actuar con otra clave solo en esa llamada, así que un proceso puede atender varios espacios de trabajo con un solo cliente.
var page = await client.Emails.ListAsync( status: new[] { "failed", "bounced" }, limit: 50, apiKey: Environment.GetEnvironmentVariable("OTHER_WORKSPACE_KEY")); Console.WriteLine($"{page.Count} {page.HasMore}");Tokens de acceso OAuth
Una app que una persona conectó con OAuth tiene un token de acceso en lugar de una clave de API. Pásalo como AccessToken, o pasa AccessTokenProvider y renueva ahí el token cuando esté a punto de caducar, así nunca hay que reconstruir el cliente.
var current = "token-from-your-oauth-flow"; var client = new OpenEmailClient(new OpenEmailOptions{ AccessTokenProvider = _ => Task.FromResult(current),}); var me = await client.Me.GetAsync(); Console.WriteLine(me["workspaceId"]);ASP.NET Core
Registra un solo cliente para toda la aplicación. No mantiene ninguna conexión propia que liberar, así que un singleton es el ciclo de vida adecuado.
using OpenEmail; var builder = WebApplication.CreateBuilder(args); builder.Services.AddSingleton(new OpenEmailClient(new OpenEmailOptions{ ApiKey = builder.Configuration["OpenEmail:ApiKey"],})); var app = builder.Build(); app.MapPost("/invoices/{number}/send", async (string number, OpenEmailClient client, CancellationToken cancellationToken) =>{ var sent = await client.Emails.SendAsync(new Body { ["from"] = "[email protected]", ["to"] = "[email protected]", ["subject"] = $"Invoice {number}", ["text"] = "The invoice is attached.", }, idempotencyKey: $"invoice-{number}", cancellationToken: cancellationToken); return Results.Ok(new { id = (string?)sent["id"] });}); app.Run();Lo que el cliente rechaza
- Una clave que no empieza por
oe_live_ooe_test_, y una clave junto con un token de acceso. - Enviar una credencial por
http:sin cifrar, salvo que el servidor esté en esta máquina, enlocalhost, en una dirección127.x.x.xo en::1. - Una URL base en
0.0.0.0, que es una dirección en la que escucha un servidor. Usa127.0.0.1con el mismo puerto. - Un id vacío, o uno formado solo por puntos, que un analizador de URL eliminaría.
- Seguir una redirección. El cliente HTTP que crea el paquete nunca sigue ninguna, así que una credencial nunca viaja a otro host.
Imprimir un cliente o una excepción nunca muestra una credencial. ToString() en un cliente da su modo y su URL base, y nada más.
Un endpoint sin método
client.Raw.RequestAsync() llama a cualquier ruta con la credencial, la URL base, el tiempo de espera y la política de reintentos del cliente. La ruta debe empezar por una sola /, y una ruta que sale del origen de la URL base se rechaza.
var label = await client.Raw.RequestAsync("/labels", "POST", body: new Body { ["name"] = "Invoices" }); Console.WriteLine(label?["id"]);