Skip to content

Java library for sending SMS via sms.ru provider.

Notifications You must be signed in to change notification settings

dezhik/sms-sender

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sms-sender

A simple way for sending SMS via sms.ru with Java.

At first sign up on sms.ru and receive your api_id, login, password which would be needed for authenticating your requests. sms.ru API description, unfortunately the page is still only in Russian.

Configuration

Use SenderServiceConfigurationBuilder to create SenderServiceConfiguration which should be passed as argument into constructor of SenderService or AsyncSenderService.

There are necessary fields in configuration, which are used by authentication provider you picked. Authentication providers are implementations of AuthProvider, by default DefaultAuthProvider is used.

CloseableHttpClient, AuthProvider class to use, SenderService to use in the AsyncSenderService, list of retry policies and other params are arbitrary in SenderServiceConfiguration.

SenderService and AsyncSenderService throw IllegalStateException during construction if some necessary fields are missing.

Configuration parameters could be set from java code or loaded from the FileInputStream or Properties object

SenderServiceConfiguration senderConfiguration = SenderServiceConfigurationBuilder.create()
      .load(new FileInputStream("test.properties"))
      .build();

Sync and Async senders

Library has sync and async services

  • SenderService executes the request parse response and retries request if needed in the same thread
  • AsyncSenderService works asynchronously using ExecutorService from the configuration or Executors.newSingleThreadExecutor() if no ExecutorService was provided. Async service has two execute(...) methods: the first one returns Future, the second has an optional argument array of ApiCallback which would be called after receiving and parsing response from the API.

For further information look at the "Usage examples" section located at the end of the file.

API requests

