-
Notifications
You must be signed in to change notification settings - Fork 0
/
handler.go
134 lines (110 loc) · 3.82 KB
/
handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package links
import (
"encoding/json"
"fmt"
"net/url"
"strings"
"google.golang.org/grpc/codes"
"github.com/desmos-labs/caerus/types"
"github.com/desmos-labs/caerus/utils"
)
type Handler struct {
deepLinksClient DeepLinksClient
db Database
}
// NewHandler allows to build a new Handler instance
func NewHandler(client DeepLinksClient, db Database) *Handler {
return &Handler{
deepLinksClient: client,
db: db,
}
}
// NewHandlerFromEnvVariables returns a new Handler instance reading the config from the env variables
func NewHandlerFromEnvVariables(client DeepLinksClient, db Database) *Handler {
return NewHandler(client, db)
}
// HandleGenerateGenericDeepLinkRequest handles the given GenerateDeepLinkRequest
// Note: This method does *NOT* check for deep link creation rate limit, as the application will have to provide
// its own API key to create the deep link. This means that the application will be rate limited by Branch itself.
func (h *Handler) HandleGenerateGenericDeepLinkRequest(request *GenerateGenericDeepLinkRequest) (*CreateLinkResponse, error) {
// Generate the deep link
deepLink, err := h.deepLinksClient.CreateDynamicLink(request.ApiKey, request.LinkConfig)
if err != nil {
return nil, err
}
// Store the created deep link
err = h.db.SaveCreatedDeepLink(types.NewCreatedDeepLink(request.AppID, deepLink, request.LinkConfig))
if err != nil {
return nil, err
}
// Return the response data
return &CreateLinkResponse{Url: deepLink}, nil
}
// checkAppLinksRateLimit checks if the given app has exceeded the rate limit for deep links creation
func (h *Handler) checkAppLinksRateLimit(appID string) error {
// Make sure the application has not exceeded the rate limit
deepLinksRateLimit, err := h.db.GetAppDeepLinksRateLimit(appID)
if err != nil {
return err
}
deepLinksCount, err := h.db.GetAppDeepLinksCount(appID)
if err != nil {
return err
}
if deepLinksRateLimit > 0 && deepLinksCount >= deepLinksRateLimit {
return utils.NewTooManyRequestsError("deep links rate limit exceeded")
}
return nil
}
// HandleGenerateDeepLinkRequest handles the given GenerateDeepLinkRequest
func (h *Handler) HandleGenerateDeepLinkRequest(request GenerateDeepLinkRequest) (*CreateLinkResponse, error) {
// Make sure the application has not exceeded the rate limit
err := h.checkAppLinksRateLimit(request.GetAppID())
if err != nil {
return nil, err
}
// Build the custom data to use in order to generate the link
customData := request.GetCustomData()
customData[types.DeepLinkActionKey] = request.GetAction()
customData[types.DeepLinkChainTypeKey] = strings.ToLower(request.GetChainType().String())
customDataBz, err := json.Marshal(customData)
if err != nil {
return nil, err
}
// Build the path to use in order to generate the link
values := url.Values{}
for key, value := range customData {
if key != types.DeepLinkActionKey {
values.Add(key, value)
}
}
deepLinkPath := fmt.Sprintf("/%s?%s", request.GetAction(), values.Encode())
linkConfig := &types.LinkConfig{
CustomData: customDataBz,
DeepLinking: &types.DeepLinkConfig{
DeepLinkPath: deepLinkPath,
},
}
// Generate the link
deepLink, err := h.deepLinksClient.CreateDynamicLink("", linkConfig)
if err != nil {
return nil, err
}
// Store the created deep link
err = h.db.SaveCreatedDeepLink(types.NewCreatedDeepLink(request.GetAppID(), deepLink, linkConfig))
if err != nil {
return nil, err
}
return &CreateLinkResponse{Url: deepLink}, nil
}
// HandleGetLinkConfigRequest handles the given GetLinkConfigRequest
func (h *Handler) HandleGetLinkConfigRequest(request *GetLinkConfigRequest) (*types.LinkConfig, error) {
config, err := h.db.GetDeepLinkConfig(request.Url)
if err != nil {
return nil, err
}
if config == nil {
return nil, utils.WrapErr(codes.NotFound, "link not found")
}
return config, nil
}