Skip to content

Commit

Permalink
Merge pull request #1274 from nyaruka/templating_reorg
Browse files Browse the repository at this point in the history
Move code to generate templating into `flows.Template`
  • Loading branch information
rowanseymour authored Jul 4, 2024
2 parents 8f35095 + 1a52cdc commit c6b3e1b
Show file tree
Hide file tree
Showing 3 changed files with 334 additions and 136 deletions.
67 changes: 20 additions & 47 deletions flows/actions/send_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,29 @@ func (a *SendMsgAction) Execute(run flows.Run, step flows.Step, logModifier flow
for _, dest := range destinations {
urn := dest.URN.URN()
channelRef := assets.NewChannelReference(dest.Channel.UUID(), dest.Channel.Name())

var msg *flows.MsgOut

if template != nil {
locales := []i18n.Locale{run.Session().MergedEnvironment().DefaultLocale(), run.Session().Environment().DefaultLocale()}
templateTranslation := template.FindTranslation(dest.Channel, locales)
if templateTranslation != nil {
msg = a.getTemplateMsg(run, urn, channelRef, templateTranslation, unsendableReason, logEvent)
translation := template.FindTranslation(dest.Channel, locales)
if translation != nil {
// TODO in future we won't be localizing template variables
localizedVariables, _ := run.GetTextArray(uuids.UUID(a.UUID()), "template_variables", a.TemplateVariables, nil)

// evaluate the variables
evaluatedVariables := make([]string, len(localizedVariables))
for i, varExp := range localizedVariables {
v, _ := run.EvaluateTemplate(varExp, logEvent)
evaluatedVariables[i] = v
}

templating := template.Templating(translation, evaluatedVariables)

// the message we return is an approximate preview of what the channel will send using the template
preview := translation.Preview(templating.Variables)
locale := translation.Locale()

msg = flows.NewMsgOut(urn, channelRef, preview.Text, preview.Attachments, preview.QuickReplies, templating, flows.NilMsgTopic, locale, unsendableReason)
}
}

Expand All @@ -111,46 +127,3 @@ func (a *SendMsgAction) Execute(run flows.Run, step flows.Step, logModifier flow

return nil
}

// for message actions that specify a template, this generates a mesage with templating information and content that can
// be used as a preview
func (a *SendMsgAction) getTemplateMsg(run flows.Run, urn urns.URN, channelRef *assets.ChannelReference, translation *flows.TemplateTranslation, unsendableReason flows.UnsendableReason, logEvent flows.EventCallback) *flows.MsgOut {
// localize and evaluate the variables
localizedVariables, _ := run.GetTextArray(uuids.UUID(a.UUID()), "template_variables", a.TemplateVariables, nil)
evaluatedVariables := make([]string, len(localizedVariables))
for i, varExp := range localizedVariables {
v, _ := run.EvaluateTemplate(varExp, logEvent)
evaluatedVariables[i] = v
}

// cross-reference with asset to get variable types and filter out invalid values
variables := make([]*flows.TemplatingVariable, len(translation.Variables()))
for i, v := range translation.Variables() {
// we pad out any missing variables with empty values
value := ""
if i < len(evaluatedVariables) {
value = evaluatedVariables[i]
}

variables[i] = &flows.TemplatingVariable{Type: v.Type(), Value: value}
}

// create a list of components that have variables
components := make([]*flows.TemplatingComponent, 0, len(translation.Components()))
for _, comp := range translation.Components() {
if len(comp.Variables()) > 0 {
components = append(components, &flows.TemplatingComponent{
Type: comp.Type(),
Name: comp.Name(),
Variables: comp.Variables(),
})
}
}

// the message we return is an approximate preview of what the channel will send using the template
preview := translation.Preview(variables)
locale := translation.Locale()
templating := flows.NewMsgTemplating(a.Template, components, variables)

return flows.NewMsgOut(urn, channelRef, preview.Text, preview.Attachments, preview.QuickReplies, templating, flows.NilMsgTopic, locale, unsendableReason)
}
27 changes: 27 additions & 0 deletions flows/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,33 @@ func (t *Template) FindTranslation(channel *Channel, locales []i18n.Locale) *Tem
return candidates[match]
}

// Templating generates a templating object for the passed in translation and variables
func (t *Template) Templating(tt *TemplateTranslation, vars []string) *MsgTemplating {
// cross-reference with asset to get variable types and pad out any missing variables
variables := make([]*TemplatingVariable, len(tt.Variables()))
for i, v := range tt.Variables() {
value := ""
if i < len(vars) {
value = vars[i]
}
variables[i] = &TemplatingVariable{Type: v.Type(), Value: value}
}

// create a list of components that have variables
components := make([]*TemplatingComponent, 0, len(tt.Components()))
for _, comp := range tt.Components() {
if len(comp.Variables()) > 0 {
components = append(components, &TemplatingComponent{
Type: comp.Type(),
Name: comp.Name(),
Variables: comp.Variables(),
})
}
}

return NewMsgTemplating(t.Reference(), components, variables)
}

// TemplateTranslation represents a single translation for a template
type TemplateTranslation struct {
assets.TemplateTranslation
Expand Down
Loading

0 comments on commit c6b3e1b

Please sign in to comment.