Skip to content

Commit

Permalink
Merge pull request #3 from MikeMwita/devmike
Browse files Browse the repository at this point in the history
Devmike
  • Loading branch information
MikeMwita authored Feb 16, 2024
2 parents 3496896 + 8225522 commit d1486fa
Show file tree
Hide file tree
Showing 7 changed files with 211 additions and 42 deletions.
18 changes: 11 additions & 7 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,19 @@
</p>


# africastalking-go
# African's Talking Go SDK

A Go SDK for Africa's Talking, a platform that provides various communication and payment services in Africa.

African's Talking Go SDK is a comprehensive Go library for interacting with the Africa's Talking API, a platform that provides various communication and payment services across Africa.

## Features

- SMS: Send and receive SMS messages to and from any network in Africa
- Voice: Make and receive voice calls, play media, and control the call flow
- USSD: Create interactive menus and sessions for your users
- Airtime: Send airtime to mobile subscribers across Africa
- Payments: Accept and disburse payments via mobile money, card, and bank

- **SMS**: Send and receive SMS messages to and from any network in Africa
- **Voice**: Make and receive voice calls, play media, and control the call flow
- **USSD**: Create interactive menus and sessions for your users
- **Airtime**: Send airtime to mobile subscribers across Africa
- **Payments**: Accept and disburse payments via mobile money, card, and bank


## Installation
Expand Down Expand Up @@ -94,3 +96,5 @@ go test -cover ./...
```




25 changes: 25 additions & 0 deletions examples/send_sms_example.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package sms_sender

import (
"fmt"
"github.com/MikeMwita/africastalking-go/pkg/sms"
"log"
)

func main() {
// Example usage
sender := sms.SmsSender{
ApiKey: "your_api_key",
ApiUser: "your_api_user",
Recipients: []string{"+1234567890"},
Message: "Hello, world!",
Sender: "your_sender",
}

response, err := sender.SendSMS()
if err != nil {
log.Fatal(err)
}

fmt.Printf("Response: %+v\n", response)
}
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
module github.com/MikeMwita/africastalking-go

go 1.21.4

require github.com/google/uuid v1.6.0
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
35 changes: 0 additions & 35 deletions main.go

This file was deleted.

139 changes: 139 additions & 0 deletions pkg/sms/sms_sender.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package sms

import (
"encoding/json"
"fmt"
"github.com/google/uuid"
"net/http"
"net/url"
"strings"
)

type SmsSender struct {
ApiKey string `json:"api_key"`
ApiUser string `json:"api_user"`
Recipients []string `json:"recipients"`
Message string `json:"message"`
Sender string `json:"sender"`
SmsKey string `json:"sms_key"`
}

type Recipient struct {
Key string `json:"key"`
Cost string `json:"cost"`
SmsKey string `json:"sms_key"`
MessageId string `json:"message_id"`
MessagePart int `json:"message_part"`
Number string `json:"number"`
Status string `json:"status"`
StatusCode string `json:"status_code"`
}

type SmsMessageData struct {
Message string `json:"message"`
Cost string `json:"cost"`
Recipients []Recipient `json:"recipients"`
}

type ErrorResponse struct {
HasError bool `json:"has_error"`
Message string `json:"message"`
}

type SmsSenderResponse struct {
ErrorResponse ErrorResponse `json:"error_response"`
SmsMessageData SmsMessageData `json:"sms_message_data"`
}

// SendSMS sends an SMS using the Africa's Talking API
func (s *SmsSender) SendSMS() (SmsSenderResponse, error) {
endpoint := "https://api.africastalking.com/version1/messaging"
parsedURL, err := url.Parse(endpoint)
if err != nil {
return SmsSenderResponse{}, err
}

body := map[string][]string{
"username": {s.ApiUser},
"to": s.Recipients,
"message": {s.Message},
"from": {s.Sender},
}

form := url.Values{}
for key, values := range body {
for _, value := range values {
form.Add(key, value)
}
}

req, err := http.NewRequest(http.MethodPost, parsedURL.String(), strings.NewReader(form.Encode()))
if err != nil {
return SmsSenderResponse{}, err
}

req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("apiKey", s.ApiKey)

client := &http.Client{}
res, err := client.Do(req)
if err != nil {
return SmsSenderResponse{}, err
}
defer res.Body.Close()

if res.StatusCode == http.StatusCreated {
recipients := make([]Recipient, 0)

var data map[string]interface{}
err = json.NewDecoder(res.Body).Decode(&data)
if err != nil {
return SmsSenderResponse{}, err
}

smsMessageData := data["SMSMessageData"].(map[string]interface{})
message := smsMessageData["Message"].(string)
cost := strings.Split(message, " ")[len(message)-1]
recipientsData := smsMessageData["Recipients"].([]interface{})

for _, recipient := range recipientsData {
recipientData := recipient.(map[string]interface{})

rct := Recipient{
Key: uuid.New().String(),
Cost: recipientData["cost"].(string),
SmsKey: s.SmsKey,
MessageId: recipientData["messageId"].(string),
MessagePart: int(recipientData["messageParts"].(float64)),
Number: recipientData["number"].(string),
Status: recipientData["status"].(string),
StatusCode: fmt.Sprintf("%v", recipientData["statusCode"]),
}

recipients = append(recipients, rct)
}

smsSenderResponse := SmsSenderResponse{
ErrorResponse: ErrorResponse{
HasError: false,
},
SmsMessageData: SmsMessageData{
Message: message,
Cost: cost,
Recipients: recipients,
},
}

return smsSenderResponse, nil
}

smsSenderResponse := SmsSenderResponse{
ErrorResponse: ErrorResponse{
HasError: true,
Message: "Message not sent",
},
}

return smsSenderResponse, fmt.Errorf("status code: %d", res.StatusCode)
}
32 changes: 32 additions & 0 deletions pkg/sms/sms_sender_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package sms

import (
"testing"
)

func TestSendSMS(t *testing.T) {
sender := SmsSender{
ApiKey: "your_api_key",
ApiUser: "your_api_user",
Recipients: []string{"+1234567890"},
Message: "Hello, world!",
Sender: "your_sender",
}

response, err := sender.SendSMS()
if err != nil {
t.Errorf("error occurred: %v", err)
}

if response.ErrorResponse.HasError {
t.Errorf("error response received: %s", response.ErrorResponse.Message)
}

if len(response.SmsMessageData.Recipients) == 0 {
t.Errorf("no recipients received in response")
}

if response.SmsMessageData.Message == "" {
t.Errorf("empty message received in response")
}
}

0 comments on commit d1486fa

Please sign in to comment.