createBatchAsync(
.execute(requestProducer, responseConsumer, callbackWrapper().wrap(callback));
}
+ /**
+ * Creates the given batch and schedules it for submission. If {@link MtBatchMmsCreate#sendAt()}
+ * returns null
then the batch submission will begin immediately.
+ *
+ * This method blocks until the request completes and its use is discouraged. Please consider
+ * using the asynchronous method {@link #createBatchAsync(MtBatchMmsCreate, FutureCallback)}
+ * instead.
+ *
+ * @param mms the batch to create
+ * @return a batch creation result
+ * @throws InterruptedException if the current thread was interrupted while waiting
+ * @throws ApiException if an error occurred while communicating with XMS
+ */
+ public MtBatchMmsResult createBatch(MtBatchMmsCreate mms)
+ throws InterruptedException, ApiException {
+ try {
+ return createBatchAsync(mms, null).get();
+ } catch (ExecutionException e) {
+ throw Utils.unwrapExecutionException(e);
+ }
+ }
+
+ /**
+ * Asynchronously creates the given mms batch and schedules it for submission. If {@link
+ * MtBatchMmsCreate#sendAt()} returns null
then the batch submission will begin
+ * immediately.
+ *
+ * @param mms the batch to create
+ * @param callback a callback that is invoked when batch is created
+ * @return a future whose result is the creation response
+ */
+ public Future createBatchAsync(
+ MtBatchMmsCreate mms, FutureCallback callback) {
+ HttpPost req = post(batchesEndpoint(), mms);
+
+ HttpAsyncRequestProducer requestProducer = new BasicAsyncRequestProducer(endpointHost(), req);
+ HttpAsyncResponseConsumer responseConsumer =
+ jsonAsyncConsumer(MtBatchMmsResult.class);
+
+ return httpClient()
+ .execute(requestProducer, responseConsumer, callbackWrapper().wrap(callback));
+ }
+
/**
* Replaces the batch with the given identifier. After this method completes the batch will match
* the provided batch description.
@@ -778,6 +824,48 @@ public Future updateBatchAsync(
return httpClient().execute(producer, consumer, callbackWrapper().wrap(callback));
}
+ /**
+ * Updates the given mms batch.
+ *
+ * This method blocks until the request completes and its use is discouraged. Please consider
+ * using the asynchronous method {@link #updateBatchAsync(BatchId, MtBatchMmsUpdate,
+ * FutureCallback)} instead.
+ *
+ * @param id identifier of the batch to update
+ * @param mms a description of the desired updated
+ * @return the batch with the updates applied
+ * @throws InterruptedException if the current thread was interrupted while waiting
+ * @throws ApiException if an error occurred while communicating with XMS
+ */
+ public MtBatchMmsResult updateBatch(BatchId id, MtBatchMmsUpdate mms)
+ throws InterruptedException, ApiException {
+ try {
+ return updateBatchAsync(id, mms, null).get();
+ } catch (ExecutionException e) {
+ throw Utils.unwrapExecutionException(e);
+ }
+ }
+
+ /**
+ * Asynchronously updates the mms batch with the given batch ID. The batch is updated to match the
+ * given update object.
+ *
+ * @param batchId the batch that should be updated
+ * @param mms description of the desired update
+ * @param callback called at call success, failure, or cancellation
+ * @return a future containing the updated batch
+ */
+ public Future updateBatchAsync(
+ BatchId batchId, MtBatchMmsUpdate mms, FutureCallback callback) {
+ HttpPost req = post(batchEndpoint(batchId), mms);
+
+ HttpAsyncRequestProducer producer = new BasicAsyncRequestProducer(endpointHost(), req);
+ HttpAsyncResponseConsumer consumer =
+ jsonAsyncConsumer(MtBatchMmsResult.class);
+
+ return httpClient().execute(producer, consumer, callbackWrapper().wrap(callback));
+ }
+
/**
* Fetches the given batch.
*
@@ -789,7 +877,7 @@ public Future updateBatchAsync(
* @throws InterruptedException if the current thread was interrupted while waiting
* @throws ApiException if an error occurred while communicating with XMS
*/
- public MtBatchSmsResult fetchBatch(BatchId id) throws InterruptedException, ApiException {
+ public MtBatchResult fetchBatch(BatchId id) throws InterruptedException, ApiException {
try {
return fetchBatchAsync(id, null).get();
} catch (ExecutionException e) {
@@ -804,14 +892,13 @@ public MtBatchSmsResult fetchBatch(BatchId id) throws InterruptedException, ApiE
* @param callback a callback that is activated at call completion
* @return a future yielding the desired batch
*/
- public Future fetchBatchAsync(
- BatchId batchId, FutureCallback callback) {
+ public Future fetchBatchAsync(
+ BatchId batchId, FutureCallback callback) {
HttpGet req = get(batchEndpoint(batchId));
HttpAsyncRequestProducer producer = new BasicAsyncRequestProducer(endpointHost(), req);
- HttpAsyncResponseConsumer consumer =
- jsonAsyncConsumer(MtBatchSmsResult.class);
+ HttpAsyncResponseConsumer consumer = jsonAsyncConsumer(MtBatchResult.class);
return httpClient().execute(producer, consumer, callbackWrapper().wrap(callback));
}
@@ -823,12 +910,12 @@ public Future fetchBatchAsync(
* @param filter the batch filter
* @return a future page
*/
- public PagedFetcher fetchBatches(final BatchFilter filter) {
- return new PagedFetcher() {
+ public PagedFetcher fetchBatches(final BatchFilter filter) {
+ return new PagedFetcher() {
@Override
- Future> fetchAsync(
- int page, FutureCallback> callback) {
+ Future> fetchAsync(
+ int page, FutureCallback> callback) {
return fetchBatches(page, filter, callbackWrapper().wrap(callback));
}
};
@@ -842,8 +929,8 @@ Future> fetchAsync(
* @param callback the callback to invoke when call is finished
* @return a future page
*/
- private Future> fetchBatches(
- int page, BatchFilter filter, FutureCallback> callback) {
+ private Future> fetchBatches(
+ int page, BatchFilter filter, FutureCallback> callback) {
List params = filter.toQueryParams(page);
URI url = endpoint("/batches", params);
@@ -851,7 +938,7 @@ private Future> fetchBatches(
HttpAsyncRequestProducer producer = new BasicAsyncRequestProducer(endpointHost(), req);
- HttpAsyncResponseConsumer> consumer =
+ HttpAsyncResponseConsumer> consumer =
jsonAsyncConsumer(PagedBatchResult.class);
return httpClient().execute(producer, consumer, callbackWrapper().wrap(callback));
@@ -868,7 +955,7 @@ private Future> fetchBatches(
* @throws InterruptedException if the current thread was interrupted while waiting
* @throws ApiException if an error occurred while communicating with XMS
*/
- public MtBatchSmsResult cancelBatch(BatchId batchId) throws InterruptedException, ApiException {
+ public MtBatchResult cancelBatch(BatchId batchId) throws InterruptedException, ApiException {
try {
return cancelBatchAsync(batchId, null).get();
} catch (ExecutionException e) {
@@ -883,14 +970,13 @@ public MtBatchSmsResult cancelBatch(BatchId batchId) throws InterruptedException
* @param callback the callback invoked when request completes
* @return a future containing the batch that was cancelled
*/
- public Future cancelBatchAsync(
- BatchId batchId, FutureCallback callback) {
+ public Future cancelBatchAsync(
+ BatchId batchId, FutureCallback callback) {
HttpDelete req = delete(batchEndpoint(batchId));
HttpAsyncRequestProducer producer = new BasicAsyncRequestProducer(endpointHost(), req);
- HttpAsyncResponseConsumer consumer =
- jsonAsyncConsumer(MtBatchSmsResult.class);
+ HttpAsyncResponseConsumer consumer = jsonAsyncConsumer(MtBatchResult.class);
return httpClient().execute(producer, consumer, callbackWrapper().wrap(callback));
}
@@ -1080,7 +1166,8 @@ private Future> fetchDeliveryReports(
}
/**
- * Create a delivery feedback for the batch with the given batch ID.
+ * Create a delivery feedback for the batch with the given batch ID. Feedback can only be provided
+ * if feedback_enabled was set when batch was submitted.
*
* This method blocks until the request completes and its use is discouraged. Please consider
* using the asynchronous method {@link #createDeliveryFeedbackAsync(BatchId,
@@ -1101,7 +1188,8 @@ public Void createDeliveryFeedback(BatchId id, FeedbackDeliveryCreate feedbackDe
}
/**
- * Create a delivery feedback for the batch with the given batch ID and recipients
+ * Create a delivery feedback for the batch with the given batch ID. Feedback can only be provided
+ * if feedback_enabled was set when batch was submitted.
*
* @param id identifier of the batch
* @param feedbackDeliveryCreate create delivery feedback input with recipients
diff --git a/src/main/java/com/sinch/xms/ErrorResponseException.java b/src/main/java/com/sinch/xms/ErrorResponseException.java
index c8b89f4..975097b 100644
--- a/src/main/java/com/sinch/xms/ErrorResponseException.java
+++ b/src/main/java/com/sinch/xms/ErrorResponseException.java
@@ -26,8 +26,7 @@
* the XMS API has been broken, the error code and text indicates the specifics.
*
*
For information about specific errors please refer to the XMS API
- * documentation.
+ * "https://developers.sinch.com/docs/sms/api-reference/status-codes/">XMS API documentation.
*/
public class ErrorResponseException extends ApiException {
diff --git a/src/main/java/com/sinch/xms/SinchSMSApi.java b/src/main/java/com/sinch/xms/SinchSMSApi.java
index 81f091a..7e4b4e0 100644
--- a/src/main/java/com/sinch/xms/SinchSMSApi.java
+++ b/src/main/java/com/sinch/xms/SinchSMSApi.java
@@ -23,8 +23,11 @@
import com.sinch.xms.api.FeedbackDeliveryCreate;
import com.sinch.xms.api.GroupCreate;
import com.sinch.xms.api.GroupUpdate;
+import com.sinch.xms.api.MediaBody;
import com.sinch.xms.api.MtBatchBinarySmsCreate;
import com.sinch.xms.api.MtBatchBinarySmsUpdate;
+import com.sinch.xms.api.MtBatchMmsCreate;
+import com.sinch.xms.api.MtBatchMmsUpdate;
import com.sinch.xms.api.MtBatchTextSmsCreate;
import com.sinch.xms.api.MtBatchTextSmsUpdate;
import com.sinch.xms.api.ParameterValues;
@@ -77,6 +80,26 @@ public static MtBatchBinarySmsUpdate.Builder batchBinarySmsUpdate() {
return MtBatchBinarySmsUpdate.builder();
}
+ /**
+ * Returns a freshly created batch MMS message builder.
+ *
+ * @return a builder of MMS batch messages
+ */
+ @Nonnull
+ public static MtBatchMmsCreate.Builder batchMms() {
+ return MtBatchMmsCreate.builder();
+ }
+
+ /**
+ * Returns a freshly created builder for MMS message updates.
+ *
+ * @return a builder of MMS message updates
+ */
+ @Nonnull
+ public static MtBatchMmsUpdate.Builder batchMmsUpdate() {
+ return MtBatchMmsUpdate.builder();
+ }
+
/**
* Returns a freshly created builder for delivery feedback.
*
@@ -186,4 +209,14 @@ public static BatchDeliveryReportParams.Builder batchDeliveryReportParams() {
public static DeliveryReportFilter.Builder deliveryReportFilter() {
return DeliveryReportFilter.builder();
}
+
+ /**
+ * Returns a freshly created builder of delivery report filters.
+ *
+ * @return a builder of delivery report filters
+ */
+ @Nonnull
+ public static MediaBody.Builder mediaBody() {
+ return MediaBody.builder();
+ }
}
diff --git a/src/main/java/com/sinch/xms/api/BatchDeliveryReport.java b/src/main/java/com/sinch/xms/api/BatchDeliveryReport.java
index 47d319d..06c1744 100644
--- a/src/main/java/com/sinch/xms/api/BatchDeliveryReport.java
+++ b/src/main/java/com/sinch/xms/api/BatchDeliveryReport.java
@@ -22,93 +22,21 @@
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSubTypes;
+import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
-import com.fasterxml.jackson.annotation.JsonTypeName;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.util.List;
-import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.immutables.value.Value;
/** A batch delivery report. */
@Value.Enclosing
-@Value.Immutable
-@ValueStylePackage
-@JsonDeserialize(builder = BatchDeliveryReport.Builder.class)
@JsonInclude(Include.NON_EMPTY)
@JsonTypeInfo(use = Id.NAME, property = "type")
-@JsonTypeName("delivery_report_sms")
+@JsonSubTypes({@Type(BatchDeliveryReportSms.class), @Type(BatchDeliveryReportMms.class)})
public abstract class BatchDeliveryReport {
- /** A description of the messages having a given delivery state. */
- @Value.Immutable
- @JsonDeserialize(builder = BatchDeliveryReport.Status.Builder.class)
- @JsonInclude(Include.NON_EMPTY)
- public abstract static class Status {
-
- /** A builder of batch delivery report statuses. */
- public static class Builder extends BatchDeliveryReportImpl.Status.Builder {
-
- Builder() {}
- }
-
- /**
- * Creates a builder of {@link Status} instances.
- *
- * @return a builder
- */
- @Nonnull
- public static final Status.Builder builder() {
- return new Builder();
- }
-
- /**
- * The delivery status code.
- *
- * @return a status code
- */
- public abstract int code();
-
- /**
- * The delivery status for this bucket.
- *
- * @return a non-null delivery status
- */
- public abstract DeliveryStatus status();
-
- /**
- * The number of individual messages in this status bucket.
- *
- * @return a positive integer
- */
- public abstract int count();
-
- /**
- * The recipients having this status. Note, this is non-empty only if a full delivery
- * report has been requested.
- *
- * @return a non-null list of recipients
- */
- public abstract List recipients();
- }
-
- /** A builder of batch delivery reports. */
- public static class Builder extends BatchDeliveryReportImpl.Builder {
-
- Builder() {}
- }
-
- /**
- * Creates a builder of {@link BatchDeliveryReport} instances.
- *
- * @return a builder
- */
- @Nonnull
- public static final BatchDeliveryReport.Builder builder() {
- return new Builder();
- }
-
/**
* Identifier of the batch to which this delivery report refers.
*
diff --git a/src/main/java/com/sinch/xms/api/BatchDeliveryReportMms.java b/src/main/java/com/sinch/xms/api/BatchDeliveryReportMms.java
new file mode 100644
index 0000000..07deb6f
--- /dev/null
+++ b/src/main/java/com/sinch/xms/api/BatchDeliveryReportMms.java
@@ -0,0 +1,56 @@
+/*-
+ * #%L
+ * SDK for Sinch SMS
+ * %%
+ * Copyright (C) 2016 Sinch
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+package com.sinch.xms.api;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import javax.annotation.Nonnull;
+import org.immutables.value.Value;
+
+/** A batch delivery report. */
+@Value.Enclosing
+@Value.Immutable
+@ValueStylePackage
+@JsonDeserialize(builder = BatchDeliveryReportMms.Builder.class)
+@JsonInclude(Include.NON_EMPTY)
+@JsonTypeInfo(use = Id.NAME, property = "type")
+@JsonTypeName("delivery_report_mms")
+public abstract class BatchDeliveryReportMms extends BatchDeliveryReport {
+
+ /** A builder of batch delivery reports. */
+ public static class Builder extends BatchDeliveryReportMmsImpl.Builder {
+
+ Builder() {}
+ }
+
+ /**
+ * Creates a builder of {@link BatchDeliveryReportMms} instances.
+ *
+ * @return a builder
+ */
+ @Nonnull
+ public static final BatchDeliveryReportMms.Builder builder() {
+ return new Builder();
+ }
+}
diff --git a/src/main/java/com/sinch/xms/api/BatchDeliveryReportSms.java b/src/main/java/com/sinch/xms/api/BatchDeliveryReportSms.java
new file mode 100644
index 0000000..3eebe5e
--- /dev/null
+++ b/src/main/java/com/sinch/xms/api/BatchDeliveryReportSms.java
@@ -0,0 +1,56 @@
+/*-
+ * #%L
+ * SDK for Sinch SMS
+ * %%
+ * Copyright (C) 2016 Sinch
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+package com.sinch.xms.api;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import javax.annotation.Nonnull;
+import org.immutables.value.Value;
+
+/** A batch delivery report. */
+@Value.Enclosing
+@Value.Immutable
+@ValueStylePackage
+@JsonDeserialize(builder = BatchDeliveryReportSms.Builder.class)
+@JsonInclude(Include.NON_EMPTY)
+@JsonTypeInfo(use = Id.NAME, property = "type")
+@JsonTypeName("delivery_report_sms")
+public abstract class BatchDeliveryReportSms extends BatchDeliveryReport {
+
+ /** A builder of batch delivery reports. */
+ public static class Builder extends BatchDeliveryReportSmsImpl.Builder {
+
+ Builder() {}
+ }
+
+ /**
+ * Creates a builder of {@link BatchDeliveryReportSms} instances.
+ *
+ * @return a builder
+ */
+ @Nonnull
+ public static final BatchDeliveryReportSms.Builder builder() {
+ return new Builder();
+ }
+}
diff --git a/src/main/java/com/sinch/xms/api/FeedbackDeliveryCreate.java b/src/main/java/com/sinch/xms/api/FeedbackDeliveryCreate.java
index 617a263..ca49186 100644
--- a/src/main/java/com/sinch/xms/api/FeedbackDeliveryCreate.java
+++ b/src/main/java/com/sinch/xms/api/FeedbackDeliveryCreate.java
@@ -27,7 +27,8 @@ public static final FeedbackDeliveryCreate.Builder builder() {
}
/**
- * The list of recipients.
+ * The list of recipients. Can be set as an empty list to indicate that all recipients received
+ * the message. If the feedback was enabled for a group, at least one phone number is required.
*
* @return a list of strings containing recipients
*/
diff --git a/src/main/java/com/sinch/xms/api/MediaBody.java b/src/main/java/com/sinch/xms/api/MediaBody.java
new file mode 100644
index 0000000..ebb6ec0
--- /dev/null
+++ b/src/main/java/com/sinch/xms/api/MediaBody.java
@@ -0,0 +1,79 @@
+/*-
+ * #%L
+ * SDK for Sinch SMS
+ * %%
+ * Copyright (C) 2016 Sinch
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+package com.sinch.xms.api;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.immutables.value.Value;
+
+/**
+ * Representation of a media body. The text part is optional but the media url is mandatory.
+ *
+ * Supported media types are:
+ *
+ *
+ * - image: .jpg, .png (please observe that .jpg files have wider support on mobile devices than
+ * .png files)
+ *
- video: .mp4, .gif, .mov
+ *
- vCard (Virtual Contact File): .vcf
+ *
- PDF files: .pdf
+ *
+ */
+@Value.Immutable
+@ValueStylePackage
+@JsonDeserialize(builder = MediaBody.Builder.class)
+@JsonInclude(Include.NON_EMPTY)
+public abstract class MediaBody {
+
+ /** A builder of media body creation descriptions. */
+ public static final class Builder extends MediaBodyImpl.Builder {
+
+ Builder() {}
+ }
+
+ /**
+ * Creates a builder of {@link MediaBody} instances.
+ *
+ * @return a builder
+ */
+ @Nonnull
+ public static final MediaBody.Builder builder() {
+ return new MediaBody.Builder();
+ }
+
+ /**
+ * The text message.
+ *
+ * @return a message
+ */
+ @Nullable
+ public abstract String message();
+
+ /**
+ * The url to the media content.
+ *
+ * @return a non-null url to the media content
+ */
+ @Nonnull
+ public abstract String url();
+}
diff --git a/src/main/java/com/sinch/xms/api/MtBatchCreate.java b/src/main/java/com/sinch/xms/api/MtBatchCreate.java
new file mode 100644
index 0000000..cfa74b1
--- /dev/null
+++ b/src/main/java/com/sinch/xms/api/MtBatchCreate.java
@@ -0,0 +1,130 @@
+/*-
+ * #%L
+ * SDK for Sinch SMS
+ * %%
+ * Copyright (C) 2016 Sinch
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+package com.sinch.xms.api;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import java.net.URI;
+import java.time.OffsetDateTime;
+import java.util.List;
+import javax.annotation.Nullable;
+import javax.annotation.OverridingMethodsMustInvokeSuper;
+import org.immutables.value.Value;
+
+/**
+ * Base class for mobile terminated batch messages. A mobile terminated message can have either a
+ * {@link MtBatchSmsCreate SMS} or a {@link MtBatchMmsCreate MMS} message payload.
+ */
+@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
+public abstract class MtBatchCreate {
+
+ /**
+ * The list of message recipients. May not be empty.
+ *
+ * @return a non-empty list of recipients
+ */
+ @JsonProperty("to")
+ public abstract List recipients();
+
+ /**
+ * The message originator. May be an MSISDN or short code.
+ *
+ * @return an originator address
+ */
+ @Nullable
+ @JsonProperty("from")
+ public abstract String sender();
+
+ /**
+ * The type of delivery report to request for this batch.
+ *
+ * @return a type of report or null
to use the default type
+ */
+ @Nullable
+ @JsonProperty("delivery_report")
+ public abstract ReportType deliveryReport();
+
+ /**
+ * The time this batch should be sent. If null
or set to a past time then the batch
+ * will be sent immediately.
+ *
+ * @return the time when this batch should be sent
+ */
+ @Nullable
+ @JsonProperty("send_at")
+ public abstract OffsetDateTime sendAt();
+
+ /**
+ * The time at which this batch will expire. Any message not delivered by this time will be placed
+ * into an expired state and no further delivery will be attempted.
+ *
+ * @return the time when this batch expires
+ */
+ @Nullable
+ @JsonProperty("expire_at")
+ public abstract OffsetDateTime expireAt();
+
+ /**
+ * The URL to which batch callbacks should be sent. If null
then callbacks will be
+ * sent to the default URL.
+ *
+ * @return an URL having a callback listener or null
to use the default callback URL
+ */
+ @Nullable
+ @JsonProperty("callback_url")
+ public abstract URI callbackUrl();
+
+ /**
+ * If set to true, then feedback is expected after successful delivery.
+ *
+ * @return boolean value
+ */
+ @Nullable
+ @JsonProperty("feedback_enabled")
+ public abstract Boolean feedbackEnabled();
+
+ /**
+ * The client identifier to attach to this message. If set, it will be added in the delivery
+ * report/callback of this batch.
+ *
+ * @return a client reference id
+ */
+ @Nullable
+ @JsonProperty("client_reference")
+ public abstract String clientReference();
+
+ @OverridingMethodsMustInvokeSuper
+ @Value.Check
+ protected void check() {
+ if (recipients().isEmpty()) {
+ throw new IllegalStateException("no destination");
+ }
+
+ for (String to : recipients()) {
+ if (to.isEmpty()) {
+ throw new IllegalStateException("contains empty destination");
+ }
+ }
+
+ if (sender() != null && sender().isEmpty()) {
+ throw new IllegalStateException("empty from address");
+ }
+ }
+}
diff --git a/src/main/java/com/sinch/xms/api/MtBatchMmsCreate.java b/src/main/java/com/sinch/xms/api/MtBatchMmsCreate.java
new file mode 100644
index 0000000..2ec6c87
--- /dev/null
+++ b/src/main/java/com/sinch/xms/api/MtBatchMmsCreate.java
@@ -0,0 +1,122 @@
+/*-
+ * #%L
+ * SDK for Sinch SMS
+ * %%
+ * Copyright (C) 2016 Sinch
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+package com.sinch.xms.api;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import java.util.Map;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.immutables.value.Value;
+
+/**
+ * Container of all necessary parameters to create a media batch message.
+ *
+ * A minimal definition has defined values for
+ *
+ *
+ * - {@link #recipients()},
+ *
- {@link #sender()},
+ *
- {@link #body()}.
+ *
+ */
+@Value.Immutable
+@ValueStylePackage
+@JsonDeserialize(builder = MtBatchMmsCreate.Builder.class)
+@JsonTypeName("mt_media")
+public abstract class MtBatchMmsCreate extends MtBatchCreate {
+
+ /** A builder of textual batch messages. */
+ public static class Builder extends MtBatchMmsCreateImpl.Builder {
+
+ Builder() {}
+ }
+
+ /**
+ * Creates a builder of {@link MtBatchMmsCreate} instances.
+ *
+ * @return a builder
+ */
+ @Nonnull
+ public static final MtBatchMmsCreate.Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * The message text or template. If this describes a template then {@link #parameters()} must
+ * describe the parameter substitutions.
+ *
+ * A parameterized message is a regular text message but having one or more named parameters
+ * embedded using the syntax ${parameter_key}
where parameter_key
is
+ * your chosen parameter name. When the messaging system is sending the message the template will
+ * be expanded and any occurrence of ${parameter_key}
in the message body is replaced
+ * by the parameter value for the message recipient.
+ *
+ *
The typical way to use templates is
+ *
+ *
+ * SinchSMSApi.batchMms()
+ * .sender("12345")
+ * .addRecipient("987654321")
+ * // Other initialization
+ * .body(
+ * SinchSMSApi.mediaBody()
+ * .message("Hello, ${name}")
+ * .url("http://media.url.com/image.jpg"))
+ * .build()
+ * .putParameter("name",
+ * SinchSMSApi.parameterValues()
+ * .putSubstitution("987654321", "Jane")
+ * .default("valued customer")
+ * .build())
+ * .build();
+ *
+ *
+ * and here the recipient with MSISDN 987654321 will receive the message "Hello, Jane" while all
+ * other recipients would receive "Hello, valued customer".
+ *
+ * @return the message to send
+ */
+ public abstract MediaBody body();
+
+ /**
+ * Whether the media included in the message to be checked against Sinch MMS channel best
+ * practices. If set to true, the message will be rejected if it doesn't conform to the listed
+ * recommendations, otherwise no validation will be performed. Defaults to false.
+ *
+ * @return boolean indicating if strict validation is meant to be performed
+ */
+ @Nullable
+ @JsonProperty("strict_validation")
+ public abstract Boolean strictValidation();
+
+ /**
+ * The message template parameter substitutions. If {@link #body()} describes a template then this
+ * must return the necessary substitutions for all template parameters.
+ *
+ * @return a map from template variable to parameter values
+ * @see #body()
+ */
+ @JsonInclude(Include.NON_EMPTY)
+ public abstract Map parameters();
+}
diff --git a/src/main/java/com/sinch/xms/api/MtBatchMmsResult.java b/src/main/java/com/sinch/xms/api/MtBatchMmsResult.java
new file mode 100644
index 0000000..cf1fc63
--- /dev/null
+++ b/src/main/java/com/sinch/xms/api/MtBatchMmsResult.java
@@ -0,0 +1,88 @@
+/*-
+ * #%L
+ * SDK for Sinch SMS
+ * %%
+ * Copyright (C) 2016 Sinch
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+package com.sinch.xms.api;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import java.util.Map;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.immutables.value.Value;
+
+/**
+ * Objects of this class contain information about a textual MMS batch. The information includes the
+ * message body, the batch identifier, the creation time, and so on.
+ */
+@Value.Immutable
+@ValueStylePackage
+@JsonDeserialize(builder = MtBatchMmsResult.Builder.class)
+@JsonTypeName("mt_media")
+public abstract class MtBatchMmsResult extends MtBatchResult {
+
+ /** Builder of MMS batch results. */
+ public static class Builder extends MtBatchMmsResultImpl.Builder {
+
+ Builder() {}
+ }
+
+ /**
+ * Creates a builder of {@link MtBatchMmsResult} instances.
+ *
+ * @return a builder
+ */
+ @Nonnull
+ public static final MtBatchMmsResult.Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * The message body including message text or template (optional) and the media content url. If
+ * this describes a template then {@link #parameters()} describes the parameter substitutions.
+ *
+ * See {@link MtBatchMmsCreate#body()} for a more thorough description of this field.
+ *
+ * @return the message to send
+ */
+ public abstract MediaBody body();
+
+ /**
+ * Whether the media included in the message to be checked against Sinch MMS channel best
+ * practices. If set to true, the message will be rejected if it doesn't conform to the listed
+ * recommendations, otherwise no validation will be performed. Defaults to false.
+ *
+ * @return boolean indicating if strict validation is meant to be performed
+ */
+ @Nullable
+ @JsonProperty("strict_validation")
+ public abstract Boolean strictValidation();
+
+ /**
+ * The message template parameter substitutions. If {@link #body()} describes a template then this
+ * returns the substitutions for the template parameters.
+ *
+ * @return a map from template variable to parameter values
+ * @see #body()
+ */
+ @JsonInclude(Include.NON_EMPTY)
+ public abstract Map parameters();
+}
diff --git a/src/main/java/com/sinch/xms/api/MtBatchMmsUpdate.java b/src/main/java/com/sinch/xms/api/MtBatchMmsUpdate.java
new file mode 100644
index 0000000..3b1e6d8
--- /dev/null
+++ b/src/main/java/com/sinch/xms/api/MtBatchMmsUpdate.java
@@ -0,0 +1,206 @@
+/*-
+ * #%L
+ * SDK for Sinch SMS
+ * %%
+ * Copyright (C) 2016 Sinch
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+package com.sinch.xms.api;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.sinch.xms.UpdateValue;
+import java.net.URI;
+import java.time.OffsetDateTime;
+import java.util.Map;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.immutables.value.Value;
+
+/** A description of updates that can be applied to a media batch message. */
+@Value.Immutable
+@ValueStylePackage
+@JsonSerialize(as = MtBatchMmsUpdateImpl.class)
+@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
+@JsonTypeName("mt_media")
+public abstract class MtBatchMmsUpdate extends MtBatchUpdate {
+
+ /** A builder of text batch message updates. */
+ public static class Builder extends MtBatchMmsUpdateImpl.Builder {
+
+ Builder() {}
+
+ /**
+ * Resets the delivery report type to the messaging system default value.
+ *
+ * @return this builder for use in a chained invocation
+ */
+ public Builder unsetDeliveryReport() {
+ return this.deliveryReport(UpdateValue.unset());
+ }
+
+ /**
+ * Updates the delivery report type of this batch. If given a null
reference then
+ * this is equivalent to calling {@link #unsetDeliveryReport()}.
+ *
+ * @param deliveryReport the new delivery report type or null
to unset
+ * @return this builder for use in a chained invocation
+ */
+ public Builder deliveryReport(ReportType deliveryReport) {
+ if (deliveryReport == null) {
+ return this.unsetDeliveryReport();
+ } else {
+ return this.deliveryReport(UpdateValue.set(deliveryReport));
+ }
+ }
+
+ /**
+ * Unsets the scheduled send time. This has the effect of immediately starting to send the
+ * batch.
+ *
+ * @return this builder for use in a chained invocation
+ */
+ public Builder unsetSendAt() {
+ return this.sendAt(UpdateValue.unset());
+ }
+
+ /**
+ * Updates the scheduled send time. If given a null
reference then this is
+ * equivalent to calling {@link #unsetSendAt()}.
+ *
+ * @param time the new scheduled send time
+ * @return this builder for use in a chained invocation
+ */
+ public Builder sendAt(OffsetDateTime time) {
+ if (time == null) {
+ return this.unsetSendAt();
+ } else {
+ return this.sendAt(UpdateValue.set(time));
+ }
+ }
+
+ /**
+ * Resets the batch expire time to the messaging system default value.
+ *
+ * @return this builder for use in a chained invocation
+ */
+ public Builder unsetExpireAt() {
+ return this.expireAt(UpdateValue.unset());
+ }
+
+ /**
+ * Updates the batch expire time. If given a null
reference then this is equivalent
+ * to calling {@link #unsetExpireAt()}.
+ *
+ * @param time the new expire time
+ * @return this builder for use in a chained invocation
+ */
+ public Builder expireAt(OffsetDateTime time) {
+ if (time == null) {
+ return this.unsetExpireAt();
+ } else {
+ return this.expireAt(UpdateValue.set(time));
+ }
+ }
+
+ /**
+ * Resets the callback URL to the default callback URL.
+ *
+ * @return this builder for use in a chained invocation
+ */
+ public Builder unsetCallbackUrl() {
+ return this.callbackUrl(UpdateValue.unset());
+ }
+
+ /**
+ * Updates the callback URL. If given a null
reference then this is equivalent to
+ * calling {@link #unsetCallbackUrl()}.
+ *
+ * @param url the new callback URL
+ * @return this builder for use in a chained invocation
+ */
+ public Builder callbackUrl(URI url) {
+ if (url == null) {
+ return this.unsetCallbackUrl();
+ } else {
+ return this.callbackUrl(UpdateValue.set(url));
+ }
+ }
+
+ /**
+ * Unsets the batch parameters.
+ *
+ * @return this builder for use in a chained invocation
+ */
+ public Builder unsetParameters() {
+ return this.parameters(UpdateValue.