androidtexttwilioclovertwilio-functions

Twilio sending texts on android problems


am creating an android app for school which will need to send text messages. I have had twilio recommended by several people so I decided to go with it. Following this tutorial: https://www.twilio.com/blog/2016/05/how-to-send-an-sms-from-android.html , with my own android app and the one including I am getting a 404 when post is called (seen through ngrok). I am at a complete loss, still new to android. The backend gives the following message through intellij: 8810 [qtp649044888-15] INFO spark.http.matching.MatcherFilter - The requested route [/] has not been mapped in Spark for Accept: [null]

Account IDs, addresses, phone numbers, etc. replaced with x's Backend:

//Heroku assigns different port each time, hence reading it from process.
        ProcessBuilder process = new ProcessBuilder();
        Integer port;
        if (process.environment().get("PORT") != null) {
            port = Integer.parseInt(process.environment().get("PORT"));
        } else {
            port = 4567;
        }
        Spark.port(port);


        get("/", (req, res) -> "Hello, World");

        TwilioRestClient client = new TwilioRestClient.Builder(System.getenv("ACxxxxxxx72279fb226f0dd162c869ce1e"), System.getenv("xxxxxxxc324a89155b93b5af26393297")).build();

        post("/sms", (req, res) -> {
            String body = req.queryParams("Body");
            String to = req.queryParams("To");
            String from = System.getenv("216450xxxx");

            Message message = new MessageCreator(
                    new PhoneNumber(to),
                    new PhoneNumber(from),
                    body).create(client);

            return message.getSid();
        });

App- post method

Call post(String url, Callback callback) throws IOException {
        RequestBody formBody = new FormBody.Builder().add("To", "609420xxxx").add("Body", "TEST").build();
        Request request = new Request.Builder().url(url).post(formBody).build();
        Call response = mClient.newCall(request);
        response.enqueue(callback);
        Log.d("CALL: ", response.toString()+ "     " + callback.toString());
        return response;
    }

App post method on button:

emailButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    post("http://xxxxxxxx.ngrok.io", new  Callback(){
                        @Override
                        public void onFailure(Call call, IOException e) {
                            e.printStackTrace();
                        }

                        @Override
                        public void onResponse(Call call, Response response) throws IOException {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Toast.makeText(getApplicationContext(),"SMS Sent!",Toast.LENGTH_SHORT).show();
                                }
                            });
                        }

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

            }
        });

This should be sending a text to my number (verified on twilio account), but I get nothing. The toast does appear saying the text has been sent.


Solution

  • Looking at the spark source code for MatcherFilter the only reference to the error you are getting is thrown when the body is not set

    if (body.notSet()) {
        LOG.info("The requested route [{}] has not been mapped in Spark for {}: [{}]",
                 uri, ACCEPT_TYPE_REQUEST_MIME_HEADER, acceptType);
    

    Looking at the Twilio tutorial you linked to (assuming your supplied code is exactly what you are using) it seems that you have altered the code to hard code your variables into classes and methods.

    I don't know much about coding for Android, but I can tell you that this line in the tutorial references an environment variable within the project containing the Twilio account SID

    (System.getenv("TWILIO_ACCOUNT_SID")
    

    Now here's your version:

    (System.getenv("ACxxxxxxx72279fb226f0dd162c869ce1e")
    

    An environment variable is a variable which is set once, usually in a file containing all the other environment variables and is specific to the user or system the code is running on. These allow developers to easily change user or syystem specific variable values even if they have referenced these variables many times within a project.

    You are attempting to reference an environment variable, but then supplying a value you wish to use. It doesn't work like that.

    Here's your app post on button method:

    post("http://xxxxxxxx.ngrok.io", new  Callback(){
    

    Here's Twilio's:

    post(mContext.getString("YOUR_NGROK_URL/sms"), new  Callback(){
    

    Your hardcoded url drops the reference to the mContext variable, I don't know if that matters, but the other thing you have overlooked is you need to add /sms to the end of your URL.

    My recommendation, seeing as you are just starting out with Android would be to follow tutorials to the letter for now. It might seem like you are saving time cutting some corners and changing a few bits here and there, but then when it doesn't work you don't have the experience to understand what is wrong.

    Cutting corners, hard coding variables etc is a bad habit to get in to anyway. We've all done it, then we've all regretted it later. Learn properly, code properly, add comments explaining your code and you'll save yourself countless hours of future frustration.