Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not able to receive calls in react-native app. #428

Open
siddiquesheikh30 opened this issue Sep 23, 2024 · 5 comments
Open

Not able to receive calls in react-native app. #428

siddiquesheikh30 opened this issue Sep 23, 2024 · 5 comments

Comments

@siddiquesheikh30
Copy link

siddiquesheikh30 commented Sep 23, 2024

Issue

I need guidance on receiving incoming calls and making outgoing calls using Twilio and React Native. Could you provide more detailed steps or support on setting this up?
for your info, I can provide you with my node Js backend code:

const express = require("express");
const twilio = require("twilio");
const cors = require("cors"); // Import cors
const bodyParser = require("body-parser");
const app = express();
const port = 3000; // You can change the port if necessary
const { VoiceResponse } = require("twilio").twiml;
// Twilio credentials
const accountSid = "Twilio Account SID"; // Twilio Account SID
const apiKey = "Twilio API Key SID"; // Twilio API Key SID
const apiSecret = "Twilio API Secret"; // Twilio API Secret
const outgoingApplicationSid = "TwiML App SID"; // TwiML App SID

const client = twilio(accountSid, "Auth token");
// Add CORS middleware
let corsOptions = {
  origin: true, // This allows all origins
};
app.use(cors(corsOptions));
app.use(
  bodyParser.urlencoded({
    extended: true,
  })
);
// parse application/json
app.use(bodyParser.json());
// Route to generate Twilio token
const identity = "client:username"; // Change this to a unique identity

app.get("/token", (req, res) => {
  // Identity could be unique per user; for testing, use 'client:username'

  // Create a new Voice Grant
  const VoiceGrant = twilio.jwt.AccessToken.VoiceGrant;
  const voiceGrant = new VoiceGrant({
    outgoingApplicationSid: outgoingApplicationSid,
    incomingAllow: true, // Allow incoming calls
  });

  // Create a new Access Token
  const AccessToken = twilio.jwt.AccessToken;
  const token = new AccessToken(accountSid, apiKey, apiSecret, { identity });
  token.addGrant(voiceGrant);

  // Serialize the token to a JWT
  const accessToken = token.toJwt();
  res.json({ token: accessToken });
});

app.post("/voice", (req, res) => {
  const { To, From } = req.body;
  console.log("to,from", req.body);
  const response = new VoiceResponse();

  const dial = response.dial({ callerId: From });
  dial.number(To);

  res.set("Content-Type", "text/xml");
  res.send(response.toString());
});

// Start the server
app.listen(port, () => {
  console.log(`Server is running on http://localhost:${port}`);
});

And also I can give you my Front-end react-native code also:

import { useEffect, useState } from 'react';
import { SafeAreaView, Text, TextInput, TouchableOpacity, View } from 'react-native';
import { Voice } from '@twilio/voice-react-native-sdk';
import axios from 'axios';
import messaging from '@react-native-firebase/messaging';
import { Alert } from 'react-native';

