@suprsend/node-sdk 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/brands.js +245 -0
- package/dist/event.js +6 -1
- package/dist/index.js +12 -0
- package/dist/request_json/event.json +5 -0
- package/dist/request_json/list_broadcast.json +70 -0
- package/dist/request_json/workflow.json +5 -0
- package/dist/signature.js +6 -5
- package/dist/subscribers_list.js +484 -0
- package/dist/utils.js +60 -2
- package/dist/workflow.js +5 -0
- package/package.json +1 -1
- package/src/brands.js +120 -0
- package/src/event.js +4 -0
- package/src/index.js +10 -1
- package/src/request_json/event.json +5 -0
- package/src/request_json/list_broadcast.json +70 -0
- package/src/request_json/workflow.json +5 -0
- package/src/signature.js +5 -4
- package/src/subscribers_list.js +296 -0
- package/src/utils.js +39 -1
- package/src/workflow.js +4 -0
package/dist/brands.js
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports["default"] = void 0;
|
|
9
|
+
|
|
10
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
11
|
+
|
|
12
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
13
|
+
|
|
14
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
15
|
+
|
|
16
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
17
|
+
|
|
18
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
19
|
+
|
|
20
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
21
|
+
|
|
22
|
+
var _signature = _interopRequireDefault(require("./signature"));
|
|
23
|
+
|
|
24
|
+
var _utils = require("./utils");
|
|
25
|
+
|
|
26
|
+
var _axios = _interopRequireDefault(require("axios"));
|
|
27
|
+
|
|
28
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
29
|
+
|
|
30
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
31
|
+
|
|
32
|
+
var BrandsApi = /*#__PURE__*/function () {
|
|
33
|
+
function BrandsApi(config) {
|
|
34
|
+
(0, _classCallCheck2["default"])(this, BrandsApi);
|
|
35
|
+
this.config = config;
|
|
36
|
+
this.list_url = this.__list_url();
|
|
37
|
+
this.__headers = this.__common_headers();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
(0, _createClass2["default"])(BrandsApi, [{
|
|
41
|
+
key: "__list_url",
|
|
42
|
+
value: function __list_url() {
|
|
43
|
+
var list_uri_template = "".concat(this.config.base_url, "v1/brand/");
|
|
44
|
+
return list_uri_template;
|
|
45
|
+
}
|
|
46
|
+
}, {
|
|
47
|
+
key: "__common_headers",
|
|
48
|
+
value: function __common_headers() {
|
|
49
|
+
return {
|
|
50
|
+
"Content-Type": "application/json; charset=utf-8",
|
|
51
|
+
"User-Agent": this.config.user_agent
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}, {
|
|
55
|
+
key: "cleaned_limit_offset",
|
|
56
|
+
value: function cleaned_limit_offset(limit, offset) {
|
|
57
|
+
var cleaned_limit = typeof limit === "number" && limit > 0 && limit <= 1000 ? limit : 20;
|
|
58
|
+
var cleaned_offset = typeof offset === "number" && offset >= 0 ? offset : 0;
|
|
59
|
+
return [cleaned_limit, cleaned_offset];
|
|
60
|
+
}
|
|
61
|
+
}, {
|
|
62
|
+
key: "__dynamic_headers",
|
|
63
|
+
value: function __dynamic_headers() {
|
|
64
|
+
return {
|
|
65
|
+
Date: new Date().toUTCString()
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}, {
|
|
69
|
+
key: "list",
|
|
70
|
+
value: function () {
|
|
71
|
+
var _list = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() {
|
|
72
|
+
var kwargs,
|
|
73
|
+
limit,
|
|
74
|
+
offset,
|
|
75
|
+
_this$cleaned_limit_o,
|
|
76
|
+
_this$cleaned_limit_o2,
|
|
77
|
+
cleaned_limit,
|
|
78
|
+
cleaner_offset,
|
|
79
|
+
final_url_obj,
|
|
80
|
+
final_url_string,
|
|
81
|
+
headers,
|
|
82
|
+
signature,
|
|
83
|
+
response,
|
|
84
|
+
_args = arguments;
|
|
85
|
+
|
|
86
|
+
return _regenerator["default"].wrap(function _callee$(_context) {
|
|
87
|
+
while (1) {
|
|
88
|
+
switch (_context.prev = _context.next) {
|
|
89
|
+
case 0:
|
|
90
|
+
kwargs = _args.length > 0 && _args[0] !== undefined ? _args[0] : {};
|
|
91
|
+
limit = kwargs === null || kwargs === void 0 ? void 0 : kwargs.limit;
|
|
92
|
+
offset = kwargs === null || kwargs === void 0 ? void 0 : kwargs.offset;
|
|
93
|
+
_this$cleaned_limit_o = this.cleaned_limit_offset(limit, offset), _this$cleaned_limit_o2 = (0, _slicedToArray2["default"])(_this$cleaned_limit_o, 2), cleaned_limit = _this$cleaned_limit_o2[0], cleaner_offset = _this$cleaned_limit_o2[1];
|
|
94
|
+
final_url_obj = new URL(this.list_url);
|
|
95
|
+
final_url_obj.searchParams.append("limit", cleaned_limit);
|
|
96
|
+
final_url_obj.searchParams.append("offset", cleaner_offset);
|
|
97
|
+
final_url_string = final_url_obj.href;
|
|
98
|
+
headers = _objectSpread(_objectSpread({}, this.__headers), this.__dynamic_headers());
|
|
99
|
+
signature = (0, _signature["default"])(final_url_string, "GET", "", headers, this.config.workspace_secret);
|
|
100
|
+
headers["Authorization"] = "".concat(this.config.workspace_key, ":").concat(signature);
|
|
101
|
+
_context.prev = 11;
|
|
102
|
+
_context.next = 14;
|
|
103
|
+
return _axios["default"].get(final_url_string, {
|
|
104
|
+
headers: headers
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
case 14:
|
|
108
|
+
response = _context.sent;
|
|
109
|
+
return _context.abrupt("return", response.data);
|
|
110
|
+
|
|
111
|
+
case 18:
|
|
112
|
+
_context.prev = 18;
|
|
113
|
+
_context.t0 = _context["catch"](11);
|
|
114
|
+
throw new _utils.SuprsendApiError(_context.t0);
|
|
115
|
+
|
|
116
|
+
case 21:
|
|
117
|
+
case "end":
|
|
118
|
+
return _context.stop();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}, _callee, this, [[11, 18]]);
|
|
122
|
+
}));
|
|
123
|
+
|
|
124
|
+
function list() {
|
|
125
|
+
return _list.apply(this, arguments);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return list;
|
|
129
|
+
}()
|
|
130
|
+
}, {
|
|
131
|
+
key: "detail_url",
|
|
132
|
+
value: function detail_url() {
|
|
133
|
+
var brand_id = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
|
|
134
|
+
var cleaned_brand_id = brand_id.toString().trim();
|
|
135
|
+
var brand_id_encoded = encodeURI(cleaned_brand_id);
|
|
136
|
+
var url = "".concat(this.list_url).concat(brand_id_encoded, "/");
|
|
137
|
+
return url;
|
|
138
|
+
}
|
|
139
|
+
}, {
|
|
140
|
+
key: "get",
|
|
141
|
+
value: function () {
|
|
142
|
+
var _get = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2() {
|
|
143
|
+
var brand_id,
|
|
144
|
+
url,
|
|
145
|
+
headers,
|
|
146
|
+
signature,
|
|
147
|
+
response,
|
|
148
|
+
_args2 = arguments;
|
|
149
|
+
return _regenerator["default"].wrap(function _callee2$(_context2) {
|
|
150
|
+
while (1) {
|
|
151
|
+
switch (_context2.prev = _context2.next) {
|
|
152
|
+
case 0:
|
|
153
|
+
brand_id = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : "";
|
|
154
|
+
url = this.detail_url(brand_id);
|
|
155
|
+
headers = _objectSpread(_objectSpread({}, this.__headers), this.__dynamic_headers());
|
|
156
|
+
signature = (0, _signature["default"])(url, "GET", "", headers, this.config.workspace_secret);
|
|
157
|
+
headers["Authorization"] = "".concat(this.config.workspace_key, ":").concat(signature);
|
|
158
|
+
_context2.prev = 5;
|
|
159
|
+
_context2.next = 8;
|
|
160
|
+
return _axios["default"].get(url, {
|
|
161
|
+
headers: headers
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
case 8:
|
|
165
|
+
response = _context2.sent;
|
|
166
|
+
return _context2.abrupt("return", response.data);
|
|
167
|
+
|
|
168
|
+
case 12:
|
|
169
|
+
_context2.prev = 12;
|
|
170
|
+
_context2.t0 = _context2["catch"](5);
|
|
171
|
+
throw new _utils.SuprsendApiError(_context2.t0);
|
|
172
|
+
|
|
173
|
+
case 15:
|
|
174
|
+
case "end":
|
|
175
|
+
return _context2.stop();
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}, _callee2, this, [[5, 12]]);
|
|
179
|
+
}));
|
|
180
|
+
|
|
181
|
+
function get() {
|
|
182
|
+
return _get.apply(this, arguments);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return get;
|
|
186
|
+
}()
|
|
187
|
+
}, {
|
|
188
|
+
key: "upsert",
|
|
189
|
+
value: function () {
|
|
190
|
+
var _upsert = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3() {
|
|
191
|
+
var brand_id,
|
|
192
|
+
brand_payload,
|
|
193
|
+
url,
|
|
194
|
+
headers,
|
|
195
|
+
content_text,
|
|
196
|
+
signature,
|
|
197
|
+
response,
|
|
198
|
+
_args3 = arguments;
|
|
199
|
+
return _regenerator["default"].wrap(function _callee3$(_context3) {
|
|
200
|
+
while (1) {
|
|
201
|
+
switch (_context3.prev = _context3.next) {
|
|
202
|
+
case 0:
|
|
203
|
+
brand_id = _args3.length > 0 && _args3[0] !== undefined ? _args3[0] : "";
|
|
204
|
+
brand_payload = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : {};
|
|
205
|
+
url = this.detail_url(brand_id);
|
|
206
|
+
headers = _objectSpread(_objectSpread({}, this.__headers), this.__dynamic_headers());
|
|
207
|
+
content_text = JSON.stringify(brand_payload);
|
|
208
|
+
signature = (0, _signature["default"])(url, "POST", content_text, headers, this.config.workspace_secret);
|
|
209
|
+
headers["Authorization"] = "".concat(this.config.workspace_key, ":").concat(signature);
|
|
210
|
+
_context3.prev = 7;
|
|
211
|
+
_context3.next = 10;
|
|
212
|
+
return _axios["default"].post(url, content_text, {
|
|
213
|
+
headers: headers
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
case 10:
|
|
217
|
+
response = _context3.sent;
|
|
218
|
+
return _context3.abrupt("return", response.data);
|
|
219
|
+
|
|
220
|
+
case 14:
|
|
221
|
+
_context3.prev = 14;
|
|
222
|
+
_context3.t0 = _context3["catch"](7);
|
|
223
|
+
throw new _utils.SuprsendApiError(_context3.t0);
|
|
224
|
+
|
|
225
|
+
case 17:
|
|
226
|
+
case "end":
|
|
227
|
+
return _context3.stop();
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}, _callee3, this, [[7, 14]]);
|
|
231
|
+
}));
|
|
232
|
+
|
|
233
|
+
function upsert() {
|
|
234
|
+
return _upsert.apply(this, arguments);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return upsert;
|
|
238
|
+
}()
|
|
239
|
+
}]);
|
|
240
|
+
return BrandsApi;
|
|
241
|
+
}();
|
|
242
|
+
|
|
243
|
+
var _default = BrandsApi;
|
|
244
|
+
exports["default"] = _default;
|
|
245
|
+
module.exports = exports.default;
|
package/dist/event.js
CHANGED
|
@@ -42,7 +42,8 @@ var Event = /*#__PURE__*/function () {
|
|
|
42
42
|
this.distinct_id = distinct_id;
|
|
43
43
|
this.event_name = event_name;
|
|
44
44
|
this.properties = properties;
|
|
45
|
-
this.idempotency_key = kwargs === null || kwargs === void 0 ? void 0 : kwargs.idempotency_key;
|
|
45
|
+
this.idempotency_key = kwargs === null || kwargs === void 0 ? void 0 : kwargs.idempotency_key;
|
|
46
|
+
this.brand_id = kwargs === null || kwargs === void 0 ? void 0 : kwargs.brand_id; // --- validate
|
|
46
47
|
|
|
47
48
|
this.__validate_distinct_id();
|
|
48
49
|
|
|
@@ -135,6 +136,10 @@ var Event = /*#__PURE__*/function () {
|
|
|
135
136
|
event_dict["$idempotency_key"] = this.idempotency_key;
|
|
136
137
|
}
|
|
137
138
|
|
|
139
|
+
if (this.brand_id) {
|
|
140
|
+
event_dict["brand_id"] = this.brand_id;
|
|
141
|
+
}
|
|
142
|
+
|
|
138
143
|
event_dict = (0, _utils.validate_track_event_schema)(event_dict);
|
|
139
144
|
var apparent_size = (0, _utils.get_apparent_event_size)(event_dict, is_part_of_bulk);
|
|
140
145
|
|
package/dist/index.js
CHANGED
|
@@ -13,6 +13,12 @@ Object.defineProperty(exports, "Event", {
|
|
|
13
13
|
return _event["default"];
|
|
14
14
|
}
|
|
15
15
|
});
|
|
16
|
+
Object.defineProperty(exports, "SubscribersListBroadcast", {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function get() {
|
|
19
|
+
return _subscribers_list.SubscribersListBroadcast;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
16
22
|
exports.Suprsend = void 0;
|
|
17
23
|
Object.defineProperty(exports, "Workflow", {
|
|
18
24
|
enumerable: true,
|
|
@@ -41,6 +47,10 @@ var _subscriber = _interopRequireDefault(require("./subscriber"));
|
|
|
41
47
|
|
|
42
48
|
var _subscribers_bulk = _interopRequireDefault(require("./subscribers_bulk"));
|
|
43
49
|
|
|
50
|
+
var _subscribers_list = require("./subscribers_list");
|
|
51
|
+
|
|
52
|
+
var _brands = _interopRequireDefault(require("./brands"));
|
|
53
|
+
|
|
44
54
|
var _constants = require("./constants");
|
|
45
55
|
|
|
46
56
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
@@ -66,6 +76,8 @@ var Suprsend = /*#__PURE__*/function () {
|
|
|
66
76
|
this._bulk_events = new _events_bulk.BulkEventsFactory(this);
|
|
67
77
|
this._bulk_users = new _subscribers_bulk["default"](this);
|
|
68
78
|
this._user = new _subscriber["default"](this);
|
|
79
|
+
this.brands = new _brands["default"](this);
|
|
80
|
+
this.subscribers_list = new _subscribers_list.SubscribersListApi(this);
|
|
69
81
|
|
|
70
82
|
this._validate();
|
|
71
83
|
}
|
|
@@ -11,6 +11,11 @@
|
|
|
11
11
|
"maxLength": 64,
|
|
12
12
|
"description": "unique id provided by client for request"
|
|
13
13
|
},
|
|
14
|
+
"brand_id": {
|
|
15
|
+
"type": ["string", "null"],
|
|
16
|
+
"maxLength": 64,
|
|
17
|
+
"description": "brand id for workflow to be run in context of a brand"
|
|
18
|
+
},
|
|
14
19
|
"$insert_id": {
|
|
15
20
|
"type": "string",
|
|
16
21
|
"minLength": 36,
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "http://github.com/suprsend/suprsend-node-sdk/request_json/list_broadcast.json",
|
|
4
|
+
"title": "list_broadcast_request",
|
|
5
|
+
"description": "Json schema for list_broadcast request",
|
|
6
|
+
"$comment": "Json schema for list_broadcast request",
|
|
7
|
+
"type": "object",
|
|
8
|
+
"properties": {
|
|
9
|
+
"$idempotency_key": {
|
|
10
|
+
"type": ["string", "null"],
|
|
11
|
+
"maxLength": 64,
|
|
12
|
+
"description": "unique id provided by client for request"
|
|
13
|
+
},
|
|
14
|
+
"brand_id": {
|
|
15
|
+
"type": ["string", "null"],
|
|
16
|
+
"maxLength": 64,
|
|
17
|
+
"description": "brand id for workflow to be run in context of a brand"
|
|
18
|
+
},
|
|
19
|
+
"$insert_id": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"minLength": 36,
|
|
22
|
+
"description": "unique uuid generated per request"
|
|
23
|
+
},
|
|
24
|
+
"$time": {
|
|
25
|
+
"type": "integer",
|
|
26
|
+
"minimum": 1640995200000,
|
|
27
|
+
"description": "Timestamp: unix epoch in milliseconds"
|
|
28
|
+
},
|
|
29
|
+
"list_id": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"minLength": 1,
|
|
32
|
+
"description": "SubscriberList id"
|
|
33
|
+
},
|
|
34
|
+
"template": {
|
|
35
|
+
"$ref": "#/definitions/non_empty_string",
|
|
36
|
+
"description": "slug of Template"
|
|
37
|
+
},
|
|
38
|
+
"notification_category": {
|
|
39
|
+
"$ref": "#/definitions/non_empty_string",
|
|
40
|
+
"description": "slug of Notification category"
|
|
41
|
+
},
|
|
42
|
+
"delay": {
|
|
43
|
+
"type": ["string", "integer"],
|
|
44
|
+
"minimum": 0,
|
|
45
|
+
"description": "If string: format [XX]d[XX]h[XX]m[XX]s e.g 1d2h30m10s(for 1day 2hours 30minutes 10sec). If integer: value in number of seconds"
|
|
46
|
+
},
|
|
47
|
+
"trigger_at": {
|
|
48
|
+
"type": "string",
|
|
49
|
+
"description": "timestamp in ISO-8601 format. e.g 2021-08-27T20:14:51.643Z"
|
|
50
|
+
},
|
|
51
|
+
"data": {
|
|
52
|
+
"type": "object",
|
|
53
|
+
"description": "variables to be used in workflow. e.g replacing templates variables."
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"required": [
|
|
57
|
+
"$insert_id",
|
|
58
|
+
"$time",
|
|
59
|
+
"list_id",
|
|
60
|
+
"template",
|
|
61
|
+
"notification_category",
|
|
62
|
+
"data"
|
|
63
|
+
],
|
|
64
|
+
"definitions": {
|
|
65
|
+
"non_empty_string": {
|
|
66
|
+
"type": "string",
|
|
67
|
+
"minLength": 2
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -11,6 +11,11 @@
|
|
|
11
11
|
"maxLength": 64,
|
|
12
12
|
"description": "unique id provided by client for request"
|
|
13
13
|
},
|
|
14
|
+
"brand_id": {
|
|
15
|
+
"type": ["string", "null"],
|
|
16
|
+
"maxLength": 64,
|
|
17
|
+
"description": "brand id for workflow to be run in context of a brand"
|
|
18
|
+
},
|
|
14
19
|
"name": {
|
|
15
20
|
"$ref": "#/definitions/non_empty_string",
|
|
16
21
|
"description": "name of workflow"
|
package/dist/signature.js
CHANGED
|
@@ -15,14 +15,15 @@ function get_path(url) {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
function get_request_signature(url, http_verb, content, headers, secret) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
18
|
+
var content_md5 = "";
|
|
19
|
+
var content_type = headers["Content-Type"] || "";
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
if (content) {
|
|
22
|
+
content_md5 = _crypto["default"].createHash("md5").update(content).digest("hex");
|
|
23
|
+
}
|
|
23
24
|
|
|
24
25
|
var request_uri = get_path(url);
|
|
25
|
-
var sign_string = http_verb + "\n" + content_md5 + "\n" +
|
|
26
|
+
var sign_string = http_verb + "\n" + content_md5 + "\n" + content_type + "\n" + headers["Date"] + "\n" + request_uri;
|
|
26
27
|
|
|
27
28
|
var hash = _crypto["default"].createHmac("sha256", secret).update(sign_string);
|
|
28
29
|
|