Skip to content

Commit

Permalink
feat: add send premium sms api
Browse files Browse the repository at this point in the history
  • Loading branch information
MelvinKim committed Jun 13, 2023
1 parent e4e6dcc commit 57dc018
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 1 deletion.
3 changes: 2 additions & 1 deletion client.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,15 @@ func (s *client) background() {
if err != nil {
s.authFailed = true
}
s.authFailed = false

case t := <-s.accessTokenTicker.C:
logrus.Println("SIL Comms Access Token updated at: ", t)
err := s.refreshAccessToken()
if err != nil {
s.authFailed = true
}

s.authFailed = false
}
}
}
Expand Down
13 changes: 13 additions & 0 deletions models.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,16 @@ type BulkSMSResponse struct {
Created string `json:"created"`
Updated string `json:"updated"`
}

// PremiumSMSResponse is the response returned after making a request to SILCOMMS to send a premium SMS
type PremiumSMSResponse struct {
GUID string `json:"guid"`
Body string `json:"body"`
Msisdn string `json:"msisdn"`
SMSType string `json:"sms_type"`
Gateway string `json:"gateway"`
Carrier string `json:"carrier"`
Subscription string `json:"subscription"`
Direction string `json:"direction"`
State string `json:"state"`
}
41 changes: 41 additions & 0 deletions sms.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ func MustNewSILCommsLib() *CommsLib {
// SendBulkSMS returns a 202 Accepted synchronous response while the API attempts to send the SMS in the background.
// An asynchronous call is made to the app's sms_callback URL with a notification that shows the Bulk SMS status.
// An asynchronous call is made to the app's sms_callback individually for each of the recipients with the SMS status.
// message - message to be sent via the Bulk SMS
// recipients - phone number(s) to receive the Bulk SMS
func (l CommsLib) SendBulkSMS(ctx context.Context, message string, recipients []string) (*BulkSMSResponse, error) {
path := "/v1/sms/bulk/"
payload := struct {
Expand Down Expand Up @@ -85,3 +87,42 @@ func (l CommsLib) SendBulkSMS(ctx context.Context, message string, recipients []

return &bulkSMS, nil
}

// SendPremiumSMS is used to send a premium SMS using SILCOMMS gateway
// message - message to be sent via the premium SMS
// msisdn - phone number to receive the premium SMS
// subscription - subscription/offer associated with the premium SMS
func (l CommsLib) SendPremiumSMS(ctx context.Context, message, msisdn, subscription string) (*PremiumSMSResponse, error) {
path := "/v1/sms/sms/"
payload := struct {
Body string `json:"body"`
Msisdn string `json:"msisdn"`
Subscription string `json:"subscription"`
}{
Body: message,
Msisdn: msisdn,
Subscription: subscription,
}

response, err := l.client.MakeRequest(ctx, http.MethodPost, path, nil, payload, true)
if err != nil {
return nil, fmt.Errorf("failed to make send premium sms request: %v", err)
}
if response.StatusCode != http.StatusOK {
return nil, fmt.Errorf("invalid send premium sms response code, got: %d", response.StatusCode)
}

var resp APIResponse
err = json.NewDecoder(response.Body).Decode(&resp)
if err != nil {
return nil, fmt.Errorf("failed to decode send premium sms api response: %w", err)
}

var premiumSMS PremiumSMSResponse
err = mapstructure.Decode(resp.Data, &premiumSMS)
if err != nil {
return nil, fmt.Errorf("failed to decode send premium sms data in api response: %w", err)
}

return &premiumSMS, nil
}
119 changes: 119 additions & 0 deletions sms_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,122 @@ func TestSILCommsLib_SendBulkSMS(t *testing.T) {
})
}
}

func TestSILCommsLib_SendPremiumSMS(t *testing.T) {
type args struct {
ctx context.Context
message string
msisdn string
subscription string
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "Happy case: send premium sms",
args: args{
ctx: context.Background(),
message: "test premium sms",
msisdn: gofakeit.Phone(),
subscription: "01262626626",
},
wantErr: false,
},
{
name: "Sad case: invalid status code",
args: args{
ctx: context.Background(),
message: "test premium sms",
msisdn: gofakeit.Phone(),
subscription: "01262626626",
},
wantErr: true,
},
{
name: "Sad case: invalid API response",
args: args{
ctx: context.Background(),
message: "test premium sms",
msisdn: gofakeit.Phone(),
subscription: "01262626626",
},
wantErr: true,
},
{
name: "Sad case: invalid premium SMS data response",
args: args{
ctx: context.Background(),
message: "test premium sms",
msisdn: gofakeit.Phone(),
subscription: "01262626626",
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()
silcomms.MockLogin()

l := silcomms.MustNewSILCommsLib()

if tt.name == "Happy case: send premium sms" {
httpmock.RegisterResponder(http.MethodPost, fmt.Sprintf("%s/v1/sms/sms/", silcomms.BaseURL), func(r *http.Request) (*http.Response, error) {
resp := silcomms.APIResponse{
Status: silcomms.StatusSuccess,
Message: "success",
Data: silcomms.PremiumSMSResponse{
GUID: gofakeit.UUID(),
},
}
return httpmock.NewJsonResponse(http.StatusOK, resp)
})
}

if tt.name == "Sad case: invalid status code" {
httpmock.RegisterResponder(http.MethodPost, fmt.Sprintf("%s/v1/sms/sms/", silcomms.BaseURL), func(r *http.Request) (*http.Response, error) {
return httpmock.NewJsonResponse(http.StatusUnauthorized, nil)
})
}

if tt.name == "Sad case: invalid API response" {
httpmock.RegisterResponder(http.MethodPost, fmt.Sprintf("%s/v1/sms/sms/", silcomms.BaseURL), func(r *http.Request) (*http.Response, error) {
resp := map[string]interface{}{
"status": 1234,
"message": 1234,
}

return httpmock.NewJsonResponse(http.StatusOK, resp)
})
}

if tt.name == "Sad case: invalid premium SMS data response" {
httpmock.RegisterResponder(http.MethodPost, fmt.Sprintf("%s/v1/sms/sms/", silcomms.BaseURL), func(r *http.Request) (*http.Response, error) {
resp := silcomms.APIResponse{
Status: silcomms.StatusSuccess,
Message: "success",
Data: map[string]interface{}{
"guid": 123456,
"carrier": 123456,
"message": 123456,
},
}
return httpmock.NewJsonResponse(http.StatusOK, resp)
})
}

got, err := l.SendPremiumSMS(tt.args.ctx, tt.args.message, tt.args.msisdn, tt.args.subscription)
if (err != nil) != tt.wantErr {
t.Errorf("SILCommsLib.SendPremiumSMS() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !tt.wantErr && got == nil {
t.Errorf("SILCommsLib.SendPremiumSMS() expected response not to be nil for %v", tt.name)
return
}
})
}
}

0 comments on commit 57dc018

Please sign in to comment.