twilio-labs / twilio-aspnet

Integrate Twilio Programmable Messaging and Voice with ASP.NET Respond to webhooks with TwiML in seconds
Apache License 2.0
58 stars 30 forks source link

No apparent way to update username/password for injected TwilioRestClients #99

Closed mducharm closed 1 year ago

mducharm commented 1 year ago

After reading this blog post about the new startup extension, I was looking forwared to injecting TwilioRestClients instead of using the static TwilioClient.Init(accountSid, authToken); approach.

But there doesn't seem to be a way to change the username & password for the injected client, like TwilioClient.SetUsername/SetPassword. For scenarios such as sending texts to different subaccounts with different accountSid & authToken from the same API, I'm not sure that I can set this dynamically per-request.

If there is a way to do this without resorting to the previous static approach, it might be good to update the docs. Thanks!

Swimburger commented 1 year ago

The TwilioClient, TwilioRestClient, and ITwilioRestClient are provided by the Twilio helper library for .NET, and this is the helper library for ASP.NET, so unfortunately, we can't add setters or methods to change the TwilioRestClient or ITwilioRestClient.

However, you can look at the source code of this project to see how we add the TwilioRestClient and ITwilioRestClient to ASP.NET Core's services, and base your own code off of that.

If you want to construct your client differently based off the HTTP Request, you can do something like the following:

using Twilio.Clients;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHttpContextAccessor();
builder.Services.AddScoped<ITwilioRestClient>(provider =>
{
    var httpContext = provider.GetService<IHttpContextAccessor>()?.HttpContext;
    if (httpContext == null) return new TwilioRestClient("", "", "", null, null, null);
    return httpContext.Request.Host.Host switch
    {
        "company1.myapp.com" => new TwilioRestClient("", "", "", null, null, null),
        "company2.myapp.com" => new TwilioRestClient("", "", "", null, null, null),
        _ => new TwilioRestClient("", "", "", null, null, null)
    };
});

Instead of hard coding the hostnames and account credentials, these would probably come from .NET Configuration or from a data store.

I don't think we can add multi-tenancy functionality like above into the library, as there's too many different ways to do multi-tenancy. I hope the source code we have and the example above helps you on your way tho!

mducharm commented 1 year ago

After peeking at the source code I simply made a TwilioClientFactorythat creates TwilioRestClients like the extension does, while allowing the user to pass the relevant args in a CreateClient method. Thanks for the help!