voicebot-react-native-expo
Version:
This is a voicebot-react-native package of Kipps AI voice bot for React Native Expo
169 lines (153 loc) • 4.73 kB
JavaScript
import React, { useState, useEffect } from "react";
import { View, Text, TouchableOpacity, StyleSheet, Alert,Linking } from "react-native";
import { LiveKitRoom, useLocalParticipant,AudioSession } from "@livekit/react-native";
import { Ionicons } from "@expo/vector-icons"; // For microphone and stop icons
import { Audio } from 'expo-av';
const ActiveRoom = ({ token, setToken }) => {
const { localParticipant, isMicrophoneEnabled } = useLocalParticipant();
useEffect(() => {
let start = async () => {
await AudioSession.startAudioSession();
};
start();
return () => {
AudioSession.stopAudioSession();
};
}, []);
const toggleMicrophone = () => {
localParticipant.setMicrophoneEnabled(!isMicrophoneEnabled);
};
return (
<View style={styles.activeRoomContainer}>
{/* <RoomAudioRenderer /> */}
<View style={styles.controlContainer}>
<Ionicons
name={isMicrophoneEnabled ? "mic-outline" : "mic-off-outline"}
size={40}
color={isMicrophoneEnabled ? "blue" : "red"}
onPress={toggleMicrophone}
/>
<Ionicons
name="stop-circle-outline"
size={40}
color="red"
onPress={() => setToken(null)}
/>
</View>
</View>
);
};
const VoiceBotButton = (props) => {
const [token, setToken] = useState(null);
const [url, setUrl] = useState(null);
const voicebot_id=props.voicebot_id
const caller_id=props.caller_id
const caller_name=props.caller_name
useEffect(() => {
const requestMicrophonePermission = async () => {
const { status } = await Audio.requestPermissionsAsync(); // Request microphone permission
if (status !== 'granted') {
Alert.alert('Permission Denied', 'Microphone access is required for the app to function.');
}
};
requestMicrophonePermission();
}, []);
useEffect(() => {
const handleDeepLink = (event) => {
const { url } = event;
if (url && url.includes("start")) {
handleCallPress();
}
};
const linkingSubscription = Linking.addEventListener("url", handleDeepLink);
Linking.getInitialURL().then((url) => {
if (url && url.includes("start")) {
handleCallPress();
}
});
return () => {
linkingSubscription.remove();
};
}, []);
const handleCallPress = async () => {
try {
const response = await fetch("https://backend.kipps.ai/speech/web-call/", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
voicebot: voicebot_id,
caller_id: caller_id,
caller_name: caller_name,
}),
});
if (!response.ok) {
throw new Error('Failed to fetch token');
}
const { accessToken, url: roomUrl } = await response.json();
// console.log("Access Token:", accessToken);
// console.log("Room URL:", roomUrl);
setToken(accessToken);
setUrl(roomUrl);
} catch (error) {
console.error("Error during call:", error);
Alert.alert("Error", "Failed to initiate the call. Please try again.");
}
};
return (
<View style={styles.container}>
{token === null ? (
<TouchableOpacity style={styles.callButton} onPress={handleCallPress}>
<Text style={styles.callText}>Call Valet</Text>
<Ionicons name="call-outline" size={24} color="white" />
</TouchableOpacity>
) : (
<LiveKitRoom
token={token}
serverUrl={url}
connectOptions={{ autoSubscribe: true }}
>
<ActiveRoom token={token} setToken={setToken} />
</LiveKitRoom>
)}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#f5f5f5",
},
callButton: {
backgroundColor: "blue",
padding: 20,
width: 300,
borderRadius: 10,
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
},
callText: {
color: "white",
marginRight: 10,
fontSize: 18,
},
activeRoomContainer: {
backgroundColor: "#AAFFE5",
padding: 10,
paddingBottom: 20,
width: 300,
borderWidth: 1,
borderColor: "#5AFF15",
borderRadius: 20,
},
controlContainer: {
flexDirection: "row",
justifyContent: "space-around",
marginTop: 20,
},
});
export default VoiceBotButton;