Mobile Number Authentication Using Truecaller.


Mobile Number Authentication Using Truecaller.

Table Of Contents:

  1. Create A Truecaller Developer Account

(1) Create A Truecaller Developer Account

https://sdk-console-noneu.truecaller.com/sign-up

(2) Create A New Project

(3) Add Credentials

  • You can find your package name from below location. Form your Android project.
app/build.gradle
  • You need to generate Debug signing certificate SHA-1:
cd android
./gradlew signingReport
  • Once you input your app details and create the app, you will be able to see a unique “ClientID” for your app which you need to include in your project to authorise all verification requests.

(4) Application Setup

Step-1: Ensure Minimum SDK Version (Mandatory if API < 24)
  • Ensure that your Minimum SDK version is at least API level 24 or above.
  • In case your android project compiles for API level below 24, you can include the following line in your AndroidManifest.xml file to avoid any compilation issues :
<uses-sdk tools:overrideLibrary="com.truecaller.android.sdk"/>
  • How To Check ?
  • Check minSdkVersion in build.gradle
  • Check In android\build.gradle
buildscript {
    ext {
        buildToolsVersion = "35.0.0"
        minSdkVersion = 24
        compileSdkVersion = 35
        targetSdkVersion = 34
        ndkVersion = "27.1.12297006"
        kotlinVersion = "2.0.21"
    }
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath("com.android.tools.build:gradle")
        classpath("com.facebook.react:react-native-gradle-plugin")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
        classpath("com.google.gms:google-services:4.4.2")
    }
}

apply plugin: "com.facebook.react.rootproject"
  • Your minSdkVersion is set to 24, meaning your project does not support API levels below 24.
  • No need to add the following line in AndroidManifest.xml:
Step-2: Add Truecaller SDK Dependency
  • Open your app-level build.gradle file (app/build.gradle) and add:
  • Path: android\app\build.gradle
dependencies {
    implementation "com.truecaller.android.sdk:truecaller-sdk:3.0.0"
}
Step-3: Ensure Java Compatibility
  • Inside the android{} section of your app-level build.gradle, add:
  • Path: android\app\build.gradle
android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}
Step-4: Add Maven Central Repository
  • Open your project-level build.gradle (build.gradle in the root folder) and ensure mavenCentral() is present:
  • Path: android\build.gradle
allprojects {
    repositories {
        google()
        mavenCentral()  // Add this if not already present
    }
}
Step-5: Check AGP & Gradle Version
  • Make sure your Android Gradle Plugin (AGP) version is 7.4.2 or higher and Gradle version is 7.5 or higher.

  • Open your gradle-wrapper.properties file (gradle/wrapper/gradle-wrapper.properties) and check:

  • android\gradle\wrapper\gradle-wrapper.properties
Step-6: Configure Client ID :
  1.  Open your strings.xml file. Example path: /app/src/main/res/values/strings.xml and add a new string with the name “clientID” and value as your “clientID”
<string name="clientID">YOUR_CLIENT_ID_HERE</string>

  2. Add Client ID in AndroidManifest.xml

  • Path: android\app\src\main\AndroidManifest.xml
<meta-data
    android:name="com.truecaller.android.sdk.ClientId"
    android:value="@string/clientID"/>

(5) Integration Successful.

Done! You have successfully integrated Truecaller SDK with OAuth in your Android app. 🚀

(6) Create a Native Module For Truecaller Authentication

  • Step-1: Create a new Kotlin file for Truecaller authentication
android/app/src/main/java/com/ammyai/truecaller/TruecallerModule.kt
  • Step-2: Add the following Kotlin code to handle Truecaller OAuth:
  • Replace the actual clientid in the code.
package com.ammyai.truecaller

import android.app.Activity
import android.content.Intent
import com.facebook.react.bridge.*
import com.truecaller.android.sdk.*

import java.math.BigInteger
import java.security.SecureRandom

class TruecallerModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext), TcOAuthCallback {

    private var promise: Promise? = null
    private var stateRequested: String? = null
    private var codeVerifier: String? = null

    override fun getName(): String {
        return "TruecallerAuth"
    }

    @ReactMethod
    fun isTruecallerInstalled(promise: Promise) {
        val sdk = TcSdk.getInstance()
        promise.resolve(sdk.isOAuthFlowUsable)
    }

    @ReactMethod
    fun login(promise: Promise) {
        val activity = currentActivity ?: run {
            promise.reject("NO_ACTIVITY", "Activity is null")
            return
        }

        this.promise = promise

        // Step 6: Generate unique state parameter
        stateRequested = BigInteger(130, SecureRandom()).toString(32)

        // Step 7: Generate unique code verifier
        codeVerifier = CodeVerifierUtil.generateRandomCodeVerifier()

        // Step 8: Generate code challenge
        val codeChallenge = CodeVerifierUtil.getCodeChallenge(codeVerifier)

        val options = TcSdkOptions.Builder(activity, this)
            .sdkKey("YOUR_CLIENT_ID")  // Replace with actual Client ID
            .setOAuthState(stateRequested)  // Step 6: Set state
            .setOAuthScopes(arrayOf("profile", "phone", "email"))  // Step 6: Request scopes
            .setCodeChallenge(codeChallenge ?: "")
            .buttonColor(Color.parseColor("#007AFF"))
            .buttonTextColor(Color.parseColor("#FFFFFF"))
            .loginTextPrefix(TcSdkOptions.LOGIN_TEXT_PREFIX_TO_GET_STARTED)
            .ctaText(TcSdkOptions.CTA_TEXT_CONTINUE)
            .buttonShapeOptions(TcSdkOptions.BUTTON_SHAPE_ROUNDED)
            .footerType(TcSdkOptions.FOOTER_TYPE_SKIP)
            .consentTitleOption(TcSdkOptions.SDK_CONSENT_TITLE_LOG_IN)
            .sdkOptions(TcSdkOptions.OPTION_VERIFY_ONLY_TC_USERS)
            .build()

        TcSdk.init(options) // Step 4: Initialize Truecaller SDK
        TcSdk.getInstance().launchTcOAuth(activity)
    }

    override fun onSuccess(tcOAuthData: TcOAuthData) {
        // Step 6: Validate state
        if (stateRequested != tcOAuthData.state) {
            promise?.reject("STATE_MISMATCH", "State validation failed.")
            return
        }

        // Step 9: Return authorization data
        promise?.resolve(Arguments.createMap().apply {
            putString("authorizationCode", tcOAuthData.authorizationCode)
            putString("state", tcOAuthData.state)
            putArray("scopesGranted", Arguments.fromList(tcOAuthData.scopesGranted))
        })
    }

    override fun onFailure(tcOAuthError: TcOAuthError) {
        promise?.reject(tcOAuthError.errorType.name, tcOAuthError.errorMessage)
    }

    @ReactMethod
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == TcSdk.SHARE_PROFILE_REQUEST_CODE) {
            TcSdk.getInstance().onActivityResultObtained(currentActivity, requestCode, resultCode, data)
        }
    }
}

(7) Register the Native Module in TruecallerPackage.kt

  • Create a new Kotlin file:
    📁 android/app/src/main/java/com/ammyai/truecaller/TruecallerPackage.kt
package com.ammyai.truecaller

import com.facebook.react.ReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ViewManager

class TruecallerPackage : ReactPackage {
    override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
        return listOf(TruecallerModule(reactContext))
    }

    override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
        return emptyList()
    }
}

(8) Link The Package In MainApplication.kt

  • Open 📁 android/app/src/main/java/com/ammyai/MainApplication.kt
    Add this inside getPackages() method:
packages.add(TruecallerPackage())

Leave a Reply

Your email address will not be published. Required fields are marked *