All requests extend ApiRequest class, which has number of execution attempts, [InvocationStatus] (https://github.com/dezhik/sms-sender/blob/master/src/main/java/ru/dezhik/sms/sender/api/InvocationStatus.java) status, exception which would be set iff status.isAbnormal() and attachment.

Attachment could be usefull if you use AsyncSenderService with callbacks and want to use some additional information related with request in callbacks, e.g. id of DB row which corresponds to the SMS sending.

API responses

Responses extend ApiResponse class, which contains plain response of the remote system (if this option is enabled in configuration) and response status specific to remote API.

SMS.RU api requests

SMS.RU response status

SMSRuResponseStatus is the enum containing possible response statuses of sms.ru API. Each status has a comment explaining the situation then it could be received. For further and more accurate information go to the sms.ru API description page.

Authentication

There are 3 ways for authenticating your API requests:

Retry policies

You can add policies/conditions under which the request should be retried and specify a delay before next retry. All retry policies should implement [RetryPolicy] (https://github.com/dezhik/sms-sender/blob/master/src/main/java/ru/dezhik/sms/sender/RetryPolicy.java) interface. SenderServiceConfigurationBuilder addRetryPolicy(RetryPolicy)

By default there is only a NetworkErrorRetryPolicy

Service shutdown

Don't forget to shutdown sender service during shutting down your application, use shutdown() for this.

This is especially necessary if you use AsyncSenderService, which has ExecutorService under the hood.

There is a special setting for AsyncSenderService shutdown() in SenderServiceConfiguration, asyncTerminationTimeoutMs which specifies how much time to wait befare call shutdownNow() on the ExecutorService if it still has running threads.

Usage examples

The most efficient way to use the library is to create SenderService or AsyncSenderService instance once then share it between threads and use numerous times.

Creating simple SenderServiceConfiguration. Note that you should provide your own ApiID:

SenderServiceConfiguration config = SenderServiceConfigurationBuilder.create()
                .setApiId("00000000-0000-0000-0000-000000000000")
                .setTestSendingEnabled(true)
                .setReturnPlainResponse(true)
                .build();

Synchronous SMSRuCostRequest execution example:

SenderService sender = new SenderService(senderConfiguration);
SMSRuCostRequest sendRequest = new SMSRuCostRequest();
sendRequest.setReceiver("+79123456789");
sendRequest.setText("Hello world");
SMSRuCostResponse getCostResponse = sender.execute(sendRequest);
if (sendRequest.getStatus() == InvocationStatus.SUCCESS) {
    /**
     * request was executed successfully now you can handle sendResponse
     * always check service API manual page for determine which codes should be treated as successful
     */
    if (getCostResponse.getResponseStatus() == SMSRuResponseStatus.IN_QUEUE) {
        System.out.println(String.format("Success. Price %4.2f, smsNeeded %d", getCostResponse.getPrice(), getCostResponse.getSmsNeeded()));
    } else {
        System.out.println(String.format("Failed with status %s", getCostResponse.getResponseStatus()));
    }
} else {
    /**
     * Something went wrong and request failed, check sendRequest.getStatus()
     * usually the problem is in params validation or network or parsing response from the remote API.
     * {@link ru.dezhik.sms.sender.api.InvocationStatus}
     */
    if (sendRequest.getStatus().isAbnormal()) {
        sendRequest.getException().printStackTrace();
    }
}
...
sender.shutdown();

Synchronous SMSRuSendRequest execution example:

SenderService sender = new SenderService(config);
SMSRuSendRequest sendRequest = new SMSRuSendRequest();
sendRequest.setReceivers(Collections.singleton("+79123456789"));
sendRequest.setText("Hello world");
SMSRuSendResponse sendResponse = sender.execute(sendRequest);
if (sendRequest.getStatus() == InvocationStatus.SUCCESS) {
    /**
     * request was executed successfully now you can handle sendResponse
     * always check service API manual page for determine which codes should be treated as successful
     */
    if (sendResponse.getResponseStatus() == SMSRuResponseStatus.IN_QUEUE) {
        System.out.println(String.format("Success. Balance %4.2f, smsIds %s",
                sendResponse.getBalance(), Arrays.toString(sendResponse.getMsgIds().toArray())));
    } else {
        System.out.println(String.format("Failed with status %s", sendResponse.getResponseStatus()));
    }
} else {
    /**
     * Something went wrong and request failed, check sendRequest.getStatus()
     * usually the problem is in params validation or network or parsing response from the remote API.
     * {@link ru.dezhik.sms.sender.api.InvocationStatus}
     */
    if (sendRequest.getStatus().isAbnormal()) {
        sendRequest.getException().printStackTrace();
    }
}

Simple asynchronous request execution:

AsyncSenderService asyncSender = new AsyncSenderService(senderConfiguration);
SMSRuCostRequest sendRequest = new SMSRuCostRequest();
sendRequest.setReceiver("+79123456789");
sendRequest.setText("Hello world");
Future<SMSRuSendResponse> sendFuture = asyncSender.execute(sendResponse);
...
SMSRuSendResponse sendResponse = sendFuture.get();
if (sendRequest.getStatus() == InvocationStatus.SUCCESS) {
    ;//request was executed successfully now you can handle sendResponse
}
...
asyncSender.shutdown();

Asynchronous request execution with callbacks, ApiCallback:

AsyncSenderService asyncSender = new AsyncSenderService(senderConfiguration);
SMSRuCostRequest sendRequest = new SMSRuCostRequest();
sendRequest.setReceiver("+79123456789");
sendRequest.setText("Hello world");
ApiCallback successCallback = new ApiCallback() {
    @Override
    public boolean apply(ApiRequest request, SimpleResponse response) {
        return request.getStatus() == InvocationStatus.SUCCESS;
    }
    
    @Override
    public void execute(ApiRequest request, SimpleResponse response) {
        //handle successful request, e.g. update sms status in your database or smth else
    }
};

ApiCallback failCallback = new ApiCallback() {
    @Override
    public boolean apply(ApiRequest request, SimpleResponse response) {
        return request.getStatus() != InvocationStatus.SUCCESS;
    }

    @Override
    public void execute(ApiRequest request, SimpleResponse response) {
        //handle failed request, e.g. print error or try to send email instead of sms
    }
};

asyncSender.execute(sendResponse, successCallback, failCallback);
...
asyncSender.shutdown();

About

Java library for sending SMS via sms.ru provider.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages