Dialogflow API Chatbot for React Native in Expo - react-native

I am learning react native as beginner.
I want to create a chatbot using Dialogflow in react native in Expo.
I have searched all the forums and googled , but did not find any reference of using Dialogflow specifically to Expo though found reference to React Native CLI.
In this context, can anyone please guide me how to create a chatbot using Dialogflow in Expo React Native

Here you will have a great tutorial!
https://blog.jscrambler.com/build-a-chatbot-with-dialogflow-and-react-native/
if this help you please check it as correct answer...
here bellow some code:
import React, { Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { GiftedChat } from 'react-native-gifted-chat';
import { Dialogflow_V2 } from 'react-native-dialogflow';
import { dialogflowConfig } from './env';
const BOT_USER = {
_id: 2,
name: 'FAQ Bot',
avatar: 'https://i.imgur.com/7k12EPD.png'
};
class App extends Component {
state = {
messages: [
{
_id: 1,
text: `Hi! I am the FAQ bot 🤖 from Jscrambler.\n\nHow may I help you with today?
`,
createdAt: new Date(),
user: BOT_USER
}
]
};
componentDidMount() {
Dialogflow_V2.setConfiguration(
dialogflowConfig.client_email,
dialogflowConfig.private_key,
Dialogflow_V2.LANG_ENGLISH_US,
dialogflowConfig.project_id
);
}
handleGoogleResponse(result) {
let text = result.queryResult.fulfillmentMessages[0].text.text[0];
this.sendBotResponse(text);
}
onSend(messages = []) {
this.setState(previousState => ({
messages: GiftedChat.append(previousState.messages, messages)
}));
let message = messages[0].text;
Dialogflow_V2.requestQuery(
message,
result => this.handleGoogleResponse(result),
error => console.log(error)
);
}
sendBotResponse(text) {
let msg = {
_id: this.state.messages.length + 1,
text,
createdAt: new Date(),
user: BOT_USER
};
this.setState(previousState => ({
messages: GiftedChat.append(previousState.messages, [msg])
}));
}
render() {
return (
<View style={{ flex: 1, backgroundColor: '#fff' }}>
<GiftedChat
messages={this.state.messages}
onSend={messages => this.onSend(messages)}
user={{
_id: 1
}}
/>
</View>
);
}
}
export default App;

Related

Issue sending & receiving streams between two clients in LiveKit's React Native SDK

I'm trying to build on the example app provided by livekit, so far I've implemented everything like the example app and I've been successful with connecting to a room on example website, I recieve audio from website, but I don't read the video stream, and I also can't send audio or video at all.
Steps to reproduce the behavior:
add the following to index.js
import { registerRootComponent } from "expo";
import { registerGlobals } from "livekit-react-native";
import App from "./App";
registerRootComponent(App);
registerGlobals();
Rendering the following component in App.tsx
import { Participant, Room, Track } from "livekit-client";
import {
useRoom,
useParticipant,
AudioSession,
VideoView,
} from "livekit-react-native";
import { useEffect, useState } from "react";
import { Text, ListRenderItem, StyleSheet, FlatList, View } from "react-native";
import { ParticipantView } from "./ParticipantView";
import { RoomControls } from "./RoomControls";
import type { TrackPublication } from "livekit-client";
const App = () => {
// Create a room state
const [, setIsConnected] = useState(false);
const [room] = useState(
() =>
new Room({
publishDefaults: { simulcast: false },
adaptiveStream: true,
})
);
// Get the participants from the room
const { participants } = useRoom(room);
const url = "[hard-coded-url]";
const token =
"[hard-coded-token";
useEffect(() => {
let connect = async () => {
// If you wish to configure audio, uncomment the following:
await AudioSession.configureAudio({
android: {
preferredOutputList: ["speaker"],
},
ios: {
defaultOutput: "speaker",
},
});
await AudioSession.startAudioSession();
await room.connect(url, token, {});
await room.localParticipant.setCameraEnabled(true);
await room.localParticipant.setMicrophoneEnabled(true);
await room.localParticipant.enableCameraAndMicrophone();
console.log("connected to ", url);
setIsConnected(true);
};
connect();
return () => {
room.disconnect();
AudioSession.stopAudioSession();
};
}, [url, token, room]);
// Setup views.
const stageView = participants.length > 0 && (
<ParticipantView participant={participants[0]} style={styles.stage} />
);
const renderParticipant: ListRenderItem<Participant> = ({ item }) => {
return (
<ParticipantView participant={item} style={styles.otherParticipantView} />
);
};
const otherParticipantsView = participants.length > 0 && (
<FlatList
data={participants}
renderItem={renderParticipant}
keyExtractor={(item) => item.sid}
horizontal={true}
style={styles.otherParticipantsList}
/>
);
const { cameraPublication, microphonePublication } = useParticipant(
room.localParticipant
);
return (
<View style={styles.container}>
{stageView}
{otherParticipantsView}
<RoomControls
micEnabled={isTrackEnabled(microphonePublication)}
setMicEnabled={(enabled: boolean) => {
room.localParticipant.setMicrophoneEnabled(enabled);
}}
cameraEnabled={isTrackEnabled(cameraPublication)}
setCameraEnabled={(enabled: boolean) => {
room.localParticipant.setCameraEnabled(enabled);
}}
onDisconnectClick={() => {
// navigation.pop();
console.log("disconnected");
}}
/>
</View>
);
};
function isTrackEnabled(pub?: TrackPublication): boolean {
return !(pub?.isMuted ?? true);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
},
stage: {
flex: 1,
width: "100%",
},
otherParticipantsList: {
width: "100%",
height: 150,
flexGrow: 0,
},
otherParticipantView: {
width: 150,
height: 150,
},
});
export default App;
the components used here are mostly the same as what's in the example, I've removed the screensharing logic and the messages
5. I run the app using an expo development build
6. it will log that it's connected, you'll be able to hear sound from the remote participant, but not see any video or send any sound.
7. if i try to add
await room.localParticipant.enableCameraAndMicrophone();
in the useEffect, I get the following error:
Possible Unhandled Promise Rejection (id: 0):
Error: Not implemented.
getSettings#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:103733:24
#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:120307:109
generatorResume#[native code]
asyncGeneratorStep#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:21908:26
_next#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:21927:29
#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:21932:14
tryCallTwo#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:26656:9
doResolve#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:26788:25
Promise#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:26675:14
#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:21924:25
#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:120173:52
generatorResume#[native code]
asyncGeneratorStep#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:21908:26
_next#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:21927:29
tryCallOne#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:26648:16
#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:26729:27
#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:27687:26
_callTimer#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:27602:17
_callReactNativeMicrotasksPass#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:27635:17
callReactNativeMicrotasks#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:27799:44
__callReactNativeMicrotasks#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:21006:46
#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:20806:45
__guard#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:20986:15
flushedQueue#http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:20805:21
flushedQueue#[native code]
Expected behavior
This should both receive & send video and audio streams between the two clients

Card with FlatList React native

im trying to achieve message view by using card with flatlist how can i arrange few elements of my flat list the left screen right screen.
I want the green card to be on the left side of the screen
You can use react-native-gifted-chat for your desired result.
npm install react-native-gifted-chat --save
import React, { useState, useCallback, useEffect } from 'react'
import { GiftedChat } from 'react-native-gifted-chat'
export function Example() {
const [messages, setMessages] = useState([]);
useEffect(() => {
setMessages([
{
_id: 1,
text: 'Hello developer',
createdAt: new Date(),
user: {
_id: 2,
name: 'React Native',
avatar: 'https://placeimg.com/140/140/any',
},
},
])
}, [])
const onSend = useCallback((messages = []) => {
setMessages(previousMessages => GiftedChat.append(previousMessages, messages))
}, [])
return (
<GiftedChat
messages={messages}
onSend={messages => onSend(messages)}
user={{
_id: 1,
}}
/>
)
}

Uhandled atob variable on screen rendering

The error I get is [Unhandled promise rejection: ReferenceError: Can't find variable: atob].
And my screen code:
import React, { Component } from "react";
import { View, StatusBar, Text } from "react-native";
import firebase from "firebase";
import "firebase/firestore";
import { RowItem } from "../components/RowItem";
import { Header, Left, Right, Icon } from "native-base";
const styles = {
container: {
flexDirection: "row",
flexWrap: "wrap",
padding: 20
}
};
class QuizIndex extends Component {
constructor(props) {
super(props);
this.state = {
docs: []
};
}
async componentDidMount() {
await this.quizes();
}
quizes = async () => {
let result = await firebase
.firestore()
.collection("quiz")
.where("parentId", "==", "")
.get()
.then(r => {
console.log("fine");
})
.catch(e => {
console.log("Not fine");
});
const docs = result.docs.map(doc => {
return { uid: doc.id, ...doc.data() };
});
return this.setState({ docs });
};
render() {
return (
<View style={styles.container}>
<StatusBar barStyle="dark-content" />
{this.state.docs.map(doc => (
<RowItem
key={doc.uid}
parentId={doc.parentId}
name={doc.title}
color={doc.color}
icon={doc.icon}
onPress={() =>
this.props.navigation.navigate("QuizSub", {
title: doc.title,
color: doc.color,
parentId: doc.uid
})
}
/>
))}
</View>
);
}
}
export default QuizIndex;
I don't get it where this problem occur because the things were working fine. Do you have any suggestion about this ? I googled it but none of the solutions helped me.
It's an issue in firebase dependency
Try to use version 7.9.0, this version will work fine.
yarn add firebase#7.9.0
I think if you install the base-64 npm package it will solve, but don't quite know why this is happening.
yarn add base-64
#or
npm install base-64
At App.js add:
import {decode, encode} from 'base-64'
if (!global.btoa) { global.btoa = encode }
if (!global.atob) { global.atob = decode }

Tour view does not have React internal Fiber

I want implementation app-tour in my project , I installed react-native-app-tour .I have a View that I want assign app-tour to it and I use ref in view that it dispatch AppTourView to inputreducer and finally in useEffect I run appTour but when I run app I encountered Error that error is Tour view does not have React internal Fiber, please can help me
import React, {
useState,
useEffect,
useCallback,
useReducer,
useRef,
} from 'react';
import {AppTour, AppTourSequence, AppTourView} from 'react-native-app-tour';
const inputReducer = (state, action) => {
if (action.type == 'SET_APPTOUR') {
return [...state.appTour, action.data];
}
};
export default function HomeScreen(props) {
const [forsat, setForSat] = useState(null);
const [appTourTargets, dispatchAppTour] = useReducer(inputReducer, {
appTour: [],
});
useEffect(() => {
setTimeout(() => {
console.log(appTourTargets);
let appTourSequence = new AppTourSequence();
appTourTargets.appTour.forEach(appTourTarget => {
appTourSequence.add(appTourTarget);
});
AppTour.ShowSequence(appTourSequence);
}, 1000);
}, [appTourTargets]);
return(
<view style={styles.container}>
<View
ref={useCallback(ref => {
if (!ref) return;
setForSat(ref);
let prop = {
order: 12,
title: 'This is a target View',
description: 'We have the best targets, believe me',
outerCircleColor: '#3f52ae',
cancelable: false,
};
dispatchAppTour({type:'SET_APPTOUR', data:AppTourView.for(ref, {...prop})});
}, [])}
style={styles.rankContainer}>
<BText font="_Light" size={15} color={color.firstColor}>
فرصت{' '}
<BText font="_Bold" color={color.secondColor} size={15}>
{FormatHelper.toPersianString(daysToGo.toString())}
</BText>{' '}
روز تا کنکور
</BText>
</View>
</view>
)
}

Lodash debounce not working all of a sudden?

I'm using a component I wrote for one app, in a newer app. The code is like 99% identical between the first app, which is working, and the second app. Everything is fine except that debounce is not activating in the new app. What am I doing wrong?
// #flow
import type { Location } from "../redux/reducers/locationReducer";
import * as React from "react";
import { Text, TextInput, View, TouchableOpacity } from "react-native";
import { Input } from "react-native-elements";
import { GoogleMapsApiKey } from "../../.secrets";
import _, { debounce } from "lodash";
import { connect } from "react-redux";
import { setCurrentRegion } from "../redux/actions/locationActions";
export class AutoFillMapSearch extends React.Component<Props, State> {
textInput: ?TextInput;
state: State = {
address: "",
addressPredictions: [],
showPredictions: false
};
async handleAddressChange() {
console.log("handleAddressChange");
const url = `https://maps.googleapis.com/maps/api/place/autocomplete/json?key=${GoogleMapsApiKey}&input=${this.state.address}`;
try {
const result = await fetch(url);
const json = await result.json();
if (json.error_message) throw Error(json.error_message);
this.setState({
addressPredictions: json.predictions,
showPredictions: true
});
// debugger;
} catch (err) {
console.warn(err);
}
}
onChangeText = async (address: string) => {
await this.setState({ address });
console.log("onChangeText");
debounce(this.handleAddressChange.bind(this), 800); // console.log(debounce) confirms that the function is importing correctly.
};
render() {
const predictions = this.state.addressPredictions.map(prediction => (
<TouchableOpacity
style={styles.prediction}
key={prediction.id}
onPress={() => {
this.props.beforeOnPress();
this.onPredictionSelect(prediction);
}}
>
<Text style={text.prediction}>{prediction.description}</Text>
</TouchableOpacity>
));
return (
<View>
<TextInput
ref={ref => (this.textInput = ref)}
onChangeText={this.onChangeText}
value={this.state.address}
style={[styles.input, this.props.style]}
placeholder={"Search"}
autoCorrect={false}
clearButtonMode={"while-editing"}
onBlur={() => {
this.setState({ showPredictions: false });
}}
/>
{this.state.showPredictions && (
<View style={styles.predictionsContainer}>{predictions}</View>
)}
</View>
);
}
}
export default connect(
null,
{ setCurrentRegion }
)(AutoFillMapSearch);
I noticed that the difference in the code was that the older app called handleAddressChange as a second argument to setState. Flow was complaining about this in the new app so I thought async/awaiting setState would work the same way.
So changing it to this works fine (with no flow complaints for some reason. maybe because I've since installed flow-typed lodash. God I love flow-typed!):
onChangeText = async (address: string) => {
this.setState(
{ address },
_.debounce(this.handleAddressChange.bind(this), 800)
);
};