Code Monkey home page Code Monkey logo

twilio-java's Introduction

twilio-java

Tests Maven Central Learn with TwilioQuest

Documentation

The documentation for the Twilio API can be found here.

The Java library documentation can be found here.

Versions

twilio-java uses a modified version of Semantic Versioning for all changes. See this document for details.

TLS 1.2 Requirements

New accounts and subaccounts are now required to use TLS 1.2 when accessing the REST API. "Upgrade Required" errors indicate that TLS 1.0/1.1 is being used.

Supported Java Versions

This library supports the following Java implementations:

  • OpenJDK 8
  • OpenJDK 11
  • OpenJDK 17
  • OracleJDK 8
  • OracleJDK 11
  • OracleJDK 17

For Java 7 support, use twilio-java major version 7.X.X.

Installation

twilio-java uses Maven. At present the jars are available from a public maven repository.

Use the following dependency in your project to grab via Maven:

<dependency>
  <groupId>com.twilio.sdk</groupId>
  <artifactId>twilio</artifactId>
  <version>10.X.X</version>
  <scope>compile</scope>
</dependency>

or Gradle:

implementation "com.twilio.sdk:twilio:10.X.X"

If you want to compile it yourself, here's how:

git clone [email protected]:twilio/twilio-java
cd twilio-java
mvn install       # Requires maven, download from https://maven.apache.org/download.html

If you want to build your own .jar, execute the following from within the cloned directory:

mvn package

If you run into trouble with local tests, use:

mvn package -Dmaven.test.skip=true

Test your installation

Try sending yourself an SMS message, like this:

import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.Message;
import com.twilio.type.PhoneNumber;

public class Example {

  // Find your Account Sid and Token at console.twilio.com
  public static final String ACCOUNT_SID = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
  public static final String AUTH_TOKEN = "your_auth_token";

  public static void main(String[] args) {
    Twilio.init(ACCOUNT_SID, AUTH_TOKEN);

    Message message = Message
      .creator(
        new PhoneNumber("+15558675309"),
        new PhoneNumber("+15017250604"),
        "This is the ship that made the Kessel Run in fourteen parsecs?"
      )
      .create();

    System.out.println(message.getSid());
  }
}

Warning It's okay to hardcode your credentials when testing locally, but you should use environment variables to keep them secret before committing any code or deploying to production. Check out How to Set Environment Variables for more information.

Usage

Initialize the Client

import com.twilio.Twilio;
import com.twilio.exception.AuthenticationException;

public class Example {

  private static final String ACCOUNT_SID =
    "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
  private static final String AUTH_TOKEN = "your_auth_token";

  public static void main(String[] args) throws AuthenticationException {
    Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
  }
}

Initialize the client when endpoints does not use basic authentication

The above example shows how to initialize the client in case the endpoints use basic authentication. When the endpoint does not require any authentication, use TwilioNoAuth client instead. There are endpoints like Organization domain which uses bearer token authentication. Custom Clients needs to be used in such cases and initialize them with the values required for access token generation.

To bypass the initialization step you can also use a custom token manager implementation. Token manager class should implement the Token interface and call a token generation endpoint of your choice. Detailed examples here

Environment Variables

twilio-java supports the credentials, region, and edge values stored in the following environment variables:

  • TWILIO_ACCOUNT_SID
  • TWILIO_AUTH_TOKEN
  • TWILIO_REGION
  • TWILIO_EDGE

If using these variables, the above client initialization can be skipped.

Make a Call

import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.Call;
import com.twilio.type.PhoneNumber;
import java.net.URI;
import java.net.URISyntaxException;

public class Example {

  public static final String ACCOUNT_SID = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
  public static final String AUTH_TOKEN = "your_auth_token";

  public static void main(String[] args) throws URISyntaxException {
    Twilio.init(ACCOUNT_SID, AUTH_TOKEN);

    Call call = Call
      .creator(
        new PhoneNumber("+14155551212"),
        new PhoneNumber("+15017250604"),
        new URI("http://demo.twilio.com/docs/voice.xml")
      )
      .create();

    System.out.println(call.getSid());
  }
}

Get an existing Call

