I'm using Botpress to implement a custom chatbot solution. I have a file upload custom component which has to accept a file and send it to my server with an authentication header. My custom component needs to have an accessToken in order to call the upload API. And this token is available in the chatbot flow as a session variable.
I found out that I can pass a session variable value from the flow to my custom component by using an action. And this is what I did:
- Created the action, content-type and custom component.
- Added the action to my flow to render the custom component.
- Pass the token from the action to the component.
- Custom component sees the passed data as undefined. And if I console.log "this.props" I'm not seeing the passed data at all.
Action:
const displayFileUpload = async () => {
try {
// Fetch options from session.options or build the list here
const options = { 'accessToken':session.accessToken }
// Generate the payload with your options
const payloads = await bp.cms.renderElement('file-upload', options, event)
// Send the final payloads to the user
await bp.events.replyToEvent(event, payloads)
}
catch (error) {
console.log(error)
const payload = await bp.cms.renderElement('builtin_text', { text: 'Error ' }, event)
await bp.events.replyToEvent(event, payload)
}
}
return displayFileUpload()
Content Type:
"use strict";
function render(data) {
return [{
type: 'custom',
module: 'custom-component',
component: 'FileUpload',
options: data.options
}];
}
function renderElement(data, channel) {
if (channel === 'web' || channel === 'api') {
return render(data);
}
return []; // TODO
}
module.exports = {
id: 'file-upload',
group: 'Custom Component',
title: 'File Upload',
jsonSchema: {
description: 'File Upload',
type: 'object',
properties: {
options: {
type: 'object',
title: 'Access token',
}
}
},
uiSchema: {},
computePreviewText: formData => 'File Upload: ' + formData.text,
renderElement: renderElement
};
File Upload - Custom Component
import React from 'react'
import { FilePond } from 'react-filepond';
import 'filepond/dist/filepond.min.css';
export class FileUpload extends React.Component {
state = {
uploaded: false
}
componentDidMount() {
console.log('FileUpload was mounted')
console.log(this.props.options)
}
render() {
return (
<div className="FileUpload">
<p className="App-intro">
_____ File D Picker _____
</p>
<FilePond
maxFiles={1}
onupdatefiles={fileItems => {
if (this.state.uploaded == false) {
this.setState({
uploaded: true
});
this.props.onSendData({ type: 'text', text: 'File Uploaded' })
}
}}
/>
</div>
)
}
}