Skip to content

Commit

Permalink
[Feature] SDK init (#1)
Browse files Browse the repository at this point in the history
* feat: init sdk

* chore: minor description
  • Loading branch information
fsandov authored Nov 4, 2023
1 parent 96da80a commit ae902ed
Show file tree
Hide file tree
Showing 15 changed files with 413 additions and 1 deletion.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@fsandov
15 changes: 15 additions & 0 deletions .github/auto_assign.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Set to true to add reviewers to pull requests
addReviewers: true

# Set to true to add assignees to pull requests
addAssignees: false

# A list of reviewers to be added to pull requests (GitHub user name)
reviewers:
- fsandov

# A number of reviewers added to the pull request
# Set 0 to add all the reviewers (default: 0)
numberOfReviewers: 1

numberOfAssignees: 1
8 changes: 8 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: 2
updates:
- package-ecosystem: gomod
directory: "/"
schedule:
interval: weekly
day: "sunday"
time: "11:00"
11 changes: 11 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## Describe tus cambios

## ¿Cuál es el comportamiento actual?

## ¿Cuál es el comportamiento esperado?

## Checklist antes de solicitar una revisión

- [ ] He realizado una revisión propia de mi código.
- [ ] Los cambios han sido probados en el servidor local.
- [ ] Me aseguré de actualizar el README, en caso que corresponda.
12 changes: 12 additions & 0 deletions .github/workflows/action_assign.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: "Auto Assign"
on:
pull_request:
types: [ opened, ready_for_review ]

jobs:
add-reviews:
runs-on: ubuntu-latest
steps:
- uses: kentaro-m/[email protected]
with:
configuration-path: ".github/auto_assign.yml"
25 changes: 25 additions & 0 deletions .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: golangci-lint
on:
push:
tags:
- v*
branches:
- develop
- main
pull_request:
permissions:
contents: read
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '1.20'
cache: false
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: latest
22 changes: 22 additions & 0 deletions .github/workflows/security.advisories.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: GoSec Security Analysis
on:
push:
branches:
- main
- develop
pull_request:
branches:
- main
- develop
jobs:
tests:
runs-on: ubuntu-latest
env:
GO111MODULE: on
steps:
- name: Checkout Source
uses: actions/checkout@v3
- name: Run Gosec Security Scanner
uses: securego/gosec@master
with:
args: ./...
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,10 @@

# Go workspace file
go.work

# Common IDE folder
.idea
.vscode

# OSx files
.DS_Store
52 changes: 51 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,51 @@
# labsmobile-sdk-go
# SDK Labsmobile SMS Gateway API

[![GoDoc](https://godoc.org/github.com/fsandov/labsmobile-sdk-go?status.svg)](https://godoc.org/github.com/fsandov/labsmobile-sdk-go)
![License](https://img.shields.io/badge/License-MIT-blue.svg)

This is a Go SDK for the [Labsmobile SMS Gateway API](https://www.labsmobile.com).

```bash
go get github.com/fsandov/labsmobile-sdk-go
```

## Documentation
All the documentation of the API can be found [here](https://apidocs.labsmobile.com).

## Usage

### Create a client

1. Create a new client with your credentials. You can find your credentials in the [API Credentials](https://websms.labsmobile.com/SY0204/api) section of your Labsmobile account. Its recommended to use environment variables to store your keys.
2. Create a context, you can use the `context.Background()` function. Also you can use the `context.WithTimeout()` function to set a timeout for the request.
3. Create a struct with data to send to the API.

Example:
```go
import "github.com/fsandov/labsmobile-sdk-go/pkg/sms"

func main() {
// Create a context
ctx := context.Background()
// Create a client
client := sms.NewClient("your-username", "your-password")
message := sms.Message{
Destination: "34600000000",
Message: "Hello World",
}
response, err := client.Send(ctx, message)
if err != nil {
panic(err)
}
fmt.Println(response)
}
```
You can see more examples in the examples folder of this repository.

## Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

## License
[MIT](LICENSE)


42 changes: 42 additions & 0 deletions examples/sms/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package main

import (
"context"
"fmt"

"github.com/fsandov/labsmobile-sdk-go/pkg/sms"
)

func main() {
ctx := context.Background()

apiKey := ""
username := ""

client, err := sms.NewClient(apiKey, username)
if err != nil {
fmt.Println("error: ", err)
}

smsData := sms.SendSMSRequest{
Message: "Prueba desde SDK con requirements",
Recipient: []sms.Recipient{
{
Msisdn: "56982601777",
},
},
}

smsResponse, err := client.SendSMS(ctx, smsData)
if err != nil {
fmt.Println("error: ", err)
}
fmt.Println(smsResponse)

balance, err := client.GetBalance(ctx)
if err != nil {
fmt.Println("error: ", err)
}
fmt.Println(balance)

}
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/fsandov/labsmobile-sdk-go

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

import (
"fmt"
"net/http"
"time"
)

const (
baseURL = "https://api.labsmobile.com/json"
defaultTimeout = 2000
)

var (
errAPIKeyRequired = fmt.Errorf("api key is required")
errUsernameRequired = fmt.Errorf("username is required")
)

type (
clientOptions struct {
Timeout int64
}

// ClientOption is the type for the options of the Client.
ClientOption func(*clientOptions)
)

// WithTimeOut sets the timeout for the http client in milliseconds. Default value is 2000. This is optional.
func WithTimeOut(timeout int64) ClientOption {
return func(o *clientOptions) {
if timeout > 0 {
o.Timeout = timeout
} else {
o.Timeout = defaultTimeout
}
}
}

func (o *clientOptions) apply(opts ...ClientOption) {
for _, opt := range opts {
opt(o)
}
}

// Client is the client for the labosmobile.com API. It contains the http client, the baseURL, the APIKey and the SecretKey.
type Client struct {
httpClient *http.Client
baseURL string
APIKey string
Username string
}

func NewClient(apiKey string, username string, opts ...ClientOption) (*Client, error) {
if apiKey == "" {
return nil, errAPIKeyRequired
}

if username == "" {
return nil, errUsernameRequired
}

options := &clientOptions{}
options.apply(opts...)

return &Client{
httpClient: &http.Client{
Timeout: time.Duration(options.Timeout) * time.Millisecond,
},
baseURL: baseURL,
APIKey: apiKey,
Username: username,
}, nil
}
42 changes: 42 additions & 0 deletions pkg/sms/credits.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package sms

import (
"context"
"encoding/json"
"fmt"
"net/http"
)

const (
getBalance = "/balance"
)

func (c *Client) GetBalance(ctx context.Context) (*GetBalanceResponse, error) {
if c.APIKey == "" {
return nil, errAPIKeyRequired
}
if c.Username == "" {
return nil, errUsernameRequired
}
URI := fmt.Sprintf("%s%s", c.baseURL, getBalance)
req, _ := http.NewRequestWithContext(ctx, http.MethodGet, URI, nil)
req.SetBasicAuth(c.Username, c.APIKey)
res, err := c.httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("error making request. err: %v", err)
}
defer func() {
_ = res.Body.Close()
}()

if res.StatusCode != http.StatusOK {
return nil, fmt.Errorf("bad request, code: %d", res.StatusCode)
}

var response *GetBalanceResponse
if err = json.NewDecoder(res.Body).Decode(&response); err != nil {
return nil, fmt.Errorf("error decoding response. err: %v", err)
}

return response, nil
}
36 changes: 36 additions & 0 deletions pkg/sms/domain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package sms

type SendSMSRequest struct {
Message string `json:"message"` // Required
Recipient []Recipient `json:"recipient"` // Required
Tpoa *string `json:"tpoa,omitempty"` // Optional
SubID *string `json:"subid,omitempty"` // Optional
Label *string `json:"label,omitempty"` // Optional
Test *int `json:"test,omitempty"` // Optional
AckURL *string `json:"ackurl,omitempty"` // Optional
ShortLink *int `json:"shortlink,omitempty"` // Optional
ClickURL *string `json:"clickurl,omitempty"` // Optional
Scheduled *string `json:"scheduled,omitempty"` // Optional
Long *int `json:"long,omitempty"` // Optional
Crt *string `json:"crt,omitempty"` // Optional
CrtID *string `json:"crt_id,omitempty"` // Optional
CrtName *string `json:"crt_name,omitempty"` // Optional
UCS2 *int `json:"ucs2,omitempty"` // Optional
NoFilter *int `json:"nofilter,omitempty"` // Optional
}

type Recipient struct {
Msisdn string `json:"msisdn"` // Required

}

type SendSMSResponse struct {
Code string `json:"code"`
Message string `json:"message"`
SubID string `json:"subid,omitempty"`
}

type GetBalanceResponse struct {
Code interface{} `json:"code"`
Credits string `json:"credits"`
}
Loading

0 comments on commit ae902ed

Please sign in to comment.