Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Map template variables to sendcloud vars from config #11

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 64 additions & 4 deletions pkg/lib/config/sendcloud.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,63 @@
package config

type SendCloudTemplateVariableKeyMappingFrom string

const (
SendCloudTemplateVariableKeyMappingFromAppName SendCloudTemplateVariableKeyMappingFrom = "app_name"
SendCloudTemplateVariableKeyMappingFromClientID SendCloudTemplateVariableKeyMappingFrom = "client_id"
SendCloudTemplateVariableKeyMappingFromCode SendCloudTemplateVariableKeyMappingFrom = "code"
SendCloudTemplateVariableKeyMappingFromEmail SendCloudTemplateVariableKeyMappingFrom = "email"
SendCloudTemplateVariableKeyMappingFromHasPassword SendCloudTemplateVariableKeyMappingFrom = "has_password"
SendCloudTemplateVariableKeyMappingFromHost SendCloudTemplateVariableKeyMappingFrom = "host"
SendCloudTemplateVariableKeyMappingFromLink SendCloudTemplateVariableKeyMappingFrom = "link"
SendCloudTemplateVariableKeyMappingFromPassword SendCloudTemplateVariableKeyMappingFrom = "password"
SendCloudTemplateVariableKeyMappingFromPhone SendCloudTemplateVariableKeyMappingFrom = "phone"
SendCloudTemplateVariableKeyMappingFromState SendCloudTemplateVariableKeyMappingFrom = "state"
SendCloudTemplateVariableKeyMappingFromUILocales SendCloudTemplateVariableKeyMappingFrom = "ui_locales"
SendCloudTemplateVariableKeyMappingFromURL SendCloudTemplateVariableKeyMappingFrom = "url"
SendCloudTemplateVariableKeyMappingFromXState SendCloudTemplateVariableKeyMappingFrom = "x_state"
)

var _ = RootSchema.Add("SendCloudTemplateVariableKeyMappingFrom", `
{
"type": "string",
"enum": [
"app_name",
"client_id",
"code",
"email",
"has_password",
"host",
"link",
"password",
"phone",
"state",
"ui_locales",
"url",
"x_state"
]
}`)

type SendCloudTemplateVariableKeyMapping struct {
From SendCloudTemplateVariableKeyMappingFrom `json:"from,omitempty"`
To string `json:"to,omitempty"`
}

var _ = RootSchema.Add("SendCloudTemplateVariableKeyMapping", `
{
"type": "object",
"additionalProperties": false,
"properties": {
"from": { "$ref": "#/$defs/SendCloudTemplateVariableKeyMappingFrom" },
"to": { "type": "string" }
},
"required": ["from", "to"]
}`)

type SendCloudTemplate struct {
TemplateID string `json:"template_id,omitempty"`
TemplateMsgType string `json:"template_msg_type,omitempty"`
TemplateID string `json:"template_id,omitempty"`
TemplateMsgType string `json:"template_msg_type,omitempty"`
TemplateVariableKeyMappings []*SendCloudTemplateVariableKeyMapping `json:"template_variable_key_mappings,omitempty"`
}

