-
-
Notifications
You must be signed in to change notification settings - Fork 692
Expand file tree
/
Copy pathmessage.go
More file actions
155 lines (124 loc) · 5.7 KB
/
Copy pathmessage.go
File metadata and controls
155 lines (124 loc) · 5.7 KB
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package entities
import (
"time"
"github.com/google/uuid"
)
// MessageType is the type of message if it is incoming or outgoing
type MessageType string
const (
// MessageTypeMobileTerminated means the message it sent to a mobile phone
MessageTypeMobileTerminated = "mobile-terminated"
// MessageTypeMobileOriginated means the message comes directly from a mobile phone
MessageTypeMobileOriginated = "mobile-originated"
)
// MessageStatus is the status of the message
type MessageStatus string
const (
// MessageStatusPending means the message has been queued to be sent
MessageStatusPending = "pending"
// MessageStatusSending means a phone has picked up the message and is currently sending it
MessageStatusSending = "sending"
// MessageStatusSent means the message has already sent by the mobile phone
MessageStatusSent = "sent"
// MessageStatusReceived means the message was received by tne mobile phone (MO)
MessageStatusReceived = "received"
// MessageStatusFailed means the mobile phone could not send the message
MessageStatusFailed = "failed"
// MessageStatusDelivered means the mobile phone has delivered the message
MessageStatusDelivered = "delivered"
// MessageStatusExpired means the message could not be sent by the mobile phone after 5 minutes
MessageStatusExpired = "expired"
)
// MessageEventName is the type of event generated by the mobile phone for a message
type MessageEventName string
const (
// MessageEventNameSent is emitted when a message is sent by the mobile phone
MessageEventNameSent = MessageEventName("SENT")
// MessageEventNameDelivered is emitted when a message is delivered by the mobile phone
MessageEventNameDelivered = MessageEventName("DELIVERED")
// MessageEventNameFailed is emitted when a message is failed by the mobile phone
MessageEventNameFailed = MessageEventName("FAILED")
)
// Message represents a message sent between 2 phone numbers
type Message struct {
ID uuid.UUID `json:"id" gorm:"primaryKey;type:uuid;" example:"32343a19-da5e-4b1b-a767-3298a73703cb"`
Owner string `json:"owner" gorm:"index:idx_messages_user_id__owner__contact" example:"+18005550199"`
UserID UserID `json:"user_id" gorm:"index:idx_messages_user_id__owner__contact" example:"WB7DRDWrJZRGbYrv2CKGkqbzvqdC"`
Contact string `json:"contact" gorm:"index:idx_messages_user_id__owner__contact" example:"+18005550100"`
Content string `json:"content" example:"This is a sample text message"`
Type MessageType `json:"type" example:"mobile-terminated"`
Status MessageStatus `json:"status" gorm:"index:idx_messages_status" example:"pending"`
// SendDuration is the number of nanoseconds from when the request was received until when the mobile phone send the message
SendDuration *int64 `json:"send_time" example:"133414"`
RequestReceivedAt time.Time `json:"request_received_at" example:"2022-06-05T14:26:01.520828+03:00"`
CreatedAt time.Time `json:"created_at" example:"2022-06-05T14:26:02.302718+03:00"`
UpdatedAt time.Time `json:"updated_at" example:"2022-06-05T14:26:10.303278+03:00"`
OrderTimestamp time.Time `json:"order_timestamp" gorm:"index:idx_messages_order_timestamp" example:"2022-06-05T14:26:09.527976+03:00"`
LastAttemptedAt *time.Time `json:"last_attempted_at" example:"2022-06-05T14:26:09.527976+03:00"`
SentAt *time.Time `json:"sent_at" example:"2022-06-05T14:26:09.527976+03:00"`
ReceivedAt *time.Time `json:"received_at" example:"2022-06-05T14:26:09.527976+03:00"`
FailureReason *string `json:"failure_reason"`
}
// IsSending determines if a message is being sent
func (message *Message) IsSending() bool {
return message.Status == MessageStatusSending
}
// IsDelivered checks if a message is delivered
func (message *Message) IsDelivered() bool {
return message.Status == MessageStatusDelivered
}
// IsPending checks if a message is pending
func (message *Message) IsPending() bool {
return message.Status == MessageStatusPending
}
// IsExpired checks if a message is expired
func (message *Message) IsExpired() bool {
return message.Status == MessageStatusExpired
}
// IsSent determines if a message has been sent
func (message *Message) IsSent() bool {
return message.Status == MessageStatusSent
}
// Sent registers a message as sent
func (message *Message) Sent(timestamp time.Time) *Message {
sendDuration := timestamp.UnixNano() - message.RequestReceivedAt.UnixNano()
message.SentAt = ×tamp
message.Status = MessageStatusSent
message.updateOrderTimestamp(timestamp)
message.SendDuration = &sendDuration
return message
}
// Failed registers a message as failed
func (message *Message) Failed(timestamp time.Time, errorMessage string) *Message {
message.SentAt = ×tamp
message.Status = MessageStatusFailed
message.FailureReason = &errorMessage
message.updateOrderTimestamp(timestamp)
return message
}
// Delivered registers a message as delivered
func (message *Message) Delivered(timestamp time.Time) *Message {
message.SentAt = ×tamp
message.Status = MessageStatusDelivered
message.updateOrderTimestamp(timestamp)
return message
}
// Expired registers a message as expired
func (message *Message) Expired(timestamp time.Time) *Message {
message.SentAt = ×tamp
message.Status = MessageStatusExpired
message.updateOrderTimestamp(timestamp)
return message
}
// AddSendAttempt configures a Message for sending
func (message *Message) AddSendAttempt(timestamp time.Time) *Message {
message.Status = MessageStatusSending
message.LastAttemptedAt = ×tamp
message.updateOrderTimestamp(timestamp)
return message
}
func (message *Message) updateOrderTimestamp(timestamp time.Time) {
if timestamp.UnixNano() > message.OrderTimestamp.UnixNano() {
message.OrderTimestamp = timestamp
}
}