Skip to content

Commit

Permalink
Refactor selector to return client name
Browse files Browse the repository at this point in the history
  • Loading branch information
chankiyu22 committed Sep 23, 2024
2 parents dab1569 + 7984341 commit 1ad8649
Show file tree
Hide file tree
Showing 16 changed files with 404 additions and 228 deletions.
6 changes: 2 additions & 4 deletions cmd/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,8 @@ func main() {
if err != nil {
panic(err)
}
smsService, err := sms.NewSMSService(logger, smsProviderConfig)
if err != nil {
panic(err)
}
smsClientMap := sms.NewSMSClientMap(smsProviderConfig, logger)
smsService := sms.NewSMSService(logger, smsProviderConfig, smsClientMap)

http.Handle("/healthz", handler.NewHealthzHandler())
http.Handle("/send", handler.NewSendHandler(
Expand Down
4 changes: 2 additions & 2 deletions pkg/handler/send.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func (h *SendHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}
h.Logger.Info(fmt.Sprintf("Attempt to send sms to %v. Body: %v. AppID: %v", body.To, body.Body, body.AppID))
clientResponse, err := h.SMSService.Send(
sendResult, err := h.SMSService.Send(
body.AppID,
body.To,
body.Body,
Expand All @@ -98,7 +98,7 @@ func (h *SendHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {

h.JSON.WriteResponse(w, &api.Response{
Result: Result{
ClientResponse: string(clientResponse),
ClientResponse: string(sendResult.ClientResponse),
},
})
}
46 changes: 44 additions & 2 deletions pkg/lib/config/sms_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,12 @@ var _ = SMSProviderConfigSchema.Add("SMSProviderConfig", `
`)

func (c *SMSProviderConfig) Validate(ctx *validation.Context) {
c.ValidateProvider(ctx)
c.ValidateProviderSelectorUseProvider(ctx)
c.ValidateProviderSelectorDefault(ctx)
c.ValidateSendCloudConfigs(ctx)
}

func (c *SMSProviderConfig) ValidateProvider(ctx *validation.Context) {
func (c *SMSProviderConfig) ValidateProviderSelectorUseProvider(ctx *validation.Context) {
providers := c.Providers
for i, switchCase := range c.ProviderSelector.Switch {
useProvider := switchCase.UseProvider
Expand All @@ -234,6 +236,46 @@ func (c *SMSProviderConfig) ValidateProvider(ctx *validation.Context) {
}
}

func (c *SMSProviderConfig) ValidateProviderSelectorDefault(ctx *validation.Context) {
for _, switchCase := range c.ProviderSelector.Switch {
if switchCase.Type == ProviderSelectorSwitchTypeDefault {
return
}
}
ctx.Child("provider_selector", "switch").EmitErrorMessage(fmt.Sprintf("provider selector default not found"))
}

func (c *SMSProviderConfig) ValidateSendCloudConfigs(ctx *validation.Context) {
for i, provider := range c.Providers {
if provider.Type == ProviderTypeSendCloud {
c.ValidateSendCloudConfig(ctx.Child("providers", strconv.Itoa(i), "sendcloud"), provider.SendCloud)
}
}
}

func (c *SMSProviderConfig) ValidateSendCloudConfig(ctx *validation.Context, sendCloudConfig *ProviderConfigSendCloud) {
templates := sendCloudConfig.Templates
for i, templateAssignment := range sendCloudConfig.TemplateAssignments {
ctxTemplateAssignment := ctx.Child("template_assignments", strconv.Itoa(i))
defaultTemplateID := templateAssignment.DefaultTemplateID
idx := slices.IndexFunc(templates, func(t *SendCloudTemplate) bool { return t.TemplateID == defaultTemplateID })

if idx == -1 {
ctxTemplateAssignment.Child("default_template_id").EmitErrorMessage(fmt.Sprintf("template_id %v not found", defaultTemplateID))
}

for j, byLanguage := range templateAssignment.ByLanguages {
ctxByLanguage := ctxTemplateAssignment.Child("by_languages", strconv.Itoa(j))
templateID := byLanguage.TemplateID
idx = slices.IndexFunc(templates, func(t *SendCloudTemplate) bool { return t.TemplateID == templateID })
if idx == -1 {
ctxByLanguage.Child("template_id").EmitErrorMessage(fmt.Sprintf("template_id %v not found", templateID))
}
}
}

}

func ParseSMSProviderConfigFromYAML(inputYAML []byte) (*SMSProviderConfig, error) {
const validationErrorMessage = "invalid configuration"

Expand Down
123 changes: 123 additions & 0 deletions pkg/lib/config/testdata/sms_provider_tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,126 @@ config:
phone_number_alpha2: HK
- type: default
use_provider: infobip
---
name: failed-provider-selector-missing-default
error: |-
invalid configuration:
/provider_selector/switch: provider selector default not found
config:
providers:
- name: twilio
type: twilio
twilio:
account_sid: "my-account-sid"
auth_token: "my-auth-token"
message_service_sid: "my-message-service-sid"
sender: "+85212345678"
- name: nexmo
type: nexmo
nexmo:
api_key: "my-api-key"
api_secret: "my-secret"
sender: "+85212345678"
- name: accessyou
type: accessyou
accessyou:
accountno: "my-accountno"
user: "my-user"
pwd: "my-pwd"
sender: "my-sender"
- name: sendcloud
type: sendcloud
sendcloud:
sms_user: "my-sms-user"
sms_key: "my-sms-key"
sender: "my-sender"
templates:
- template_id: "919888"
template_msg_type: "2"
- template_id: "919879"
template_msg_type: "2"
template_assignments:
- authgear_template_name: "verficiation_sms.txt"
default_template_id: "919888"
by_languages:
- authgear_languag: en
template_id: "919888"
provider_selector:
switch:
- type: match_app_id_and_phone_number_alpha2
use_provider: accessyou
phone_number_alpha2: HK
app_id: "123"
- type: match_app_id_and_phone_number_alpha2
use_provider: sendcloud
phone_number_alpha2: CN
app_id: "123"
- type: match_phone_number_alpha2
use_provider: accessyou
phone_number_alpha2: HK
- type: match_phone_number_alpha2
use_provider: sendcloud
phone_number_alpha2: CN
---
name: failed-sendcloud-config
error: |-
invalid configuration:
/providers/3/sendcloud/template_assignments/0/default_template_id: template_id 919889 not found
/providers/3/sendcloud/template_assignments/0/by_languages/0/template_id: template_id 919890 not found
config:
providers:
- name: twilio
type: twilio
twilio:
account_sid: "my-account-sid"
auth_token: "my-auth-token"
message_service_sid: "my-message-service-sid"
sender: "+85212345678"
- name: nexmo
type: nexmo
nexmo:
api_key: "my-api-key"
api_secret: "my-secret"
sender: "+85212345678"
- name: accessyou
type: accessyou
accessyou:
accountno: "my-accountno"
user: "my-user"
pwd: "my-pwd"
sender: "my-sender"
- name: sendcloud
type: sendcloud
sendcloud:
sms_user: "my-sms-user"
sms_key: "my-sms-key"
sender: "my-sender"
templates:
- template_id: "919888"
template_msg_type: "2"
- template_id: "919879"
template_msg_type: "2"
template_assignments:
- authgear_template_name: "verficiation_sms.txt"
default_template_id: "919889"
by_languages:
- authgear_languag: en
template_id: "919890"
provider_selector:
switch:
- type: match_app_id_and_phone_number_alpha2
use_provider: accessyou
phone_number_alpha2: HK
app_id: "123"
- type: match_app_id_and_phone_number_alpha2
use_provider: sendcloud
phone_number_alpha2: CN
app_id: "123"
- type: match_phone_number_alpha2
use_provider: accessyou
phone_number_alpha2: HK
- type: match_phone_number_alpha2
use_provider: sendcloud
phone_number_alpha2: CN
- type: default
use_provider: twilio
27 changes: 8 additions & 19 deletions pkg/lib/infra/sms/accessyou.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
)

type AccessYouClient struct {
Name string
BaseUrl string
Client *http.Client
AccountNo string
Expand All @@ -25,7 +24,6 @@ type AccessYouClient struct {
}

func NewAccessYouClient(
name string,
baseUrl string,
accountNo string,
user string,
Expand All @@ -37,7 +35,6 @@ func NewAccessYouClient(
baseUrl = "http://sms.accessyou-anyip.com"
}
return &AccessYouClient{
Name: name,
BaseUrl: baseUrl,
Client: &http.Client{},
AccountNo: accountNo,
Expand All @@ -48,20 +45,10 @@ func NewAccessYouClient(
}
}

func (n *AccessYouClient) GetName() string {
return n.Name
}

func (n *AccessYouClient) Send(
to string,
body string,
templateName string,
languageTag string,
templateVariables *TemplateVariables,
) (ClientResponse, error) {
func (n *AccessYouClient) Send(options *SendOptions) (*SendResult, error) {
// Access you phone number should have no +
m1 := regexp.MustCompile(`[\+\-]+`)
to = m1.ReplaceAllString(to, "")
to := m1.ReplaceAllString(options.To, "")
req, _ := http.NewRequest(
"POST",
fmt.Sprintf(
Expand All @@ -70,7 +57,7 @@ func (n *AccessYouClient) Send(
n.AccountNo,
n.Pwd,
to,
url.QueryEscape(body),
url.QueryEscape(options.Body),
n.User,
n.Sender),
nil)
Expand All @@ -79,7 +66,7 @@ func (n *AccessYouClient) Send(
resp, err := n.Client.Do(req)
if err != nil {
n.Logger.Error(fmt.Sprintf("%v", err))
return ClientResponse{}, err
return nil, err
}
defer resp.Body.Close()

Expand All @@ -96,10 +83,12 @@ func (n *AccessYouClient) Send(
err = json.Unmarshal(respData, &accessYouResponse)
if err != nil {
n.Logger.Error(fmt.Sprintf("Unmarshal error: %v", err))
return ClientResponse{}, err
return nil, err
}
n.Logger.Info(fmt.Sprintf("%v", accessYouResponse))
return ClientResponse(respData), nil
return &SendResult{
ClientResponse: respData,
}, nil
}

type AccessYouResponse struct {
Expand Down
36 changes: 19 additions & 17 deletions pkg/lib/infra/sms/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,57 +9,59 @@ import (
"github.com/authgear/authgear-sms-gateway/pkg/lib/infra/sms/sendcloud"
)

type ClientResponse []byte
type SendOptions struct {
To string
Body string
TemplateName string
LanguageTag string
TemplateVariables *TemplateVariables
}

type SendResult struct {
ClientResponse []byte
}

type RawClient interface {
Send(to string, body string, templateName string, languageTag string, templateVariables *TemplateVariables) (ClientResponse, error)
GetName() string
Send(options *SendOptions) (*SendResult, error)
}

func NewClientFromConfigProvider(p *config.Provider, logger *slog.Logger) (RawClient, error) {
func NewClientFromConfigProvider(p *config.Provider, logger *slog.Logger) RawClient {
switch p.Type {
case config.ProviderTypeTwilio:
return NewTwilioClient(
p.Name,
p.Twilio.AccountSID,
p.Twilio.AuthToken,
p.Twilio.Sender,
p.Twilio.MessagingServiceSID,
), nil
)
case config.ProviderTypeNexmo:
return NewNexmoClient(
p.Name,
p.Nexmo.APIKey,
p.Nexmo.APISecret,
p.Nexmo.Sender,
), nil
)
case config.ProviderTypeAccessYou:
return NewAccessYouClient(
p.Name,
p.AccessYou.BaseUrl,
p.AccessYou.AccountNo,
p.AccessYou.User,
p.AccessYou.Pwd,
p.AccessYou.Sender,
logger,
), nil
)
case config.ProviderTypeSendCloud:
templateResolver, err := sendcloud.NewSendCloudTemplateResolver(
templateResolver := sendcloud.NewSendCloudTemplateResolver(
p.SendCloud.Templates,
p.SendCloud.TemplateAssignments,
)
if err != nil {
return nil, err
}
return NewSendCloudClient(
p.Name,
p.SendCloud.BaseUrl,
p.SendCloud.SMSUser,
p.SendCloud.SMSKey,
templateResolver,
logger,
), nil
)
default:
return nil, errors.New(fmt.Sprintf("Unknown type %s", p.Type))
panic(errors.New(fmt.Sprintf("Unknown type %s", p.Type)))
}
}
Loading

0 comments on commit 1ad8649

Please sign in to comment.