-
Notifications
You must be signed in to change notification settings - Fork 1
/
api-interface.txt
148 lines (113 loc) · 3.91 KB
/
api-interface.txt
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
We are writing a framework for building USSD applications in nodejs. Write out routing module syntax for the following:
# Features
* Validation
* Easy routing
* Session management via redis
# Routing
* Automatic handling of back accounts
Menus.add(cls, name).name("test")
.actions([..action objects])
.back("home")
.addAction({..action object})
Menus.name("test")
.actions([..action objects])
.back("home")
.addAction({..action object})
# Router Syntax
Router.menu("home", {
"1": "home",
"2": "about",
"3": "contact"
})
Router.menu("__main_menu__")
// .back("goodbye_route" || USSD_EXIT)
.option([
# Each option can have 'route' (and 'display') field, redirects to another menu or 'action', returned by a class
# 'display' field to display static information
{"choice": "1", "route"?: "transfer_money", action?: TransferMoneyAction()},
{"choice": "2", "route": "my_wallet", display: "My Wallet"},
{"choice": "3", "route": "exit_app", action: ExitAppAction()}
])
Router.menu("my_wallet")
.back("goodbye_route)
.option([
# 'method' field for directly calling a function in a class
# 'validation' field for validating user input
{
"choice": "1",
"id": "transfer_money",
action?: TransferMoneyAction(),
method?: 'startInit',
validation?: 'regex-expression' | async function() => boolean,
# next menu to show after receiving the input. should it be named 'next_menu'?
redirect_to?: 'enter_wallet_pin_1'
},
{"choice": "2", "id": "my_wallet", action: MyWalletAction()}
{"choice": "3", "id": "exit_app", action: ExitAppAction()}
])
# Form Syntax
Router.menu("my_wallet")
.back("goodbye_route)
.isForm("my_wallet_form")
.option([
# 'method' field for directly calling a function in a class
# 'validation' field for validating user input
{
"choice": "1",
"id": "transfer_money",
action?: TransferMoneyAction(),
method?: 'startInit',
validation?: 'regex-expression' | async function() => boolean,
# next menu to show after receiving the input. should it be named 'next_menu'?
redirect_to?: 'enter_wallet_pin_1'
},
{"choice": "2", "id": "my_wallet", action: MyWalletAction()}
# For form route, the last option is always the submit option
# it'll have all the fields & response in the form
{"choice": "3", "id": "exit_app", action: ExitAppAction()}
])
# Action Syntaxi
class MyAction extends Action {
message?: () => string?
# basically all useful hooks from rejoice framework
}
# Form Action
class MyFormAction extends FormAction {
inputs () => Map<{key: string, value: string, is_valid: boolean}>
message?: () => string?
# basically all usefull hooks from rejoice framework
}
# Middleware Syntax/flow
class Middleware {
handleRequest(req: Request, resp: Response, next: NextFunction){
# extract ussd params from request body/parameters/json/form-data
# extract session from redis
next()
}
handleResponse(req: Request, resp: Response, next: NextFunction){
# pick data from session, eg. req.session
# AND
# return response based on the expected format of the ussd gateway
}
}
class AfricasTalkingMiddleware extends Middleware {
# basically all usefull hooks from rejoice framework
}
Japap Plugin
==============
* use macros
scorpionClient({url, config: {..same config}, provider?, phone?, sessionId?})
scorpion.config({..same config})
scorpion.setProvider()
.setSessionId()
.setPhone()
.setUrl()
.setSession()
scorpion.input(1).input(2)
scorpion.steps([1, 3, 4, 3324454, 4434])
.text() -> return response text visible to the user
.rawResponse -> return raw response
-> assertions
.assertStatus
.assertText
.assertTextIncludes