@@ -58,8 +58,8 @@ interface ApiConfig {
5858 method: string
5959 headers: Record <string , string >
6060 body: string
61- response_path: string
6261 fallback_message: string
62+ response_mapping: Record <string , string > // Maps session variables to API response paths
6363}
6464
6565interface ButtonConfig {
@@ -156,8 +156,8 @@ const defaultApiConfig: ApiConfig = {
156156 method: ' GET' ,
157157 headers: {},
158158 body: ' ' ,
159- response_path : ' ' ,
160- fallback_message: ' '
159+ fallback_message : ' ' ,
160+ response_mapping: {}
161161}
162162
163163const defaultTransferConfig: TransferConfig = {
@@ -274,7 +274,8 @@ async function openEditDialog(flow: ChatbotFlow) {
274274 api_config: {
275275 ... defaultApiConfig ,
276276 ... (s .api_config || s .ApiConfig || {}),
277- headers: (s .api_config || s .ApiConfig || {}).headers || {}
277+ headers: (s .api_config || s .ApiConfig || {}).headers || {},
278+ response_mapping: (s .api_config || s .ApiConfig || {}).response_mapping || {}
278279 },
279280 buttons: s .buttons || s .Buttons || [],
280281 transfer_config: {
@@ -350,6 +351,28 @@ function removeStepHeader(stepIndex: number, key: string) {
350351 delete formData .value .steps [stepIndex ].api_config .headers [key ]
351352}
352353
354+ // Step API response mapping helpers
355+ function addStepResponseMapping(stepIndex : number ) {
356+ const step = formData .value .steps [stepIndex ]
357+ if (! step .api_config .response_mapping ) {
358+ step .api_config .response_mapping = {}
359+ }
360+ const mappingNum = Object .keys (step .api_config .response_mapping ).length + 1
361+ step .api_config .response_mapping [` var_${mappingNum } ` ] = ' '
362+ }
363+
364+ function updateStepResponseMappingKey(stepIndex : number , oldKey : string , newKey : string ) {
365+ if (oldKey === newKey ) return
366+ const step = formData .value .steps [stepIndex ]
367+ const value = step .api_config .response_mapping [oldKey ]
368+ delete step .api_config .response_mapping [oldKey ]
369+ step .api_config .response_mapping [newKey ] = value
370+ }
371+
372+ function removeStepResponseMapping(stepIndex : number , key : string ) {
373+ delete formData .value .steps [stepIndex ].api_config .response_mapping [key ]
374+ }
375+
353376function removeStep(index : number ) {
354377 formData .value .steps .splice (index , 1 )
355378 // Reorder remaining steps
@@ -767,14 +790,17 @@ function removeButton(step: FlowStep, index: number) {
767790 </Select >
768791 </div >
769792
770- <!-- Static Message (for text type ) -->
771- <div v-if =" step.message_type !== 'api_fetch'" class =" space-y-2" >
793+ <!-- Static Message (for text, buttons, whatsapp_flow types - not api_fetch which has its own template section ) -->
794+ <div v-if =" step.message_type !== 'api_fetch' && step.message_type !== 'transfer' " class =" space-y-2" >
772795 <Label >Message to Send *</Label >
773796 <Textarea
774797 v-model =" step.message"
775798 placeholder =" What is your name?"
776799 :rows =" 2"
777800 />
801+ <p v-if =" step.message_type === 'text' || step.message_type === 'buttons'" class =" text-xs text-muted-foreground" >
802+ Use <code v-pre class =" bg-muted px-1 rounded" >{{variable}}</code > for dynamic values from session data
803+ </p >
778804 </div >
779805
780806 <!-- Buttons Configuration (for buttons type) -->
@@ -845,7 +871,7 @@ function removeButton(step: FlowStep, index: number) {
845871 v-model =" step.api_config.url"
846872 placeholder =" https://api.example.com/data/{{customer_id}}"
847873 />
848- <p class =" text-xs text-muted-foreground" >Use {{variable}} to include session data</p >
874+ <p class =" text-xs text-muted-foreground" >Use < code v-pre class = " text-xs bg-muted px-1 rounded " > {{variable}}</ code > to include session data</p >
849875 </div >
850876 </div >
851877
@@ -881,7 +907,7 @@ function removeButton(step: FlowStep, index: number) {
881907 </div >
882908 </div >
883909 <p class =" text-xs text-muted-foreground" >
884- Add custom headers like Authorization, API keys. Use {{variable}} for dynamic values.
910+ Add custom headers like Authorization, API keys.
885911 </p >
886912 </div >
887913
@@ -894,23 +920,76 @@ function removeButton(step: FlowStep, index: number) {
894920 />
895921 </div >
896922
897- <div class = " grid grid-cols-2 gap-4 " >
898- <div class =" space-y-2" >
899- < Label >Response Path</ Label >
900- <Input
901- v-model = " step.api_config.response_path "
902- placeholder = " data.message "
903- />
904- <p class = " text-xs text-muted-foreground " >Dot notation path to extract message (e.g., data.message)</ p >
923+ <!-- Response Mapping -- >
924+ <div class =" space-y-2 border-t pt-4 " >
925+ < div class = " flex items-center justify-between " >
926+ <Label >Response Mapping (extract API data)</ Label >
927+ < Button variant = " outline " size = " sm " @click = " addStepResponseMapping(index) " >
928+ < Plus class = " h-3 w-3 mr-1 " />
929+ Add Mapping
930+ </ Button >
905931 </div >
906- <div class =" space-y-2" >
907- <Label >Fallback Message</Label >
908- <Input
909- v-model =" step.api_config.fallback_message"
910- placeholder =" Sorry, we couldn't fetch your data."
911- />
912- <p class =" text-xs text-muted-foreground" >Sent if API call fails</p >
932+ <div v-if =" step.api_config.response_mapping && Object.keys(step.api_config.response_mapping).length > 0" class =" space-y-2" >
933+ <div
934+ v-for =" (value, key) in step.api_config.response_mapping"
935+ :key =" key"
936+ class =" flex items-center gap-2"
937+ >
938+ <Input
939+ :model-value =" key"
940+ placeholder =" Variable name"
941+ class =" flex-1"
942+ @update:model-value =" updateStepResponseMappingKey(index, key as string, $event)"
943+ />
944+ <span class =" text-muted-foreground" >=</span >
945+ <Input
946+ v-model =" step.api_config.response_mapping[key as string]"
947+ placeholder =" API path (e.g., data.user.name)"
948+ class =" flex-1"
949+ />
950+ <Button variant =" ghost" size =" icon" @click =" removeStepResponseMapping(index, key as string)" >
951+ <Trash2 class =" h-4 w-4 text-destructive" />
952+ </Button >
953+ </div >
913954 </div >
955+ <p class =" text-xs text-muted-foreground" >
956+ Map API response fields to session variables for use in the message template below.
957+ <br />
958+ Example: <code v-pre class =" text-xs bg-muted px-1 rounded" >name</code > = <code class =" text-xs bg-muted px-1 rounded" >data.client.name</code >,
959+ <code v-pre class =" text-xs bg-muted px-1 rounded" >positions</code > = <code class =" text-xs bg-muted px-1 rounded" >data.portfolio.items</code >
960+ </p >
961+ </div >
962+
963+ <!-- Message Template -->
964+ <div class =" space-y-2 border-t pt-4" >
965+ <Label >Message Template *</Label >
966+ <Textarea
967+ v-model =" step.message"
968+ placeholder =" Hi {{name}}, here are your positions:
969+
970+ {{for pos in positions}}
971+ - {{pos.symbol}}: {{pos.quantity}} @ ₹{{pos.price}}
972+ {{if pos.is_loss}} ⚠️ Loss: ₹{{pos.loss}}
973+ {{else}} ✅ Profit: ₹{{pos.profit}}
974+ {{endif}}{{endfor}}"
975+ :rows =" 6"
976+ />
977+ <div class =" text-xs text-muted-foreground space-y-1" >
978+ <p ><strong >Template Syntax:</strong ></p >
979+ <p >• Variables: <code v-pre class =" bg-muted px-1 rounded" >{{name}}</code >, <code v-pre class =" bg-muted px-1 rounded" >{{user.profile.email}}</code ></p >
980+ <p >• Conditionals: <code v-pre class =" bg-muted px-1 rounded" >{{if is_premium}}...{{else}}...{{endif}}</code ></p >
981+ <p >• Comparisons: <code v-pre class =" bg-muted px-1 rounded" >{{if amount > 100}}</code >, <code v-pre class =" bg-muted px-1 rounded" >{{if status == 'active'}}</code ></p >
982+ <p >• Loops: <code v-pre class =" bg-muted px-1 rounded" >{{for item in items}}...{{endfor}}</code ></p >
983+ </div >
984+ </div >
985+
986+ <div class =" space-y-2 border-t pt-4" >
987+ <Label >Fallback Message</Label >
988+ <Input
989+ v-model =" step.api_config.fallback_message"
990+ placeholder =" Sorry, we couldn't fetch your data."
991+ />
992+ <p class =" text-xs text-muted-foreground" >Sent if API call fails</p >
914993 </div >
915994 </div >
916995
0 commit comments