import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.Call;

public class Example {

  public static final String ACCOUNT_SID = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
  public static final String AUTH_TOKEN = "your_auth_token";

  public static void main(String[] args) {
    Twilio.init(ACCOUNT_SID, AUTH_TOKEN);

    Call call = Call.fetcher("CA42ed11f93dc08b952027ffbc406d0868").fetch();

    System.out.println(call.getTo());
  }
}

Iterate through records

The library automatically handles paging for you. With the read method, you can specify the number of records you want to receive (limit) and the maximum size you want each page fetch to be (pageSize). The library will then handle the task for you, fetching new pages under the hood as you iterate over the records.

For more information, view the auto-generated library docs.

Use the read method

import com.twilio.Twilio;
import com.twilio.base.ResourceSet;
import com.twilio.rest.api.v2010.account.Call;

public class Example {

  public static final String ACCOUNT_SID = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
  public static final String AUTH_TOKEN = "your_auth_token";

  public static void main(String[] args) {
    Twilio.init(ACCOUNT_SID, AUTH_TOKEN);

    ResourceSet<Call> calls = Call.reader().read();

    for (Call call : calls) {
      System.out.println(call.getDirection());
    }
  }
}

Specify Region and/or Edge

To take advantage of Twilio's Global Infrastructure, specify the target Region and/or Edge for the client:

Twilio.init(accountSid, authToken);
Twilio.setRegion("au1");
Twilio.setEdge("sydney");

This will result in the hostname transforming from api.twilio.com to api.sydney.au1.twilio.com.

Enable Debug Logging

This library uses SLF4J for logging. Consult the SFL4J documentation for information about logging configuration.

For example, if you are using log4j:

  • Make sure you have log4j-slf4j-impl, log4j-core and log4j-api in your pom.xml file

  • Define the logging level for the Twilio HTTP client in your configuration. For example, in src/main/resources/log4j2.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="WARN">
        <Appenders>
            <Console name="Console" target="SYSTEM_OUT">
                <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level - %msg%n"/>
            </Console>
        </Appenders>
        <Loggers>
            <!--Your Twilio logging configuration goes here-->
            <Logger name="com.twilio.http" level="debug" additivity="false">
                <AppenderRef ref="Console"/>
            </Logger>
            <Root level="info">
                <AppenderRef ref="Console"/>
            </Root>
        </Loggers>
    </Configuration>

Handle Exceptions

import com.twilio.exception.ApiException;

try {
    Message message = Message.creator(
        new PhoneNumber("+15558881234"),  // To number
        new PhoneNumber("+15559994321"),  // From number
        "Hello world!"                    // SMS body
    ).create();

    System.out.println(message.getSid());
} catch (final ApiException e) {
    System.err.println(e);
}

Use a Client With PKCV Authentication

Additional documentation here: https://twilio.com/docs/iam/pkcv/quickstart

ValidationClient httpClient = new ValidationClient(ACCOUNT_SID, key.getSid(), signingKey.getSid(), pair.getPrivate());
TwilioRestClient client = new TwilioRestClient.Builder(signingKey.getSid(), signingKey.getSecret())
    .accountSid(ACCOUNT_SID)
    .httpClient(httpClient)
    .build();

Generate TwiML

To control phone calls, your application needs to output TwiML.

TwiML in twilio-java now use the builder pattern!

TwiML twiml = new VoiceResponse.Builder()
    .say(new Say.Builder("Hello World!").build())
    .play(new Play.Builder("https://api.twilio.com/cowbell.mp3").loop(5).build())
    .build();

That will output XML that looks like this:

<Response>
    <Say>Hello World!</Say>
    <Play loop="5">https://api.twilio.com/cowbell.mp3</Play>
</Response>

Use a custom HTTP Client

To use a custom HTTP client with this helper library, please see the advanced example of how to do so.

Docker image

The Dockerfile present in this repository and its respective twilio/twilio-java Docker image are currently used by Twilio for testing purposes only.

Getting Help

If you need help installing or using the library, please check the Twilio Support Help Center first, and file a support ticket if you don't find an answer to your question.