function App() {
  const [screenName, setScreenName] = useState('');
  const [token, setToken] = useState('');
  const [voiceInstance, setVoiceInstance] = useState<any>(null);
  const [toNumber, setToNumber] = useState('+919405237197');
  const [fromNumber, setFromNumber] = useState('+447446527790');
  const [baseUrl, setBaseUrl] = useState(
    'https://d660-103-190-12-135.ngrok-free.app',
  );

  const handleToken = async () => {
    const response: any = await axios.get(baseUrl + '/token');
    console.log('response?.data?.token', response?.data?.token);
    setToken(response?.data?.token);
  };

  async function requestUserPermission() {
    const authStatus = await messaging().requestPermission();
    const enabled =
      authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
      authStatus === messaging.AuthorizationStatus.PROVISIONAL;

    if (enabled) {
      console.log('Authorization status:', authStatus);
    }
  }

  useEffect(() => {
    requestUserPermission();
    const unsubscribe = messaging().onMessage(async remoteMessage => {
      Alert.alert('A new FCM message arrived!', JSON.stringify(remoteMessage));
    });

    return unsubscribe;
  }, []);

  useEffect(() => {
    handleToken();
  }, []);
  // Handle incoming calls
  useEffect(() => {
    if (token) {
      const instance = new Voice();

      // Allow incoming calls
      instance.register(token);

      // Handle incoming calls
      instance.on(Voice.Event.CallInvite, (callInvite: any) => {
        console.log('Incoming call invite received:', callInvite);
        if (callInvite) {
          callInvite.accept(); // Accept the incoming call
          console.log('Call accepted');
        } else {
          console.error('No callInvite received');
        }
      });

      instance.on(Voice.Event.Registered, () => {
        console.log('Device registered successfully for incoming calls.');
      });
      instance.on(Voice.Event.Error, error => {
        console.error('Error during call event:', error);
      });

      setVoiceInstance(instance);

      // return () => {
      //   instance
      //     .unregister(token)
      //     .then(() => {
      //       console.log('Device unregistered successfully.');
      //     })
      //     .catch(error => {
      //       console.error('Error unregistering device:', error);
      //     });
      // };
    }
  }, [token]);

  return (
    <SafeAreaView>
      <View
        style={{
          display: 'flex',
          backgroundColor: 'black',
          height: '100%',
          padding: 10,
          alignItems: 'center',
          justifyContent: 'center',
        }}>
        <TextInput
          style={{
            height: 40,
            margin: 12,
            borderWidth: 1,
            padding: 10,
            backgroundColor: 'white',
            borderRadius: 10,
            width: 200,
            color: 'black'
          }}
          onChangeText={setToNumber}
          value={toNumber}
          placeholder="To"
          placeholderTextColor='black'
        />
        <TextInput
          style={{
            height: 40,
            margin: 12,
            borderWidth: 1,
            padding: 10,
            backgroundColor: 'white',
            borderRadius: 10,
            width: 200,
            color: 'black'
          }}
          onChangeText={setFromNumber}
          value={fromNumber}
          placeholder="From"
          placeholderTextColor='black'
        />
        <TouchableOpacity
          onPress={async () => {
            await voiceInstance.connect(token, {
              params: {
                To: toNumber,
                From: fromNumber,
              },
            }).then((res: any) => { console.log("Request Successfull" + JSON.stringify(res)) }).catch((err: any) => {
              console.log(err)
            })
          }}
          style={{
            backgroundColor: 'white',
            padding: 10,
            borderRadius: 10,
            width: 100,
            margin: 10,
          }}>
          <Text style={{ color: 'black', fontWeight: 700, textAlign: 'center' }}>
            Call
          </Text>
        </TouchableOpacity>
      </View>
    </SafeAreaView>
  );
}
export default App;

The above code is my react-native code when I try to make an outbound call from my app using Twilio number to the verified number given in the code:
the response I am getting on my server console is also given below:

to,from {
  ApplicationSid: '*********',
  ApiVersion: '2010-04-01',
  Called: '',
  Caller: 'client:client:username',
  CallStatus: 'ringing',
  From: '+447446527790',
  To: '+9194******97',
  CallSid: 'CA7a376ab036bae5e8ee9b66b2bc7a8aa6',
  Direction: 'inbound',
  AccountSid: '****'
}

As we can see here we are making an outbound call but getting Direction as 'inbound' but I can still call this number so can you please help me understand this? Also, what do I do to make an incoming call successful here and show it in the react-native app that I am receiving a call and can receive it? I am also adding call logs of my Twilio call logs so that you can see I can make calls here but please help make an app that can receive incoming calls also.

Software and Device Information

Please complete the following information.

  • Device: [Samsung Galaxy A51]
  • React version: [18.3.1]
  • React Native version: [0.75.2]
  • @twilio/voice-react-native-sdk: [^1.1.1]
    WhatsApp Image 2024-09-23 at 3 12 12 PM
@mhuynh5757
Copy link
Collaborator

Hello @siddiquesheikh30 you have some personal info in your code blocks that you might want to redact, including your account SIDs and phone numbers. Also, please format your code blocks using triple backticks.

@siddiquesheikh30
Copy link
Author

siddiquesheikh30 commented Sep 24, 2024

Hi @mhuynh5757, I have updated it also I understood why it is saying Direction: 'inbound' it is because:
caller---- parent call ----> Twilio ---- child call ----> Called
okay, but I want to see incoming calls here what particular changes do I have to make in my node Js server and also in my react-native code?

@mhuynh5757
Copy link
Collaborator

Hi @siddiquesheikh30 have you seen our reference app that utilizes this SDK? https://github.com/twilio/twilio-voice-react-native-app

It may provide some help and inspiration for getting incoming calls working in your application.

@siddiquesheikh30
Copy link
Author

siddiquesheikh30 commented Oct 4, 2024

Yes, hi @mhuynh5757 thank you, the incoming calls are working, but please tell me how to switch the mobile speaker on/off, hold/uphold the call, and mute/unmute the call. I have gone through https://github.com/twilio/twilio-voice-react-native-app this reference app but I am still unable to find the solution so if possible, please provide me the required methods to use.

@mhuynh5757
Copy link
Collaborator

Hi @siddiquesheikh30 that repo has examples on how to mute/unmute a call, as well as hold/resume a call. Here are some relevant links.

For hold functionality: https://github.com/twilio/twilio-voice-react-native-app/blob/main/app/src/store/voice/call/activeCall.ts#L181

For mute functionality: https://github.com/twilio/twilio-voice-react-native-app/blob/main/app/src/store/voice/call/activeCall.ts#L145

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants