new: feat: add b3 lambda
This commit is contained in:
29
README.md
Normal file
29
README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# vercel-lambdas
|
||||
|
||||
This is a collection of lambdas for personal use powered by [vercel](https://vercel.com/).
|
||||
|
||||
## statusinvest
|
||||
|
||||
The path `statusinvest` contains lambdas that fetches the status of a company (fundamentalist analysis) from [statusinvest.com](https://statusinvest.com/).
|
||||
|
||||
## b3
|
||||
|
||||
The path `b3` contains lambdas that fetches stock prices data directly from from [b3.com](https://b3.com/).
|
||||
|
||||
- `b3/prices/:symbol` [Test it!](https://vercel-lambdas-felipemarinho.vercel.app/api/b3/prices/IBOV)
|
||||
- Returns the stock prices for a given symbol.
|
||||
- Example Response:
|
||||
```json
|
||||
{
|
||||
"symbol": "IBOV",
|
||||
"name": "IBOVESPA",
|
||||
"market": "Indices",
|
||||
"openingPrice": 112295.87,
|
||||
"minPrice": 111689.15,
|
||||
"maxPrice": 113221.54,
|
||||
"averagePrice": 112702.99,
|
||||
"currentPrice": 112323.12,
|
||||
"priceVariation": 0.02,
|
||||
"indexComponentIndicator": false
|
||||
}
|
||||
```
|
||||
143
api/b3/prices/[ticker].go
Normal file
143
api/b3/prices/[ticker].go
Normal file
@@ -0,0 +1,143 @@
|
||||
package quotation
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type RawResponse struct {
|
||||
BizSts struct {
|
||||
Cd string `json:"cd"`
|
||||
} `json:"BizSts"`
|
||||
Msg struct {
|
||||
DtTm string `json:"dtTm"`
|
||||
} `json:"Msg"`
|
||||
Trad []struct {
|
||||
Scty struct {
|
||||
SctyQtn struct {
|
||||
OpngPric float64 `json:"opngPric"`
|
||||
MinPric float64 `json:"minPric"`
|
||||
MaxPric float64 `json:"maxPric"`
|
||||
AvrgPric float64 `json:"avrgPric"`
|
||||
CurPrc float64 `json:"curPrc"`
|
||||
PrcFlcn float64 `json:"prcFlcn"`
|
||||
} `json:"SctyQtn"`
|
||||
Mkt struct {
|
||||
Nm string `json:"nm"`
|
||||
} `json:"mkt"`
|
||||
Symb string `json:"symb"`
|
||||
Desc string `json:"desc"`
|
||||
IndxCmpnInd bool `json:"indxCmpnInd"`
|
||||
} `json:"scty"`
|
||||
TTLQty int `json:"ttlQty"`
|
||||
} `json:"Trad"`
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
Symbol string `json:"symbol"`
|
||||
Name string `json:"name"`
|
||||
Market string `json:"market"`
|
||||
OpeningPrice float64 `json:"openingPrice"`
|
||||
MinPrice float64 `json:"minPrice"`
|
||||
MaxPrice float64 `json:"maxPrice"`
|
||||
AveragePrice float64 `json:"averagePrice"`
|
||||
CurrentPrice float64 `json:"currentPrice"`
|
||||
PriceVariation float64 `json:"priceVariation"`
|
||||
IndexComponentIndicator bool `json:"indexComponentIndicator"`
|
||||
}
|
||||
|
||||
type RawErrorResponse struct {
|
||||
BizSts struct {
|
||||
Cd string `json:"cd"`
|
||||
Desc string `json:"desc"`
|
||||
} `json:"BizSts"`
|
||||
Msg struct {
|
||||
DtTm string `json:"dtTm"`
|
||||
} `json:"Msg"`
|
||||
}
|
||||
|
||||
type Error struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func HandlerListCompanies(w http.ResponseWriter, r *http.Request) {
|
||||
ticker := strings.Split(r.URL.Path, "/")[4]
|
||||
log.Info("Getting quotation info for ticker: " + ticker)
|
||||
if ticker == "" {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte("Ticker is required"))
|
||||
return
|
||||
}
|
||||
|
||||
client := http.Client{}
|
||||
res, err := client.Get(fmt.Sprintf("https://cotacao.b3.com.br/mds/api/v1/instrumentQuotation/%s", ticker))
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
defer res.Body.Close()
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
// add 1min cache header
|
||||
w.Header().Set("Cache-Control", "max-age=60, public")
|
||||
|
||||
out, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
var raw RawResponse
|
||||
err = json.Unmarshal(out, &raw)
|
||||
if err != nil || raw.BizSts.Cd != "OK" {
|
||||
var errorResponse RawErrorResponse
|
||||
err = json.Unmarshal(out, &errorResponse)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// 404
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
formatedError := Error{Message: errorResponse.BizSts.Desc}
|
||||
err := json.NewEncoder(w).Encode(formatedError)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var response []Response
|
||||
for _, trad := range raw.Trad {
|
||||
response = append(response, Response{
|
||||
Symbol: trad.Scty.Symb,
|
||||
Name: trad.Scty.Desc,
|
||||
Market: trad.Scty.Mkt.Nm,
|
||||
OpeningPrice: trad.Scty.SctyQtn.OpngPric,
|
||||
MinPrice: trad.Scty.SctyQtn.MinPric,
|
||||
MaxPrice: trad.Scty.SctyQtn.MaxPric,
|
||||
AveragePrice: trad.Scty.SctyQtn.AvrgPric,
|
||||
CurrentPrice: trad.Scty.SctyQtn.CurPrc,
|
||||
PriceVariation: trad.Scty.SctyQtn.PrcFlcn,
|
||||
IndexComponentIndicator: trad.Scty.IndxCmpnInd,
|
||||
})
|
||||
}
|
||||
|
||||
err = json.NewEncoder(w).Encode(response[0])
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
4
go.mod
4
go.mod
@@ -1,3 +1,7 @@
|
||||
module github.com/felipemarinho97/vercel-lambdas
|
||||
|
||||
go 1.17
|
||||
|
||||
require github.com/sirupsen/logrus v1.9.0
|
||||
|
||||
require golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
|
||||
|
||||
15
go.sum
Normal file
15
go.sum
Normal file
@@ -0,0 +1,15 @@
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
Reference in New Issue
Block a user