Passed
Pull Request — main (#9)
by Acho
01:36
created

entities.*Message.Expired   A

Complexity

Conditions 1

Size

Total Lines 5
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
package entities
2
3
import (
4
	"time"
5
6
	"github.com/google/uuid"
7
)
8
9
// MessageType is the type of message if it is incoming or outgoing
10
type MessageType string
11
12
const (
13
	// MessageTypeMobileTerminated means the message it sent to a mobile phone
14
	MessageTypeMobileTerminated = "mobile-terminated"
15
16
	// MessageTypeMobileOriginated means the message comes directly from a mobile phone
17
	MessageTypeMobileOriginated = "mobile-originated"
18
)
19
20
// MessageStatus is the status of the message
21
type MessageStatus string
22
23
const (
24
	// MessageStatusPending means the message has been queued to be sent
25
	MessageStatusPending = "pending"
26
27
	// MessageStatusSending means a phone has picked up the message and is currently sending it
28
	MessageStatusSending = "sending"
29
30
	// MessageStatusSent means the message has already sent by the mobile phone
31
	MessageStatusSent = "sent"
32
33
	// MessageStatusReceived means the message was received by tne mobile phone (MO)
34
	MessageStatusReceived = "received"
35
36
	// MessageStatusFailed means the mobile phone could not send the message
37
	MessageStatusFailed = "failed"
38
39
	// MessageStatusDelivered means the mobile phone has delivered the message
40
	MessageStatusDelivered = "delivered"
41
42
	// MessageStatusExpired means the message could not be sent by the mobile phone after 5 minutes
43
	MessageStatusExpired = "expired"
44
)
45
46
// MessageEventName is the type of event generated by the mobile phone for a message
47
type MessageEventName string
48
49
const (
50
	// MessageEventNameSent is emitted when a message is sent by the mobile phone
51
	MessageEventNameSent = MessageEventName("SENT")
52
53
	// MessageEventNameDelivered is emitted when a message is delivered by the mobile phone
54
	MessageEventNameDelivered = MessageEventName("DELIVERED")
55
56
	// MessageEventNameFailed is emitted when a message is failed by the mobile phone
57
	MessageEventNameFailed = MessageEventName("FAILED")
58
)
59
60
// Message represents a message sent between 2 phone numbers
61
type Message struct {
62
	ID      uuid.UUID     `json:"id" gorm:"primaryKey;type:uuid;" example:"32343a19-da5e-4b1b-a767-3298a73703cb"`
63
	Owner   string        `json:"owner" gorm:"index:idx_messages_user_id__owner__contact" example:"+18005550199"`
64
	UserID  UserID        `json:"user_id" gorm:"index:idx_messages_user_id__owner__contact" example:"WB7DRDWrJZRGbYrv2CKGkqbzvqdC"`
65
	Contact string        `json:"contact" gorm:"index:idx_messages_user_id__owner__contact" example:"+18005550100"`
66
	Content string        `json:"content" example:"This is a sample text message"`
67
	Type    MessageType   `json:"type" example:"mobile-terminated"`
68
	Status  MessageStatus `json:"status" gorm:"index:idx_messages_status" example:"pending"`
69
70
	// SendDuration is the number of nanoseconds from when the request was received until when the mobile phone send the message
71
	SendDuration *int64 `json:"send_time" example:"133414"`
72
73
	RequestReceivedAt time.Time  `json:"request_received_at" example:"2022-06-05T14:26:01.520828+03:00"`
74
	CreatedAt         time.Time  `json:"created_at" example:"2022-06-05T14:26:02.302718+03:00"`
75
	UpdatedAt         time.Time  `json:"updated_at" example:"2022-06-05T14:26:10.303278+03:00"`
76
	OrderTimestamp    time.Time  `json:"order_timestamp" gorm:"index:idx_messages_order_timestamp" example:"2022-06-05T14:26:09.527976+03:00"`
77
	LastAttemptedAt   *time.Time `json:"last_attempted_at" example:"2022-06-05T14:26:09.527976+03:00"`
78
	SentAt            *time.Time `json:"sent_at" example:"2022-06-05T14:26:09.527976+03:00"`
79
	ReceivedAt        *time.Time `json:"received_at" example:"2022-06-05T14:26:09.527976+03:00"`
80
	FailureReason     *string    `json:"failure_reason"`
81
}
82
83
// IsSending determines if a message is being sent
84
func (message *Message) IsSending() bool {
85
	return message.Status == MessageStatusSending
86
}
87
88
// IsDelivered checks if a message is delivered
89
func (message *Message) IsDelivered() bool {
90
	return message.Status == MessageStatusDelivered
91
}
92
93
// IsPending checks if a message is pending
94
func (message *Message) IsPending() bool {
95
	return message.Status == MessageStatusPending
96
}
97
98
// IsExpired checks if a message is expired
99
func (message *Message) IsExpired() bool {
100
	return message.Status == MessageStatusExpired
101
}
102
103
// IsSent determines if a message has been sent
104
func (message *Message) IsSent() bool {
105
	return message.Status == MessageStatusSent
106
}
107
108
// Sent registers a message as sent
109
func (message *Message) Sent(timestamp time.Time) *Message {
110
	sendDuration := timestamp.UnixNano() - message.RequestReceivedAt.UnixNano()
111
	message.SentAt = &timestamp
112
	message.Status = MessageStatusSent
113
	message.updateOrderTimestamp(timestamp)
114
	message.SendDuration = &sendDuration
115
	return message
116
}
117
118
// Failed registers a message as failed
119
func (message *Message) Failed(timestamp time.Time, errorMessage string) *Message {
120
	message.SentAt = &timestamp
121
	message.Status = MessageStatusFailed
122
	message.FailureReason = &errorMessage
123
	message.updateOrderTimestamp(timestamp)
124
	return message
125
}
126
127
// Delivered registers a message as delivered
128
func (message *Message) Delivered(timestamp time.Time) *Message {
129
	message.SentAt = &timestamp
130
	message.Status = MessageStatusDelivered
131
	message.updateOrderTimestamp(timestamp)
132
	return message
133
}
134
135
// Expired registers a message as expired
136
func (message *Message) Expired(timestamp time.Time) *Message {
137
	message.SentAt = &timestamp
138
	message.Status = MessageStatusExpired
139
	message.updateOrderTimestamp(timestamp)
140
	return message
141
}
142
143
// AddSendAttempt configures a Message for sending
144
func (message *Message) AddSendAttempt(timestamp time.Time) *Message {
145
	message.Status = MessageStatusSending
146
	message.LastAttemptedAt = &timestamp
147
	message.updateOrderTimestamp(timestamp)
148
	return message
149
}
150
151
func (message *Message) updateOrderTimestamp(timestamp time.Time) {
152
	if timestamp.UnixNano() > message.OrderTimestamp.UnixNano() {
153
		message.OrderTimestamp = timestamp
154
	}
155
}
156