var _ = RootSchema.Add("SendCloudTemplate", `
Expand All @@ -11,9 +66,14 @@ var _ = RootSchema.Add("SendCloudTemplate", `
"additionalProperties": false,
"properties": {
"template_id": { "type": "string" },
"template_msg_type": { "type": "string" }
"template_msg_type": { "type": "string" },
"template_variable_key_mappings": {
"type": "array",
"minItems": 1,
"items": { "$ref": "#/$defs/SendCloudTemplateVariableKeyMapping" }
}
},
"required": ["template_id", "template_msg_type"]
"required": ["template_id", "template_msg_type", "template_variable_key_mappings"]
}
`)

Expand Down
7 changes: 7 additions & 0 deletions pkg/lib/config/sms_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,13 @@ func (c *RootConfig) ValidateSendCloudConfigs(ctx *validation.Context) {

func (c *RootConfig) ValidateSendCloudConfig(ctx *validation.Context, sendCloudConfig *ProviderConfigSendCloud) {
templates := sendCloudConfig.Templates
for i, template := range templates {
ctxTemplates := ctx.Child("templates", strconv.Itoa(i))
if len(template.TemplateVariableKeyMappings) == 0 {
ctxTemplates.Child("template_variable_key_mappings").EmitErrorMessage("missing template_variable_key_mappings")
}
}

for i, templateAssignment := range sendCloudConfig.TemplateAssignments {
ctxTemplateAssignment := ctx.Child("template_assignments", strconv.Itoa(i))
defaultTemplateID := templateAssignment.DefaultTemplateID
Expand Down
15 changes: 15 additions & 0 deletions pkg/lib/config/testdata/authgear-sms-gateway.tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,14 @@ config:
templates:
- template_id: "919888"
template_msg_type: "2"
template_variable_key_mappings:
- from: app_name
to: app
- template_id: "919879"
template_msg_type: "2"
template_variable_key_mappings:
- from: app_name
to: app
template_assignments:
- authgear_template_name: "verficiation_sms.txt"
default_template_id: "919888"
Expand Down Expand Up @@ -119,8 +125,14 @@ config:
templates:
- template_id: "919888"
template_msg_type: "2"
template_variable_key_mappings:
- from: app_name
to: app
- template_id: "919879"
template_msg_type: "2"
template_variable_key_mappings:
- from: app_name
to: app
template_assignments:
- authgear_template_name: "verficiation_sms.txt"
default_template_id: "919888"
Expand All @@ -147,6 +159,8 @@ config:
name: failed-sendcloud-config
error: |-
invalid configuration:
/providers/2/sendcloud/templates/0/template_variable_key_mappings: missing template_variable_key_mappings
/providers/2/sendcloud/templates/1/template_variable_key_mappings: missing template_variable_key_mappings
/providers/2/sendcloud/template_assignments/0/default_template_id: template_id 919889 not found
/providers/2/sendcloud/template_assignments/0/by_languages/0/template_id: template_id 919890 not found
config:
Expand All @@ -172,6 +186,7 @@ config:
templates:
- template_id: "919888"
template_msg_type: "2"
template_variable_key_mappings: []
- template_id: "919879"
template_msg_type: "2"
template_assignments:
Expand Down
28 changes: 12 additions & 16 deletions pkg/lib/sms/sendcloud/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,42 +48,38 @@ func NewSendRequest(
}

func (r *SendRequest) Presign() string {
vars, _ := json.Marshal(r.vars)

// According to the [doc](https://www.sendcloud.net/doc/sms/),
// - The keys should be arranged alphabetically
// - The values no need to be url encoded
return strings.Join([]string{
res := strings.Join([]string{
fmt.Sprintf("msgType=%v", r.msgType),
fmt.Sprintf("phone=%v", strings.Join(r.phone, ",")),
fmt.Sprintf("sendRequestId=%v", r.sendRequestId),
fmt.Sprintf("smsUser=%v", r.smsUser),
fmt.Sprintf("templateId=%v", r.templateId),
fmt.Sprintf("vars=%v", string(vars)),
}, "&")
}

func (r *SendRequest) ToMap() map[string]interface{} {
vars, _ := json.Marshal(r.vars)
return map[string]interface{}{
"msgType": r.msgType,
"phone": strings.Join(r.phone, ","),
"sendRequestId": r.sendRequestId,
"smsUser": r.smsUser,
"templateId": r.templateId,
"vars": vars,
if len(r.vars) != 0 {
vars, _ := json.Marshal(r.vars)
res = strings.Join([]string{
res,
fmt.Sprintf("vars=%v", string(vars)),
}, "&")
}
return res
}

func (r *SendRequest) ToValues() url.Values {
vars, _ := json.Marshal(r.vars)
values := url.Values{}
values.Set("msgType", r.msgType)
values.Set("phone", strings.Join(r.phone, ","))
values.Set("sendRequestId", r.sendRequestId)
values.Set("smsUser", r.smsUser)
values.Set("templateId", r.templateId)
values.Set("vars", string(vars))
if len(r.vars) != 0 {
vars, _ := json.Marshal(r.vars)
values.Set("vars", string(vars))
}
return values
}

Expand Down
71 changes: 47 additions & 24 deletions pkg/lib/sms/sendcloud/smsclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,57 @@ import (
"log/slog"
"net/http"

"github.com/authgear/authgear-sms-gateway/pkg/lib/config"
"github.com/authgear/authgear-sms-gateway/pkg/lib/sms/smsclient"
)

func makeVarsFromTemplateVariables(variables *smsclient.TemplateVariables) map[string]interface{} {
wrapped := func(field string) string {
return fmt.Sprintf("%%%v%%", field)
type EffectiveTemplateVariables map[string]interface{}

func wrapped(field string) string {
return fmt.Sprintf("%%%v%%", field)
}

func (v EffectiveTemplateVariables) WrapKeys() map[string]interface{} {
res := make(map[string]interface{})
for key, value := range v {
res[wrapped(key)] = value
}
wrapKeys := func(obj map[string]interface{}) map[string]interface{} {
res := make(map[string]interface{})
for key, value := range obj {
res[wrapped(key)] = value
return res
}

func MakeEffectiveTemplateVariables(variables *smsclient.TemplateVariables, mappings []*config.SendCloudTemplateVariableKeyMapping) EffectiveTemplateVariables {
res := make(EffectiveTemplateVariables)
for _, mapping := range mappings {
switch mapping.From {
case config.SendCloudTemplateVariableKeyMappingFromAppName:
res[mapping.To] = variables.AppName
case config.SendCloudTemplateVariableKeyMappingFromClientID:
res[mapping.To] = variables.ClientID
case config.SendCloudTemplateVariableKeyMappingFromCode:
res[mapping.To] = variables.Code
case config.SendCloudTemplateVariableKeyMappingFromEmail:
res[mapping.To] = variables.Email
case config.SendCloudTemplateVariableKeyMappingFromHasPassword:
res[mapping.To] = variables.HasPassword
case config.SendCloudTemplateVariableKeyMappingFromHost:
res[mapping.To] = variables.Host
case config.SendCloudTemplateVariableKeyMappingFromLink:
res[mapping.To] = variables.Link
case config.SendCloudTemplateVariableKeyMappingFromPassword:
res[mapping.To] = variables.Password
case config.SendCloudTemplateVariableKeyMappingFromPhone:
res[mapping.To] = variables.Phone
case config.SendCloudTemplateVariableKeyMappingFromState:
res[mapping.To] = variables.State
case config.SendCloudTemplateVariableKeyMappingFromUILocales:
res[mapping.To] = variables.UILocales
case config.SendCloudTemplateVariableKeyMappingFromURL:
res[mapping.To] = variables.URL
case config.SendCloudTemplateVariableKeyMappingFromXState:
res[mapping.To] = variables.XState
}
return res
}
return wrapKeys(map[string]interface{}{
"app": variables.AppName,
"client_id": variables.ClientID,
"code": variables.Code,
"email": variables.Email,
"has_password": variables.HasPassword,
"host": variables.Host,
"link": variables.Link,
"password": variables.Password,
"phone": variables.Phone,
"state": variables.State,
"ui_locales": variables.UILocales,
"url": variables.URL,
"x_state": variables.XState,
})
return res
}

type SendCloudClient struct {
Expand Down Expand Up @@ -71,14 +93,15 @@ func (n *SendCloudClient) Send(options *smsclient.SendOptions) (*smsclient.SendR
if err != nil {
return nil, err
}
templateVariables := MakeEffectiveTemplateVariables(options.TemplateVariables, template.TemplateVariableKeyMappings)
sendRequest := NewSendRequest(
chankiyu22 marked this conversation as resolved.
Show resolved Hide resolved
string(template.TemplateMsgType),
[]string{
string(options.To),
},
n.SMSUser,
string(template.TemplateID),
makeVarsFromTemplateVariables(options.TemplateVariables),
templateVariables.WrapKeys(),
)

dumpedResponse, sendResponse, err := Send(n.Client, n.BaseUrl, &sendRequest, n.SMSKey, n.Logger)
Expand Down
45 changes: 45 additions & 0 deletions pkg/lib/sms/sendcloud/smsclient_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package sendcloud

import (
"testing"

. "github.com/smartystreets/goconvey/convey"

"github.com/authgear/authgear-sms-gateway/pkg/lib/config"
"github.com/authgear/authgear-sms-gateway/pkg/lib/sms/smsclient"
)

func TestMakeEffectiveTemplateVariables(t *testing.T) {
Convey("MakeEffectiveTemplateVariables", t, func() {
So(MakeEffectiveTemplateVariables(&smsclient.TemplateVariables{}, []*config.SendCloudTemplateVariableKeyMapping{
{
From: config.SendCloudTemplateVariableKeyMappingFromAppName,
To: "app",
},
{
From: config.SendCloudTemplateVariableKeyMappingFromCode,
To: "mycode",
},
}), ShouldEqual, EffectiveTemplateVariables(map[string]interface{}{
"app": "",
"mycode": "",
}))

So(MakeEffectiveTemplateVariables(&smsclient.TemplateVariables{
AppName: "my-app-name",
Code: "123456",
}, []*config.SendCloudTemplateVariableKeyMapping{
{
From: config.SendCloudTemplateVariableKeyMappingFromAppName,
To: "app",
},
{
From: config.SendCloudTemplateVariableKeyMappingFromCode,
To: "somecode",
},
}), ShouldEqual, EffectiveTemplateVariables(map[string]interface{}{
"app": "my-app-name",
"somecode": "123456",
}))
})
}
10 changes: 6 additions & 4 deletions pkg/lib/sms/sendcloud/template_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@ type AuthgearTemplateName string
type AuthgearLanguage string

type SendCloudTemplate struct {
TemplateID TemplateID
TemplateMsgType TemplateMessageType
TemplateID TemplateID
TemplateMsgType TemplateMessageType
TemplateVariableKeyMappings []*config.SendCloudTemplateVariableKeyMapping
}

func NewSendCloudTemplate(template *config.SendCloudTemplate) *SendCloudTemplate {
return &SendCloudTemplate{
TemplateID: TemplateID(template.TemplateID),
TemplateMsgType: TemplateMessageType(template.TemplateMsgType),
TemplateID: TemplateID(template.TemplateID),
TemplateMsgType: TemplateMessageType(template.TemplateMsgType),
TemplateVariableKeyMappings: template.TemplateVariableKeyMappings,
}
}

Expand Down
Loading
Loading