-
-
Notifications
You must be signed in to change notification settings - Fork 431
feat: add USSD management feature #938
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| package entities | ||
|
|
||
| import ( | ||
| "time" | ||
|
|
||
| "github.com/google/uuid" | ||
| ) | ||
|
|
||
| // USSDType represents the type of USSD session | ||
| type USSDType string | ||
|
|
||
| const ( | ||
| // USSDTypeRequest is a USSD request from a mobile phone | ||
| USSDTypeRequest = USSDType("request") | ||
| // USSDTypeResponse is a USSD response from the application | ||
| USSDTypeResponse = USSDType("response") | ||
| ) | ||
|
|
||
| // USSDDirection represents the direction of USSD communication | ||
| type USSDDirection string | ||
|
|
||
| const ( | ||
| // USSDDirectionMoToApp means the USSD message comes from the mobile phone to the application | ||
| USSDDirectionMoToApp = USSDDirection("MO-to-App") | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can use the same MobileOriginated or MobileTerminated directions which we use for the |
||
| // USSDDirectionAppToMO means the USSD message goes from the application to the mobile phone | ||
| USSDDirectionAppToMO = USSDDirection("App-to-MO") | ||
| ) | ||
|
|
||
| // USSDStatus represents the status of a USSD session | ||
| type USSDStatus string | ||
|
|
||
| const ( | ||
| // USSDStatusPending means the USSD session is pending | ||
| USSDStatusPending = USSDStatus("pending") | ||
| // USSDStatusActive means the USSD session is active | ||
| USSDStatusActive = USSDStatus("active") | ||
| // USSDStatusCompleted means the USSD session is completed | ||
| USSDStatusCompleted = USSDStatus("completed") | ||
| // USSDStatusFailed means the USSD session has failed | ||
| USSDStatusFailed = USSDStatus("failed") | ||
| // USSDStatusTimedOut means the USSD session has timed out | ||
| USSDStatusTimedOut = USSDStatus("timed-out") | ||
| ) | ||
|
|
||
| // USSD represents a USSD session on the phone | ||
| type USSD struct { | ||
| ID uuid.UUID `json:"id" gorm:"primaryKey;type:uuid;" example:"32343a19-da5e-4b1b-a767-3298a73703cb"` | ||
| UserID UserID `json:"user_id" gorm:"index:idx_ussds__user_id" example:"WB7DRDWrJZRGbYrv2CKGkqbzvqdC"` | ||
| PhoneID uuid.UUID `json:"phone_id" gorm:"type:uuid;index:idx_ussds__phone_id" example:"32343a19-da5e-4b1b-a767-3298a73703cb"` | ||
| Owner string `json:"owner" example:"+18005550199"` | ||
| SessionID string `json:"session_id" example:"USSDSESSION12345" gorm:"index:idx_ussds__session_id"` | ||
| Type USSDType `json:"type" example:"request"` | ||
| Direction USSDDirection `json:"direction" example:"MO-to-App"` | ||
| Content string `json:"content" example:"*123#"` | ||
| Response *string `json:"response" example:"Welcome to USSD menu" validate:"optional"` | ||
| Status USSDStatus `json:"status" example:"pending" gorm:"default:pending"` | ||
| SIM SIM `json:"sim" example:"SIM1"` | ||
| Timestamp time.Time `json:"timestamp" example:"2022-06-05T14:26:09.527976+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"` | ||
| } | ||
|
|
||
| // TableName specifies the table name for the USSD entity | ||
| func (USSD) TableName() string { | ||
| return "ussds" | ||
| } | ||
|
|
||
| // IsActive checks if the USSD session is active | ||
| func (ussd *USSD) IsActive() bool { | ||
| return ussd.Status == USSDStatusActive | ||
| } | ||
|
|
||
| // IsPending checks if the USSD session is pending | ||
| func (ussd *USSD) IsPending() bool { | ||
| return ussd.Status == USSDStatusPending | ||
| } | ||
|
|
||
| // IsCompleted checks if the USSD session is completed | ||
| func (ussd *USSD) IsCompleted() bool { | ||
| return ussd.Status == USSDStatusCompleted | ||
| } | ||
|
|
||
| // IsFailed checks if the USSD session has failed | ||
| func (ussd *USSD) IsFailed() bool { | ||
| return ussd.Status == USSDStatusFailed | ||
| } | ||
|
|
||
| // IsTimedOut checks if the USSD session has timed out | ||
| func (ussd *USSD) IsTimedOut() bool { | ||
| return ussd.Status == USSDStatusTimedOut | ||
| } | ||
|
|
||
| // MarkActive marks the USSD session as active | ||
| func (ussd *USSD) MarkActive() *USSD { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of this you can use |
||
| ussd.Status = USSDStatusActive | ||
| return ussd | ||
| } | ||
|
|
||
| // MarkCompleted marks the USSD session as completed | ||
| func (ussd *USSD) MarkCompleted(response string) *USSD { | ||
| ussd.Status = USSDStatusCompleted | ||
| ussd.Response = &response | ||
| return ussd | ||
| } | ||
|
|
||
| // MarkFailed marks the USSD session as failed | ||
| func (ussd *USSD) MarkFailed() *USSD { | ||
| ussd.Status = USSDStatusFailed | ||
| return ussd | ||
| } | ||
|
|
||
| // MarkTimedOut marks the USSD session as timed out | ||
| func (ussd *USSD) MarkTimedOut() *USSD { | ||
| ussd.Status = USSDStatusTimedOut | ||
| return ussd | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| package events | ||
|
|
||
| import ( | ||
| "time" | ||
|
|
||
| "github.com/NdoleStudio/httpsms/pkg/entities" | ||
|
|
||
| "github.com/google/uuid" | ||
| ) | ||
|
|
||
| // EventTypeUSSDReceived is emitted when a USSD request is received from a mobile phone | ||
| const EventTypeUSSDReceived = "ussd.phone.received" | ||
|
|
||
| // USSDReceivedPayload is the payload of the EventTypeUSSDReceived event | ||
| type USSDReceivedPayload struct { | ||
| USSDID uuid.UUID `json:"ussd_id"` | ||
| UserID entities.UserID `json:"user_id"` | ||
| PhoneID uuid.UUID `json:"phone_id"` | ||
| Owner string `json:"owner"` | ||
| SessionID string `json:"session_id"` | ||
| Content string `json:"content"` | ||
| SIM entities.SIM `json:"sim"` | ||
| Timestamp time.Time `json:"timestamp"` | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| package events | ||
|
|
||
| import ( | ||
| "time" | ||
|
|
||
| "github.com/NdoleStudio/httpsms/pkg/entities" | ||
|
|
||
| "github.com/google/uuid" | ||
| ) | ||
|
|
||
| // EventTypeUSSDResponse is emitted when a USSD response is sent to a mobile phone | ||
| const EventTypeUSSDResponse = "ussd.phone.sent" | ||
|
|
||
| // USSDResponsePayload is the payload of the EventTypeUSSDResponse event | ||
| type USSDResponsePayload struct { | ||
| USSDID uuid.UUID `json:"ussd_id"` | ||
| UserID entities.UserID `json:"user_id"` | ||
| PhoneID uuid.UUID `json:"phone_id"` | ||
| Owner string `json:"owner"` | ||
| SessionID string `json:"session_id"` | ||
| Response string `json:"response"` | ||
| SIM entities.SIM `json:"sim"` | ||
| Timestamp time.Time `json:"timestamp"` | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add listener to delete all USSD messages when the phone is deleted and when the user account is deleted.