If you've instead found a bug in the library or would like new features added, go ahead and open issues or pull requests against this repo!

twilio-java's People

Contributors

alexpayment avatar asabuhere avatar beans0063 avatar christerf avatar codejudas avatar codylerum avatar dependabot[bot] avatar dougblack avatar eanderle avatar eshanholtz avatar frankstratton avatar gbin avatar gramanathaiah avatar ilanbiala avatar jennifermah avatar jingming avatar jmctwilio avatar juggernaut avatar jwitz10 avatar krisgutta avatar kwhinnery avatar kyleconroy avatar ragil avatar sbansla avatar senthgit avatar skimbrel avatar sullis avatar thinkingserious avatar twilio-ci avatar twilio-dx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

twilio-java's Issues

Java 5 support

Can we update the library to support Java 5 or build a separate Java 5 version?

The Java 5 dependencies are as follows:

jackson-mapper-asl-1.9.12.jar
jackson-core-asl-1.9.12.jar
httpclient-4.2.5.jar
httpclient-cache-4.2.5.jar
httpcore-4.2.4.jar
httpmime-4.2.5.jar
commons-codec-1.6.jar
commons-lang-2.3.jar
commons-lang3-3.1.jar

Not sure why both commons-lang jars are required, but project doesn't compile if one is taken out.

Implement a Twilio-specific runtime exception

There are places in code like this:

https://github.com/twilio/twilio-java/blob/master/src/main/java/com/twilio/sdk/TwilioRestClient.java#L428

where checked exceptions are wrapped in generic RuntimeException.

If instead these were wrapped in e.g. a TwilioRestRuntimeException this would allow code calling the API to catching these exceptions instead of having to catch RuntimeException.

http://forum.twilio.com/twilio/topics/please_fix_your_java_libraries_to_correctly_use_checked_exceptions

Tag 3.10 release

Hi, I saw that the latest version in pom.xml is 3.3.10-SNAPSHOT. Can you add a git tag for this 3.3.10 release?

Thanks,
Kevin

JSON library dependency?

Should the required JSON library actually be the json-simple-1.1.jar? See TwilioCapability.java below:

import org.json.simple.JSONValue;

/**
 * This class represents a token that will grant someone access to resources
 * within Twilio.
 */
