ayush
ayush

Reputation: 714

com.twilio.exception.ApiException: Invalid parameter: Spring Boot

I am working on a SpringBoot project, where I want to implement Mobile Number OTP Verification using Twilio. I am using the following versions-

  1. Spring: 6
  2. SpringBoot: 3.1.3
  3. Java: 17
  4. Twilio-
<dependency>
           <groupId>com.twilio.sdk</groupId>
           <artifactId>twilio</artifactId>
           <version>9.11.0</version>
       </dependency>

I referred the following docs and implemented accordingly-
https://www.twilio.com/docs/verify/api#user-verification-workflow and https://www.twilio.com/blog/phone-number-verification-java-spring-boot-verify-totp.

My code-
Config- I have verified all the ids and tokens


import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConfigurationProperties("twilio")
public class TwilioConfig {
    private String accountSid;
    private String authToken;
    private String trialNumber;

    private String messagingServiceSid;

    public void setAccountSid(String accountSid) {
        this.accountSid = accountSid;
    }

    public void setAuthToken(String authToken) {
        this.authToken = authToken;
    }

    public void setTrialNumber(String trialNumber) {
        this.trialNumber = trialNumber;
    }

    public void setMessagingServiceSid(String messagingServiceSid) {
        this.messagingServiceSid = messagingServiceSid;
    }

    public TwilioConfig(){

    }

    public String getAccountSid() {
        return accountSid;
    }

    public String getAuthToken() {
        return authToken;
    }

    public String getTrialNumber() {
        return trialNumber;
    }

    public String getMessagingServiceSid() {
        return messagingServiceSid;
    }


    @Override
    public String toString() {
        return "TwilioConfig{" +
                "accountSid='" + accountSid + '\'' +
                ", authToken='" + authToken + '\'' +
                ", trialNumber='" + trialNumber + '\'' +
                ", messagingServiceSid='" + messagingServiceSid + '\'' +
                '}';
    }
}

Twilio Initializer-

import com.twilio.Twilio;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

@Configuration
public class TwilioInitializer {

    Logger logger= LoggerFactory.getLogger(TwilioInitializer.class);

    private final TwilioConfig twilioConfig;

    @Autowired
    public TwilioInitializer(TwilioConfig twilioConfig) {
        this.twilioConfig = twilioConfig;
        logger.info("Initializing Twilio");
        Twilio.init(
                twilioConfig.getAccountSid(),
                twilioConfig.getAuthToken()
        );
        com.twilio.rest.verify.v2.Service service = com.twilio.rest.verify.v2.Service.creator("My First Verify Service").create();
        logger.info("Twilio initialized");

    }
}

and, Service-

import com.twilio.Twilio;
import com.twilio.rest.verify.v2.service.Verification;
import com.twilio.rest.verify.v2.service.VerificationCheck;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

@Service
public class SmsSenderImpl implements SmsSender {
    private final Logger logger = LoggerFactory.getLogger(SmsSenderImpl.class);

    private final TwilioConfig twilioConfig;

    @Autowired
    public SmsSenderImpl(TwilioConfig twilioConfig) {
        this.twilioConfig = twilioConfig;
    }

    @Override
    public void sendSms(SmsRequest smsRequest) {
        Twilio.init(twilioConfig.getAccountSid(), twilioConfig.getAuthToken());

        String phoneNumber = "+91" + smsRequest.getPhoneNumber().trim();
        try {
            logger.info("twilioConfig: " + twilioConfig);
            logger.info("Sending otp: " + smsRequest);
            Verification verification = Verification.creator(twilioConfig.getMessagingServiceSid(), // this is your verification sid
                    phoneNumber, //this is your Twilio verified recipient phone number
                    "sms" // this is your channel type
            ).create();

            logger.info("Verification status: " + verification.getStatus());

            logger.info("OTP has been successfully generated, and awaits your verification {}", LocalDateTime.now());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void verifyOTP(String otp, String to) {
        Twilio.init(twilioConfig.getAccountSid(), twilioConfig.getAuthToken());
        logger.info("Verifying otp: " + otp);

        try {

            VerificationCheck verificationCheck = VerificationCheck.creator(twilioConfig.getMessagingServiceSid()).setTo(to.trim()).setCode(otp.trim()).create();

            logger.info("verify otp, Verification status: " + verificationCheck.getStatus());

        } catch (Exception e) {
            e.printStackTrace();
        }

    }


}

Problem- When I use the method- sendSms in service layer, I get the following error-

com.twilio.exception.ApiException: Invalid parameter
    at com.twilio.rest.verify.v2.service.VerificationCreator.create(VerificationCreator.java:184)
    at com.twilio.rest.verify.v2.service.VerificationCreator.create(VerificationCreator.java:32)
    at com.twilio.base.Creator.create(Creator.java:40)

I have chosen the service-
Messaging->Services->New-Service-> Service Type- "Verify Users". enter image description here I am not able to understand where is the issue. I have also created a service on Twilio and tested it on using https://console.twilio.com/us1/develop/sms/try-it-out/send-an-sms. But, I am getting error in the code and I can't find the issue. Please help!

Upvotes: 0

Views: 469

Answers (1)

İsmail Y.
İsmail Y.

Reputation: 3965

You need to use a service SID that starts with VA.

You want to use the "Verify (VA)" service but you are using the SID for the "Messaging (MG)" service.

There are some more mistakes (if you don't do it on purpose);

  • Your TwilioInitializer class is creating a service for the Verify Service every time you run your code. If you do this on purpose, it's fine, but if you do it unknowingly; you don't need to create a service every time.

  • You only need to run the Twilio.init(...); block once, you don't need to run it in every method.

Upvotes: 1

Related Questions