forked from nyaruka/goflow
-
Notifications
You must be signed in to change notification settings - Fork 0
/
msg.go
133 lines (113 loc) · 3.74 KB
/
msg.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package inputs
import (
"encoding/json"
"strings"
"time"
"github.com/nyaruka/gocommon/urns"
"github.com/nyaruka/goflow/excellent/types"
"github.com/nyaruka/goflow/flows"
"github.com/nyaruka/goflow/utils"
)
func init() {
RegisterType(TypeMsg, ReadMsgInput)
}
// TypeMsg is a constant for incoming messages
const TypeMsg string = "msg"
// MsgInput is a message which can be used as input
type MsgInput struct {
baseInput
urn *flows.ContactURN
text string
attachments flows.AttachmentList
}
// NewMsgInput creates a new user input based on a message
func NewMsgInput(uuid flows.InputUUID, channel flows.Channel, createdOn time.Time, urn urns.URN, text string, attachments []flows.Attachment) *MsgInput {
return &MsgInput{
baseInput: baseInput{uuid: uuid, channel: channel, createdOn: createdOn},
urn: flows.NewContactURN(urn, nil),
text: text,
attachments: attachments,
}
}
// Type returns the type of this event
func (i *MsgInput) Type() string { return TypeMsg }
// Resolve resolves the given key when this input is referenced in an expression
func (i *MsgInput) Resolve(env utils.Environment, key string) types.XValue {
switch key {
case "type":
return types.NewXText(TypeMsg)
case "urn":
return i.urn
case "text":
return types.NewXText(i.text)
case "attachments":
return i.attachments
}
return i.baseInput.Resolve(env, key)
}
// Describe returns a representation of this type for error messages
func (i *MsgInput) Describe() string { return "input" }
// Reduce is called when this object needs to be reduced to a primitive
func (i *MsgInput) Reduce(env utils.Environment) types.XPrimitive {
var parts []string
if i.text != "" {
parts = append(parts, i.text)
}
for _, attachment := range i.attachments {
parts = append(parts, attachment.URL())
}
return types.NewXText(strings.Join(parts, "\n"))
}
// ToXJSON is called when this type is passed to @(json(...))
func (i *MsgInput) ToXJSON(env utils.Environment) types.XText {
return types.ResolveKeys(env, i, "uuid", "created_on", "channel", "type", "urn", "text", "attachments").ToXJSON(env)
}
var _ types.XValue = (*MsgInput)(nil)
var _ types.XResolvable = (*MsgInput)(nil)
var _ flows.Input = (*MsgInput)(nil)
//------------------------------------------------------------------------------------------
// JSON Encoding / Decoding
//------------------------------------------------------------------------------------------
type msgInputEnvelope struct {
baseInputEnvelope
URN urns.URN `json:"urn" validate:"omitempty,urn"`
Text string `json:"text"`
Attachments flows.AttachmentList `json:"attachments,omitempty"`
}
// ReadMsgInput reads a message input from the given JSON
func ReadMsgInput(session flows.Session, data json.RawMessage) (flows.Input, error) {
input := MsgInput{}
i := msgInputEnvelope{}
err := utils.UnmarshalAndValidate(data, &i)
if err != nil {
return nil, err
}
// lookup the channel
var channel flows.Channel
if i.Channel != nil {
channel, err = session.Assets().GetChannel(i.Channel.UUID)
if err != nil {
return nil, err
}
}
input.baseInput.uuid = i.UUID
input.baseInput.channel = channel
input.baseInput.createdOn = i.CreatedOn
input.urn = flows.NewContactURN(i.URN, nil)
input.text = i.Text
input.attachments = i.Attachments
return &input, nil
}
// MarshalJSON marshals this msg input into JSON
func (i *MsgInput) MarshalJSON() ([]byte, error) {
var envelope msgInputEnvelope
if i.Channel() != nil {
envelope.baseInputEnvelope.Channel = i.Channel().Reference()
}
envelope.baseInputEnvelope.UUID = i.UUID()
envelope.baseInputEnvelope.CreatedOn = i.CreatedOn()
envelope.URN = i.urn.URN
envelope.Text = i.text
envelope.Attachments = i.attachments
return json.Marshal(envelope)
}