public class TwilioCapability {

ivy.xml could use this...

<dependency org="com.googlecode.json-simple" name="json-simple" rev="1.1" />

Thanks!

Update IncomingPhoneNumber for subaccount?

Probably my fault, but when I try to update a phone number, I get an "Authenticate" error. I can get the call to work in APIGEE. I'm trying to update a number's URLs, and said number belongs to a subaccount. I authenticate the client with the master account, then ask for numbers for the subaccount. I even tried to add the AccountSid parameter manually (which is the subaccount's sid?). Do you see what I'm doing wrong? Thanks!

    /* Top level account is needed for this */
    TwilioRestClient client = new TwilioRestClient(
            Credentials.TWILIO_MASTER_ACCOUNT_SID, Credentials.TWILIO_MASTER_AUTH_TOKEN);

    Account TwilioSubAccount = client.getAccount(Credentials.TWILIO_SUBACCOUNT_SID);
    IncomingPhoneNumberList list = TwilioSubAccount.getIncomingPhoneNumbers();

    String sid = null;
    for (IncomingPhoneNumber phoneNumber : list) {
        if (phoneNumber.getPhoneNumber().equals(number)) {
            Logger.info("Found matching number for subaccount, it's SID is: "
                    + phoneNumber.getSid());
            Logger.info("Number we found: " + phoneNumber.getPhoneNumber());
            Logger.info("Number voice url (current): "
                    + phoneNumber.getVoiceUrl());
            sid = phoneNumber.getSid();
        }
    }

    IncomingPhoneNumber phoneNumber = new IncomingPhoneNumber(client,
            Credentials.TWILIO_SUBACCOUNT_SID);

    Map<String, String> params = new HashMap<String, String>();
    params.put("AccountSid", Credentials.TWILIO_SUBACCOUNT_SID);
    params.put("VoiceUrl", "my new url");
    params.put("VoiceMethod", "GET");
    params.put("StatusCallback", "my new url");
    params.put("StatusCallbackMethod", "GET");

    try {
        phoneNumber.update(params);
        Logger.info("Updated phone number successfully");
    } catch (TwilioRestException e1) {
        Logger.info("Error updating phone number");
        e1.printStackTrace();
        return false;
    }
    return true;

Deprecated ThreadSafeClientConnManager constructor causes problems in Android

It looks like Android OS does not include deprecated methods/constructors from Apache HttpClient 4.

http://developer.android.com/reference/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.html

As a result a runtime exception is encountered when the Twilio Java helper library is used, similar to this:

E/AndroidRuntime(618): java.lang.NoSuchMethodError: org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager.
E/AndroidRuntime(618): at com.twilio.sdk.TwilioRestClient.(TwilioRestClient.java:137)
E/AndroidRuntime(618): at com.twilio.sdk.TwilioRestClient.(TwilioRestClient.java:108)

If we can remove references to deprecated methods/constructors it should improve the experience of using Twilio Java helper library in Android OS.

UsageRecord isn't prepared for new categories to appear

When you ask for the category on a usage record, it performs a lookup using the UsageCategory enum. Here are the relevant lines:

public UsageCategory getCategory() {
    return UsageCategory.valueOf(getProperty("Category").replace('-', '_'));
}

The problem is this throws an IllegalArgumentException when it encounters a category that isn't in the enum. Right now (2013-10-08) the API is returning a category named "calls_sip" which isn't in the enum in the current version of the code (enum last updated in commit d9cf649).

Here is the exact stack trace:


java.lang.IllegalArgumentException: No enum const class com.twilio.sdk.resource.instance.UsageCategory.calls_sip
    at java.lang.Enum.valueOf(Enum.java:196)
    at com.twilio.sdk.resource.instance.UsageCategory.valueOf(UsageCategory.java:10)
    at com.twilio.sdk.resource.instance.UsageRecord.getCategory(UsageRecord.java:70)
    (called from my code)

This means that whenever a new stats category is added, the existing Java code can suddenly start to error out where it worked before. I'd suggest putting a try/catch around the valueOf and returning null if it's not in the enum. At least it could be documented (say with Javadoc) that this may occur.

Minor POM Correction

groupid should be groupId (with capital "I")
artifactid should be artifactId (with capital "I")

Remove test code from precompiled jar

It appears that the precompiled binary for Twilio contains library code to support tests, such as the EasyMock classes. As you are using EasyMock 2.4, this makes it impossible to use EasyMock 3.0 or later with the Twilio jars. Presumably the production Twilio jar should not include tests, so removing the EasyMock classes from the binary would:

(1) Decrease the size of the binary.
(2) Make it easier to use a newer version of EasyMock alongside Twilio.

EasyMock 3.0 and later has important class extensions.

Maven repository?

It'll be awesome if you can put this library in a maven repository.
Thanks.

Error with Eclipse- Web Application

I get the below error i have added the required jar file but still get the below errror

Caused by:

java.lang.NoClassDefFoundError: com/twilio/sdk/TwilioRestException
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2483)
at java.lang.Class.getConstructor0(Class.java:2793)
at java.lang.Class.newInstance(Class.java:345)
at org.mortbay.jetty.servlet.Holder.newInstance(Holder.java:153)
at org.mortbay.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:428)
at org.mortbay.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:339)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:123)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:63)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectRequest(DevAppServerModulesFilter.java:368)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectModuleRequest(DevAppServerModulesFilter.java:351)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doFilter(DevAppServerModulesFilter.java:116)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:97)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:485)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:547)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Caused by: java.lang.ClassNotFoundException: com.twilio.sdk.TwilioRestException
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at com.google.appengine.tools.development.IsolatedAppClassLoader.loadClass(IsolatedAppClassLoader.java:215)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 42 more
Caused by:

java.lang.ClassNotFoundException: com.twilio.sdk.TwilioRestException
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at com.google.appengine.tools.development.IsolatedAppClassLoader.loadClass(IsolatedAppClassLoader.java:215)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2483)
at java.lang.Class.getConstructor0(Class.java:2793)
at java.lang.Class.newInstance(Class.java:345)
at org.mortbay.jetty.servlet.Holder.newInstance(Holder.java:153)
at org.mortbay.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:428)
at org.mortbay.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:339)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:123)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:63)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectRequest(DevAppServerModulesFilter.java:368)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectModuleRequest(DevAppServerModulesFilter.java:351)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doFilter(DevAppServerModulesFilter.java:116)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:97)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:485)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:547)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

SmsFactory.create(Map params) doesn't handle exceptions properly

InstanceResource.getProperty(String name) throws an IllegalArgumentException, when it should return an error code/status code instead. For instance, if the SMS message is too long, an exception is never thrown.

Add the following around line 71 of InstanceResource.java to fix the problem:

            if (prop instanceof Integer) {
                    return String.valueOf(prop);
            }

Java Sms resource throws NullPointerException for null date properties

The Java client library class com.twilio.sdk.resource.instance.Sms has 3 get date methods, none of which are null safe. The code as it is currently written is:

    public Date getDateCreated() {
        SimpleDateFormat format = new SimpleDateFormat(
                "EEE, dd MMM yyyy HH:mm:ss Z");
        try {
            return format.parse(this.getProperty("date_created"));
        } catch (ParseException e) {
            return null;
        }
    }

If the "date_created" property is null, SimpleDateFormat.parse() will throw a NullPointerException, not a ParseException.

I suggest doing a null check first on the result of the this.getProperty("date_created") call and return null if it is null:

    public Date getDateCreated() {
        String dateCreated = this.getProperty("date_created");
        if (dateCreated == null) {
            return null;
        }
        try {
            SimpleDateFormat format = new SimpleDateFormat(
                "EEE, dd MMM yyyy HH:mm:ss Z");
            return format.parse(dateCreated);
        } catch (ParseException e) {
            return null;
        }
    }

You will need to make this fix to all three methods that return dates, getDateCreated(), getDateUpdated(), and getDateSent().

Which also leads me to suggest extracting the common code out to a single method that takes the property name as an argument so that you don't have so much code duplication.

Constructors for resource instances must not accept null Sid

Currently, if you accidentally pass in a null for the sid in the constructor of a Resource, e.g. Call and try to do call.getSid() for example, it will fail with a StackOverflow exception due to a null property indicating the need to load the property. And the load in its turn is referencing getResourceLocation which calls getSid which calls getProperty which call load() which calls getResourceLocation etc...

AccountList error

Copied the code example verbatim, and get an error while trying to list accounts in JUnit:

Code:
AccountList accountList = client.getAccounts();

Stack:
java.lang.NoSuchMethodError: org.codehaus.jackson.type.JavaType.getHandler()Ljava/lang/Object;
at org.codehaus.jackson.map.deser.BasicDeserializerFactory.createMapDeserializer(BasicDeserializerFactory.java:202)
at org.codehaus.jackson.map.deser.StdDeserializerProvider._createDeserializer(StdDeserializerProvider.java:253)
at org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCacheValueDeserializer(StdDeserializerProvider.java:198)
at org.codehaus.jackson.map.deser.StdDeserializerProvider.findValueDeserializer(StdDeserializerProvider.java:100)
at org.codehaus.jackson.map.ObjectMapper._findRootDeserializer(ObjectMapper.java:1347)
at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:1280)
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:883)
at com.twilio.sdk.parser.JsonResponseParser.parseJson(JsonResponseParser.java:34)
at com.twilio.sdk.parser.JsonResponseParser.parse(JsonResponseParser.java:20)
at com.twilio.sdk.TwilioRestResponse.toMap(TwilioRestResponse.java:245)
at com.twilio.sdk.resource.list.AccountList.create(AccountList.java:60)
at integrations.TwilioAPI.createSubAccount(TwilioAPI.java:108)

Verbs don't escape the body for XML embedding

I'm trying to reply to incoming SMS messages, and I'm using the SMS verb.

The constructor for SMS passes the body directly to the body field in the Verb base class. The toXML() on the base Verb class looks like this:

public String toXML(){
        String xml = "<" + this.tag;

        for (String key : attributes.keySet()) {
            xml += " " + key + "=\"" + attributes.get(key) + "\"";
        }

        xml += ">";

        if(this.body != null)
            xml += this.body;

        for (Verb child : children){
            xml += child.toXML();
        }

        return xml += "</" + this.tag + ">";
}

This doesn't escape the body element at all. Here is a simple test case:

TwiMLResponse twiml = new TwiMLResponse();

Sms sms = new Sms("I enjoy peanut butter & jelly");

twiml.append(sms);

System.out.println(twiml.toXML());

That produces the following output:

<Response><Sms>I enjoy peanut butter & jelly</Sms></Response>

I expected:

<Response><Sms>I enjoy peanut butter &amp; jelly</Sms></Response>

It's not escaping the string passed it. I think the principal of least surprise would suggest that the string be automatically be escaped. At the least an alternate constructor could be provided which would automatically escape the content.

Library does not work on Google App Engine

We should subclass the TwilioRestClient with a TwilioAppEngineRestClient or something that uses the java.net.URL class instead of org.apache.HttpClient, which is not supported on App Engine.

bug in httpclient 4.1.2 can cause problems for other libraries

httpclient 4.1.2 has a bug in SSL certificate checking. the bug is somewhat confusingly documented here:
https://issues.apache.org/jira/browse/HTTPCLIENT-1118
and it causes exceptions that look like this:
javax.net.ssl.SSLException: hostname in certificate didn't match: <www.google.com/173.194.75.105> != <www.google.com>

From what I can tell, the bug only manifests for callers of a deprecated API and does not affect the twilio sdk. However, many other libraries use httpclient, including some that still call the deprecated API. This means that introducing the twilio sdk to a project may cause other libraries in the project to break.

I was able to work around the issue by forcing my project to use 4.2.1 (4.1.3 has the same bug as 4.1.2). So changing the SDK dependency to 4.2.1+ or 4.1.1- are both possible solutions (I'm not sure about the implications of going back to 4.1.1 for twilio).

Account.getSid() returns the main account SID instead of its own SID

            TwilioRestClient client = new TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN);
            AccountList accountList = client.getAccounts();
            for (Account account : accountList) {
                    System.out.println(account.getFriendlyName() + " " + account.getSid());
            }

When iterating through the account list resource with the snippet above, Account.getSid() returns the requestAccountSid instead of account.getProperty("sid").

JDK 1.5 Support

Is it possible to get support for Java5 with this library?

remove the references to ThreadSafeClientConnManager in TwilioRestClient.java

How to remove the reference to ThreadSafeClientConnManager since Android OS does not include deprecated methods/constructors from Apache HttpClient 4. and how to build prebuilt version of the library. I dont know how to use maven.
Because if i am using twilio sms in android iam getting following error.

E/AndroidRuntime(618): java.lang.NoSuchMethodError: org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager.
E/AndroidRuntime(618): at com.twilio.sdk.TwilioRestClient.(TwilioRestClient.java:137)
E/AndroidRuntime(618): at com.twilio.sdk.TwilioRestClient.(TwilioRestClient.java:108)

Removal of subaccounts?

I do not see delete methods for removing subaccounts, maybe something like setStatus(boolean), based on the REST API docs. Is this is there, or do I have to build a request?

Getting non-null price returns error

Trying to send an SMS internationally resulted in the following error when attempting to retrieve the price:

getObject is protected and there is no way to access it.

Caused by: java.lang.IllegalArgumentException: Property price is an object. Use getObject() instead.
at com.twilio.sdk.resource.InstanceResource.getProperty(InstanceResource.java:70)
at com.twilio.sdk.resource.instance.Sms.getPrice(Sms.java:172)
at com.xoom.sms.twilio.transform.TwilioSmsResourceTransformer.getPrice(TwilioSmsResourceTransformer.java:32)
at com.xoom.sms.twilio.transform.TwilioSmsResourceTransformer.transform(TwilioSmsResourceTransformer.java:25)
at com.xoom.sms.service.send.SmsTemplateProcessingSendingService.send(SmsTemplateProcessingSendingService.java:42)
at com.xoom.sms.service.notification.XferSmsNotificationServiceImpl.sendSms(XferSmsNotificationServiceImpl.java:59)
at com.xoom.sms.service.notification.XferSmsNotificationServiceImpl.notify(XferSmsNotificationServiceImpl.java:50)

call.getStatus() results in com.twilio.sdk.TwilioRestException: Authenticate

When I do:

      TwilioRestClient client = new TwilioRestClient(accountSid, authToken);
      Call call = client.getAccount().getCall(callSid);
      System.out.println(call.getStatus());

I get:

    Exception in thread "main" java.lang.RuntimeException: com.twilio.sdk.TwilioRestException: Authenticate
        at com.twilio.sdk.resource.InstanceResource.getProperty(InstanceResource.java:56)
        at com.twilio.sdk.resource.instance.Call.getStatus(Call.java:158)
        at Test.main(Test.java:13)
    Caused by: com.twilio.sdk.TwilioRestException: Authenticate
        at com.twilio.sdk.TwilioRestException.parseResponse(TwilioRestException.java:74)
        at com.twilio.sdk.TwilioRestClient.safeRequest(TwilioRestClient.java:484)
        at com.twilio.sdk.resource.Resource.load(Resource.java:50)
        at com.twilio.sdk.resource.InstanceResource.getProperty(InstanceResource.java:53)
        ... 2 more

The RequestAccountSid is not set when getStatus() is called, resulting in path:
/2010-04-01/Accounts/null/Calls/xxxxxxx.json"

Fix:
Change com.twilio.sdk.resource.instance.Account.getCall(String) to look like this:

    public Call getCall(String sid) {
        Call call = new Call(this.getClient(), sid);
        call.setRequestAccountSid(getRequestAccountSid());
        return call;
    }

CallList.create is hard coded to use Post method

The CallList.create method is hard coded to use Post. Unfortunately, this won't work if the TwiML files are on S3 for example.

It would be great if the method could be set in the paramters map.

mvn install fails on Mountain Lion 10.8

I cannot build local jars with 3.3.9, master or twilio-java-sdk-3.3.10.

git co twilio-java-sdk-3.3.10
mvn install

... skipping output...
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.twilio.sdk.resource.instance.MemberTest
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.32 sec
Running com.twilio.sdk.resource.instance.QueueTest
Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.032 sec
Running com.twilio.sdk.resource.instance.UsageRecordTest
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.381 sec <<< FAILURE!
Running com.twilio.sdk.resource.instance.UsageTriggerTest
Tests run: 4, Failures: 0, Errors: 4, Skipped: 0, Time elapsed: 0.091 sec <<< FAILURE!
Running com.twilio.sdk.TwilioRestClientTest
Tests run: 6, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 4.81 sec

Results :

Tests in error: 
  testListingUsageRecords(com.twilio.sdk.resource.instance.UsageRecordTest): com.twilio.sdk.TwilioRestClient.setHttpclient(Lorg/apache/http/client/HttpClient;)V
  testListingUsageTrigger(com.twilio.sdk.resource.instance.UsageTriggerTest): com.twilio.sdk.TwilioRestClient.setHttpclient(Lorg/apache/http/client/HttpClient;)V
  testCreateUsageTrigger(com.twilio.sdk.resource.instance.UsageTriggerTest): com.twilio.sdk.TwilioRestClient.setHttpclient(Lorg/apache/http/client/HttpClient;)V
  testDeleteUsageTrigger(com.twilio.sdk.resource.instance.UsageTriggerTest): com.twilio.sdk.TwilioRestClient.setHttpclient(Lorg/apache/http/client/HttpClient;)V
  testDeleteErrorUsageTrigger(com.twilio.sdk.resource.instance.UsageTriggerTest): com.twilio.sdk.TwilioRestClient.setHttpclient(Lorg/apache/http/client/HttpClient;)V

Tests run: 18, Failures: 0, Errors: 5, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 13.119s
[INFO] Finished at: Fri Dec 21 01:14:50 PST 2012
[INFO] Final Memory: 14M/81M

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.