From 1ecdcbdac0dc88b015c345966a2709e15704a749 Mon Sep 17 00:00:00 2001 From: Dan Gurgui Date: Wed, 7 Aug 2019 14:46:32 +0200 Subject: [PATCH 001/516] Implemented creation and listing of VoiceCallFlow --- .../com/messagebird/MessageBirdClient.java | 56 ++++++- .../objects/voicecalls/VoiceCallFlow.java | 25 ++- .../objects/voicecalls/VoiceCallFlowList.java | 65 ++++++++ .../voicecalls/VoiceCallFlowRequest.java | 110 +++++++++++++ .../voicecalls/VoiceCallFlowResponse.java | 32 ++++ .../test/java/com/messagebird/TestUtil.java | 33 ++++ .../com/messagebird/VoiceCallFlowTest.java | 149 ++++++++++++++++++ .../main/java/ExampleListVoiceCallFlow.java | 43 +++++ 8 files changed, 510 insertions(+), 3 deletions(-) create mode 100644 api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowList.java create mode 100644 api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowRequest.java create mode 100644 api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowResponse.java create mode 100644 api/src/test/java/com/messagebird/VoiceCallFlowTest.java create mode 100644 examples/src/main/java/ExampleListVoiceCallFlow.java diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 57c42f29..3a3d155e 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -6,8 +6,6 @@ import com.messagebird.objects.*; import com.messagebird.objects.conversations.*; import com.messagebird.objects.voicecalls.*; -import com.messagebird.objects.voicecalls.VoiceCallLeg; -import com.messagebird.objects.voicecalls.VoiceCallLegResponse; import java.io.UnsupportedEncodingException; import java.math.BigInteger; @@ -64,6 +62,7 @@ public class MessageBirdClient { static final String RECORDINGPATH = "/recordings"; static final String TRANSCRIPTIONPATH = "/transcriptions"; static final String WEBHOOKS = "/webhooks"; + static final String VOICECALLFLOWPATH = "/call-flows"; private static final String VOICELEGS_SUFFIX_PATH = "/legs"; private MessageBirdService messageBirdService; @@ -534,6 +533,59 @@ public LookupHlr viewLookupHlr(final BigInteger phoneNumber) throws Unauthorized return this.viewLookupHlr(lookupHlr); } + /** + * Convenient function to list all call flows + * + * @param offset + * @param limit + * @return VoiceCallFlowList + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + */ + public VoiceCallFlowList listVoiceCallFlows(final Integer offset, final Integer limit) + throws UnauthorizedException, GeneralException { + if (offset != null && offset < 0) { + throw new IllegalArgumentException("Offset must be > 0"); + } + if (limit != null && limit < 0) { + throw new IllegalArgumentException("Limit must be > 0"); + } + String url = String.format("%s%s", VOICE_CALLS_BASE_URL, VOICECALLFLOWPATH); + + return messageBirdService.requestList(url, offset, limit, VoiceCallFlowList.class); + } + + /** + * Convenient function to create a call flow + * + * @param VoiceCallFlowRequest + * @return VoiceCallFlowResponse + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + */ + public VoiceCallFlowResponse sendVoiceCallFlow(final VoiceCallFlowRequest voiceCallFlowRequest) + throws UnauthorizedException, GeneralException { + String url = String.format("%s%s", VOICE_CALLS_BASE_URL, VOICECALLFLOWPATH); + + return messageBirdService.sendPayLoad(url, voiceCallFlowRequest, VoiceCallFlowResponse.class); + } + + /** + * Convenient function to delete call flow + * + * @param String + * @return void + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + */ + void deleteVoiceCallFlow(final String id) throws NotFoundException, GeneralException, UnauthorizedException { + if (id == null) { + throw new IllegalArgumentException("Voice Call Flow ID must be specified."); + } + String url = String.format("%s%s", VOICE_CALLS_BASE_URL, VOICECALLFLOWPATH); + messageBirdService.deleteByID(url, id); + } + /** * Deletes an existing contact. You only need to supply the unique id that * was returned upon creation. diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java index fc638cf6..b4799eef 100644 --- a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java @@ -1,10 +1,12 @@ package com.messagebird.objects.voicecalls; import com.messagebird.objects.VoiceStep; +import com.fasterxml.jackson.annotation.JsonProperty; import java.io.Serializable; import java.util.Date; import java.util.List; +import java.util.Map; public class VoiceCallFlow implements Serializable { @@ -14,10 +16,22 @@ public class VoiceCallFlow implements Serializable { private String title; private boolean record; private List steps; + + /* + * default is reserved name in JAVA so we use alternate name + */ + @JsonProperty("default") private boolean defaultCall; + + /* Possibly deprecated */ + private boolean defaultWebRtc; + private Date createdAt; private Date updatedAt; + @JsonProperty("_links") + private Map links; + public String getId() { return id; } @@ -50,6 +64,14 @@ public void setSteps(List steps) { this.steps = steps; } + public boolean isDefaultWebRtc() { + return this.defaultWebRtc; + } + + public void setDefaultWebRtc(boolean defaultWebRtc) { + this.defaultWebRtc = defaultWebRtc; + } + public boolean isDefaultCall() { return defaultCall; } @@ -81,7 +103,8 @@ public String toString() { ", title='" + title + '\'' + ", record=" + record + ", steps=" + steps + - ", defaultCall=" + defaultCall + + ", default=" + defaultCall + + ", defaultWebRtc=" + defaultWebRtc + ", createdAt=" + createdAt + ", updatedAt=" + updatedAt + '}'; diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowList.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowList.java new file mode 100644 index 00000000..f79341b0 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowList.java @@ -0,0 +1,65 @@ +package com.messagebird.objects.voicecalls; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Represents a listing of VoiceCallFlow objects, along with pagination details. + * @TODO needs a little polishing (reorganise methods, rename properties, add + * missing properties) + */ +public class VoiceCallFlowList implements Serializable { + + private Integer offset; + private Integer limit; + private Integer totalCount; + + @JsonProperty("_links") + private Map links; + + @JsonProperty("pagination") + private Map pagination; + + private List items; + + @JsonCreator + public VoiceCallFlowList(@JsonProperty("data") List data) { + this.items = data; + } + + @Override + public String toString() { + return "ListBase{" + + "offset=" + offset + + ", limit=" + limit + + ", totalCount=" + totalCount + + ", items=" + items + + '}'; + } + + + public Integer getOffset() { + return offset; + } + + public Integer getLimit() { + return limit; + } + + public Integer getTotalCount() { + return totalCount; + } + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } +} + + diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowRequest.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowRequest.java new file mode 100644 index 00000000..8741f0de --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowRequest.java @@ -0,0 +1,110 @@ +package com.messagebird.objects.voicecalls; + +import java.util.List; +import java.util.Date; +import com.messagebird.objects.*; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Contains writable values for VoiceCallFlow objects. + */ +public class VoiceCallFlowRequest { + + + private String id; + private String title; + private boolean record; + private List steps; + + @JsonProperty("default") + private boolean defaultCall; + private boolean defaultWebRtc; + private Date createdAt; + private Date updatedAt; + + public VoiceCallFlowRequest(String id) + { + this.id = id; + } + + public VoiceCallFlowRequest() + { + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public boolean isRecord() { + return record; + } + + public void setRecord(boolean record) { + this.record = record; + } + + public List getSteps() { + return steps; + } + + public void setSteps(List steps) { + this.steps = steps; + } + + public boolean isDefaultCall() { + return defaultCall; + } + + public void setDefaultCall(boolean defaultCall) { + this.defaultCall = defaultCall; + } + + public boolean isDefaultWebRtc() { + return defaultWebRtc; + } + + public void setDefaultWebRtc(boolean defaultWebRtc) { + this.defaultWebRtc = defaultWebRtc; + } + + public Date getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + public Date getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Date updatedAt) { + this.updatedAt = updatedAt; + } + + @Override + public String toString() { + return "VoiceCallFlow{" + + "title='" + title + '\'' + + ", record=" + record + + ", steps=" + steps + + ", default=" + defaultCall + + ", defaultWebRtc=" + defaultWebRtc + + ", createdAt=" + createdAt + + ", updatedAt=" + updatedAt + + '}'; + } +} diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowResponse.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowResponse.java new file mode 100644 index 00000000..b9e3cb12 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowResponse.java @@ -0,0 +1,32 @@ +package com.messagebird.objects.voicecalls; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/* + * Used for registering the response returned by a VoiceCallFlow POST method + * @TODO add any missing information + */ +public class VoiceCallFlowResponse implements Serializable { + + private List data; + + @JsonProperty("_links") + private Map links; + + @JsonCreator + public VoiceCallFlowResponse(@JsonProperty("data") List data) { + this.data = data; + } + + public List getData() { + return data; + } + + public void setLinks(Map links) { + this.links = links; + } +} diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index 584b6834..07e5ca15 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -146,6 +146,39 @@ static ContactList createContactList() { return contactList; } + /* + * @TODO add more options here + */ + private static VoiceStepOption createVoiceStepOption() + { + final VoiceStepOption voiceStepOption = new VoiceStepOption(); + voiceStepOption.setDestination("31612345678"); + return voiceStepOption; + } + + /* + * @TODO consider expanding the voiceStep to include more options + */ + public static VoiceStep createVoiceStep() { + final VoiceStep voiceStep = new VoiceStep(); + voiceStep.setId("ANY_ID"); + voiceStep.setAction("transfer"); + voiceStep.setOptions(createVoiceStepOption()); + return voiceStep; + } + + private static VoiceCallFlow createCallFlow() { + final VoiceCallFlow voiceCallFlow = new VoiceCallFlow(); + voiceCallFlow.setId("ANY_ID"); + voiceCallFlow.setTitle("ANY_TITLE"); + voiceCallFlow.setRecord(true); + voiceCallFlow.setSteps(Collections.singletonList(createVoiceStep())); + voiceCallFlow.setDefaultWebRtc(true); + voiceCallFlow.setDefaultCall(true); + + return voiceCallFlow; + } + static ConversationWebhook createConversationWebhook() { ConversationWebhook conversationWebhookResponse = new ConversationWebhook(); conversationWebhookResponse.setId("whid"); diff --git a/api/src/test/java/com/messagebird/VoiceCallFlowTest.java b/api/src/test/java/com/messagebird/VoiceCallFlowTest.java new file mode 100644 index 00000000..a6c1cb58 --- /dev/null +++ b/api/src/test/java/com/messagebird/VoiceCallFlowTest.java @@ -0,0 +1,149 @@ +package com.messagebird; + +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.*; +import com.messagebird.objects.voicecalls.*; + +import org.junit.*; +import org.mockito.Mockito; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; +import static org.unitils.reflectionassert.ReflectionAssert.assertReflectionEquals; +import java.util.*; + +/* + * Class used for covering all the CallFlows functionality with tests + * The purpose is solely on the individual CallFlow + * and not on the associated callFlows to voiceCall + */ +public class VoiceCallFlowTest { + + private static MessageBirdServiceImpl messageBirdService; + private static MessageBirdClient messageBirdClient; + + /** + * VoiceCallFlow object to operate on during tests. + */ + private static VoiceCallFlow voiceCallFlow; + private static VoiceCallFlow voiceCallFlowFixture; + + @BeforeClass + public static void setUpClass() throws UnauthorizedException, GeneralException { + String accessKey = System.getProperty("messageBirdAccessKey"); + messageBirdService = new MessageBirdServiceImpl(accessKey); + messageBirdClient = new MessageBirdClient(messageBirdService); + voiceCallFlowFixture = new VoiceCallFlow(); + voiceCallFlowFixture.setTitle("Test Title"); + voiceCallFlowFixture.setDefaultCall(false); + voiceCallFlowFixture.setDefaultWebRtc(true); + voiceCallFlowFixture.setRecord(true); + voiceCallFlowFixture.setSteps(Collections.singletonList(TestUtil.createVoiceStep())); + VoiceCallFlowResponse voiceCallFlowResponse = createVoiceCallFlow(voiceCallFlowFixture); + voiceCallFlow = voiceCallFlowResponse.getData().get(0); + + } + + /* + * static method used for creating a VoiceCallFlow from the fixture defined at class level + */ + private static VoiceCallFlowResponse createVoiceCallFlow(VoiceCallFlow voiceCallFlowFixture) throws UnauthorizedException, GeneralException { + VoiceCallFlowRequest voiceCallFlowRequest = new VoiceCallFlowRequest(); + voiceCallFlowRequest.setTitle(voiceCallFlowFixture.getTitle()); + voiceCallFlowRequest.setRecord(voiceCallFlowFixture.isRecord()); + voiceCallFlowRequest.setDefaultCall(voiceCallFlowFixture.isDefaultCall()); + voiceCallFlowRequest.setSteps(voiceCallFlowFixture.getSteps()); + + return messageBirdClient.sendVoiceCallFlow(voiceCallFlowRequest); + } + + /* + * For this test we are checking if the CallFlow inserted in the setup is visible in the list + * This way we test the Create SDK and the List method in one test + */ + @Test + public void testCreateAndList() throws UnauthorizedException, GeneralException { + VoiceCallFlowList voiceCallFlowList = messageBirdClient.listVoiceCallFlows(0, 0); + VoiceCallFlow foundVoiceCall = null; + Iterator items = voiceCallFlowList.getItems().iterator(); + while (items.hasNext()) { + VoiceCallFlow nextItem = items.next(); + if (nextItem.getId().equals(voiceCallFlow.getId())) { + foundVoiceCall = nextItem; + } + } + assertNotNull(foundVoiceCall); + assertEquals(foundVoiceCall.getTitle(), this.voiceCallFlowFixture.getTitle()); + assertEquals(foundVoiceCall.isDefaultCall(), this.voiceCallFlowFixture.isDefaultCall()); + assertEquals(foundVoiceCall.getSteps().size(), this.voiceCallFlowFixture.getSteps().size()); + } + + /* + * In this test we are making use of the previous fixture and object defined + */ + @Test + public void testUpdate() throws UnauthorizedException, GeneralException { + + } + + @Test + public void testView() throws UnauthorizedException, GeneralException { + + } + + /* + * The purpose of this method is to create various scenarios in regards + * to creating steps + */ + public void testCreateSteps() { + // null steps + // duplicate steps + // test Media field - string + // test media field - array + // test 2 Steps + // test 3 options for a step + // ensure each type of option is visible + } + + /* + * The purpose of this method is to update stepOptions and stepActions + * with various values and ensure that these values become visible + */ + public void testUpdateSteps() { + // test update for all fields + // ensure the values have been update for each field + // convert media field from string to array + // update all elements and ensure they are visible + } + + /** + * This method tests the create and delete at the same time. In case the delete + * fails, then the fixture inserted in setup() will still be avaialble + * on the environment and will require a separate removal + */ + @Test + public void testCreateAndDelete() + throws UnauthorizedException, GeneralException, NotFoundException { + VoiceCallFlowResponse voiceCallFlowResponse = createVoiceCallFlow(voiceCallFlowFixture); + String id = voiceCallFlowResponse.getData().get(0).getId(); + messageBirdClient.deleteVoiceCallFlow( + id + ); + VoiceCallFlowList voiceCallFlowList = messageBirdClient.listVoiceCallFlows(0, 0); + boolean isVoiceCallFound = false; + Iterator items = voiceCallFlowList.getItems().iterator(); + while (items.hasNext()) { + VoiceCallFlow nextItem = items.next(); + if (nextItem.getId().equals(id)) { + isVoiceCallFound = true; + } + } + assertEquals(false, isVoiceCallFound); + } + + @AfterClass + public static void tearDown() throws UnauthorizedException, GeneralException, NotFoundException { + messageBirdClient.deleteVoiceCallFlow(voiceCallFlow.getId()); + } +} diff --git a/examples/src/main/java/ExampleListVoiceCallFlow.java b/examples/src/main/java/ExampleListVoiceCallFlow.java new file mode 100644 index 00000000..96ea10b2 --- /dev/null +++ b/examples/src/main/java/ExampleListVoiceCallFlow.java @@ -0,0 +1,43 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.objects.MessageResponse; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +/* + * @TODO - not working, needs implementation + */ +public class ExampleListVoiceCallFlow { + + public static void main(String[] args) { + if (args.length < 1) { + System.out.println("Please specify your access key, example : java -jar test_accesskey"); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the cligient + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + // Get list of call flows with offset and limit + System.out.println("Retrieving message list"); + final MessageList messageList = messageBirdClient.listCallFlow(3, null); + + // Display balance + System.out.println(messageList.toString()); + } catch (UnauthorizedException | GeneralException exception) { + if (exception.getErrors() != null) { + System.out.println(exception.getErrors().toString()); + } + exception.printStackTrace(); + } + } +} From 3f5754f925684678fdc927ea3a2b9bf6b44bc75b Mon Sep 17 00:00:00 2001 From: Dan Gurgui Date: Thu, 8 Aug 2019 17:45:43 +0200 Subject: [PATCH 002/516] Implemented unit tests and methods implementation --- .../com/messagebird/MessageBirdClient.java | 28 ++ .../messagebird/MessageBirdServiceImpl.java | 6 +- .../messagebird/objects/VoiceStepOption.java | 10 + .../objects/voicecalls/VoiceCallFlow.java | 12 - .../objects/voicecalls/VoiceCallFlowList.java | 23 +- .../voicecalls/VoiceCallFlowRequest.java | 32 +- .../voicecalls/VoiceCallFlowResponse.java | 28 +- .../java/com/messagebird/ContactTest.java | 4 + .../test/java/com/messagebird/TestUtil.java | 11 +- .../com/messagebird/VoiceCallFlowTest.java | 320 ++++++++++++------ .../fixtures/call_flow_update_response.json | 41 +++ .../resources/fixtures/call_flow_view.json | 41 +++ .../resources/fixtures/call_flows_list.json | 50 +++ .../resources/fixtures/call_flows_post.json | 41 +++ 14 files changed, 474 insertions(+), 173 deletions(-) create mode 100644 api/src/test/resources/fixtures/call_flow_update_response.json create mode 100644 api/src/test/resources/fixtures/call_flow_view.json create mode 100644 api/src/test/resources/fixtures/call_flows_list.json create mode 100644 api/src/test/resources/fixtures/call_flows_post.json diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 3a3d155e..56cf56b1 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -555,6 +555,19 @@ public VoiceCallFlowList listVoiceCallFlows(final Integer offset, final Integer return messageBirdService.requestList(url, offset, limit, VoiceCallFlowList.class); } + /** + * Retrieves the information of an existing Call Flow. You only need to supply + * the unique call flow ID that was returned upon creation or receiving. + */ + public VoiceCallFlowResponse viewVoiceCallFlow(final String id) throws NotFoundException, GeneralException, UnauthorizedException { + if (id == null) { + throw new IllegalArgumentException("Call Flow ID must be specified."); + } + String url = String.format("%s%s", VOICE_CALLS_BASE_URL, VOICECALLFLOWPATH); + + return messageBirdService.requestByID(url, id, VoiceCallFlowResponse.class); + } + /** * Convenient function to create a call flow * @@ -570,6 +583,21 @@ public VoiceCallFlowResponse sendVoiceCallFlow(final VoiceCallFlowRequest voiceC return messageBirdService.sendPayLoad(url, voiceCallFlowRequest, VoiceCallFlowResponse.class); } + /** + * Updates an existing Call Flow. You only need to supply the unique id that + * was returned upon creation. + */ + public VoiceCallFlowResponse updateVoiceCallFlow(final String id, VoiceCallFlowRequest voiceCallFlowRequest) + throws UnauthorizedException, GeneralException { + if (id == null) { + throw new IllegalArgumentException("Call Flow ID must be specified."); + } + String url = String.format("%s%s", VOICE_CALLS_BASE_URL, VOICECALLFLOWPATH); + String request = url + "/" + id; + + return messageBirdService.sendPayLoad("PUT", request, voiceCallFlowRequest, VoiceCallFlowResponse.class); + } + /** * Convenient function to delete call flow * diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 09a4f758..a4b4ab51 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -42,9 +42,10 @@ public class MessageBirdServiceImpl implements MessageBirdService { private static final String METHOD_GET = "GET"; private static final String METHOD_PATCH = "PATCH"; private static final String METHOD_POST = "POST"; + private static final String METHOD_PUT = "PUT"; - private static final List REQUEST_METHODS = Arrays.asList(METHOD_DELETE, METHOD_GET, METHOD_PATCH, METHOD_POST); - private static final List REQUEST_METHODS_WITH_PAYLOAD = Arrays.asList(METHOD_PATCH, METHOD_POST); + private static final List REQUEST_METHODS = Arrays.asList(METHOD_DELETE, METHOD_GET, METHOD_PATCH, METHOD_POST, METHOD_PUT); + private static final List REQUEST_METHODS_WITH_PAYLOAD = Arrays.asList(METHOD_PATCH, METHOD_POST, METHOD_PUT); private static final String[] PROTOCOL_LISTS = new String[]{"http://", "https://"}; private static final List PROTOCOLS = Arrays.asList(PROTOCOL_LISTS); @@ -302,6 +303,7 @@ private static String[] getAllowedMethods(String[] existingMethods) { allowedMethods.addAll(Arrays.asList(existingMethods)); allowedMethods.add(METHOD_PATCH); + allowedMethods.add(METHOD_PUT); return allowedMethods.toArray(new String[0]); } diff --git a/api/src/main/java/com/messagebird/objects/VoiceStepOption.java b/api/src/main/java/com/messagebird/objects/VoiceStepOption.java index 179513e3..33cdec54 100644 --- a/api/src/main/java/com/messagebird/objects/VoiceStepOption.java +++ b/api/src/main/java/com/messagebird/objects/VoiceStepOption.java @@ -23,6 +23,7 @@ public class VoiceStepOption implements Serializable { private String ifMachine; private int machineTimeout; private String onFinish; + private boolean mask; public String getDestination() { return destination; @@ -160,6 +161,14 @@ public void setOnFinish(String onFinish) { this.onFinish = onFinish; } + public boolean isMask() { + return mask; + } + + public void setMask(boolean mask) { + this.mask = mask; + } + @Override public String toString() { return "VoiceStepOption{" + @@ -180,6 +189,7 @@ public String toString() { ", ifMachine='" + ifMachine + '\'' + ", machineTimeout=" + machineTimeout + ", onFinish='" + onFinish + '\'' + + ", mask='" + mask + '\'' + '}'; } } diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java index b4799eef..efe00f40 100644 --- a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java @@ -23,9 +23,6 @@ public class VoiceCallFlow implements Serializable { @JsonProperty("default") private boolean defaultCall; - /* Possibly deprecated */ - private boolean defaultWebRtc; - private Date createdAt; private Date updatedAt; @@ -64,14 +61,6 @@ public void setSteps(List steps) { this.steps = steps; } - public boolean isDefaultWebRtc() { - return this.defaultWebRtc; - } - - public void setDefaultWebRtc(boolean defaultWebRtc) { - this.defaultWebRtc = defaultWebRtc; - } - public boolean isDefaultCall() { return defaultCall; } @@ -104,7 +93,6 @@ public String toString() { ", record=" + record + ", steps=" + steps + ", default=" + defaultCall + - ", defaultWebRtc=" + defaultWebRtc + ", createdAt=" + createdAt + ", updatedAt=" + updatedAt + '}'; diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowList.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowList.java index f79341b0..b5d135c8 100644 --- a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowList.java +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowList.java @@ -20,8 +20,7 @@ public class VoiceCallFlowList implements Serializable { @JsonProperty("_links") private Map links; - @JsonProperty("pagination") - private Map pagination; + private Pagination pagination; private List items; @@ -40,19 +39,27 @@ public String toString() { '}'; } + public void setPagination(Pagination pagination) { + this.pagination = pagination; + } - public Integer getOffset() { - return offset; + public Integer getTotalCount() { + return this.pagination.getTotalCount(); } - public Integer getLimit() { - return limit; + public Integer getPageCount() { + return this.pagination.getPageCount(); } - public Integer getTotalCount() { - return totalCount; + public Integer getCurrentPage() { + return this.pagination.getCurrentPage(); } + public Integer getPerPage() { + return this.pagination.getPerPage(); + } + + public List getItems() { return items; } diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowRequest.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowRequest.java index 8741f0de..3990cfb2 100644 --- a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowRequest.java +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowRequest.java @@ -18,9 +18,6 @@ public class VoiceCallFlowRequest { @JsonProperty("default") private boolean defaultCall; - private boolean defaultWebRtc; - private Date createdAt; - private Date updatedAt; public VoiceCallFlowRequest(String id) { @@ -71,40 +68,13 @@ public void setDefaultCall(boolean defaultCall) { this.defaultCall = defaultCall; } - public boolean isDefaultWebRtc() { - return defaultWebRtc; - } - - public void setDefaultWebRtc(boolean defaultWebRtc) { - this.defaultWebRtc = defaultWebRtc; - } - - public Date getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(Date createdAt) { - this.createdAt = createdAt; - } - - public Date getUpdatedAt() { - return updatedAt; - } - - public void setUpdatedAt(Date updatedAt) { - this.updatedAt = updatedAt; - } - @Override public String toString() { - return "VoiceCallFlow{" + + return "VoiceCallFlowRequest{" + "title='" + title + '\'' + ", record=" + record + ", steps=" + steps + ", default=" + defaultCall + - ", defaultWebRtc=" + defaultWebRtc + - ", createdAt=" + createdAt + - ", updatedAt=" + updatedAt + '}'; } } diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowResponse.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowResponse.java index b9e3cb12..ec4da8d0 100644 --- a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowResponse.java +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowResponse.java @@ -1,32 +1,40 @@ package com.messagebird.objects.voicecalls; -import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; + import java.io.Serializable; import java.util.List; import java.util.Map; -/* - * Used for registering the response returned by a VoiceCallFlow POST method - * @TODO add any missing information - */ public class VoiceCallFlowResponse implements Serializable { - private List data; + private static final long serialVersionUID = -3429781513863789117L; + private List data; @JsonProperty("_links") private Map links; - @JsonCreator - public VoiceCallFlowResponse(@JsonProperty("data") List data) { + public List getData() { + return data; + } + + public void setData(List data) { this.data = data; } - public List getData() { - return data; + public Map getLinks() { + return links; } public void setLinks(Map links) { this.links = links; } + + @Override + public String toString() { + return "VoiceCallResponse{" + + "data=" + data + + ", links=" + links + + '}'; + } } diff --git a/api/src/test/java/com/messagebird/ContactTest.java b/api/src/test/java/com/messagebird/ContactTest.java index d289a4fe..2377733d 100644 --- a/api/src/test/java/com/messagebird/ContactTest.java +++ b/api/src/test/java/com/messagebird/ContactTest.java @@ -10,6 +10,10 @@ import static org.mockito.Mockito.*; import static org.unitils.reflectionassert.ReflectionAssert.assertReflectionEquals; +/** + * @deprecated - This is an integration test, not a unit test and it should + * be refactored to use mocks instead of LIVE API + */ public class ContactTest { private static MessageBirdServiceImpl messageBirdService; diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index 07e5ca15..c2a29329 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -146,9 +146,6 @@ static ContactList createContactList() { return contactList; } - /* - * @TODO add more options here - */ private static VoiceStepOption createVoiceStepOption() { final VoiceStepOption voiceStepOption = new VoiceStepOption(); @@ -156,9 +153,6 @@ private static VoiceStepOption createVoiceStepOption() return voiceStepOption; } - /* - * @TODO consider expanding the voiceStep to include more options - */ public static VoiceStep createVoiceStep() { final VoiceStep voiceStep = new VoiceStep(); voiceStep.setId("ANY_ID"); @@ -167,13 +161,12 @@ public static VoiceStep createVoiceStep() { return voiceStep; } - private static VoiceCallFlow createCallFlow() { - final VoiceCallFlow voiceCallFlow = new VoiceCallFlow(); + public static VoiceCallFlowRequest createVoiceCallFlowRequest() { + final VoiceCallFlowRequest voiceCallFlow = new VoiceCallFlowRequest(); voiceCallFlow.setId("ANY_ID"); voiceCallFlow.setTitle("ANY_TITLE"); voiceCallFlow.setRecord(true); voiceCallFlow.setSteps(Collections.singletonList(createVoiceStep())); - voiceCallFlow.setDefaultWebRtc(true); voiceCallFlow.setDefaultCall(true); return voiceCallFlow; diff --git a/api/src/test/java/com/messagebird/VoiceCallFlowTest.java b/api/src/test/java/com/messagebird/VoiceCallFlowTest.java index a6c1cb58..a207cbe9 100644 --- a/api/src/test/java/com/messagebird/VoiceCallFlowTest.java +++ b/api/src/test/java/com/messagebird/VoiceCallFlowTest.java @@ -5,12 +5,14 @@ import com.messagebird.exceptions.UnauthorizedException; import com.messagebird.objects.*; import com.messagebird.objects.voicecalls.*; +import com.messagebird.util.Resources; import org.junit.*; import org.mockito.Mockito; import static org.junit.Assert.*; import static org.mockito.Mockito.*; -import static org.unitils.reflectionassert.ReflectionAssert.assertReflectionEquals; +import static java.net.HttpURLConnection.HTTP_NO_CONTENT; +import static java.net.HttpURLConnection.HTTP_NOT_FOUND; import java.util.*; /* @@ -22,128 +24,244 @@ public class VoiceCallFlowTest { private static MessageBirdServiceImpl messageBirdService; private static MessageBirdClient messageBirdClient; + private static String NOT_FOUND_ERROR = "{\"data\":null,\"errors\":[{\"message\":\"No call flow found for ID `1`.\",\"code\":13}]}"; - /** - * VoiceCallFlow object to operate on during tests. + /* + * We define a fixture and we test against the fixture all the setters and getters + * as well as the transformation of the JSON retrieved */ - private static VoiceCallFlow voiceCallFlow; - private static VoiceCallFlow voiceCallFlowFixture; - - @BeforeClass - public static void setUpClass() throws UnauthorizedException, GeneralException { - String accessKey = System.getProperty("messageBirdAccessKey"); - messageBirdService = new MessageBirdServiceImpl(accessKey); - messageBirdClient = new MessageBirdClient(messageBirdService); - voiceCallFlowFixture = new VoiceCallFlow(); - voiceCallFlowFixture.setTitle("Test Title"); - voiceCallFlowFixture.setDefaultCall(false); - voiceCallFlowFixture.setDefaultWebRtc(true); - voiceCallFlowFixture.setRecord(true); - voiceCallFlowFixture.setSteps(Collections.singletonList(TestUtil.createVoiceStep())); - VoiceCallFlowResponse voiceCallFlowResponse = createVoiceCallFlow(voiceCallFlowFixture); - voiceCallFlow = voiceCallFlowResponse.getData().get(0); + @Test + public void testCreate() throws GeneralException, UnauthorizedException { + VoiceCallFlowRequest voiceCallFlowRequest = TestUtil.createVoiceCallFlowRequest(); + String responseFixture = Resources.readResourceText("/fixtures/call_flows_post.json"); + MessageBirdService messageBirdService = SpyService + .expects("POST", "call-flows", voiceCallFlowRequest) + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse(responseFixture)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + VoiceCallFlow voiceCallFlow = messageBirdClient.sendVoiceCallFlow(voiceCallFlowRequest).getData().get(0); + this.testVoiceCallFlowAgainstFixture(voiceCallFlow); } - /* - * static method used for creating a VoiceCallFlow from the fixture defined at class level - */ - private static VoiceCallFlowResponse createVoiceCallFlow(VoiceCallFlow voiceCallFlowFixture) throws UnauthorizedException, GeneralException { - VoiceCallFlowRequest voiceCallFlowRequest = new VoiceCallFlowRequest(); - voiceCallFlowRequest.setTitle(voiceCallFlowFixture.getTitle()); - voiceCallFlowRequest.setRecord(voiceCallFlowFixture.isRecord()); - voiceCallFlowRequest.setDefaultCall(voiceCallFlowFixture.isDefaultCall()); - voiceCallFlowRequest.setSteps(voiceCallFlowFixture.getSteps()); - - return messageBirdClient.sendVoiceCallFlow(voiceCallFlowRequest); + @Test + public void testView() throws GeneralException, UnauthorizedException, NotFoundException { + String responseFixture = Resources.readResourceText("/fixtures/call_flow_view.json"); + MessageBirdService messageBirdService = SpyService + .expects("GET", "call-flows/e781a76f-14ad-45b0-8490-409300244e20") + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse(responseFixture)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + VoiceCallFlow voiceCallFlow = messageBirdClient + .viewVoiceCallFlow("e781a76f-14ad-45b0-8490-409300244e20") + .getData() + .get(0); + this.testVoiceCallFlowAgainstFixture(voiceCallFlow); } - /* - * For this test we are checking if the CallFlow inserted in the setup is visible in the list - * This way we test the Create SDK and the List method in one test - */ - @Test - public void testCreateAndList() throws UnauthorizedException, GeneralException { - VoiceCallFlowList voiceCallFlowList = messageBirdClient.listVoiceCallFlows(0, 0); - VoiceCallFlow foundVoiceCall = null; - Iterator items = voiceCallFlowList.getItems().iterator(); - while (items.hasNext()) { - VoiceCallFlow nextItem = items.next(); - if (nextItem.getId().equals(voiceCallFlow.getId())) { - foundVoiceCall = nextItem; - } - } - assertNotNull(foundVoiceCall); - assertEquals(foundVoiceCall.getTitle(), this.voiceCallFlowFixture.getTitle()); - assertEquals(foundVoiceCall.isDefaultCall(), this.voiceCallFlowFixture.isDefaultCall()); - assertEquals(foundVoiceCall.getSteps().size(), this.voiceCallFlowFixture.getSteps().size()); + @Test (expected = IllegalArgumentException.class) + public void testViewShouldThrowInvalidArgumentException() throws NotFoundException, GeneralException, UnauthorizedException { + String responseFixture = Resources.readResourceText("/fixtures/call_flow_view.json"); + MessageBirdService messageBirdService = SpyService + .expects("GET", "call-flows/e781a76f-14ad-45b0-8490-409300244e20") + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse(responseFixture)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + messageBirdClient + .viewVoiceCallFlow(null); } - /* - * In this test we are making use of the previous fixture and object defined - */ @Test - public void testUpdate() throws UnauthorizedException, GeneralException { + public void testUpdate() throws GeneralException, UnauthorizedException, NotFoundException { + String responseFixture = Resources.readResourceText("/fixtures/call_flow_update_response.json"); - } + VoiceCallFlowRequest voiceCallFlowRequest = new VoiceCallFlowRequest("e781a76f-14ad-45b0-8490-409300244e20"); + voiceCallFlowRequest.setTitle("Forward call to 316123456782"); + voiceCallFlowRequest.setDefaultCall(true); + voiceCallFlowRequest.setRecord(true); + VoiceStep voiceStep = new VoiceStep(); + voiceStep.setId("a8e44a38-b935-482f-b17f-ed3472c6292c"); + voiceStep.setAction("transfer"); + VoiceStepOption voiceStepOption = new VoiceStepOption(); + voiceStepOption.setDestination("123"); + voiceStepOption.setPayload("Test payload Update"); + voiceStepOption.setLanguage("en-US"); + voiceStepOption.setVoice("female"); + voiceStepOption.setRepeat("5"); + voiceStepOption.setMedia("test.wav"); + voiceStepOption.setLength(10); + voiceStepOption.setMaxLength(20); + voiceStepOption.setTimeout(30); + voiceStepOption.setFinishOnKey("#"); + voiceStepOption.setTranscribe(true); + voiceStepOption.setTranscribeLanguage("en-US"); + voiceStepOption.setRecord("in"); + voiceStepOption.setUrl("http://www."); + voiceStepOption.setIfMachine("machine1"); + voiceStepOption.setMachineTimeout(2000); + voiceStepOption.setOnFinish("http://www."); + voiceStepOption.setMask(false); + voiceStep.setOptions(voiceStepOption); + voiceCallFlowRequest.setSteps(Collections.singletonList(voiceStep)); - @Test - public void testView() throws UnauthorizedException, GeneralException { + MessageBirdService messageBirdService = SpyService + .expects("PUT", "call-flows/e781a76f-14ad-45b0-8490-409300244e20", voiceCallFlowRequest) + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse(responseFixture)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + + VoiceCallFlow voiceCallFlow = messageBirdClient + .updateVoiceCallFlow("e781a76f-14ad-45b0-8490-409300244e20", voiceCallFlowRequest) + .getData() + .get(0); + this.testVoiceCallFlowAgainstFixture(voiceCallFlow); + } + @Test (expected = GeneralException.class) + public void testUpdateGeneralException() throws GeneralException, UnauthorizedException { + VoiceCallFlowRequest voiceCallFlowRequest = new VoiceCallFlowRequest("123"); + MessageBirdService messageBirdService = SpyService + .expects("PUT", "call-flows/123", voiceCallFlowRequest) + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse(NOT_FOUND_ERROR, HTTP_NOT_FOUND)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + messageBirdClient + .updateVoiceCallFlow("123", voiceCallFlowRequest); } - /* - * The purpose of this method is to create various scenarios in regards - * to creating steps - */ - public void testCreateSteps() { - // null steps - // duplicate steps - // test Media field - string - // test media field - array - // test 2 Steps - // test 3 options for a step - // ensure each type of option is visible + @Test (expected = IllegalArgumentException.class) + public void testUpdateIllegalArgumentException() throws GeneralException, UnauthorizedException { + VoiceCallFlowRequest voiceCallFlowRequest = new VoiceCallFlowRequest("123"); + MessageBirdService messageBirdService = SpyService + .expects("PUT", "call-flows/123", voiceCallFlowRequest) + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse(NOT_FOUND_ERROR, HTTP_NOT_FOUND)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + messageBirdClient + .updateVoiceCallFlow(null, voiceCallFlowRequest); } - /* - * The purpose of this method is to update stepOptions and stepActions - * with various values and ensure that these values become visible - */ - public void testUpdateSteps() { - // test update for all fields - // ensure the values have been update for each field - // convert media field from string to array - // update all elements and ensure they are visible + @Test (expected = NotFoundException.class) + public void testViewNotFoundException() throws NotFoundException, GeneralException, UnauthorizedException { + String responseFixture = Resources.readResourceText("/fixtures/call_flow_view.json"); + MessageBirdService messageBirdService = SpyService + .expects("GET", "call-flows/e781a76f-14ad-45b0-8490-409300244e20") + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse(NOT_FOUND_ERROR, HTTP_NOT_FOUND)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + VoiceCallFlow voiceCallFlow = messageBirdClient + .viewVoiceCallFlow("e781a76f-14ad-45b0-8490-409300244e20") + .getData() + .get(0); + } - /** - * This method tests the create and delete at the same time. In case the delete - * fails, then the fixture inserted in setup() will still be avaialble - * on the environment and will require a separate removal - */ @Test - public void testCreateAndDelete() - throws UnauthorizedException, GeneralException, NotFoundException { - VoiceCallFlowResponse voiceCallFlowResponse = createVoiceCallFlow(voiceCallFlowFixture); - String id = voiceCallFlowResponse.getData().get(0).getId(); - messageBirdClient.deleteVoiceCallFlow( - id - ); + public void testList() throws GeneralException, UnauthorizedException { + String responseFixture = Resources.readResourceText("/fixtures/call_flows_list.json"); + MessageBirdService messageBirdService = SpyService + .expects("GET", "call-flows?offset=0&limit=0") + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse(responseFixture)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); VoiceCallFlowList voiceCallFlowList = messageBirdClient.listVoiceCallFlows(0, 0); - boolean isVoiceCallFound = false; - Iterator items = voiceCallFlowList.getItems().iterator(); - while (items.hasNext()) { - VoiceCallFlow nextItem = items.next(); - if (nextItem.getId().equals(id)) { - isVoiceCallFound = true; - } - } - assertEquals(false, isVoiceCallFound); + assertEquals((int) voiceCallFlowList.getItems().size(), 1); + assertEquals((int) voiceCallFlowList.getTotalCount(), 10); + assertEquals((int) voiceCallFlowList.getPageCount(), 3); + assertEquals((int) voiceCallFlowList.getCurrentPage(), 2); + assertEquals((int) voiceCallFlowList.getPerPage(), 12); + VoiceCallFlow voiceCallFlow = voiceCallFlowList.getItems().get(0); + this.testVoiceCallFlowAgainstFixture(voiceCallFlow); } - @AfterClass - public static void tearDown() throws UnauthorizedException, GeneralException, NotFoundException { - messageBirdClient.deleteVoiceCallFlow(voiceCallFlow.getId()); + @Test (expected = IllegalArgumentException.class) + public void testListShouldThrowInvalidArgumentException() + throws GeneralException, UnauthorizedException { + String responseFixture = Resources.readResourceText("/fixtures/call_flows_list.json"); + MessageBirdService messageBirdService = SpyService + .expects("GET", "call-flows?offset=0&limit=0") + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse(responseFixture)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + VoiceCallFlowList voiceCallFlowList = messageBirdClient.listVoiceCallFlows(-1, 0); + } + + @Test (expected = IllegalArgumentException.class) + public void testListShouldThrowInvalidArgumentExceptionForLimit() + throws GeneralException, UnauthorizedException { + String responseFixture = Resources.readResourceText("/fixtures/call_flows_list.json"); + MessageBirdService messageBirdService = SpyService + .expects("GET", "call-flows?offset=0&limit=0") + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse(responseFixture)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + VoiceCallFlowList voiceCallFlowList = messageBirdClient.listVoiceCallFlows(0, -1); + } + + @Test + public void testDelete() throws GeneralException, UnauthorizedException, NotFoundException { + MessageBirdService messageBirdService = SpyService + .expects("DELETE", "call-flows/123abc") + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse("", HTTP_NO_CONTENT)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + messageBirdClient.deleteVoiceCallFlow("123abc"); + } + + @Test (expected = NotFoundException.class) + public void testDeleteNotFoundException() throws NotFoundException, GeneralException, UnauthorizedException { + // test not found exception + MessageBirdService messageBirdService = SpyService + .expects("DELETE", "call-flows/123abc") + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse("", HTTP_NOT_FOUND)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + messageBirdClient.deleteVoiceCallFlow("123abc"); + } + + @Test (expected = IllegalArgumentException.class) + public void testDeleteIllegalArgumentException() throws NotFoundException, GeneralException, UnauthorizedException { + // test not found exception + MessageBirdService messageBirdService = SpyService + .expects("DELETE", "call-flows/123abc") + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse("", HTTP_NOT_FOUND)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + messageBirdClient.deleteVoiceCallFlow(null); + } + + /** + * In order to reuse this method for further tests you need to make sure that the fixtures + * match the date in this test. See call_flows_post.json + */ + private void testVoiceCallFlowAgainstFixture(VoiceCallFlow voiceCallFlow) { + assertEquals(voiceCallFlow.getId(), "e781a76f-14ad-45b0-8490-409300244e20"); + assertEquals(voiceCallFlow.getTitle(), "Forward call to 31612345678"); + assertEquals(voiceCallFlow.isRecord(), true); + assertEquals(voiceCallFlow.isDefaultCall(), false); + assertEquals(voiceCallFlow.getCreatedAt().toString(), "Tue Aug 06 16:13:06 CEST 2019"); + assertEquals(voiceCallFlow.getUpdatedAt().toString(), "Tue Aug 06 16:13:06 CEST 2019"); + assertEquals(voiceCallFlow.getSteps().size(), 1); + VoiceStep voiceStep = voiceCallFlow.getSteps().get(0); + assertEquals(voiceStep.getId(), "a8e44a38-b935-482f-b17f-ed3472c6292c"); + assertEquals(voiceStep.getAction(), "transfer"); + VoiceStepOption voiceStepOption = voiceStep.getOptions(); + assertEquals(voiceStepOption.getDestination(), "31612345678"); + assertEquals(voiceStepOption.getPayload(), "Test payload"); + assertEquals(voiceStepOption.getLanguage(), "en-GB"); + assertEquals(voiceStepOption.getVoice(), "male"); + assertEquals(voiceStepOption.getRepeat(), "1"); + assertEquals(voiceStepOption.getMedia(), "test.mp3"); + assertEquals(voiceStepOption.getFinishOnKey(), "1"); + assertEquals(voiceStepOption.getTranscribeLanguage(), "en-GB"); + assertEquals(voiceStepOption.getRecord(), "both"); + assertEquals(voiceStepOption.getUrl(), "http://"); + assertEquals(voiceStepOption.getIfMachine(), "ifMachine"); + assertEquals(voiceStepOption.getMachineTimeout(), 200); + assertEquals(voiceStepOption.getOnFinish(), "http://"); + assertEquals(voiceStepOption.getLength(), 1); + assertEquals(voiceStepOption.getTimeout(), 3); + assertEquals(voiceStepOption.getMaxLength(), 2); + assertEquals(voiceStepOption.isTranscribe(), false); } } diff --git a/api/src/test/resources/fixtures/call_flow_update_response.json b/api/src/test/resources/fixtures/call_flow_update_response.json new file mode 100644 index 00000000..7659ccfa --- /dev/null +++ b/api/src/test/resources/fixtures/call_flow_update_response.json @@ -0,0 +1,41 @@ +{ + "data": [ + { + "id": "e781a76f-14ad-45b0-8490-409300244e20", + "title": "Forward call to 31612345678", + "steps": [ + { + "id": "a8e44a38-b935-482f-b17f-ed3472c6292c", + "action": "transfer", + "options": { + "destination" : "31612345678", + "payload" : "Test payload", + "language" : "en-GB", + "voice" : "male", + "repeat" : "1", + "media" : "test.mp3", + "length" : 1, + "maxLength" : 2, + "timeout" : 3, + "finishOnKey" : "1", + "transcribe" : "false", + "transcribeLanguage" : "en-GB", + "record" : "both", + "url" : "http://", + "ifMachine" : "ifMachine", + "machineTimeout" : 200, + "onFinish" : "http://", + "mask" : false + } + } + ], + "record": true, + "default": false, + "createdAt": "2019-08-06T14:13:06Z", + "updatedAt": "2019-08-06T14:13:06Z" + } + ], + "_links": { + "self": "/call-flows/e781a76f-14ad-45b0-8490-409300244e20" + } +} \ No newline at end of file diff --git a/api/src/test/resources/fixtures/call_flow_view.json b/api/src/test/resources/fixtures/call_flow_view.json new file mode 100644 index 00000000..8feed38d --- /dev/null +++ b/api/src/test/resources/fixtures/call_flow_view.json @@ -0,0 +1,41 @@ +{ + "data": [ + { + "id": "e781a76f-14ad-45b0-8490-409300244e20", + "title": "Forward call to 31612345678", + "steps": [ + { + "id": "a8e44a38-b935-482f-b17f-ed3472c6292c", + "action": "transfer", + "options": { + "destination" : "31612345678", + "payload" : "Test payload", + "language" : "en-GB", + "voice" : "male", + "repeat" : "1", + "media" : "test.mp3", + "length" : 1, + "maxLength" : 2, + "timeout" : 3, + "finishOnKey" : "1", + "transcribe" : "false", + "transcribeLanguage" : "en-GB", + "record" : "both", + "url" : "http://", + "ifMachine" : "ifMachine", + "machineTimeout" : 200, + "onFinish" : "http://", + "mask" : false + } + } + ], + "record": true, + "default": false, + "createdAt": "2019-08-06T14:13:06Z", + "updatedAt": "2019-08-06T14:13:06Z" + } + ], + "_links": { + "self": "/call-flows/70fbdda2-4f1f-44ce-8792-75af32cf598c" + } +} \ No newline at end of file diff --git a/api/src/test/resources/fixtures/call_flows_list.json b/api/src/test/resources/fixtures/call_flows_list.json new file mode 100644 index 00000000..0cebcef1 --- /dev/null +++ b/api/src/test/resources/fixtures/call_flows_list.json @@ -0,0 +1,50 @@ +{ + "data": [ + { + "id": "e781a76f-14ad-45b0-8490-409300244e20", + "title": "Forward call to 31612345678", + "steps": [ + { + "id": "a8e44a38-b935-482f-b17f-ed3472c6292c", + "action": "transfer", + "options": { + "destination" : "31612345678", + "payload" : "Test payload", + "language" : "en-GB", + "voice" : "male", + "repeat" : "1", + "media" : "test.mp3", + "length" : 1, + "maxLength" : 2, + "timeout" : 3, + "finishOnKey" : "1", + "transcribe" : "false", + "transcribeLanguage" : "en-GB", + "record" : "both", + "url" : "http://", + "ifMachine" : "ifMachine", + "machineTimeout" : 200, + "onFinish" : "http://", + "mask" : false + } + } + ], + "record": true, + "default": false, + "createdAt": "2019-08-06T14:13:06Z", + "updatedAt": "2019-08-06T14:13:06Z", + "_links": { + "self": "/call-flows/70fbdda2-4f1f-44ce-8792-75af32cf598c" + } + } + ], + "_links": { + "self": "/call-flows?page=1" + }, + "pagination": { + "totalCount": 10, + "pageCount": 3, + "currentPage": 2, + "perPage": 12 + } +} \ No newline at end of file diff --git a/api/src/test/resources/fixtures/call_flows_post.json b/api/src/test/resources/fixtures/call_flows_post.json new file mode 100644 index 00000000..7659ccfa --- /dev/null +++ b/api/src/test/resources/fixtures/call_flows_post.json @@ -0,0 +1,41 @@ +{ + "data": [ + { + "id": "e781a76f-14ad-45b0-8490-409300244e20", + "title": "Forward call to 31612345678", + "steps": [ + { + "id": "a8e44a38-b935-482f-b17f-ed3472c6292c", + "action": "transfer", + "options": { + "destination" : "31612345678", + "payload" : "Test payload", + "language" : "en-GB", + "voice" : "male", + "repeat" : "1", + "media" : "test.mp3", + "length" : 1, + "maxLength" : 2, + "timeout" : 3, + "finishOnKey" : "1", + "transcribe" : "false", + "transcribeLanguage" : "en-GB", + "record" : "both", + "url" : "http://", + "ifMachine" : "ifMachine", + "machineTimeout" : 200, + "onFinish" : "http://", + "mask" : false + } + } + ], + "record": true, + "default": false, + "createdAt": "2019-08-06T14:13:06Z", + "updatedAt": "2019-08-06T14:13:06Z" + } + ], + "_links": { + "self": "/call-flows/e781a76f-14ad-45b0-8490-409300244e20" + } +} \ No newline at end of file From df21520d2292e6b13202905bdb72fc68b903461b Mon Sep 17 00:00:00 2001 From: Dan Gurgui Date: Thu, 8 Aug 2019 17:45:43 +0200 Subject: [PATCH 003/516] Implemented unit tests and methods --- .../com/messagebird/MessageBirdClient.java | 28 ++ .../messagebird/MessageBirdServiceImpl.java | 6 +- .../messagebird/objects/VoiceStepOption.java | 10 + .../objects/voicecalls/VoiceCallFlow.java | 12 - .../objects/voicecalls/VoiceCallFlowList.java | 23 +- .../voicecalls/VoiceCallFlowRequest.java | 32 +- .../voicecalls/VoiceCallFlowResponse.java | 28 +- .../java/com/messagebird/ContactTest.java | 4 + .../test/java/com/messagebird/TestUtil.java | 11 +- .../com/messagebird/VoiceCallFlowTest.java | 320 ++++++++++++------ .../fixtures/call_flow_update_response.json | 41 +++ .../resources/fixtures/call_flow_view.json | 41 +++ .../resources/fixtures/call_flows_list.json | 50 +++ .../resources/fixtures/call_flows_post.json | 41 +++ 14 files changed, 474 insertions(+), 173 deletions(-) create mode 100644 api/src/test/resources/fixtures/call_flow_update_response.json create mode 100644 api/src/test/resources/fixtures/call_flow_view.json create mode 100644 api/src/test/resources/fixtures/call_flows_list.json create mode 100644 api/src/test/resources/fixtures/call_flows_post.json diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 3a3d155e..56cf56b1 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -555,6 +555,19 @@ public VoiceCallFlowList listVoiceCallFlows(final Integer offset, final Integer return messageBirdService.requestList(url, offset, limit, VoiceCallFlowList.class); } + /** + * Retrieves the information of an existing Call Flow. You only need to supply + * the unique call flow ID that was returned upon creation or receiving. + */ + public VoiceCallFlowResponse viewVoiceCallFlow(final String id) throws NotFoundException, GeneralException, UnauthorizedException { + if (id == null) { + throw new IllegalArgumentException("Call Flow ID must be specified."); + } + String url = String.format("%s%s", VOICE_CALLS_BASE_URL, VOICECALLFLOWPATH); + + return messageBirdService.requestByID(url, id, VoiceCallFlowResponse.class); + } + /** * Convenient function to create a call flow * @@ -570,6 +583,21 @@ public VoiceCallFlowResponse sendVoiceCallFlow(final VoiceCallFlowRequest voiceC return messageBirdService.sendPayLoad(url, voiceCallFlowRequest, VoiceCallFlowResponse.class); } + /** + * Updates an existing Call Flow. You only need to supply the unique id that + * was returned upon creation. + */ + public VoiceCallFlowResponse updateVoiceCallFlow(final String id, VoiceCallFlowRequest voiceCallFlowRequest) + throws UnauthorizedException, GeneralException { + if (id == null) { + throw new IllegalArgumentException("Call Flow ID must be specified."); + } + String url = String.format("%s%s", VOICE_CALLS_BASE_URL, VOICECALLFLOWPATH); + String request = url + "/" + id; + + return messageBirdService.sendPayLoad("PUT", request, voiceCallFlowRequest, VoiceCallFlowResponse.class); + } + /** * Convenient function to delete call flow * diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 09a4f758..a4b4ab51 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -42,9 +42,10 @@ public class MessageBirdServiceImpl implements MessageBirdService { private static final String METHOD_GET = "GET"; private static final String METHOD_PATCH = "PATCH"; private static final String METHOD_POST = "POST"; + private static final String METHOD_PUT = "PUT"; - private static final List REQUEST_METHODS = Arrays.asList(METHOD_DELETE, METHOD_GET, METHOD_PATCH, METHOD_POST); - private static final List REQUEST_METHODS_WITH_PAYLOAD = Arrays.asList(METHOD_PATCH, METHOD_POST); + private static final List REQUEST_METHODS = Arrays.asList(METHOD_DELETE, METHOD_GET, METHOD_PATCH, METHOD_POST, METHOD_PUT); + private static final List REQUEST_METHODS_WITH_PAYLOAD = Arrays.asList(METHOD_PATCH, METHOD_POST, METHOD_PUT); private static final String[] PROTOCOL_LISTS = new String[]{"http://", "https://"}; private static final List PROTOCOLS = Arrays.asList(PROTOCOL_LISTS); @@ -302,6 +303,7 @@ private static String[] getAllowedMethods(String[] existingMethods) { allowedMethods.addAll(Arrays.asList(existingMethods)); allowedMethods.add(METHOD_PATCH); + allowedMethods.add(METHOD_PUT); return allowedMethods.toArray(new String[0]); } diff --git a/api/src/main/java/com/messagebird/objects/VoiceStepOption.java b/api/src/main/java/com/messagebird/objects/VoiceStepOption.java index 179513e3..33cdec54 100644 --- a/api/src/main/java/com/messagebird/objects/VoiceStepOption.java +++ b/api/src/main/java/com/messagebird/objects/VoiceStepOption.java @@ -23,6 +23,7 @@ public class VoiceStepOption implements Serializable { private String ifMachine; private int machineTimeout; private String onFinish; + private boolean mask; public String getDestination() { return destination; @@ -160,6 +161,14 @@ public void setOnFinish(String onFinish) { this.onFinish = onFinish; } + public boolean isMask() { + return mask; + } + + public void setMask(boolean mask) { + this.mask = mask; + } + @Override public String toString() { return "VoiceStepOption{" + @@ -180,6 +189,7 @@ public String toString() { ", ifMachine='" + ifMachine + '\'' + ", machineTimeout=" + machineTimeout + ", onFinish='" + onFinish + '\'' + + ", mask='" + mask + '\'' + '}'; } } diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java index b4799eef..efe00f40 100644 --- a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java @@ -23,9 +23,6 @@ public class VoiceCallFlow implements Serializable { @JsonProperty("default") private boolean defaultCall; - /* Possibly deprecated */ - private boolean defaultWebRtc; - private Date createdAt; private Date updatedAt; @@ -64,14 +61,6 @@ public void setSteps(List steps) { this.steps = steps; } - public boolean isDefaultWebRtc() { - return this.defaultWebRtc; - } - - public void setDefaultWebRtc(boolean defaultWebRtc) { - this.defaultWebRtc = defaultWebRtc; - } - public boolean isDefaultCall() { return defaultCall; } @@ -104,7 +93,6 @@ public String toString() { ", record=" + record + ", steps=" + steps + ", default=" + defaultCall + - ", defaultWebRtc=" + defaultWebRtc + ", createdAt=" + createdAt + ", updatedAt=" + updatedAt + '}'; diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowList.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowList.java index f79341b0..b5d135c8 100644 --- a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowList.java +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowList.java @@ -20,8 +20,7 @@ public class VoiceCallFlowList implements Serializable { @JsonProperty("_links") private Map links; - @JsonProperty("pagination") - private Map pagination; + private Pagination pagination; private List items; @@ -40,19 +39,27 @@ public String toString() { '}'; } + public void setPagination(Pagination pagination) { + this.pagination = pagination; + } - public Integer getOffset() { - return offset; + public Integer getTotalCount() { + return this.pagination.getTotalCount(); } - public Integer getLimit() { - return limit; + public Integer getPageCount() { + return this.pagination.getPageCount(); } - public Integer getTotalCount() { - return totalCount; + public Integer getCurrentPage() { + return this.pagination.getCurrentPage(); } + public Integer getPerPage() { + return this.pagination.getPerPage(); + } + + public List getItems() { return items; } diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowRequest.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowRequest.java index 8741f0de..3990cfb2 100644 --- a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowRequest.java +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowRequest.java @@ -18,9 +18,6 @@ public class VoiceCallFlowRequest { @JsonProperty("default") private boolean defaultCall; - private boolean defaultWebRtc; - private Date createdAt; - private Date updatedAt; public VoiceCallFlowRequest(String id) { @@ -71,40 +68,13 @@ public void setDefaultCall(boolean defaultCall) { this.defaultCall = defaultCall; } - public boolean isDefaultWebRtc() { - return defaultWebRtc; - } - - public void setDefaultWebRtc(boolean defaultWebRtc) { - this.defaultWebRtc = defaultWebRtc; - } - - public Date getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(Date createdAt) { - this.createdAt = createdAt; - } - - public Date getUpdatedAt() { - return updatedAt; - } - - public void setUpdatedAt(Date updatedAt) { - this.updatedAt = updatedAt; - } - @Override public String toString() { - return "VoiceCallFlow{" + + return "VoiceCallFlowRequest{" + "title='" + title + '\'' + ", record=" + record + ", steps=" + steps + ", default=" + defaultCall + - ", defaultWebRtc=" + defaultWebRtc + - ", createdAt=" + createdAt + - ", updatedAt=" + updatedAt + '}'; } } diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowResponse.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowResponse.java index b9e3cb12..ec4da8d0 100644 --- a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowResponse.java +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowResponse.java @@ -1,32 +1,40 @@ package com.messagebird.objects.voicecalls; -import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; + import java.io.Serializable; import java.util.List; import java.util.Map; -/* - * Used for registering the response returned by a VoiceCallFlow POST method - * @TODO add any missing information - */ public class VoiceCallFlowResponse implements Serializable { - private List data; + private static final long serialVersionUID = -3429781513863789117L; + private List data; @JsonProperty("_links") private Map links; - @JsonCreator - public VoiceCallFlowResponse(@JsonProperty("data") List data) { + public List getData() { + return data; + } + + public void setData(List data) { this.data = data; } - public List getData() { - return data; + public Map getLinks() { + return links; } public void setLinks(Map links) { this.links = links; } + + @Override + public String toString() { + return "VoiceCallResponse{" + + "data=" + data + + ", links=" + links + + '}'; + } } diff --git a/api/src/test/java/com/messagebird/ContactTest.java b/api/src/test/java/com/messagebird/ContactTest.java index d289a4fe..2377733d 100644 --- a/api/src/test/java/com/messagebird/ContactTest.java +++ b/api/src/test/java/com/messagebird/ContactTest.java @@ -10,6 +10,10 @@ import static org.mockito.Mockito.*; import static org.unitils.reflectionassert.ReflectionAssert.assertReflectionEquals; +/** + * @deprecated - This is an integration test, not a unit test and it should + * be refactored to use mocks instead of LIVE API + */ public class ContactTest { private static MessageBirdServiceImpl messageBirdService; diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index 07e5ca15..c2a29329 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -146,9 +146,6 @@ static ContactList createContactList() { return contactList; } - /* - * @TODO add more options here - */ private static VoiceStepOption createVoiceStepOption() { final VoiceStepOption voiceStepOption = new VoiceStepOption(); @@ -156,9 +153,6 @@ private static VoiceStepOption createVoiceStepOption() return voiceStepOption; } - /* - * @TODO consider expanding the voiceStep to include more options - */ public static VoiceStep createVoiceStep() { final VoiceStep voiceStep = new VoiceStep(); voiceStep.setId("ANY_ID"); @@ -167,13 +161,12 @@ public static VoiceStep createVoiceStep() { return voiceStep; } - private static VoiceCallFlow createCallFlow() { - final VoiceCallFlow voiceCallFlow = new VoiceCallFlow(); + public static VoiceCallFlowRequest createVoiceCallFlowRequest() { + final VoiceCallFlowRequest voiceCallFlow = new VoiceCallFlowRequest(); voiceCallFlow.setId("ANY_ID"); voiceCallFlow.setTitle("ANY_TITLE"); voiceCallFlow.setRecord(true); voiceCallFlow.setSteps(Collections.singletonList(createVoiceStep())); - voiceCallFlow.setDefaultWebRtc(true); voiceCallFlow.setDefaultCall(true); return voiceCallFlow; diff --git a/api/src/test/java/com/messagebird/VoiceCallFlowTest.java b/api/src/test/java/com/messagebird/VoiceCallFlowTest.java index a6c1cb58..a207cbe9 100644 --- a/api/src/test/java/com/messagebird/VoiceCallFlowTest.java +++ b/api/src/test/java/com/messagebird/VoiceCallFlowTest.java @@ -5,12 +5,14 @@ import com.messagebird.exceptions.UnauthorizedException; import com.messagebird.objects.*; import com.messagebird.objects.voicecalls.*; +import com.messagebird.util.Resources; import org.junit.*; import org.mockito.Mockito; import static org.junit.Assert.*; import static org.mockito.Mockito.*; -import static org.unitils.reflectionassert.ReflectionAssert.assertReflectionEquals; +import static java.net.HttpURLConnection.HTTP_NO_CONTENT; +import static java.net.HttpURLConnection.HTTP_NOT_FOUND; import java.util.*; /* @@ -22,128 +24,244 @@ public class VoiceCallFlowTest { private static MessageBirdServiceImpl messageBirdService; private static MessageBirdClient messageBirdClient; + private static String NOT_FOUND_ERROR = "{\"data\":null,\"errors\":[{\"message\":\"No call flow found for ID `1`.\",\"code\":13}]}"; - /** - * VoiceCallFlow object to operate on during tests. + /* + * We define a fixture and we test against the fixture all the setters and getters + * as well as the transformation of the JSON retrieved */ - private static VoiceCallFlow voiceCallFlow; - private static VoiceCallFlow voiceCallFlowFixture; - - @BeforeClass - public static void setUpClass() throws UnauthorizedException, GeneralException { - String accessKey = System.getProperty("messageBirdAccessKey"); - messageBirdService = new MessageBirdServiceImpl(accessKey); - messageBirdClient = new MessageBirdClient(messageBirdService); - voiceCallFlowFixture = new VoiceCallFlow(); - voiceCallFlowFixture.setTitle("Test Title"); - voiceCallFlowFixture.setDefaultCall(false); - voiceCallFlowFixture.setDefaultWebRtc(true); - voiceCallFlowFixture.setRecord(true); - voiceCallFlowFixture.setSteps(Collections.singletonList(TestUtil.createVoiceStep())); - VoiceCallFlowResponse voiceCallFlowResponse = createVoiceCallFlow(voiceCallFlowFixture); - voiceCallFlow = voiceCallFlowResponse.getData().get(0); + @Test + public void testCreate() throws GeneralException, UnauthorizedException { + VoiceCallFlowRequest voiceCallFlowRequest = TestUtil.createVoiceCallFlowRequest(); + String responseFixture = Resources.readResourceText("/fixtures/call_flows_post.json"); + MessageBirdService messageBirdService = SpyService + .expects("POST", "call-flows", voiceCallFlowRequest) + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse(responseFixture)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + VoiceCallFlow voiceCallFlow = messageBirdClient.sendVoiceCallFlow(voiceCallFlowRequest).getData().get(0); + this.testVoiceCallFlowAgainstFixture(voiceCallFlow); } - /* - * static method used for creating a VoiceCallFlow from the fixture defined at class level - */ - private static VoiceCallFlowResponse createVoiceCallFlow(VoiceCallFlow voiceCallFlowFixture) throws UnauthorizedException, GeneralException { - VoiceCallFlowRequest voiceCallFlowRequest = new VoiceCallFlowRequest(); - voiceCallFlowRequest.setTitle(voiceCallFlowFixture.getTitle()); - voiceCallFlowRequest.setRecord(voiceCallFlowFixture.isRecord()); - voiceCallFlowRequest.setDefaultCall(voiceCallFlowFixture.isDefaultCall()); - voiceCallFlowRequest.setSteps(voiceCallFlowFixture.getSteps()); - - return messageBirdClient.sendVoiceCallFlow(voiceCallFlowRequest); + @Test + public void testView() throws GeneralException, UnauthorizedException, NotFoundException { + String responseFixture = Resources.readResourceText("/fixtures/call_flow_view.json"); + MessageBirdService messageBirdService = SpyService + .expects("GET", "call-flows/e781a76f-14ad-45b0-8490-409300244e20") + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse(responseFixture)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + VoiceCallFlow voiceCallFlow = messageBirdClient + .viewVoiceCallFlow("e781a76f-14ad-45b0-8490-409300244e20") + .getData() + .get(0); + this.testVoiceCallFlowAgainstFixture(voiceCallFlow); } - /* - * For this test we are checking if the CallFlow inserted in the setup is visible in the list - * This way we test the Create SDK and the List method in one test - */ - @Test - public void testCreateAndList() throws UnauthorizedException, GeneralException { - VoiceCallFlowList voiceCallFlowList = messageBirdClient.listVoiceCallFlows(0, 0); - VoiceCallFlow foundVoiceCall = null; - Iterator items = voiceCallFlowList.getItems().iterator(); - while (items.hasNext()) { - VoiceCallFlow nextItem = items.next(); - if (nextItem.getId().equals(voiceCallFlow.getId())) { - foundVoiceCall = nextItem; - } - } - assertNotNull(foundVoiceCall); - assertEquals(foundVoiceCall.getTitle(), this.voiceCallFlowFixture.getTitle()); - assertEquals(foundVoiceCall.isDefaultCall(), this.voiceCallFlowFixture.isDefaultCall()); - assertEquals(foundVoiceCall.getSteps().size(), this.voiceCallFlowFixture.getSteps().size()); + @Test (expected = IllegalArgumentException.class) + public void testViewShouldThrowInvalidArgumentException() throws NotFoundException, GeneralException, UnauthorizedException { + String responseFixture = Resources.readResourceText("/fixtures/call_flow_view.json"); + MessageBirdService messageBirdService = SpyService + .expects("GET", "call-flows/e781a76f-14ad-45b0-8490-409300244e20") + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse(responseFixture)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + messageBirdClient + .viewVoiceCallFlow(null); } - /* - * In this test we are making use of the previous fixture and object defined - */ @Test - public void testUpdate() throws UnauthorizedException, GeneralException { + public void testUpdate() throws GeneralException, UnauthorizedException, NotFoundException { + String responseFixture = Resources.readResourceText("/fixtures/call_flow_update_response.json"); - } + VoiceCallFlowRequest voiceCallFlowRequest = new VoiceCallFlowRequest("e781a76f-14ad-45b0-8490-409300244e20"); + voiceCallFlowRequest.setTitle("Forward call to 316123456782"); + voiceCallFlowRequest.setDefaultCall(true); + voiceCallFlowRequest.setRecord(true); + VoiceStep voiceStep = new VoiceStep(); + voiceStep.setId("a8e44a38-b935-482f-b17f-ed3472c6292c"); + voiceStep.setAction("transfer"); + VoiceStepOption voiceStepOption = new VoiceStepOption(); + voiceStepOption.setDestination("123"); + voiceStepOption.setPayload("Test payload Update"); + voiceStepOption.setLanguage("en-US"); + voiceStepOption.setVoice("female"); + voiceStepOption.setRepeat("5"); + voiceStepOption.setMedia("test.wav"); + voiceStepOption.setLength(10); + voiceStepOption.setMaxLength(20); + voiceStepOption.setTimeout(30); + voiceStepOption.setFinishOnKey("#"); + voiceStepOption.setTranscribe(true); + voiceStepOption.setTranscribeLanguage("en-US"); + voiceStepOption.setRecord("in"); + voiceStepOption.setUrl("http://www."); + voiceStepOption.setIfMachine("machine1"); + voiceStepOption.setMachineTimeout(2000); + voiceStepOption.setOnFinish("http://www."); + voiceStepOption.setMask(false); + voiceStep.setOptions(voiceStepOption); + voiceCallFlowRequest.setSteps(Collections.singletonList(voiceStep)); - @Test - public void testView() throws UnauthorizedException, GeneralException { + MessageBirdService messageBirdService = SpyService + .expects("PUT", "call-flows/e781a76f-14ad-45b0-8490-409300244e20", voiceCallFlowRequest) + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse(responseFixture)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + + VoiceCallFlow voiceCallFlow = messageBirdClient + .updateVoiceCallFlow("e781a76f-14ad-45b0-8490-409300244e20", voiceCallFlowRequest) + .getData() + .get(0); + this.testVoiceCallFlowAgainstFixture(voiceCallFlow); + } + @Test (expected = GeneralException.class) + public void testUpdateGeneralException() throws GeneralException, UnauthorizedException { + VoiceCallFlowRequest voiceCallFlowRequest = new VoiceCallFlowRequest("123"); + MessageBirdService messageBirdService = SpyService + .expects("PUT", "call-flows/123", voiceCallFlowRequest) + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse(NOT_FOUND_ERROR, HTTP_NOT_FOUND)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + messageBirdClient + .updateVoiceCallFlow("123", voiceCallFlowRequest); } - /* - * The purpose of this method is to create various scenarios in regards - * to creating steps - */ - public void testCreateSteps() { - // null steps - // duplicate steps - // test Media field - string - // test media field - array - // test 2 Steps - // test 3 options for a step - // ensure each type of option is visible + @Test (expected = IllegalArgumentException.class) + public void testUpdateIllegalArgumentException() throws GeneralException, UnauthorizedException { + VoiceCallFlowRequest voiceCallFlowRequest = new VoiceCallFlowRequest("123"); + MessageBirdService messageBirdService = SpyService + .expects("PUT", "call-flows/123", voiceCallFlowRequest) + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse(NOT_FOUND_ERROR, HTTP_NOT_FOUND)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + messageBirdClient + .updateVoiceCallFlow(null, voiceCallFlowRequest); } - /* - * The purpose of this method is to update stepOptions and stepActions - * with various values and ensure that these values become visible - */ - public void testUpdateSteps() { - // test update for all fields - // ensure the values have been update for each field - // convert media field from string to array - // update all elements and ensure they are visible + @Test (expected = NotFoundException.class) + public void testViewNotFoundException() throws NotFoundException, GeneralException, UnauthorizedException { + String responseFixture = Resources.readResourceText("/fixtures/call_flow_view.json"); + MessageBirdService messageBirdService = SpyService + .expects("GET", "call-flows/e781a76f-14ad-45b0-8490-409300244e20") + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse(NOT_FOUND_ERROR, HTTP_NOT_FOUND)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + VoiceCallFlow voiceCallFlow = messageBirdClient + .viewVoiceCallFlow("e781a76f-14ad-45b0-8490-409300244e20") + .getData() + .get(0); + } - /** - * This method tests the create and delete at the same time. In case the delete - * fails, then the fixture inserted in setup() will still be avaialble - * on the environment and will require a separate removal - */ @Test - public void testCreateAndDelete() - throws UnauthorizedException, GeneralException, NotFoundException { - VoiceCallFlowResponse voiceCallFlowResponse = createVoiceCallFlow(voiceCallFlowFixture); - String id = voiceCallFlowResponse.getData().get(0).getId(); - messageBirdClient.deleteVoiceCallFlow( - id - ); + public void testList() throws GeneralException, UnauthorizedException { + String responseFixture = Resources.readResourceText("/fixtures/call_flows_list.json"); + MessageBirdService messageBirdService = SpyService + .expects("GET", "call-flows?offset=0&limit=0") + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse(responseFixture)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); VoiceCallFlowList voiceCallFlowList = messageBirdClient.listVoiceCallFlows(0, 0); - boolean isVoiceCallFound = false; - Iterator items = voiceCallFlowList.getItems().iterator(); - while (items.hasNext()) { - VoiceCallFlow nextItem = items.next(); - if (nextItem.getId().equals(id)) { - isVoiceCallFound = true; - } - } - assertEquals(false, isVoiceCallFound); + assertEquals((int) voiceCallFlowList.getItems().size(), 1); + assertEquals((int) voiceCallFlowList.getTotalCount(), 10); + assertEquals((int) voiceCallFlowList.getPageCount(), 3); + assertEquals((int) voiceCallFlowList.getCurrentPage(), 2); + assertEquals((int) voiceCallFlowList.getPerPage(), 12); + VoiceCallFlow voiceCallFlow = voiceCallFlowList.getItems().get(0); + this.testVoiceCallFlowAgainstFixture(voiceCallFlow); } - @AfterClass - public static void tearDown() throws UnauthorizedException, GeneralException, NotFoundException { - messageBirdClient.deleteVoiceCallFlow(voiceCallFlow.getId()); + @Test (expected = IllegalArgumentException.class) + public void testListShouldThrowInvalidArgumentException() + throws GeneralException, UnauthorizedException { + String responseFixture = Resources.readResourceText("/fixtures/call_flows_list.json"); + MessageBirdService messageBirdService = SpyService + .expects("GET", "call-flows?offset=0&limit=0") + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse(responseFixture)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + VoiceCallFlowList voiceCallFlowList = messageBirdClient.listVoiceCallFlows(-1, 0); + } + + @Test (expected = IllegalArgumentException.class) + public void testListShouldThrowInvalidArgumentExceptionForLimit() + throws GeneralException, UnauthorizedException { + String responseFixture = Resources.readResourceText("/fixtures/call_flows_list.json"); + MessageBirdService messageBirdService = SpyService + .expects("GET", "call-flows?offset=0&limit=0") + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse(responseFixture)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + VoiceCallFlowList voiceCallFlowList = messageBirdClient.listVoiceCallFlows(0, -1); + } + + @Test + public void testDelete() throws GeneralException, UnauthorizedException, NotFoundException { + MessageBirdService messageBirdService = SpyService + .expects("DELETE", "call-flows/123abc") + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse("", HTTP_NO_CONTENT)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + messageBirdClient.deleteVoiceCallFlow("123abc"); + } + + @Test (expected = NotFoundException.class) + public void testDeleteNotFoundException() throws NotFoundException, GeneralException, UnauthorizedException { + // test not found exception + MessageBirdService messageBirdService = SpyService + .expects("DELETE", "call-flows/123abc") + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse("", HTTP_NOT_FOUND)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + messageBirdClient.deleteVoiceCallFlow("123abc"); + } + + @Test (expected = IllegalArgumentException.class) + public void testDeleteIllegalArgumentException() throws NotFoundException, GeneralException, UnauthorizedException { + // test not found exception + MessageBirdService messageBirdService = SpyService + .expects("DELETE", "call-flows/123abc") + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse("", HTTP_NOT_FOUND)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + messageBirdClient.deleteVoiceCallFlow(null); + } + + /** + * In order to reuse this method for further tests you need to make sure that the fixtures + * match the date in this test. See call_flows_post.json + */ + private void testVoiceCallFlowAgainstFixture(VoiceCallFlow voiceCallFlow) { + assertEquals(voiceCallFlow.getId(), "e781a76f-14ad-45b0-8490-409300244e20"); + assertEquals(voiceCallFlow.getTitle(), "Forward call to 31612345678"); + assertEquals(voiceCallFlow.isRecord(), true); + assertEquals(voiceCallFlow.isDefaultCall(), false); + assertEquals(voiceCallFlow.getCreatedAt().toString(), "Tue Aug 06 16:13:06 CEST 2019"); + assertEquals(voiceCallFlow.getUpdatedAt().toString(), "Tue Aug 06 16:13:06 CEST 2019"); + assertEquals(voiceCallFlow.getSteps().size(), 1); + VoiceStep voiceStep = voiceCallFlow.getSteps().get(0); + assertEquals(voiceStep.getId(), "a8e44a38-b935-482f-b17f-ed3472c6292c"); + assertEquals(voiceStep.getAction(), "transfer"); + VoiceStepOption voiceStepOption = voiceStep.getOptions(); + assertEquals(voiceStepOption.getDestination(), "31612345678"); + assertEquals(voiceStepOption.getPayload(), "Test payload"); + assertEquals(voiceStepOption.getLanguage(), "en-GB"); + assertEquals(voiceStepOption.getVoice(), "male"); + assertEquals(voiceStepOption.getRepeat(), "1"); + assertEquals(voiceStepOption.getMedia(), "test.mp3"); + assertEquals(voiceStepOption.getFinishOnKey(), "1"); + assertEquals(voiceStepOption.getTranscribeLanguage(), "en-GB"); + assertEquals(voiceStepOption.getRecord(), "both"); + assertEquals(voiceStepOption.getUrl(), "http://"); + assertEquals(voiceStepOption.getIfMachine(), "ifMachine"); + assertEquals(voiceStepOption.getMachineTimeout(), 200); + assertEquals(voiceStepOption.getOnFinish(), "http://"); + assertEquals(voiceStepOption.getLength(), 1); + assertEquals(voiceStepOption.getTimeout(), 3); + assertEquals(voiceStepOption.getMaxLength(), 2); + assertEquals(voiceStepOption.isTranscribe(), false); } } diff --git a/api/src/test/resources/fixtures/call_flow_update_response.json b/api/src/test/resources/fixtures/call_flow_update_response.json new file mode 100644 index 00000000..7659ccfa --- /dev/null +++ b/api/src/test/resources/fixtures/call_flow_update_response.json @@ -0,0 +1,41 @@ +{ + "data": [ + { + "id": "e781a76f-14ad-45b0-8490-409300244e20", + "title": "Forward call to 31612345678", + "steps": [ + { + "id": "a8e44a38-b935-482f-b17f-ed3472c6292c", + "action": "transfer", + "options": { + "destination" : "31612345678", + "payload" : "Test payload", + "language" : "en-GB", + "voice" : "male", + "repeat" : "1", + "media" : "test.mp3", + "length" : 1, + "maxLength" : 2, + "timeout" : 3, + "finishOnKey" : "1", + "transcribe" : "false", + "transcribeLanguage" : "en-GB", + "record" : "both", + "url" : "http://", + "ifMachine" : "ifMachine", + "machineTimeout" : 200, + "onFinish" : "http://", + "mask" : false + } + } + ], + "record": true, + "default": false, + "createdAt": "2019-08-06T14:13:06Z", + "updatedAt": "2019-08-06T14:13:06Z" + } + ], + "_links": { + "self": "/call-flows/e781a76f-14ad-45b0-8490-409300244e20" + } +} \ No newline at end of file diff --git a/api/src/test/resources/fixtures/call_flow_view.json b/api/src/test/resources/fixtures/call_flow_view.json new file mode 100644 index 00000000..8feed38d --- /dev/null +++ b/api/src/test/resources/fixtures/call_flow_view.json @@ -0,0 +1,41 @@ +{ + "data": [ + { + "id": "e781a76f-14ad-45b0-8490-409300244e20", + "title": "Forward call to 31612345678", + "steps": [ + { + "id": "a8e44a38-b935-482f-b17f-ed3472c6292c", + "action": "transfer", + "options": { + "destination" : "31612345678", + "payload" : "Test payload", + "language" : "en-GB", + "voice" : "male", + "repeat" : "1", + "media" : "test.mp3", + "length" : 1, + "maxLength" : 2, + "timeout" : 3, + "finishOnKey" : "1", + "transcribe" : "false", + "transcribeLanguage" : "en-GB", + "record" : "both", + "url" : "http://", + "ifMachine" : "ifMachine", + "machineTimeout" : 200, + "onFinish" : "http://", + "mask" : false + } + } + ], + "record": true, + "default": false, + "createdAt": "2019-08-06T14:13:06Z", + "updatedAt": "2019-08-06T14:13:06Z" + } + ], + "_links": { + "self": "/call-flows/70fbdda2-4f1f-44ce-8792-75af32cf598c" + } +} \ No newline at end of file diff --git a/api/src/test/resources/fixtures/call_flows_list.json b/api/src/test/resources/fixtures/call_flows_list.json new file mode 100644 index 00000000..0cebcef1 --- /dev/null +++ b/api/src/test/resources/fixtures/call_flows_list.json @@ -0,0 +1,50 @@ +{ + "data": [ + { + "id": "e781a76f-14ad-45b0-8490-409300244e20", + "title": "Forward call to 31612345678", + "steps": [ + { + "id": "a8e44a38-b935-482f-b17f-ed3472c6292c", + "action": "transfer", + "options": { + "destination" : "31612345678", + "payload" : "Test payload", + "language" : "en-GB", + "voice" : "male", + "repeat" : "1", + "media" : "test.mp3", + "length" : 1, + "maxLength" : 2, + "timeout" : 3, + "finishOnKey" : "1", + "transcribe" : "false", + "transcribeLanguage" : "en-GB", + "record" : "both", + "url" : "http://", + "ifMachine" : "ifMachine", + "machineTimeout" : 200, + "onFinish" : "http://", + "mask" : false + } + } + ], + "record": true, + "default": false, + "createdAt": "2019-08-06T14:13:06Z", + "updatedAt": "2019-08-06T14:13:06Z", + "_links": { + "self": "/call-flows/70fbdda2-4f1f-44ce-8792-75af32cf598c" + } + } + ], + "_links": { + "self": "/call-flows?page=1" + }, + "pagination": { + "totalCount": 10, + "pageCount": 3, + "currentPage": 2, + "perPage": 12 + } +} \ No newline at end of file diff --git a/api/src/test/resources/fixtures/call_flows_post.json b/api/src/test/resources/fixtures/call_flows_post.json new file mode 100644 index 00000000..7659ccfa --- /dev/null +++ b/api/src/test/resources/fixtures/call_flows_post.json @@ -0,0 +1,41 @@ +{ + "data": [ + { + "id": "e781a76f-14ad-45b0-8490-409300244e20", + "title": "Forward call to 31612345678", + "steps": [ + { + "id": "a8e44a38-b935-482f-b17f-ed3472c6292c", + "action": "transfer", + "options": { + "destination" : "31612345678", + "payload" : "Test payload", + "language" : "en-GB", + "voice" : "male", + "repeat" : "1", + "media" : "test.mp3", + "length" : 1, + "maxLength" : 2, + "timeout" : 3, + "finishOnKey" : "1", + "transcribe" : "false", + "transcribeLanguage" : "en-GB", + "record" : "both", + "url" : "http://", + "ifMachine" : "ifMachine", + "machineTimeout" : 200, + "onFinish" : "http://", + "mask" : false + } + } + ], + "record": true, + "default": false, + "createdAt": "2019-08-06T14:13:06Z", + "updatedAt": "2019-08-06T14:13:06Z" + } + ], + "_links": { + "self": "/call-flows/e781a76f-14ad-45b0-8490-409300244e20" + } +} \ No newline at end of file From cdd86222b5905a179ce5591f31df2a023165e251 Mon Sep 17 00:00:00 2001 From: Dan Gurgui Date: Fri, 9 Aug 2019 11:19:58 +0200 Subject: [PATCH 004/516] Fixed CI build fails and moved to TestUtil VoiceStep field population --- api/src/main/java/com/messagebird/.DS_Store | Bin 0 -> 6148 bytes .../java/com/messagebird/objects/.DS_Store | Bin 0 -> 10244 bytes .../test/java/com/messagebird/TestUtil.java | 21 +++++++++-- .../com/messagebird/VoiceCallFlowTest.java | 34 ++++++------------ 4 files changed, 29 insertions(+), 26 deletions(-) create mode 100644 api/src/main/java/com/messagebird/.DS_Store create mode 100644 api/src/main/java/com/messagebird/objects/.DS_Store diff --git a/api/src/main/java/com/messagebird/.DS_Store b/api/src/main/java/com/messagebird/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..d63b3ce32156ba6bf76a558f85a1e6d6112b518b GIT binary patch literal 6148 zcmeHKO-~a+7=8z;Y>UY94N;Sgjfn|8Km>{h<61DLYC@$1O90DmyOh;sr|xd4P;2@x zO!Vjv@E@3X_2AW`2mgQ<&-%_s`DpcOjF~r?dER|LX6Ai1JF^1-BvUKT0_XssVPhCe zVD}qge%89AM_PIj2_K^b5rlR(5~~VuD2_VC;Bf8 zTpZMghDU}*hsMUnCnm?HhA&+%>La#QdR7V8nwO|YgN#>miuz!PEM!a6&jro_R$Pdj z7g63lLf3Fd!m3k#a$;ILtYXaQiGdG#FK`@xvl6)FmEGOYi3+Fm4K`aTpq`hbp&Pl> z-`L`_N6voM-=#PsTfs_|xx#fP2obw-3L91sSboLH9BzA-?RYDGhDH(HFSu9*TRERH zU$siEUrFBnF1U;*&FezbA=#!kX|@)*uIXgWr@n(xIpIv24`h@E({Km!um#Vd1+U>9 zyoZnQ8NR^}_(=xHIJruuNs7#qG%-n*+$RsoBeF_1MSf5F-CmL7Ng!oZI^OL;KJY#2 zSJ2bWI-8`Pj+xQ=6&Z>F#eiaL|!q7NJqON<4lPyfg&9UpBcxIGZT43A$)eU8$29{DNyx_0mZ;s2H3wp ziq6jeyMMm_^B~nJ1{4GTCj%t5oL|mhZSrjGs*;_x2DTk+Ojuk?AWy+g9>-i^NAV;! bF6c9uf@n%?2}BEu`VrtXs7^8PR~h&Pdco1- literal 0 HcmV?d00001 diff --git a/api/src/main/java/com/messagebird/objects/.DS_Store b/api/src/main/java/com/messagebird/objects/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..90bbb52d604c735a4f7d10fde5a3568617bfb76c GIT binary patch literal 10244 zcmeHN&2Jk;6n~Qju;YAeKHG>QS>!;aMvy{7DsjL#{U8vO5JzpQexz%A<1E?in%#BM z5LJqhxN-%-k?#}#0TO~roH%piz@dX6YhL>VNO+90wv55MQs^7Mr@FF*?5iEOHnLC@1Wq_?zAD^dnh22uu622uu6 z2L25UV9(|!lM7^;rwpVFqzoK0!0{oE#Ig{|qd>~gflM9&Ap21*ACz$pkeGZZ3!yv; zq=Z6eaC#6SRD?$i5y0_2&&?qVp*#v?04EW^NraX~ctR1{4aVGGGc>No=NK}^$l8%^(01A033=Z~0{A&j1R*pq$mz=n?zagEo8 z!H*RN$6&u9Z8@|{7lCIkP0WSYkxf;{IB;xHmt&~{ZBvcb>456cmoO)iQ&o#bm%yKk zUc1D6)@3PiP9>8nK1Wx8vZ;#PO|;6)si*;<*k%Lv5_-yBCo&3W!wRO0=MX$Ef*n_| zy?YJ(FQR2Mrlq^b!0#d&GW0s;xFb)I_9J2Y-aLdEyQ?rZMoU;9Z^1(~!_12MR;O z5md*yk<6&r5iq+bqo;?S_OR}RiXH@-qYX!mPOLIRDo%^xdf}-PzR7ooRoJ(oFg6*p z-}7o>{vw(t+Gz4*{6YNeF!NZI5k056=;_7~7>?*0is?&?$O1kXLGqk>-D5CEw!WVf zPBmH$y`UPFf>@q3C(NXZ&(T%zzvv-xScd>n)Iqi-q z?|b#|+tgp>x@CI)+}tms??nF-Pd=5&4&<`A;av7sY1`Q^`MTfmin_b0oi3SGqpZ8v z%&Nb=ZrGPBW6!Wx+-2Q2+#B3@-Ek~52+Df-s%h+RY7>i&?dzs(xKdxBy@3F%L7_;EXOTc4P#Rq@j%N`#j#giV-Iv} z_{LqoWWI-2V==&*QN8`BYW<*&HWQC3q|z&{Vc0inu325#+VTv4Ln&WpYZceAtX0P| zebce8-;~yUV|U5ka$u2ruu|t&-c`f(AX_jS*LBy`?V3?MxMk^O!&_jpKeXYcxVWn>+ zd^6{7(@F7*qm7E4XoFn=zImcZ&?6&|sz>cZw|I=5FVcr_HdFDKGjJjpU!L#(FD3u} z|CqCo4liZk|IL8tzgW6h1P9G+Jx&MTwdaxUAo0WPjshtm$mDfAWIw9;55A6 Date: Mon, 12 Aug 2019 09:14:21 +0200 Subject: [PATCH 005/516] Added examples for voice call flows methods implemented --- .../test/java/com/messagebird/TestUtil.java | 1 - .../main/java/ExampleCreateVoiceCallFlow.java | 39 ++++++++++++++++ .../main/java/ExampleDeleteVoiceCallFlow.java | 33 ++++++++++++++ .../main/java/ExampleListVoiceCallFlow.java | 12 ++--- .../main/java/ExampleUpdateVoiceCallFlow.java | 44 +++++++++++++++++++ .../main/java/ExampleViewVoiceCallFlow.java | 33 ++++++++++++++ 6 files changed, 152 insertions(+), 10 deletions(-) create mode 100644 examples/src/main/java/ExampleCreateVoiceCallFlow.java create mode 100644 examples/src/main/java/ExampleDeleteVoiceCallFlow.java create mode 100644 examples/src/main/java/ExampleUpdateVoiceCallFlow.java create mode 100644 examples/src/main/java/ExampleViewVoiceCallFlow.java diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index c892e733..09cfc3c9 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -180,7 +180,6 @@ public static VoiceStep createVoiceStep() { public static VoiceCallFlowRequest createVoiceCallFlowRequest() { final VoiceCallFlowRequest voiceCallFlow = new VoiceCallFlowRequest(); - voiceCallFlow.setId("ANY_ID"); voiceCallFlow.setTitle("ANY_TITLE"); voiceCallFlow.setRecord(true); voiceCallFlow.setSteps(Collections.singletonList(createVoiceStep())); diff --git a/examples/src/main/java/ExampleCreateVoiceCallFlow.java b/examples/src/main/java/ExampleCreateVoiceCallFlow.java new file mode 100644 index 00000000..374cb96a --- /dev/null +++ b/examples/src/main/java/ExampleCreateVoiceCallFlow.java @@ -0,0 +1,39 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; + +public class ExampleCreateVoiceCallFlow { + + public static void main(String[] args) { + if (args.length < 4) { + System.out.println("Please specify your access key and voice call flow arguments"); + return; + } + + //First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + //Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + final VoiceCallFlowRequest voiceCallFlow = new VoiceCallFlowRequest(); + + voiceCallFlow.setTitle(args[1]); + voiceCallFlow.setRecord(args[2]); + voiceCallFlow.setSteps(args[3]); // VoiceStep Object + voiceCallFlow.setDefaultCall(args[4]); + + try { + //Deleting voice call by id + System.out.println("Creting a Voice Call Flow"); + messageBirdClient.sendVoiceCallFlow(voiceCallFlow); + System.out.println("Voice call flow created"); + + } catch (GeneralException | UnauthorizedException exception) { + exception.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/examples/src/main/java/ExampleDeleteVoiceCallFlow.java b/examples/src/main/java/ExampleDeleteVoiceCallFlow.java new file mode 100644 index 00000000..fff2b776 --- /dev/null +++ b/examples/src/main/java/ExampleDeleteVoiceCallFlow.java @@ -0,0 +1,33 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; + +public class ExampleDeleteVoiceCallFlow { + + public static void main(String[] args) { + if (args.length < 2) { + System.out.println("Please specify your access key and a voice call flow ID"); + return; + } + + //First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + //Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + //Deleting voice call by id + System.out.println("Deleting a Voice Call Flow"); + VoiceCallFlow voiceCallFlow = messageBirdClient + .deleteVoiceCallFlow(args[1]); + System.out.println("Voice call flow deleted "); + + } catch (GeneralException | UnauthorizedException exception) { + exception.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/examples/src/main/java/ExampleListVoiceCallFlow.java b/examples/src/main/java/ExampleListVoiceCallFlow.java index 96ea10b2..8b867fc2 100644 --- a/examples/src/main/java/ExampleListVoiceCallFlow.java +++ b/examples/src/main/java/ExampleListVoiceCallFlow.java @@ -9,9 +9,6 @@ import java.util.ArrayList; import java.util.List; -/* - * @TODO - not working, needs implementation - */ public class ExampleListVoiceCallFlow { public static void main(String[] args) { @@ -28,15 +25,12 @@ public static void main(String[] args) { try { // Get list of call flows with offset and limit - System.out.println("Retrieving message list"); - final MessageList messageList = messageBirdClient.listCallFlow(3, null); + System.out.println("Retrieving call flows list"); + VoiceCallFlowList voiceCallFlowList = messageBirdClient.listVoiceCallFlows(0, 0); // Display balance - System.out.println(messageList.toString()); + System.out.println(voiceCallFlowList.toString()); } catch (UnauthorizedException | GeneralException exception) { - if (exception.getErrors() != null) { - System.out.println(exception.getErrors().toString()); - } exception.printStackTrace(); } } diff --git a/examples/src/main/java/ExampleUpdateVoiceCallFlow.java b/examples/src/main/java/ExampleUpdateVoiceCallFlow.java new file mode 100644 index 00000000..dc242901 --- /dev/null +++ b/examples/src/main/java/ExampleUpdateVoiceCallFlow.java @@ -0,0 +1,44 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; + +public class ExampleCreateVoiceCallFlow { + + public static void main(String[] args) { + if (args.length < 6) { + System.out.println("Please specify your access key and voice call flow arguments"); + return; + } + + //First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + //Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + final VoiceCallFlowRequest voiceCallFlow = new VoiceCallFlowRequest(); + + voiceCallFlow.setTitle(args[2]); + voiceCallFlow.setRecord(args[3]); + voiceCallFlow.setSteps(args[4]); // VoiceStep Object + voiceCallFlow.setDefaultCall(args[5]); + + try { + //Deleting voice call by id + System.out.println("Updating a Voice Call Flow"); + VoiceCallFlow voiceCallFlow = messageBirdClient + .updateVoiceCallFlow(args[1], voiceCallFlowRequest) + .getData() + .get(0); + System.out.println("Voice call flow updated"); + + } catch (GeneralException | UnauthorizedException exception) { + exception.printStackTrace(); + } + + System.out.print(voiceCallFlow.toString()); + } +} \ No newline at end of file diff --git a/examples/src/main/java/ExampleViewVoiceCallFlow.java b/examples/src/main/java/ExampleViewVoiceCallFlow.java new file mode 100644 index 00000000..5dcfe272 --- /dev/null +++ b/examples/src/main/java/ExampleViewVoiceCallFlow.java @@ -0,0 +1,33 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; + +public class ExampleViewVoiceCallFlow { + + public static void main(String[] args) { + if (args.length < 2) { + System.out.println("Please specify your access key and a voice call flow ID"); + return; + } + + //First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + //Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + //Deleting voice call by id + System.out.println("Requesting a Voice Call Flow"); + VoiceCallFlow voiceCallFlow = messageBirdClient + .viewVoiceCallFlow(args[1]); + System.out.println("Voice call flow retrieved "); + + } catch (GeneralException | UnauthorizedException exception) { + exception.printStackTrace(); + } + } +} \ No newline at end of file From 61da45dc1b97fbff4a9e607485efd1dbd60d6733 Mon Sep 17 00:00:00 2001 From: Dan Gurgui Date: Tue, 13 Aug 2019 12:08:59 +0200 Subject: [PATCH 006/516] Fixed examples --- .../java/com/messagebird/objects/.DS_Store | Bin 10244 -> 0 bytes .../main/java/ExampleCreateVoiceCallFlow.java | 20 +++++++++------- .../src/main/java/ExampleDeleteVoiceCall.java | 2 +- .../main/java/ExampleListVoiceCallFlow.java | 1 + .../main/java/ExampleUpdateVoiceCallFlow.java | 22 +++++++++++------- 5 files changed, 27 insertions(+), 18 deletions(-) delete mode 100644 api/src/main/java/com/messagebird/objects/.DS_Store diff --git a/api/src/main/java/com/messagebird/objects/.DS_Store b/api/src/main/java/com/messagebird/objects/.DS_Store deleted file mode 100644 index 90bbb52d604c735a4f7d10fde5a3568617bfb76c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10244 zcmeHN&2Jk;6n~Qju;YAeKHG>QS>!;aMvy{7DsjL#{U8vO5JzpQexz%A<1E?in%#BM z5LJqhxN-%-k?#}#0TO~roH%piz@dX6YhL>VNO+90wv55MQs^7Mr@FF*?5iEOHnLC@1Wq_?zAD^dnh22uu622uu6 z2L25UV9(|!lM7^;rwpVFqzoK0!0{oE#Ig{|qd>~gflM9&Ap21*ACz$pkeGZZ3!yv; zq=Z6eaC#6SRD?$i5y0_2&&?qVp*#v?04EW^NraX~ctR1{4aVGGGc>No=NK}^$l8%^(01A033=Z~0{A&j1R*pq$mz=n?zagEo8 z!H*RN$6&u9Z8@|{7lCIkP0WSYkxf;{IB;xHmt&~{ZBvcb>456cmoO)iQ&o#bm%yKk zUc1D6)@3PiP9>8nK1Wx8vZ;#PO|;6)si*;<*k%Lv5_-yBCo&3W!wRO0=MX$Ef*n_| zy?YJ(FQR2Mrlq^b!0#d&GW0s;xFb)I_9J2Y-aLdEyQ?rZMoU;9Z^1(~!_12MR;O z5md*yk<6&r5iq+bqo;?S_OR}RiXH@-qYX!mPOLIRDo%^xdf}-PzR7ooRoJ(oFg6*p z-}7o>{vw(t+Gz4*{6YNeF!NZI5k056=;_7~7>?*0is?&?$O1kXLGqk>-D5CEw!WVf zPBmH$y`UPFf>@q3C(NXZ&(T%zzvv-xScd>n)Iqi-q z?|b#|+tgp>x@CI)+}tms??nF-Pd=5&4&<`A;av7sY1`Q^`MTfmin_b0oi3SGqpZ8v z%&Nb=ZrGPBW6!Wx+-2Q2+#B3@-Ek~52+Df-s%h+RY7>i&?dzs(xKdxBy@3F%L7_;EXOTc4P#Rq@j%N`#j#giV-Iv} z_{LqoWWI-2V==&*QN8`BYW<*&HWQC3q|z&{Vc0inu325#+VTv4Ln&WpYZceAtX0P| zebce8-;~yUV|U5ka$u2ruu|t&-c`f(AX_jS*LBy`?V3?MxMk^O!&_jpKeXYcxVWn>+ zd^6{7(@F7*qm7E4XoFn=zImcZ&?6&|sz>cZw|I=5FVcr_HdFDKGjJjpU!L#(FD3u} z|CqCo4liZk|IL8tzgW6h1P9G+Jx&MTwdaxUAo0WPjshtm$mDfAWIw9;55A6 Date: Mon, 19 Aug 2019 11:26:24 +0200 Subject: [PATCH 007/516] Implemented feedback from CR --- examples/src/main/java/ExampleCreateVoiceCallFlow.java | 4 ++-- examples/src/main/java/ExampleDeleteVoiceCallFlow.java | 1 - examples/src/main/java/ExampleViewVoiceCallFlow.java | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/src/main/java/ExampleCreateVoiceCallFlow.java b/examples/src/main/java/ExampleCreateVoiceCallFlow.java index 84a6e3d1..8a39c177 100644 --- a/examples/src/main/java/ExampleCreateVoiceCallFlow.java +++ b/examples/src/main/java/ExampleCreateVoiceCallFlow.java @@ -11,7 +11,7 @@ public class ExampleCreateVoiceCallFlow { public static void main(String[] args) { - if (args.length < 4) { + if (args.length < 2) { System.out.println("Please specify your access key and voice call flow arguments"); return; } @@ -24,7 +24,7 @@ public static void main(String[] args) { final VoiceCallFlowRequest voiceCallFlowRequest = new VoiceCallFlowRequest(); - voiceCallFlowRequest.setTitle(args[2]); + voiceCallFlowRequest.setTitle(args[1]); voiceCallFlowRequest.setRecord(true); // Can be false as well, see docs VoiceStep voiceStep = new VoiceStep(); voiceCallFlowRequest.setSteps(Collections.singletonList(voiceStep)); // VoiceStep Object diff --git a/examples/src/main/java/ExampleDeleteVoiceCallFlow.java b/examples/src/main/java/ExampleDeleteVoiceCallFlow.java index fff2b776..aeded131 100644 --- a/examples/src/main/java/ExampleDeleteVoiceCallFlow.java +++ b/examples/src/main/java/ExampleDeleteVoiceCallFlow.java @@ -2,7 +2,6 @@ import com.messagebird.MessageBirdService; import com.messagebird.MessageBirdServiceImpl; import com.messagebird.exceptions.GeneralException; -import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; public class ExampleDeleteVoiceCallFlow { diff --git a/examples/src/main/java/ExampleViewVoiceCallFlow.java b/examples/src/main/java/ExampleViewVoiceCallFlow.java index 5dcfe272..fdf28977 100644 --- a/examples/src/main/java/ExampleViewVoiceCallFlow.java +++ b/examples/src/main/java/ExampleViewVoiceCallFlow.java @@ -2,8 +2,8 @@ import com.messagebird.MessageBirdService; import com.messagebird.MessageBirdServiceImpl; import com.messagebird.exceptions.GeneralException; -import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.voicecalls.VoiceCallFlow; public class ExampleViewVoiceCallFlow { From 8d77c75d98fa5df4c7c1b485f42332f4223f52e8 Mon Sep 17 00:00:00 2001 From: Dan Gurgui Date: Mon, 19 Aug 2019 12:00:03 +0200 Subject: [PATCH 008/516] Updated the code after reconfiguring the editor --- api/src/main/java/com/messagebird/.DS_Store | Bin 6148 -> 0 bytes .../com/messagebird/MessageBirdClient.java | 18 ++++++++++++++---- .../main/java/ExampleDeleteVoiceCallFlow.java | 6 +++--- .../main/java/ExampleListVoiceCallFlow.java | 1 - .../main/java/ExampleViewVoiceCallFlow.java | 7 ++++--- 5 files changed, 21 insertions(+), 11 deletions(-) delete mode 100644 api/src/main/java/com/messagebird/.DS_Store diff --git a/api/src/main/java/com/messagebird/.DS_Store b/api/src/main/java/com/messagebird/.DS_Store deleted file mode 100644 index d63b3ce32156ba6bf76a558f85a1e6d6112b518b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKO-~a+7=8z;Y>UY94N;Sgjfn|8Km>{h<61DLYC@$1O90DmyOh;sr|xd4P;2@x zO!Vjv@E@3X_2AW`2mgQ<&-%_s`DpcOjF~r?dER|LX6Ai1JF^1-BvUKT0_XssVPhCe zVD}qge%89AM_PIj2_K^b5rlR(5~~VuD2_VC;Bf8 zTpZMghDU}*hsMUnCnm?HhA&+%>La#QdR7V8nwO|YgN#>miuz!PEM!a6&jro_R$Pdj z7g63lLf3Fd!m3k#a$;ILtYXaQiGdG#FK`@xvl6)FmEGOYi3+Fm4K`aTpq`hbp&Pl> z-`L`_N6voM-=#PsTfs_|xx#fP2obw-3L91sSboLH9BzA-?RYDGhDH(HFSu9*TRERH zU$siEUrFBnF1U;*&FezbA=#!kX|@)*uIXgWr@n(xIpIv24`h@E({Km!um#Vd1+U>9 zyoZnQ8NR^}_(=xHIJruuNs7#qG%-n*+$RsoBeF_1MSf5F-CmL7Ng!oZI^OL;KJY#2 zSJ2bWI-8`Pj+xQ=6&Z>F#eiaL|!q7NJqON<4lPyfg&9UpBcxIGZT43A$)eU8$29{DNyx_0mZ;s2H3wp ziq6jeyMMm_^B~nJ1{4GTCj%t5oL|mhZSrjGs*;_x2DTk+Ojuk?AWy+g9>-i^NAV;! bF6c9uf@n%?2}BEu`VrtXs7^8PR~h&Pdco1- diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 56cf56b1..412277db 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -558,6 +558,11 @@ public VoiceCallFlowList listVoiceCallFlows(final Integer offset, final Integer /** * Retrieves the information of an existing Call Flow. You only need to supply * the unique call flow ID that was returned upon creation or receiving. + * @param id String + * @return VoiceCallFlowResponse + * @throws NotFoundException + * @throws GeneralException + * @throws UnauthorizedException */ public VoiceCallFlowResponse viewVoiceCallFlow(final String id) throws NotFoundException, GeneralException, UnauthorizedException { if (id == null) { @@ -571,7 +576,7 @@ public VoiceCallFlowResponse viewVoiceCallFlow(final String id) throws NotFoundE /** * Convenient function to create a call flow * - * @param VoiceCallFlowRequest + * @param voiceCallFlowRequest VoiceCallFlowRequest * @return VoiceCallFlowResponse * @throws UnauthorizedException if client is unauthorized * @throws GeneralException general exception @@ -586,8 +591,13 @@ public VoiceCallFlowResponse sendVoiceCallFlow(final VoiceCallFlowRequest voiceC /** * Updates an existing Call Flow. You only need to supply the unique id that * was returned upon creation. + * @param id String + * @param voiceCallFlowRequest VoiceCallFlowRequest + * @return VoiceCallFlowResponse + * @throws UnauthorizedException + * @throws GeneralException */ - public VoiceCallFlowResponse updateVoiceCallFlow(final String id, VoiceCallFlowRequest voiceCallFlowRequest) + public VoiceCallFlowResponse updateVoiceCallFlow(String id, VoiceCallFlowRequest voiceCallFlowRequest) throws UnauthorizedException, GeneralException { if (id == null) { throw new IllegalArgumentException("Call Flow ID must be specified."); @@ -601,12 +611,12 @@ public VoiceCallFlowResponse updateVoiceCallFlow(final String id, VoiceCallFlowR /** * Convenient function to delete call flow * - * @param String + * @param id String * @return void * @throws UnauthorizedException if client is unauthorized * @throws GeneralException general exception */ - void deleteVoiceCallFlow(final String id) throws NotFoundException, GeneralException, UnauthorizedException { + public void deleteVoiceCallFlow(final String id) throws NotFoundException, GeneralException, UnauthorizedException { if (id == null) { throw new IllegalArgumentException("Voice Call Flow ID must be specified."); } diff --git a/examples/src/main/java/ExampleDeleteVoiceCallFlow.java b/examples/src/main/java/ExampleDeleteVoiceCallFlow.java index aeded131..af5e3be8 100644 --- a/examples/src/main/java/ExampleDeleteVoiceCallFlow.java +++ b/examples/src/main/java/ExampleDeleteVoiceCallFlow.java @@ -3,6 +3,7 @@ import com.messagebird.MessageBirdServiceImpl; import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.exceptions.NotFoundException; public class ExampleDeleteVoiceCallFlow { @@ -21,11 +22,10 @@ public static void main(String[] args) { try { //Deleting voice call by id System.out.println("Deleting a Voice Call Flow"); - VoiceCallFlow voiceCallFlow = messageBirdClient - .deleteVoiceCallFlow(args[1]); + messageBirdClient.deleteVoiceCallFlow(args[1]); System.out.println("Voice call flow deleted "); - } catch (GeneralException | UnauthorizedException exception) { + } catch (GeneralException | NotFoundException | UnauthorizedException exception) { exception.printStackTrace(); } } diff --git a/examples/src/main/java/ExampleListVoiceCallFlow.java b/examples/src/main/java/ExampleListVoiceCallFlow.java index cbad85da..20189be4 100644 --- a/examples/src/main/java/ExampleListVoiceCallFlow.java +++ b/examples/src/main/java/ExampleListVoiceCallFlow.java @@ -1,7 +1,6 @@ import com.messagebird.MessageBirdClient; import com.messagebird.MessageBirdService; import com.messagebird.MessageBirdServiceImpl; -import com.messagebird.objects.MessageResponse; import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.UnauthorizedException; import com.messagebird.objects.voicecalls.VoiceCallFlowList; diff --git a/examples/src/main/java/ExampleViewVoiceCallFlow.java b/examples/src/main/java/ExampleViewVoiceCallFlow.java index fdf28977..69e73037 100644 --- a/examples/src/main/java/ExampleViewVoiceCallFlow.java +++ b/examples/src/main/java/ExampleViewVoiceCallFlow.java @@ -3,7 +3,8 @@ import com.messagebird.MessageBirdServiceImpl; import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.UnauthorizedException; -import com.messagebird.objects.voicecalls.VoiceCallFlow; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.objects.voicecalls.VoiceCallFlowResponse; public class ExampleViewVoiceCallFlow { @@ -22,11 +23,11 @@ public static void main(String[] args) { try { //Deleting voice call by id System.out.println("Requesting a Voice Call Flow"); - VoiceCallFlow voiceCallFlow = messageBirdClient + VoiceCallFlowResponse voiceCallFlowResponse = messageBirdClient .viewVoiceCallFlow(args[1]); System.out.println("Voice call flow retrieved "); - } catch (GeneralException | UnauthorizedException exception) { + } catch (GeneralException | UnauthorizedException | NotFoundException exception) { exception.printStackTrace(); } } From 38fb5171eadf340d45c2a944fe9d669f039b5133 Mon Sep 17 00:00:00 2001 From: Dan Gurgui Date: Mon, 19 Aug 2019 12:06:27 +0200 Subject: [PATCH 009/516] removed unused imports --- examples/src/main/java/ExampleListVoiceCallFlow.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/examples/src/main/java/ExampleListVoiceCallFlow.java b/examples/src/main/java/ExampleListVoiceCallFlow.java index 20189be4..12ed0982 100644 --- a/examples/src/main/java/ExampleListVoiceCallFlow.java +++ b/examples/src/main/java/ExampleListVoiceCallFlow.java @@ -5,10 +5,6 @@ import com.messagebird.exceptions.UnauthorizedException; import com.messagebird.objects.voicecalls.VoiceCallFlowList; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; - public class ExampleListVoiceCallFlow { public static void main(String[] args) { From 3b4edea8198624f778ce702e2e960dce1e7db9dd Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 23 Sep 2019 10:36:16 +0200 Subject: [PATCH 010/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 65bdd1ba..fca48e61 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.0 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index a4b4ab51..5286eb30 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -58,7 +58,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.0.0"; + private final String clientVersion = "3.0.1"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 88d378fd..2c14ec2e 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.0 + 3.0.1 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.0 + 3.0.1 compile From df1c4717f74b0bad6f68a936f14e145c153fe7d1 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 23 Sep 2019 10:40:15 +0200 Subject: [PATCH 011/516] [maven-release-plugin] prepare release HEAD --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index fca48e61..b67a3885 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.1-SNAPSHOT From 3235026df2ee54bf91ce66b6efea5d65e9fe2d85 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 23 Sep 2019 10:50:39 +0200 Subject: [PATCH 012/516] updated pom xml --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index b67a3885..fca48e61 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.1 From c9151b4fee2e9f80272a5b7a16d44587eb2ec61b Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 23 Sep 2019 10:54:43 +0200 Subject: [PATCH 013/516] [maven-release-plugin] prepare release messagebird-api-3.0.1 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index fca48e61..8c87cf43 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.1-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + messagebird-api-3.0.1 From 4c500fd5f9055c012f7724a5cba92e93398350dd Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 23 Sep 2019 11:17:40 +0200 Subject: [PATCH 014/516] updated pom --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 8c87cf43..e5e8390f 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.1 From 5fe1020d09a1abe302d8d1ce33e7005b4d28c150 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 23 Sep 2019 11:18:54 +0200 Subject: [PATCH 015/516] [maven-release-plugin] prepare release HEAD --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index e5e8390f..b67a3885 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.1-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - messagebird-api-3.0.1 + HEAD From 489e3d363cef05525dcfd09361945dfb08dd1756 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 23 Sep 2019 11:26:34 +0200 Subject: [PATCH 016/516] updated pom --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index b67a3885..fca48e61 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.1 From c482e701dfb5aabfbaf7a35b1abd7b256a541b79 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 23 Sep 2019 11:27:16 +0200 Subject: [PATCH 017/516] [maven-release-plugin] prepare release HEAD --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index fca48e61..b67a3885 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.1-SNAPSHOT From 2f4c2764e7b9dff576be85a874f23a287a8b42c5 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 23 Sep 2019 11:35:05 +0200 Subject: [PATCH 018/516] updated pom --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index b67a3885..fca48e61 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.1 From da7d4f193c216c73c784b99177a9166161f1c597 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 23 Sep 2019 11:35:40 +0200 Subject: [PATCH 019/516] [maven-release-plugin] prepare release HEAD --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index fca48e61..b67a3885 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.1-SNAPSHOT From e5a75d576a782a56f771437462a79acfd424f774 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 23 Sep 2019 11:59:58 +0200 Subject: [PATCH 020/516] updated pom --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index b67a3885..fca48e61 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.1 From b83dfaeb043e9af91488871a3d978b50a35a850a Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 23 Sep 2019 12:01:44 +0200 Subject: [PATCH 021/516] [maven-release-plugin] prepare release messagebird-api-3.0.1 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index fca48e61..4fa117c1 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.1-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + messagebird-api-3.0.1 From e23b0df26ae2c2abdb662fe0245f9f6d47934810 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 23 Sep 2019 12:03:58 +0200 Subject: [PATCH 022/516] updated scm tag --- api/pom.xml | 4 ++-- api/release.properties | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 api/release.properties diff --git a/api/pom.xml b/api/pom.xml index 4fa117c1..e5e8390f 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.1 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - messagebird-api-3.0.1 + messagebird-api-3.0.1 diff --git a/api/release.properties b/api/release.properties new file mode 100644 index 00000000..30e14fd5 --- /dev/null +++ b/api/release.properties @@ -0,0 +1,12 @@ +#release configuration +#Mon Sep 23 12:03:09 CEST 2019 +projectVersionPolicyId=default +scm.tagNameFormat=@{project.artifactId}-@{project.version} +exec.additionalArguments=-P artifactory +remoteTagging=true +scm.commentPrefix=[maven-release-plugin] +pushChanges=true +completedPhase=check-poms +scm.url=scm\:git\:git@github.com\:messagebird/java-rest-api.git +exec.snapshotReleasePluginAllowed=false +preparationGoals=clean verify From 62dee998927c8819f2500350d1e9db3569de4e13 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 23 Sep 2019 12:04:29 +0200 Subject: [PATCH 023/516] updated scm tag --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index e5e8390f..fca48e61 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - messagebird-api-3.0.1 + HEAD From d1838cd837f3b796927e27ed318cfd2faae69368 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 23 Sep 2019 12:05:18 +0200 Subject: [PATCH 024/516] [maven-release-plugin] prepare release messagebird-api-3.0.1 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index fca48e61..8c87cf43 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.1-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + messagebird-api-3.0.1 From d984a7bd654fc99353275e2410348f906ee6d5d9 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 23 Sep 2019 12:05:26 +0200 Subject: [PATCH 025/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 8c87cf43..d94fccd3 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.1 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - messagebird-api-3.0.1 + HEAD From c095bbc7a1a165804fa410b74f116993f9964401 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 23 Sep 2019 15:32:59 +0200 Subject: [PATCH 026/516] deleted release prop --- api/release.properties | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 api/release.properties diff --git a/api/release.properties b/api/release.properties deleted file mode 100644 index 30e14fd5..00000000 --- a/api/release.properties +++ /dev/null @@ -1,12 +0,0 @@ -#release configuration -#Mon Sep 23 12:03:09 CEST 2019 -projectVersionPolicyId=default -scm.tagNameFormat=@{project.artifactId}-@{project.version} -exec.additionalArguments=-P artifactory -remoteTagging=true -scm.commentPrefix=[maven-release-plugin] -pushChanges=true -completedPhase=check-poms -scm.url=scm\:git\:git@github.com\:messagebird/java-rest-api.git -exec.snapshotReleasePluginAllowed=false -preparationGoals=clean verify From 9c0f1c84e56c2fdc1931071fff675333dc166618 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 23 Sep 2019 15:59:40 +0200 Subject: [PATCH 027/516] deleted snapshot from 3.0.2 version number --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index d94fccd3..823b264f 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.2-SNAPSHOT From a806473482f7c235733ed8faff728dd1165f468a Mon Sep 17 00:00:00 2001 From: xevgeny Date: Mon, 23 Sep 2019 18:09:00 +0200 Subject: [PATCH 028/516] list voice webhooks --- api/pom.xml | 3 +- .../com/messagebird/MessageBirdClient.java | 21 ++++++++ .../objects/voicecalls/WebhookList.java | 50 +++++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 api/src/main/java/com/messagebird/objects/voicecalls/WebhookList.java diff --git a/api/pom.xml b/api/pom.xml index 823b264f..2bd51b69 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,8 @@ com.messagebird messagebird-api - 3.0.2 diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 4204fd85..f9b0d7cb 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1309,4 +1309,25 @@ public WebhookResponseData viewWebHook(String id) throws NotFoundException, Gene String url = String.format("%s%s", VOICE_CALLS_BASE_URL, WEBHOOKS); return messageBirdService.requestByID(url, id, WebhookResponseData.class); } + + /** + * Function to list webhooks + * + * @param offset offset for result list + * @param limit limit for result list + * @return WebhookList + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + */ + public WebhookList listWebHooks(final Integer offset, final Integer limit) throws UnauthorizedException, GeneralException { + if (offset != null && offset < 0) { + throw new IllegalArgumentException("Offset must be > 0"); + } + if (limit != null && limit < 0) { + throw new IllegalArgumentException("Limit must be > 0"); + } + + String url = String.format("%s%s", VOICE_CALLS_BASE_URL, WEBHOOKS); + return messageBirdService.requestList(url, offset, limit, WebhookList.class); + } } \ No newline at end of file diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/WebhookList.java b/api/src/main/java/com/messagebird/objects/voicecalls/WebhookList.java new file mode 100644 index 00000000..da39f342 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/voicecalls/WebhookList.java @@ -0,0 +1,50 @@ +package com.messagebird.objects.voicecalls; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +public class WebhookList implements Serializable { + + private static final long serialVersionUID = -5524142916135114801L; + + private List data; + @JsonProperty("_list") + private Map links; + private Pagination pagination; + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + + public Map getLinks() { + return links; + } + + public void setLinks(Map links) { + this.links = links; + } + + public Pagination getPagination() { + return pagination; + } + + public void setPagination(Pagination pagination) { + this.pagination = pagination; + } + + @Override + public String toString() { + return "WebhookList{" + + "data=" + data + + ", links=" + links + + ", pagination=" + pagination + + '}'; + } +} From 2b018b99e0b406abbed2381fe8a24888cbaf1955 Mon Sep 17 00:00:00 2001 From: xevgeny Date: Tue, 24 Sep 2019 18:19:49 +0200 Subject: [PATCH 029/516] remove title from Webhook --- .../com/messagebird/objects/voicecalls/Webhook.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/Webhook.java b/api/src/main/java/com/messagebird/objects/voicecalls/Webhook.java index 2ac11c01..ce236cb3 100644 --- a/api/src/main/java/com/messagebird/objects/voicecalls/Webhook.java +++ b/api/src/main/java/com/messagebird/objects/voicecalls/Webhook.java @@ -6,18 +6,9 @@ public class Webhook implements Serializable { private static final long serialVersionUID = 727746356185518354L; - private String title; private String url; private String token; - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - public String getUrl() { return url; } @@ -37,8 +28,7 @@ public void setToken(String token) { @Override public String toString() { return "Webhook{" + - "title='" + title + '\'' + - ", url='" + url + '\'' + + "url='" + url + '\'' + ", token='" + token + '\'' + '}'; } From eff81fa7211f19fabb95f2d6f63ed30bd918137a Mon Sep 17 00:00:00 2001 From: xevgeny Date: Tue, 24 Sep 2019 18:21:52 +0200 Subject: [PATCH 030/516] add update/list webhooks --- .../com/messagebird/MessageBirdClient.java | 60 ++++++++++++++----- .../messagebird/MessageBirdClientTest.java | 22 +------ .../test/java/com/messagebird/TestUtil.java | 3 +- 3 files changed, 49 insertions(+), 36 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index f9b0d7cb..427a81c5 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1009,7 +1009,7 @@ ConversationWebhookList listConversationWebhooks(final int offset, final int lim * * @return List of webhooks. */ - public ConversationWebhookList listConversationWebHooks() throws UnauthorizedException, GeneralException { + public ConversationWebhookList listConversationWebhooks() throws UnauthorizedException, GeneralException { final int offset = 0; final int limit = 10; @@ -1273,18 +1273,14 @@ public TranscriptionResponse viewTranscription(String callID, String legId, Stri } /** - * Function to create web hook + * Function to create a webhook * - * @param webhook title, url and token of webHook - * @return WebHookResponseData + * @param webhook webhook to create + * @return WebhookResponseData created webhook * @throws UnauthorizedException if client is unauthorized * @throws GeneralException general exception */ - public WebhookResponseData createWebHook(Webhook webhook) throws UnauthorizedException, GeneralException { - if (webhook.getTitle() == null) { - throw new IllegalArgumentException("Title of webhook must be specified."); - } - + public WebhookResponseData createWebhook(Webhook webhook) throws UnauthorizedException, GeneralException { if (webhook.getUrl() == null) { throw new IllegalArgumentException("URL of webhook must be specified."); } @@ -1294,16 +1290,33 @@ public WebhookResponseData createWebHook(Webhook webhook) throws UnauthorizedExc } /** - * Function to view webhook + * Function to update a webhook * - * @param id webHook id - * @return WebHookResponseData + * @param webhook webhook fields to update + * @return WebhookResponseData updated webhook * @throws UnauthorizedException if client is unauthorized * @throws GeneralException general exception */ - public WebhookResponseData viewWebHook(String id) throws NotFoundException, GeneralException, UnauthorizedException { + public WebhookResponseData updateWebhook(String id, Webhook webhook) throws UnauthorizedException, GeneralException { if (id == null) { - throw new IllegalArgumentException("Id of webHook must be specified."); + throw new IllegalArgumentException("Id of webhook must be specified."); + } + + String url = String.format("%s%s/%s", VOICE_CALLS_BASE_URL, WEBHOOKS, id); + return messageBirdService.sendPayLoad("PUT", url, webhook, WebhookResponseData.class); + } + + /** + * Function to view a webhook + * + * @param id id of a webhook + * @return WebhookResponseData + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + */ + public WebhookResponseData viewWebhook(String id) throws NotFoundException, GeneralException, UnauthorizedException { + if (id == null) { + throw new IllegalArgumentException("Id of webhook must be specified."); } String url = String.format("%s%s", VOICE_CALLS_BASE_URL, WEBHOOKS); @@ -1319,7 +1332,7 @@ public WebhookResponseData viewWebHook(String id) throws NotFoundException, Gene * @throws UnauthorizedException if client is unauthorized * @throws GeneralException general exception */ - public WebhookList listWebHooks(final Integer offset, final Integer limit) throws UnauthorizedException, GeneralException { + public WebhookList listWebhooks(final Integer offset, final Integer limit) throws UnauthorizedException, GeneralException { if (offset != null && offset < 0) { throw new IllegalArgumentException("Offset must be > 0"); } @@ -1330,4 +1343,21 @@ public WebhookList listWebHooks(final Integer offset, final Integer limit) throw String url = String.format("%s%s", VOICE_CALLS_BASE_URL, WEBHOOKS); return messageBirdService.requestList(url, offset, limit, WebhookList.class); } + + /** + * Function to delete a webhook + * + * @param id A unique random ID which is created on the MessageBird platform + * @throws NotFoundException if id is not found + * @throws GeneralException general exception + * @throws UnauthorizedException if client is unauthorized + */ + public void deleteWebhook(String id) throws NotFoundException, GeneralException, UnauthorizedException { + if (id == null) { + throw new IllegalArgumentException("Webhook ID must be specified."); + } + + String url = String.format("%s%s", VOICE_CALLS_BASE_URL, WEBHOOKS); + messageBirdService.deleteByID(url, id); + } } \ No newline at end of file diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 9b22afbb..96e88ea9 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -603,7 +603,7 @@ public void testViewTranscription() throws UnauthorizedException, GeneralExcepti @Test public void testCreateWebhook() throws UnauthorizedException, GeneralException { - final Webhook webhook = TestUtil.createWebHook(); + final Webhook webhook = TestUtil.createWebhook(); final WebhookResponseData webhookResponseData = TestUtil.createWebhookResponseData(); MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); @@ -611,28 +611,12 @@ public void testCreateWebhook() throws UnauthorizedException, GeneralException { when(messageBirdServiceMock.sendPayLoad(VOICE_CALLS_BASE_URL + WEBHOOKS, webhook, WebhookResponseData.class)) .thenReturn(webhookResponseData); - final WebhookResponseData response = messageBirdClientInjectMock.createWebHook(webhook); + final WebhookResponseData response = messageBirdClientInjectMock.createWebhook(webhook); verify(messageBirdServiceMock, times(1)).sendPayLoad(VOICE_CALLS_BASE_URL + WEBHOOKS, webhook, WebhookResponseData.class); assertNotNull(response); assertEquals(response.getData().get(0).getId(), webhookResponseData.getData().get(0).getId()); } - @Test(expected = IllegalArgumentException.class) - public void shouldThrowIllegalArgumentExceptionWhenCreateWebhookWithMissingTitle() throws UnauthorizedException, GeneralException { - final Webhook webhook = new Webhook(); - webhook.setUrl("ANY_URL"); - messageBirdClient.createWebHook(webhook); - - } - - @Test(expected = IllegalArgumentException.class) - public void shouldThrowIllegalArgumentExceptionWhenCreateWebhookWithMissingUrl() throws UnauthorizedException, GeneralException { - final Webhook webhook = new Webhook(); - webhook.setTitle("ANY_TITLE"); - messageBirdClient.createWebHook(webhook); - - } - @Test public void testViewWebhook() throws UnauthorizedException, GeneralException, NotFoundException { final WebhookResponseData webhookResponseData = TestUtil.createWebhookResponseData(); @@ -642,7 +626,7 @@ public void testViewWebhook() throws UnauthorizedException, GeneralException, No when(messageBirdServiceMock.requestByID(VOICE_CALLS_BASE_URL + WEBHOOKS, "ANY_ID", WebhookResponseData.class)) .thenReturn(webhookResponseData); - final WebhookResponseData response = messageBirdClientInjectMock.viewWebHook("ANY_ID"); + final WebhookResponseData response = messageBirdClientInjectMock.viewWebhook("ANY_ID"); verify(messageBirdServiceMock, times(1)).requestByID(VOICE_CALLS_BASE_URL + WEBHOOKS, "ANY_ID", WebhookResponseData.class); assertNotNull(response); diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index 09cfc3c9..06eae43e 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -93,9 +93,8 @@ static TranscriptionResponse createTranscriptionResponse() { return transcriptionResponse; } - static Webhook createWebHook() { + static Webhook createWebhook() { final Webhook webhook = new Webhook(); - webhook.setTitle("ANY_TITLE"); webhook.setUrl("ANY_URL"); return webhook; } From 3919903c0a04a8cbd36d05a11991d709926e54b4 Mon Sep 17 00:00:00 2001 From: xevgeny Date: Tue, 24 Sep 2019 18:23:02 +0200 Subject: [PATCH 031/516] send body with PUT requests --- .../java/com/messagebird/MessageBirdServiceImpl.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 5286eb30..07b83c17 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -341,18 +341,18 @@ private boolean isURLAbsolute(String url) { * Create a HttpURLConnection connection object * * @param serviceUrl URL that needs to be requested - * @param postData PostDATA, must be not null for requestType is POST + * @param body body could not be empty for POST or PUT requests * @param requestType Request type POST requests without a payload will generate a exception * @return base class * @throws IOException io exception */ - public

HttpURLConnection getConnection(final String serviceUrl, final P postData, final String requestType) throws IOException { + public

HttpURLConnection getConnection(final String serviceUrl, final P body, final String requestType) throws IOException { if (requestType == null || !REQUEST_METHODS.contains(requestType)) { throw new IllegalArgumentException(String.format(REQUEST_METHOD_NOT_ALLOWED, requestType)); } - if (postData == null && "POST".equals(requestType)) { - throw new IllegalArgumentException("POST detected without a payload, please supply a payload with a POST request"); + if (body == null && ("POST".equals(requestType) || "PUT".equals(requestType))) { + throw new IllegalArgumentException("Empty body is not allowed for POST or PUT requests"); } final URL restService = new URL(serviceUrl); @@ -370,7 +370,7 @@ public

HttpURLConnection getConnection(final String serviceUrl, final P post connection.setRequestProperty("Authorization", "AccessKey " + accessKey); connection.setRequestProperty("User-agent", userAgentString); - if ("POST".equals(requestType) || "PATCH".equals(requestType)) { + if ("POST".equals(requestType) || "PUT".equals(requestType) || "PATCH".equals(requestType)) { connection.setRequestMethod(requestType); connection.setDoOutput(true); connection.setRequestProperty("Content-Type", "application/json"); @@ -383,7 +383,7 @@ public

HttpURLConnection getConnection(final String serviceUrl, final P post DateFormat df = getDateFormat(); mapper.setDateFormat(df); - final String json = mapper.writeValueAsString(postData); + final String json = mapper.writeValueAsString(body); connection.getOutputStream().write(json.getBytes(String.valueOf(StandardCharsets.UTF_8))); } else if ("DELETE".equals(requestType)) { // could have just used rquestType as it is From 19c349e7dbecb66ff4f03befa9c17b8427591295 Mon Sep 17 00:00:00 2001 From: xevgeny Date: Tue, 24 Sep 2019 18:24:07 +0200 Subject: [PATCH 032/516] bump examples --- examples/src/main/java/ExampleSendWebhook.java | 16 ++++++++-------- .../java/ExampleUpdateConversationWebhook.java | 12 ++++++------ examples/src/main/java/ExampleViewWebhook.java | 10 +++++----- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/examples/src/main/java/ExampleSendWebhook.java b/examples/src/main/java/ExampleSendWebhook.java index a1ec27a5..7eab5a6d 100644 --- a/examples/src/main/java/ExampleSendWebhook.java +++ b/examples/src/main/java/ExampleSendWebhook.java @@ -10,8 +10,8 @@ public class ExampleSendWebhook { public static void main(String[] args) { if (args.length < 3) { - System.out.println("Please specify your access key, title of webhook and url of webhook :" + - " java -jar test_accesskey webhook_title webhook-url"); + System.out.println("Please specify your access key, url and token of webhook :" + + " java -jar test_accesskey webhook-url webhook-token"); return; } @@ -22,14 +22,14 @@ public static void main(String[] args) { final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); try { - //Creating webHook object to send client + //Creating webhook object to send client System.out.println("Creating new webhook.."); final Webhook webhook = new Webhook(); - webhook.setTitle(args[1]); - webhook.setUrl(args[2]); - //Sending webHook object to client - final WebhookResponseData webhookResponseDataList = messageBirdClient.createWebHook(webhook); - //Display webHook response + webhook.setUrl(args[1]); + webhook.setToken(args[2]); + //Sending webhook object to client + final WebhookResponseData webhookResponseDataList = messageBirdClient.createWebhook(webhook); + //Display webhook response System.out.println(webhookResponseDataList.toString()); } catch (GeneralException | UnauthorizedException exception) { exception.printStackTrace(); diff --git a/examples/src/main/java/ExampleUpdateConversationWebhook.java b/examples/src/main/java/ExampleUpdateConversationWebhook.java index 37b46955..a4a659cd 100644 --- a/examples/src/main/java/ExampleUpdateConversationWebhook.java +++ b/examples/src/main/java/ExampleUpdateConversationWebhook.java @@ -28,16 +28,16 @@ public static void main(String[] args) { final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); try { - //Creating webHook object to send client + //Creating webhook object to send client System.out.println("Updating conversation webhook.."); ConversationWebhookUpdateRequest request = new ConversationWebhookUpdateRequest( getStatus(args) , getWebhookUrl(args), - getConversationWebHookEvents(args) + getConversationWebhookEvents(args) ); - //Sending ConversationWebHook update request + //Sending ConversationWebhook update request final ConversationWebhook conversationWebhookResponse = messageBirdClient.updateConversationWebhook(args[1], request); //Display conversationWebhook response System.out.println(conversationWebhookResponse); @@ -54,7 +54,7 @@ private static String getWebhookUrl(String[] args) { return args.length > 4 ? args[3] : "https://example-web-hook-url"; } - private static List parseConversationWebHookEvents(String[] args) { + private static List parseConversationWebhookEvents(String[] args) { List conversationWebhookEventList = new ArrayList<>(); for (String arg : args ) { @@ -71,13 +71,13 @@ private static List parseConversationWebHookEvents(Str return conversationWebhookEventList; } - private static List getConversationWebHookEvents(String[] args) { + private static List getConversationWebhookEvents(String[] args) { if (args.length < 5) return Arrays.asList(ConversationWebhookEvent.CONVERSATION_CREATED, ConversationWebhookEvent.MESSAGE_CREATED); String[] arrayOfEvents = new String[args.length - 4]; System.arraycopy(args, 4, arrayOfEvents, 0, args.length - 4); - return parseConversationWebHookEvents(arrayOfEvents); + return parseConversationWebhookEvents(arrayOfEvents); } } diff --git a/examples/src/main/java/ExampleViewWebhook.java b/examples/src/main/java/ExampleViewWebhook.java index e0976ec6..f7eb2b7c 100644 --- a/examples/src/main/java/ExampleViewWebhook.java +++ b/examples/src/main/java/ExampleViewWebhook.java @@ -22,11 +22,11 @@ public static void main(String[] args) { try { System.out.println("Viewing webhook.."); - final String webHookId = args[1]; - //Viewing webHook by webHook id - final WebhookResponseData webHookResponseDataList = messageBirdClient.viewWebHook(webHookId); - //Display WebHook Response Data - System.out.println(webHookResponseDataList.toString()); + final String webhookId = args[1]; + //Viewing webhook by webhook id + final WebhookResponseData webhookResponseDataList = messageBirdClient.viewWebhook(webhookId); + //Display Webhook Response Data + System.out.println(webhookResponseDataList.toString()); } catch (GeneralException | UnauthorizedException | NotFoundException exception) { exception.printStackTrace(); } From 5ff18f64e5ed54984daf074b02b31467487252a7 Mon Sep 17 00:00:00 2001 From: xevgeny Date: Tue, 24 Sep 2019 18:32:28 +0200 Subject: [PATCH 033/516] bump examples --- examples/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/pom.xml b/examples/pom.xml index 2c14ec2e..0a520149 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.1 + 3.0.2 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.1 + 3.0.2 compile From f2c3386ab6bf076e8b7773bab1dd6edd425cf2a4 Mon Sep 17 00:00:00 2001 From: xevgeny Date: Wed, 25 Sep 2019 13:43:40 +0200 Subject: [PATCH 034/516] revert test --- .../test/java/com/messagebird/MessageBirdClientTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 96e88ea9..5d243076 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -4,6 +4,7 @@ import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; import com.messagebird.objects.*; +import com.messagebird.objects.conversations.ConversationWebhookList; import com.messagebird.objects.voicecalls.*; import org.junit.Before; import org.junit.BeforeClass; @@ -617,6 +618,12 @@ public void testCreateWebhook() throws UnauthorizedException, GeneralException { assertEquals(response.getData().get(0).getId(), webhookResponseData.getData().get(0).getId()); } + @Test(expected = IllegalArgumentException.class) + public void shouldThrowIllegalArgumentExceptionWhenCreateWebhookWithMissingUrl() throws UnauthorizedException, GeneralException { + final Webhook webhook = new Webhook(); + messageBirdClient.createWebhook(webhook); + } + @Test public void testViewWebhook() throws UnauthorizedException, GeneralException, NotFoundException { final WebhookResponseData webhookResponseData = TestUtil.createWebhookResponseData(); From 633c8c9ab7770af12f4a9c54b9f71bd11e470021 Mon Sep 17 00:00:00 2001 From: xevgeny Date: Wed, 25 Sep 2019 14:53:21 +0200 Subject: [PATCH 035/516] add webhook tests --- .../messagebird/MessageBirdClientTest.java | 45 +++++++++++++++++++ .../test/java/com/messagebird/TestUtil.java | 7 +++ 2 files changed, 52 insertions(+) diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 5d243076..dde0980e 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -640,4 +640,49 @@ public void testViewWebhook() throws UnauthorizedException, GeneralException, No assertEquals(response.getData().get(0).getId(), webhookResponseData.getData().get(0).getId()); assertEquals(response.getData().get(0).getUrl(), webhookResponseData.getData().get(0).getUrl()); } + + @Test + public void testListWebhooks() throws UnauthorizedException, GeneralException { + final WebhookList webhookList = TestUtil.createWebhookList(); + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); + + when(messageBirdServiceMock.requestList(anyString(), anyInt(), anyInt(), eq(WebhookList.class))) + .thenReturn(webhookList); + final WebhookList response = messageBirdClientMock.listWebhooks(0, 0); + verify(messageBirdServiceMock, times(1)) + .requestList(VOICE_CALLS_BASE_URL + WEBHOOKS, 0, 0, WebhookList.class); + assertNotNull(response); + assertEquals(response.getData().get(0).getId(), webhookList.getData().get(0).getId()); + assertEquals(response.getData().get(0).getUrl(), webhookList.getData().get(0).getUrl()); + } + + @Test + public void testUpdateWebhook() throws UnauthorizedException, GeneralException { + final Webhook webhook = TestUtil.createWebhook(); + final WebhookResponseData webhookResponseData = TestUtil.createWebhookResponseData(); + final String id = webhookResponseData.getData().get(0).getId(); + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); + + String url = String.format("%s%s/%s", VOICE_CALLS_BASE_URL, WEBHOOKS, id); + when(messageBirdServiceMock.sendPayLoad(anyString(), anyString(), eq(webhook), eq(WebhookResponseData.class))) + .thenReturn(webhookResponseData); + final WebhookResponseData response = messageBirdClientMock.updateWebhook(id, webhook); + verify(messageBirdServiceMock, times(1)) + .sendPayLoad("PUT", url, webhook, WebhookResponseData.class); + assertNotNull(response); + assertEquals(response.getData().get(0).getUrl(), webhookResponseData.getData().get(0).getUrl()); + } + + @Test + public void testDeleteWebhook() throws NotFoundException, GeneralException, UnauthorizedException { + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); + + messageBirdClientMock.deleteWebhook("id"); + verify(messageBirdServiceMock, times(1)).deleteByID(VOICE_CALLS_BASE_URL + WEBHOOKS, "id"); + } } diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index 06eae43e..098cf0c1 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -113,6 +113,13 @@ static WebhookResponseData createWebhookResponseData() { return webhookResponseData; } + static WebhookList createWebhookList() { + final WebhookList webhookList = new WebhookList(); + webhookList.setData(Collections.singletonList(createWebhookResponse())); + webhookList.setLinks(Collections.singletonMap("self", "ANY_ID")); + return webhookList; + } + private static Contact createContact(){ final CustomDetails customDetails = new CustomDetails(); customDetails.setCustom1("ANY_DETAIL"); From ebb0fea4f254f69b39c386385e4d174bd7741a28 Mon Sep 17 00:00:00 2001 From: xevgeny Date: Wed, 25 Sep 2019 16:38:45 +0200 Subject: [PATCH 036/516] minor changes --- api/src/test/java/com/messagebird/MessageBirdClientTest.java | 1 - examples/pom.xml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index dde0980e..4b589379 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -4,7 +4,6 @@ import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; import com.messagebird.objects.*; -import com.messagebird.objects.conversations.ConversationWebhookList; import com.messagebird.objects.voicecalls.*; import org.junit.Before; import org.junit.BeforeClass; diff --git a/examples/pom.xml b/examples/pom.xml index 0a520149..0903044d 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.2 + 3.0.1 From 8e740ae99276008732237dfe75cce9b5b53d54f8 Mon Sep 17 00:00:00 2001 From: xevgeny Date: Wed, 25 Sep 2019 17:35:43 +0200 Subject: [PATCH 037/516] revert poms --- api/pom.xml | 3 +-- examples/pom.xml | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 2bd51b69..823b264f 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,8 +4,7 @@ com.messagebird messagebird-api - 3.0.2 - diff --git a/examples/pom.xml b/examples/pom.xml index 0903044d..2c14ec2e 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.2 + 3.0.1 compile From 19fb9eb5830d0c110dd1e63f5c04ceaa03627118 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 26 Sep 2019 17:49:00 +0200 Subject: [PATCH 038/516] new release with voice webhook --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdClient.java | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 823b264f..d94fccd3 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.2 diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 427a81c5..ddc7fc8e 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -998,7 +998,7 @@ public ConversationWebhook viewConversationWebhook(final String webhookId) throw * @param limit Number of objects to skip. * @return List of webhooks. */ - ConversationWebhookList listConversationWebhooks(final int offset, final int limit) + public ConversationWebhookList listConversationWebhooks(final int offset, final int limit) throws UnauthorizedException, GeneralException { String url = this.conversationsBaseUrl + CONVERSATION_WEBHOOK_PATH; return messageBirdService.requestList(url, offset, limit, ConversationWebhookList.class); diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 07b83c17..832964e4 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -58,7 +58,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.0.1"; + private final String clientVersion = "3.0.2"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 2c14ec2e..0a520149 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.1 + 3.0.2 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.1 + 3.0.2 compile From 86a6206f29e285c1e3eb8d1995b9ffc7f3ec3dda Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 27 Sep 2019 10:20:19 +0200 Subject: [PATCH 039/516] [maven-release-plugin] prepare release v3.0.2 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index d94fccd3..31c82c45 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.2-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.0.2 From ecce386095378304e0bace4cd684be2586a54c78 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 27 Sep 2019 10:20:26 +0200 Subject: [PATCH 040/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 31c82c45..0b21bf8e 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.2 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.0.2 + HEAD From cb9fd4a4b25cbfd6fe165b650f690b3d71acf3c4 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 27 Sep 2019 15:40:29 +0200 Subject: [PATCH 041/516] updated pom --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 0b21bf8e..823b264f 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.3-SNAPSHOT From 48f3fc52288dd6d25dbd97316912c80c093e6b5e Mon Sep 17 00:00:00 2001 From: cemturker Date: Tue, 8 Oct 2019 12:55:38 +0200 Subject: [PATCH 042/516] *List all recordings *Downloading the recording file. *Some missing properties are added --- .../com/messagebird/MessageBirdClient.java | 164 +++++++++++++++--- .../com/messagebird/MessageBirdService.java | 13 ++ .../messagebird/MessageBirdServiceImpl.java | 84 ++++++++- .../com/messagebird/objects/VoiceStep.java | 12 ++ .../messagebird/objects/VoiceStepOption.java | 23 ++- .../voicecalls/RecordingResponseList.java | 20 +++ .../voicecalls/VoiceCallCondition.java | 34 ++++ .../objects/voicecalls/VoiceCallFlow.java | 8 + .../objects/voicecalls/VoiceCallFlowList.java | 11 +- .../messagebird/MessageBirdClientTest.java | 64 +++++++ .../test/java/com/messagebird/TestUtil.java | 13 ++ .../main/java/ExampleDownloadRecording.java | 38 ++++ .../src/main/java/ExampleListOfRecording.java | 42 +++++ 13 files changed, 484 insertions(+), 42 deletions(-) create mode 100644 api/src/main/java/com/messagebird/objects/voicecalls/RecordingResponseList.java create mode 100644 api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallCondition.java create mode 100644 examples/src/main/java/ExampleDownloadRecording.java create mode 100644 examples/src/main/java/ExampleListOfRecording.java diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index ddc7fc8e..45f7d3e1 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -3,15 +3,58 @@ import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; -import com.messagebird.objects.*; -import com.messagebird.objects.conversations.*; -import com.messagebird.objects.voicecalls.*; +import com.messagebird.objects.Balance; +import com.messagebird.objects.Contact; +import com.messagebird.objects.ContactList; +import com.messagebird.objects.ContactRequest; +import com.messagebird.objects.ErrorReport; +import com.messagebird.objects.Group; +import com.messagebird.objects.GroupList; +import com.messagebird.objects.GroupRequest; +import com.messagebird.objects.Hlr; +import com.messagebird.objects.Lookup; +import com.messagebird.objects.LookupHlr; +import com.messagebird.objects.Message; +import com.messagebird.objects.MessageList; +import com.messagebird.objects.MessageResponse; +import com.messagebird.objects.MsgType; +import com.messagebird.objects.PagedPaging; +import com.messagebird.objects.Verify; +import com.messagebird.objects.VerifyRequest; +import com.messagebird.objects.VoiceMessage; +import com.messagebird.objects.VoiceMessageList; +import com.messagebird.objects.VoiceMessageResponse; +import com.messagebird.objects.conversations.Conversation; +import com.messagebird.objects.conversations.ConversationList; +import com.messagebird.objects.conversations.ConversationMessage; +import com.messagebird.objects.conversations.ConversationMessageList; +import com.messagebird.objects.conversations.ConversationMessageRequest; +import com.messagebird.objects.conversations.ConversationStartRequest; +import com.messagebird.objects.conversations.ConversationStatus; +import com.messagebird.objects.conversations.ConversationWebhook; +import com.messagebird.objects.conversations.ConversationWebhookCreateRequest; +import com.messagebird.objects.conversations.ConversationWebhookList; +import com.messagebird.objects.conversations.ConversationWebhookUpdateRequest; +import com.messagebird.objects.voicecalls.RecordingResponse; +import com.messagebird.objects.voicecalls.RecordingResponseList; +import com.messagebird.objects.voicecalls.TranscriptionResponse; +import com.messagebird.objects.voicecalls.VoiceCall; +import com.messagebird.objects.voicecalls.VoiceCallFlowList; +import com.messagebird.objects.voicecalls.VoiceCallFlowRequest; +import com.messagebird.objects.voicecalls.VoiceCallFlowResponse; +import com.messagebird.objects.voicecalls.VoiceCallLeg; +import com.messagebird.objects.voicecalls.VoiceCallLegResponse; +import com.messagebird.objects.voicecalls.VoiceCallResponse; +import com.messagebird.objects.voicecalls.VoiceCallResponseList; +import com.messagebird.objects.voicecalls.Webhook; +import com.messagebird.objects.voicecalls.WebhookList; +import com.messagebird.objects.voicecalls.WebhookResponseData; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.nio.charset.StandardCharsets; -import java.util.*; import java.net.URLEncoder; +import java.util.Arrays; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; @@ -66,6 +109,7 @@ public class MessageBirdClient { static final String WEBHOOKS = "/webhooks"; static final String VOICECALLFLOWPATH = "/call-flows"; private static final String VOICELEGS_SUFFIX_PATH = "/legs"; + static final String RECORDING_DOWNLOAD_FORMAT = ".wav"; private MessageBirdService messageBirdService; private String conversationsBaseUrl; @@ -220,12 +264,7 @@ public MessageResponse sendFlashMessage(final String originator, final String bo } public MessageList listMessages(final Integer offset, final Integer limit) throws UnauthorizedException, GeneralException { - if (offset != null && offset < 0) { - throw new IllegalArgumentException("Offset must be > 0"); - } - if (limit != null && limit < 0) { - throw new IllegalArgumentException("Limit must be > 0"); - } + verifyOffsetAndLimit(offset, limit); return messageBirdService.requestList(MESSAGESPATH, offset, limit, MessageList.class); } @@ -343,12 +382,7 @@ public VoiceMessageResponse viewVoiceMessage(final String id) throws Unauthorize * @throws GeneralException general exception */ public VoiceMessageList listVoiceMessages(final Integer offset, final Integer limit) throws UnauthorizedException, GeneralException { - if (offset != null && offset < 0) { - throw new IllegalArgumentException("Offset must be > 0"); - } - if (limit != null && limit < 0) { - throw new IllegalArgumentException("Limit must be > 0"); - } + verifyOffsetAndLimit(offset, limit); return messageBirdService.requestList(VOICEMESSAGESPATH, offset, limit, VoiceMessageList.class); } @@ -558,12 +592,7 @@ public LookupHlr viewLookupHlr(final BigInteger phoneNumber) throws Unauthorized */ public VoiceCallFlowList listVoiceCallFlows(final Integer offset, final Integer limit) throws UnauthorizedException, GeneralException { - if (offset != null && offset < 0) { - throw new IllegalArgumentException("Offset must be > 0"); - } - if (limit != null && limit < 0) { - throw new IllegalArgumentException("Limit must be > 0"); - } + verifyOffsetAndLimit(offset, limit); String url = String.format("%s%s", VOICE_CALLS_BASE_URL, VOICECALLFLOWPATH); return messageBirdService.requestList(url, offset, limit, VoiceCallFlowList.class); @@ -1189,6 +1218,81 @@ public RecordingResponse viewRecording(String callID, String legId, String recor return messageBirdService.requestByID(url, callID, params, RecordingResponse.class); } + /** + * Downloads the record in .wav format by using callId, legId and recordId and stores to basePath + * @param callID Voice call ID + * @param legId Leg ID + * @param recordingId Recording ID + * @param basePath store location + * @return + * @throws NotFoundException + * @throws GeneralException + * @throws UnauthorizedException + */ + public String downloadRecording(String callID, String legId, String recordingId, String basePath) throws NotFoundException, GeneralException, UnauthorizedException { + + if (callID == null) { + throw new IllegalArgumentException("Voice call ID must be specified."); + } + + if (legId == null) { + throw new IllegalArgumentException("Leg ID must be specified."); + } + + if (recordingId == null) { + throw new IllegalArgumentException("Recording ID must be specified."); + } + + String url = String.format( + "%s%s/%s%s/%s%s/%s%s", + VOICE_CALLS_BASE_URL, + VOICECALLSPATH, + callID, + LEGSPATH, + legId, + RECORDINGPATH, + recordingId, + RECORDING_DOWNLOAD_FORMAT + ); + String fileName = String.format("%s%s",recordingId, RECORDING_DOWNLOAD_FORMAT); + return messageBirdService.getBinaryData(url, basePath, fileName); + } + + /** + * + * @param callID Voice call ID + * @param legId Leg ID + * @param offset + * @param limit + * @param offset Number of objects to skip. + * @param limit Number of objects to take. + * @return Recordings for CallID and LegID + * @throws GeneralException if client is unauthorized + * @throws UnauthorizedException general exception + */ + public RecordingResponseList listRecordings(String callID, String legId, final Integer offset, final Integer limit) + throws GeneralException, UnauthorizedException { + verifyOffsetAndLimit(offset, limit); + if (callID == null) { + throw new IllegalArgumentException("Voice call ID must be specified."); + } + + if (legId == null) { + throw new IllegalArgumentException("Leg ID must be specified."); + } + + String url = String.format( + "%s%s/%s%s/%s%s", + VOICE_CALLS_BASE_URL, + VOICECALLSPATH, + callID, + LEGSPATH, + legId, + RECORDINGPATH); + + return messageBirdService.requestList(url, offset, limit, RecordingResponseList.class); + } + /** * Function to view recording by call id , leg id and recording id * @@ -1333,12 +1437,7 @@ public WebhookResponseData viewWebhook(String id) throws NotFoundException, Gene * @throws GeneralException general exception */ public WebhookList listWebhooks(final Integer offset, final Integer limit) throws UnauthorizedException, GeneralException { - if (offset != null && offset < 0) { - throw new IllegalArgumentException("Offset must be > 0"); - } - if (limit != null && limit < 0) { - throw new IllegalArgumentException("Limit must be > 0"); - } + verifyOffsetAndLimit(offset, limit); String url = String.format("%s%s", VOICE_CALLS_BASE_URL, WEBHOOKS); return messageBirdService.requestList(url, offset, limit, WebhookList.class); @@ -1360,4 +1459,13 @@ public void deleteWebhook(String id) throws NotFoundException, GeneralException, String url = String.format("%s%s", VOICE_CALLS_BASE_URL, WEBHOOKS); messageBirdService.deleteByID(url, id); } + + private void verifyOffsetAndLimit(Integer offset, Integer limit) { + if (offset != null && offset < 0) { + throw new IllegalArgumentException("Offset must be > 0"); + } + if (limit != null && limit < 0) { + throw new IllegalArgumentException("Limit must be > 0"); + } + } } \ No newline at end of file diff --git a/api/src/main/java/com/messagebird/MessageBirdService.java b/api/src/main/java/com/messagebird/MessageBirdService.java index 61775534..9a993c4d 100644 --- a/api/src/main/java/com/messagebird/MessageBirdService.java +++ b/api/src/main/java/com/messagebird/MessageBirdService.java @@ -90,4 +90,17 @@ public interface MessageBirdService { * @throws GeneralException general exception */ R sendPayLoad(String method, String request, P payload, Class clazz) throws UnauthorizedException, GeneralException; + + /** + * Gets the data from the request URL and stores it to basePath/fileName + * + * @param request path to the request, for example "/messages" + * @param basePath base path for storing directory + * @param fileName the fileName that is going to be stored. + * @return basePath/fileName + * @throws UnauthorizedException + * @throws GeneralException + * @throws NotFoundException + */ + String getBinaryData(String request, String basePath, String fileName) throws UnauthorizedException, GeneralException, NotFoundException; } diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 832964e4..faf47fa8 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -56,6 +56,8 @@ public class MessageBirdServiceImpl implements MessageBirdService { // allow PATCH requests yet. Also see docs on allowPatchRequestsIfNeeded(). private static boolean isPatchRequestAllowed = false; + private static final int BUFFER_SIZE = 4096; + private final String accessKey; private final String serviceUrl; private final String clientVersion = "3.0.2"; @@ -165,6 +167,20 @@ public R sendPayLoad(String method, String request, P payload, Class c } } + @Override + public String getBinaryData(String request, String basePath, String fileName) throws GeneralException, UnauthorizedException, NotFoundException { + File file = new File(basePath); + if(!file.exists()) { + throw new IllegalArgumentException("basePath must be existed as directory."); + } + + if(!file.isDirectory()) { + throw new IllegalArgumentException("basePath must be a directory."); + } + String filePath = String.format("%s/%s", basePath, fileName); + return doGetRequestForFileAndStore(request, filePath); + } + public T getJsonData(final String request, final P payload, final String requestType, final Class clazz) throws UnauthorizedException, GeneralException, NotFoundException { if (request == null) { @@ -194,7 +210,13 @@ public T getJsonData(final String request, final P payload, final String } } else if (status == HttpURLConnection.HTTP_NO_CONTENT) { return null; // no content doesn't mean an error - } else if (status == HttpURLConnection.HTTP_UNAUTHORIZED) { + } + handleHttpFailStatuses(status, body); + return null; + } + + private void handleHttpFailStatuses(final int status, String body) throws UnauthorizedException, NotFoundException, GeneralException { + if (status == HttpURLConnection.HTTP_UNAUTHORIZED) { final List errorReport = getErrorReportOrNull(body); throw new UnauthorizedException(NOT_AUTHORISED_MSG, errorReport); } else if (status >= 400 && status < 500) { // Any code in the 400 range will have a list of error codes attached @@ -207,7 +229,6 @@ public T getJsonData(final String request, final P payload, final String throw new GeneralException(FAILED_DATA_RESPONSE_CODE + status, status); } } - /** * Actually sends a HTTP request and returns its body and HTTP status code. * @@ -253,6 +274,63 @@

APIResponse doRequest(final String method, final String url, final P payload } } + /** + * + * Do get request for file from input url and stores the file in filepath. + * @param url Absolute URL. + * @param filePath the path where the downloaded file is going to be stored. + * @return if it succeed, it returns filepath otherwise null or exception. + */ + String doGetRequestForFileAndStore(final String url, final String filePath) throws GeneralException, UnauthorizedException, NotFoundException { + HttpURLConnection connection = null; + InputStream inputStream = null; + + try { + connection = getConnection(url, null, METHOD_GET); + int status = connection.getResponseCode(); + + if (APIResponse.isSuccessStatus(status)) { + inputStream = connection.getInputStream(); + } else { + inputStream = connection.getErrorStream(); + } + if (status == HttpURLConnection.HTTP_OK) { + return writeInputStreamToFile(inputStream, filePath); + } + String body = readToEnd(inputStream); + handleHttpFailStatuses(status, body); + } catch (IOException ioe) { + throw new GeneralException(ioe); + } finally { + saveClose(inputStream); + if (connection != null) { + connection.disconnect(); + } + } + return null; + } + + /** + * Writes input stream from IO to filepath. + * @param inputStream stream that has been collected file input + * @param filepath the storage path for the file + * @return if it succeed, it returns filepath otherwise null or exception. + * @throws IOException + */ + private String writeInputStreamToFile(InputStream inputStream, String filepath) throws IOException { + // opens an output stream to save into file + FileOutputStream outputStream = new FileOutputStream(filepath); + + int bytesRead = -1; + byte[] buffer = new byte[BUFFER_SIZE]; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + + outputStream.close(); + return filepath; + } + /** * By default, HttpURLConnection does not support PATCH requests. We can * however work around this with reflection. Many thanks to okutane on @@ -431,7 +509,7 @@ private double getVersion() throws GeneralException { /** * Get the MessageBird error report data. * - * @param body Raw request body. + * @param body Raw response body. * @return Error report, or null if the body can not be deserialized. */ private List getErrorReportOrNull(final String body) { diff --git a/api/src/main/java/com/messagebird/objects/VoiceStep.java b/api/src/main/java/com/messagebird/objects/VoiceStep.java index 25d56c20..066dd207 100644 --- a/api/src/main/java/com/messagebird/objects/VoiceStep.java +++ b/api/src/main/java/com/messagebird/objects/VoiceStep.java @@ -1,5 +1,7 @@ package com.messagebird.objects; +import com.messagebird.objects.voicecalls.VoiceCallCondition; + import java.io.Serializable; public class VoiceStep implements Serializable { @@ -10,6 +12,8 @@ public class VoiceStep implements Serializable { private String action; private VoiceStepOption options; + private VoiceCallCondition[] conditions; + public String getId() { return id; } @@ -34,6 +38,14 @@ public void setOptions(VoiceStepOption options) { this.options = options; } + public VoiceCallCondition[] getConditions() { + return conditions; + } + + public void setConditions(VoiceCallCondition[] conditions) { + this.conditions = conditions; + } + @Override public String toString() { return "VoiceStep{" + diff --git a/api/src/main/java/com/messagebird/objects/VoiceStepOption.java b/api/src/main/java/com/messagebird/objects/VoiceStepOption.java index 33cdec54..85415ef0 100644 --- a/api/src/main/java/com/messagebird/objects/VoiceStepOption.java +++ b/api/src/main/java/com/messagebird/objects/VoiceStepOption.java @@ -25,6 +25,9 @@ public class VoiceStepOption implements Serializable { private String onFinish; private boolean mask; + private String onKeypressGoto; + private String onKeypressVar; + public String getDestination() { return destination; } @@ -169,6 +172,22 @@ public void setMask(boolean mask) { this.mask = mask; } + public String getOnKeypressGoto() { + return onKeypressGoto; + } + + public void setOnKeypressGoto(String onKeypressGoto) { + this.onKeypressGoto = onKeypressGoto; + } + + public String getOnKeypressVar() { + return onKeypressVar; + } + + public void setOnKeypressVar(String onKeypressVar) { + this.onKeypressVar = onKeypressVar; + } + @Override public String toString() { return "VoiceStepOption{" + @@ -189,7 +208,9 @@ public String toString() { ", ifMachine='" + ifMachine + '\'' + ", machineTimeout=" + machineTimeout + ", onFinish='" + onFinish + '\'' + - ", mask='" + mask + '\'' + + ", mask=" + mask + + ", onKeypressGoto='" + onKeypressGoto + '\'' + + ", onKeypressVar='" + onKeypressVar + '\'' + '}'; } } diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/RecordingResponseList.java b/api/src/main/java/com/messagebird/objects/voicecalls/RecordingResponseList.java new file mode 100644 index 00000000..fa0c7e13 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/voicecalls/RecordingResponseList.java @@ -0,0 +1,20 @@ +package com.messagebird.objects.voicecalls; + +public class RecordingResponseList { + private RecordingResponse[] data; + + public RecordingResponseList(RecordingResponse[] data) { + this.data = data; + } + + public RecordingResponseList() { + } + + public RecordingResponse[] getData() { + return data; + } + + public void setData(RecordingResponse[] data) { + this.data = data; + } +} diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallCondition.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallCondition.java new file mode 100644 index 00000000..de99a1b9 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallCondition.java @@ -0,0 +1,34 @@ +package com.messagebird.objects.voicecalls; + +public class VoiceCallCondition { + private String variable; + private String operator; + private String value; + + public VoiceCallCondition() { + } + + public String getVariable() { + return variable; + } + + public void setVariable(String variable) { + this.variable = variable; + } + + public String getOperator() { + return operator; + } + + public void setOperator(String operator) { + this.operator = operator; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java index efe00f40..d64f0d2c 100644 --- a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java @@ -85,6 +85,14 @@ public void setUpdatedAt(Date updatedAt) { this.updatedAt = updatedAt; } + public Map getLinks() { + return links; + } + + public void setLinks(Map links) { + this.links = links; + } + @Override public String toString() { return "VoiceCallFlow{" + diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowList.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowList.java index b5d135c8..dc2ad000 100644 --- a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowList.java +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowList.java @@ -13,10 +13,6 @@ */ public class VoiceCallFlowList implements Serializable { - private Integer offset; - private Integer limit; - private Integer totalCount; - @JsonProperty("_links") private Map links; @@ -31,12 +27,7 @@ public VoiceCallFlowList(@JsonProperty("data") List data) { @Override public String toString() { - return "ListBase{" + - "offset=" + offset + - ", limit=" + limit + - ", totalCount=" + totalCount + - ", items=" + items + - '}'; + return pagination.toString(); } public void setPagination(Pagination pagination) { diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 4b589379..6f58284d 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -565,6 +565,70 @@ public void testCreateTranscription() throws UnauthorizedException, GeneralExcep assertEquals(response.getData().get(0).getCreatedAt(), transcriptionResponse.getData().get(0).getCreatedAt()); } + @Test + public void testListRecordings() throws UnauthorizedException, GeneralException { + final RecordingResponseList recordingResponseList = TestUtil.createRecordingResponseList(); + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + + String url = String.format( + "%s%s/%s%s/%s%s", + VOICE_CALLS_BASE_URL, + VOICECALLSPATH, + "ANY_CALL_ID", + LEGSPATH, + "ANY_LEG_ID", + RECORDINGPATH + ); + when(messageBirdServiceMock.requestList(Mockito.eq(url), 0, 0, Mockito.eq(RecordingResponseList.class))) + .thenReturn(recordingResponseList); + + final RecordingResponseList response = messageBirdClientInjectMock + .listRecordings("ANY_CALL_ID", "ANY_LEG_ID", 0, 0); + verify(messageBirdServiceMock, times(1)).requestList(url, 0, 0, RecordingResponseList.class); + assertNotNull(response); + for(int i = 0; i < response.getData().length ; i++) { + assertEquals(response.getData()[0].getData().get(0).getId(), recordingResponseList.getData()[0].getData().get(0).getId()); + assertEquals(response.getData()[0].getData().get(0).getFormat(), recordingResponseList.getData()[0].getData().get(0).getFormat()); + assertEquals(response.getData()[0].getData().get(0).getState(), recordingResponseList.getData()[0].getData().get(0).getState()); + assertEquals(response.getData()[0].getData().get(0).getLegId(), recordingResponseList.getData()[0].getData().get(0).getLegId()); + assertEquals(response.getData()[0].getData().get(0).getDuration(), recordingResponseList.getData()[0].getData().get(0).getDuration()); + assertEquals(response.getData()[0].getData().get(0).getCreatedAt(), recordingResponseList.getData()[0].getData().get(0).getCreatedAt()); + assertEquals(response.getData()[0].getData().get(0).getUpdatedAt(), recordingResponseList.getData()[0].getData().get(0).getUpdatedAt()); + assertEquals(response.getData()[0].getData().get(0).getLinks().get("self"), recordingResponseList.getData()[0].getLinks().get("self")); + assertEquals(response.getData()[0].getData().get(0).getLinks().get("file"), recordingResponseList.getData()[0].getLinks().get("file")); + } + } + + @Test + public void testDownloadRecording() throws NotFoundException, GeneralException, UnauthorizedException { + String recordId = "123123123"; + String basePath = "test"; + String fileName = String.format("%s%s", recordId, RECORDING_DOWNLOAD_FORMAT); + final String downloadPath = TestUtil.createDownloadPath(recordId, basePath); + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + + String url = String.format( + "%s%s/%s%s/%s%s/%s", + VOICE_CALLS_BASE_URL, + VOICECALLSPATH, + "ANY_CALL_ID", + LEGSPATH, + "ANY_LEG_ID", + RECORDINGPATH, + fileName + ); + when(messageBirdServiceMock.getBinaryData(url, basePath, fileName)) + .thenReturn(downloadPath); + final String response = messageBirdClientInjectMock + .downloadRecording("ANY_CALL_ID", "ANY_LEG_ID", recordId, basePath); + verify(messageBirdServiceMock, times(1)).getBinaryData(url, basePath, fileName); + assertNotNull(response); + assertEquals(downloadPath, response); + } + @Test(expected = IllegalArgumentException.class) public void shouldThrowIllegalArgumentExceptionWhenLanguageIsNotSupported() throws UnauthorizedException, GeneralException { messageBirdClient.createTranscription("ANY_CALL_ID", "ANY_LEG_ID", "ANY_ID", "tr-TR"); diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index 098cf0c1..f47e8040 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -83,6 +83,19 @@ static RecordingResponse createRecordingResponse(){ return new RecordingResponse(Collections.singletonList(createRecording()), links, new Pagination()); } + static RecordingResponseList createRecordingResponseList() { + Map links = new LinkedHashMap<>(); + links.put("self", "ANY_SELF"); + links.put("file", "ANY_FILE"); + RecordingResponse[] responses = new RecordingResponse[]{new RecordingResponse(Collections.singletonList(createRecording()), + links, new Pagination())}; + return new RecordingResponseList(responses); + } + + static String createDownloadPath(String recordId , String basePath) { + return String.format("%s/%s%s",basePath, recordId, MessageBirdClient.RECORDING_DOWNLOAD_FORMAT); + } + static TranscriptionResponse createTranscriptionResponse() { final TranscriptionResponse transcriptionResponse = new TranscriptionResponse(); final Transcription transcription = new Transcription(); diff --git a/examples/src/main/java/ExampleDownloadRecording.java b/examples/src/main/java/ExampleDownloadRecording.java new file mode 100644 index 00000000..c013dd46 --- /dev/null +++ b/examples/src/main/java/ExampleDownloadRecording.java @@ -0,0 +1,38 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; + +public class ExampleDownloadRecording { + public static void main(String[] args) { + if (args.length < 5) { + System.out.println("Please specify your access key and call id and leg id and recording id example :" + + " java -jar test_accesskey e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938"); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + System.out.println("Getting a recording"); + final String callId = args[1]; + final String legId = args[2]; + final String recordingId = args[3]; + final String basePath = args[4]; + //Sending call id and leg id and recording id parameters to client + final String filePath = messageBirdClient.downloadRecording(callId, legId, recordingId, basePath); + if (filePath != null) { + System.out.println("Record file is downloaded to "+filePath); + } + + } catch (GeneralException | NotFoundException | UnauthorizedException exception) { + exception.printStackTrace(); + } + } +} diff --git a/examples/src/main/java/ExampleListOfRecording.java b/examples/src/main/java/ExampleListOfRecording.java new file mode 100644 index 00000000..d1ec0d7b --- /dev/null +++ b/examples/src/main/java/ExampleListOfRecording.java @@ -0,0 +1,42 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.voicecalls.RecordingResponseList; + +public class ExampleListOfRecording { + public static void main(String[] args) { + if (args.length < 3) { + System.out.println("Please specify your access key and call id and leg id and recording id example :" + + " java -jar test_accesskey e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938"); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + System.out.println("Getting a recording"); + final String callId = args[1]; + final String legId = args[2]; + //Sending call id and leg id and recording id parameters to client + final RecordingResponseList recordings = messageBirdClient.listRecordings(callId, legId, 0, 0); + if (recordings.getData() == null) { + System.out.println("No record data found"); + } + //Display recording responses + for(int i = 0; i< recordings.getData().length; i++) { + System.out.println(recordings.getData()[i].toString()); + } + + + } catch (GeneralException | UnauthorizedException exception) { + exception.printStackTrace(); + } + + } +} From eb8a20ef5ede0ffc3bdedc5556d91b7620e6375f Mon Sep 17 00:00:00 2001 From: cemturker Date: Tue, 8 Oct 2019 15:28:29 +0200 Subject: [PATCH 043/516] Mocking problem is fixed. --- api/src/test/java/com/messagebird/MessageBirdClientTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 6f58284d..e7df6967 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -581,7 +581,7 @@ public void testListRecordings() throws UnauthorizedException, GeneralException "ANY_LEG_ID", RECORDINGPATH ); - when(messageBirdServiceMock.requestList(Mockito.eq(url), 0, 0, Mockito.eq(RecordingResponseList.class))) + when(messageBirdServiceMock.requestList(url, 0, 0, RecordingResponseList.class)) .thenReturn(recordingResponseList); final RecordingResponseList response = messageBirdClientInjectMock From 5687021dea0ae293f20f967b991359e07db0bdc3 Mon Sep 17 00:00:00 2001 From: cemturker Date: Tue, 8 Oct 2019 15:41:26 +0200 Subject: [PATCH 044/516] documentation is updated for some methods --- api/src/main/java/com/messagebird/MessageBirdClient.java | 4 +++- api/src/main/java/com/messagebird/MessageBirdService.java | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 45f7d3e1..54a83776 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1220,11 +1220,12 @@ public RecordingResponse viewRecording(String callID, String legId, String recor /** * Downloads the record in .wav format by using callId, legId and recordId and stores to basePath + * * @param callID Voice call ID * @param legId Leg ID * @param recordingId Recording ID * @param basePath store location - * @return + * @return the path that file is stored * @throws NotFoundException * @throws GeneralException * @throws UnauthorizedException @@ -1259,6 +1260,7 @@ public String downloadRecording(String callID, String legId, String recordingId, } /** + * List the all recordings related to CallID and LegId * * @param callID Voice call ID * @param legId Leg ID diff --git a/api/src/main/java/com/messagebird/MessageBirdService.java b/api/src/main/java/com/messagebird/MessageBirdService.java index 9a993c4d..fc43f0c6 100644 --- a/api/src/main/java/com/messagebird/MessageBirdService.java +++ b/api/src/main/java/com/messagebird/MessageBirdService.java @@ -97,7 +97,7 @@ public interface MessageBirdService { * @param request path to the request, for example "/messages" * @param basePath base path for storing directory * @param fileName the fileName that is going to be stored. - * @return basePath/fileName + * @return the path that file is stored * @throws UnauthorizedException * @throws GeneralException * @throws NotFoundException From 18c035307c9dcdd96c88687bcc2c66c36c2dd5ab Mon Sep 17 00:00:00 2001 From: cemturker Date: Wed, 9 Oct 2019 12:10:28 +0200 Subject: [PATCH 045/516] RecordingResponseList is removed. Test methods are modified. --- .../com/messagebird/MessageBirdClient.java | 7 ++--- .../com/messagebird/objects/VoiceStep.java | 27 +++++++++++++++++ .../messagebird/objects/VoiceStepOption.java | 21 ------------- .../voicecalls/RecordingResponseList.java | 20 ------------- .../messagebird/MessageBirdClientTest.java | 30 +++++++++---------- .../test/java/com/messagebird/TestUtil.java | 9 +++--- .../src/main/java/ExampleListOfRecording.java | 10 +++---- 7 files changed, 55 insertions(+), 69 deletions(-) delete mode 100644 api/src/main/java/com/messagebird/objects/voicecalls/RecordingResponseList.java diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 54a83776..607c3e4b 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -36,7 +36,6 @@ import com.messagebird.objects.conversations.ConversationWebhookList; import com.messagebird.objects.conversations.ConversationWebhookUpdateRequest; import com.messagebird.objects.voicecalls.RecordingResponse; -import com.messagebird.objects.voicecalls.RecordingResponseList; import com.messagebird.objects.voicecalls.TranscriptionResponse; import com.messagebird.objects.voicecalls.VoiceCall; import com.messagebird.objects.voicecalls.VoiceCallFlowList; @@ -1224,7 +1223,7 @@ public RecordingResponse viewRecording(String callID, String legId, String recor * @param callID Voice call ID * @param legId Leg ID * @param recordingId Recording ID - * @param basePath store location + * @param basePath store location. It should be directory * @return the path that file is stored * @throws NotFoundException * @throws GeneralException @@ -1272,7 +1271,7 @@ public String downloadRecording(String callID, String legId, String recordingId, * @throws GeneralException if client is unauthorized * @throws UnauthorizedException general exception */ - public RecordingResponseList listRecordings(String callID, String legId, final Integer offset, final Integer limit) + public RecordingResponse listRecordings(String callID, String legId, final Integer offset, final Integer limit) throws GeneralException, UnauthorizedException { verifyOffsetAndLimit(offset, limit); if (callID == null) { @@ -1292,7 +1291,7 @@ public RecordingResponseList listRecordings(String callID, String legId, final I legId, RECORDINGPATH); - return messageBirdService.requestList(url, offset, limit, RecordingResponseList.class); + return messageBirdService.requestList(url, offset, limit, RecordingResponse.class); } /** diff --git a/api/src/main/java/com/messagebird/objects/VoiceStep.java b/api/src/main/java/com/messagebird/objects/VoiceStep.java index 066dd207..8958f8b8 100644 --- a/api/src/main/java/com/messagebird/objects/VoiceStep.java +++ b/api/src/main/java/com/messagebird/objects/VoiceStep.java @@ -3,6 +3,7 @@ import com.messagebird.objects.voicecalls.VoiceCallCondition; import java.io.Serializable; +import java.util.Arrays; public class VoiceStep implements Serializable { @@ -14,6 +15,9 @@ public class VoiceStep implements Serializable { private VoiceCallCondition[] conditions; + private String onKeypressGoto; + private String onKeypressVar; + public String getId() { return id; } @@ -46,12 +50,35 @@ public void setConditions(VoiceCallCondition[] conditions) { this.conditions = conditions; } + public static long getSerialVersionUID() { + return serialVersionUID; + } + + public String getOnKeypressGoto() { + return onKeypressGoto; + } + + public void setOnKeypressGoto(String onKeypressGoto) { + this.onKeypressGoto = onKeypressGoto; + } + + public String getOnKeypressVar() { + return onKeypressVar; + } + + public void setOnKeypressVar(String onKeypressVar) { + this.onKeypressVar = onKeypressVar; + } + @Override public String toString() { return "VoiceStep{" + "id='" + id + '\'' + ", action='" + action + '\'' + ", options=" + options + + ", conditions=" + Arrays.toString(conditions) + + ", onKeypressGoto='" + onKeypressGoto + '\'' + + ", onKeypressVar='" + onKeypressVar + '\'' + '}'; } } diff --git a/api/src/main/java/com/messagebird/objects/VoiceStepOption.java b/api/src/main/java/com/messagebird/objects/VoiceStepOption.java index 85415ef0..51e74962 100644 --- a/api/src/main/java/com/messagebird/objects/VoiceStepOption.java +++ b/api/src/main/java/com/messagebird/objects/VoiceStepOption.java @@ -25,9 +25,6 @@ public class VoiceStepOption implements Serializable { private String onFinish; private boolean mask; - private String onKeypressGoto; - private String onKeypressVar; - public String getDestination() { return destination; } @@ -172,22 +169,6 @@ public void setMask(boolean mask) { this.mask = mask; } - public String getOnKeypressGoto() { - return onKeypressGoto; - } - - public void setOnKeypressGoto(String onKeypressGoto) { - this.onKeypressGoto = onKeypressGoto; - } - - public String getOnKeypressVar() { - return onKeypressVar; - } - - public void setOnKeypressVar(String onKeypressVar) { - this.onKeypressVar = onKeypressVar; - } - @Override public String toString() { return "VoiceStepOption{" + @@ -209,8 +190,6 @@ public String toString() { ", machineTimeout=" + machineTimeout + ", onFinish='" + onFinish + '\'' + ", mask=" + mask + - ", onKeypressGoto='" + onKeypressGoto + '\'' + - ", onKeypressVar='" + onKeypressVar + '\'' + '}'; } } diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/RecordingResponseList.java b/api/src/main/java/com/messagebird/objects/voicecalls/RecordingResponseList.java deleted file mode 100644 index fa0c7e13..00000000 --- a/api/src/main/java/com/messagebird/objects/voicecalls/RecordingResponseList.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.messagebird.objects.voicecalls; - -public class RecordingResponseList { - private RecordingResponse[] data; - - public RecordingResponseList(RecordingResponse[] data) { - this.data = data; - } - - public RecordingResponseList() { - } - - public RecordingResponse[] getData() { - return data; - } - - public void setData(RecordingResponse[] data) { - this.data = data; - } -} diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index e7df6967..54c2b302 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -567,7 +567,7 @@ public void testCreateTranscription() throws UnauthorizedException, GeneralExcep @Test public void testListRecordings() throws UnauthorizedException, GeneralException { - final RecordingResponseList recordingResponseList = TestUtil.createRecordingResponseList(); + final RecordingResponse recordings = TestUtil.createRecordingResponseList(); MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); @@ -581,23 +581,23 @@ public void testListRecordings() throws UnauthorizedException, GeneralException "ANY_LEG_ID", RECORDINGPATH ); - when(messageBirdServiceMock.requestList(url, 0, 0, RecordingResponseList.class)) - .thenReturn(recordingResponseList); + when(messageBirdServiceMock.requestList(url, 0, 0, RecordingResponse.class)) + .thenReturn(recordings); - final RecordingResponseList response = messageBirdClientInjectMock + final RecordingResponse response = messageBirdClientInjectMock .listRecordings("ANY_CALL_ID", "ANY_LEG_ID", 0, 0); - verify(messageBirdServiceMock, times(1)).requestList(url, 0, 0, RecordingResponseList.class); + verify(messageBirdServiceMock, times(1)).requestList(url, 0, 0, RecordingResponse.class); assertNotNull(response); - for(int i = 0; i < response.getData().length ; i++) { - assertEquals(response.getData()[0].getData().get(0).getId(), recordingResponseList.getData()[0].getData().get(0).getId()); - assertEquals(response.getData()[0].getData().get(0).getFormat(), recordingResponseList.getData()[0].getData().get(0).getFormat()); - assertEquals(response.getData()[0].getData().get(0).getState(), recordingResponseList.getData()[0].getData().get(0).getState()); - assertEquals(response.getData()[0].getData().get(0).getLegId(), recordingResponseList.getData()[0].getData().get(0).getLegId()); - assertEquals(response.getData()[0].getData().get(0).getDuration(), recordingResponseList.getData()[0].getData().get(0).getDuration()); - assertEquals(response.getData()[0].getData().get(0).getCreatedAt(), recordingResponseList.getData()[0].getData().get(0).getCreatedAt()); - assertEquals(response.getData()[0].getData().get(0).getUpdatedAt(), recordingResponseList.getData()[0].getData().get(0).getUpdatedAt()); - assertEquals(response.getData()[0].getData().get(0).getLinks().get("self"), recordingResponseList.getData()[0].getLinks().get("self")); - assertEquals(response.getData()[0].getData().get(0).getLinks().get("file"), recordingResponseList.getData()[0].getLinks().get("file")); + for(int i = 0; i < response.getData().size() ; i++) { + assertEquals(response.getData().get(i).getId(), recordings.getData().get(i).getId()); + assertEquals(response.getData().get(i).getFormat(), recordings.getData().get(i).getFormat()); + assertEquals(response.getData().get(i).getState(), recordings.getData().get(i).getState()); + assertEquals(response.getData().get(i).getLegId(), recordings.getData().get(i).getLegId()); + assertEquals(response.getData().get(i).getDuration(), recordings.getData().get(i).getDuration()); + assertEquals(response.getData().get(i).getCreatedAt(), recordings.getData().get(i).getCreatedAt()); + assertEquals(response.getData().get(i).getUpdatedAt(), recordings.getData().get(i).getUpdatedAt()); + assertEquals(response.getData().get(i).getLinks().get("self"), recordings.getLinks().get("self")); + assertEquals(response.getData().get(i).getLinks().get("file"), recordings.getLinks().get("file")); } } diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index f47e8040..7e12d349 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -83,13 +83,14 @@ static RecordingResponse createRecordingResponse(){ return new RecordingResponse(Collections.singletonList(createRecording()), links, new Pagination()); } - static RecordingResponseList createRecordingResponseList() { + static RecordingResponse createRecordingResponseList() { Map links = new LinkedHashMap<>(); links.put("self", "ANY_SELF"); links.put("file", "ANY_FILE"); - RecordingResponse[] responses = new RecordingResponse[]{new RecordingResponse(Collections.singletonList(createRecording()), - links, new Pagination())}; - return new RecordingResponseList(responses); + List recordingList = new ArrayList<>(); + recordingList.add(createRecording()); + recordingList.add(createRecording()); + return new RecordingResponse(recordingList, links, new Pagination()); } static String createDownloadPath(String recordId , String basePath) { diff --git a/examples/src/main/java/ExampleListOfRecording.java b/examples/src/main/java/ExampleListOfRecording.java index d1ec0d7b..d20240e6 100644 --- a/examples/src/main/java/ExampleListOfRecording.java +++ b/examples/src/main/java/ExampleListOfRecording.java @@ -3,7 +3,7 @@ import com.messagebird.MessageBirdServiceImpl; import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.UnauthorizedException; -import com.messagebird.objects.voicecalls.RecordingResponseList; +import com.messagebird.objects.voicecalls.RecordingResponse; public class ExampleListOfRecording { public static void main(String[] args) { @@ -24,16 +24,16 @@ public static void main(String[] args) { final String callId = args[1]; final String legId = args[2]; //Sending call id and leg id and recording id parameters to client - final RecordingResponseList recordings = messageBirdClient.listRecordings(callId, legId, 0, 0); + final RecordingResponse recordings = messageBirdClient.listRecordings(callId, legId, 0, 0); if (recordings.getData() == null) { System.out.println("No record data found"); } //Display recording responses - for(int i = 0; i< recordings.getData().length; i++) { - System.out.println(recordings.getData()[i].toString()); + for(int i = 0; i< recordings.getData().size(); i++) { + System.out.println(recordings.getData().get(i).toString()); + System.out.println(); } - } catch (GeneralException | UnauthorizedException exception) { exception.printStackTrace(); } From f67e6a38b4c97ac03b650fc3f82ce6913110d902 Mon Sep 17 00:00:00 2001 From: cemturker Date: Wed, 9 Oct 2019 15:43:19 +0200 Subject: [PATCH 046/516] Some changes for documentation Get default path as home path --- .../com/messagebird/MessageBirdClient.java | 24 +++++++++++++------ .../com/messagebird/MessageBirdService.java | 6 ++--- .../messagebird/MessageBirdServiceImpl.java | 5 +++- .../messagebird/MessageBirdClientTest.java | 11 ++------- .../main/java/ExampleDownloadRecording.java | 11 +++++---- .../src/main/java/ExampleListOfRecording.java | 4 ++-- 6 files changed, 35 insertions(+), 26 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 607c3e4b..5a72f09c 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -110,6 +110,8 @@ public class MessageBirdClient { private static final String VOICELEGS_SUFFIX_PATH = "/legs"; static final String RECORDING_DOWNLOAD_FORMAT = ".wav"; + private final String DOWNLOADS = "Downloads"; + private MessageBirdService messageBirdService; private String conversationsBaseUrl; @@ -1218,16 +1220,17 @@ public RecordingResponse viewRecording(String callID, String legId, String recor } /** - * Downloads the record in .wav format by using callId, legId and recordId and stores to basePath + * Downloads the record in .wav format by using callId, legId and recordId and stores to basePath. basePath is not mandatory to set. + * If basePath is not set, default download will be the /Download folder in user group. * * @param callID Voice call ID * @param legId Leg ID * @param recordingId Recording ID - * @param basePath store location. It should be directory + * @param basePath store location. It should be directory. Property is Optional if $HOME is accessible * @return the path that file is stored - * @throws NotFoundException - * @throws GeneralException - * @throws UnauthorizedException + * @throws NotFoundException if the recording does not found + * @throws GeneralException general exception + * @throws UnauthorizedException if client is unauthorized */ public String downloadRecording(String callID, String legId, String recordingId, String basePath) throws NotFoundException, GeneralException, UnauthorizedException { @@ -1243,6 +1246,15 @@ public String downloadRecording(String callID, String legId, String recordingId, throw new IllegalArgumentException("Recording ID must be specified."); } + if (basePath == null) { + String homePath = System.getProperty("user.home"); + //Home path is not existing + if (homePath == null) { + throw new IllegalArgumentException("BasePath must be specified."); + } + basePath = String.format("%s/%s",homePath,DOWNLOADS); + } + String url = String.format( "%s%s/%s%s/%s%s/%s%s", VOICE_CALLS_BASE_URL, @@ -1263,8 +1275,6 @@ public String downloadRecording(String callID, String legId, String recordingId, * * @param callID Voice call ID * @param legId Leg ID - * @param offset - * @param limit * @param offset Number of objects to skip. * @param limit Number of objects to take. * @return Recordings for CallID and LegID diff --git a/api/src/main/java/com/messagebird/MessageBirdService.java b/api/src/main/java/com/messagebird/MessageBirdService.java index fc43f0c6..c100da10 100644 --- a/api/src/main/java/com/messagebird/MessageBirdService.java +++ b/api/src/main/java/com/messagebird/MessageBirdService.java @@ -98,9 +98,9 @@ public interface MessageBirdService { * @param basePath base path for storing directory * @param fileName the fileName that is going to be stored. * @return the path that file is stored - * @throws UnauthorizedException - * @throws GeneralException - * @throws NotFoundException + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + * @throws NotFoundException if the file is not found */ String getBinaryData(String request, String basePath, String fileName) throws UnauthorizedException, GeneralException, NotFoundException; } diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index faf47fa8..45e4030c 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -281,7 +281,7 @@

APIResponse doRequest(final String method, final String url, final P payload * @param filePath the path where the downloaded file is going to be stored. * @return if it succeed, it returns filepath otherwise null or exception. */ - String doGetRequestForFileAndStore(final String url, final String filePath) throws GeneralException, UnauthorizedException, NotFoundException { + private String doGetRequestForFileAndStore(final String url, final String filePath) throws GeneralException, UnauthorizedException, NotFoundException { HttpURLConnection connection = null; InputStream inputStream = null; @@ -293,6 +293,9 @@ String doGetRequestForFileAndStore(final String url, final String filePath) thro inputStream = connection.getInputStream(); } else { inputStream = connection.getErrorStream(); + if (inputStream == null) { + throw new GeneralException("Error stream was empty"); + } } if (status == HttpURLConnection.HTTP_OK) { return writeInputStreamToFile(inputStream, filePath); diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 54c2b302..779a88f7 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -19,6 +19,7 @@ import static com.messagebird.MessageBirdClient.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; +import static org.unitils.reflectionassert.ReflectionAssert.assertReflectionEquals; /** * Created by rvt on 1/8/15. @@ -589,15 +590,7 @@ public void testListRecordings() throws UnauthorizedException, GeneralException verify(messageBirdServiceMock, times(1)).requestList(url, 0, 0, RecordingResponse.class); assertNotNull(response); for(int i = 0; i < response.getData().size() ; i++) { - assertEquals(response.getData().get(i).getId(), recordings.getData().get(i).getId()); - assertEquals(response.getData().get(i).getFormat(), recordings.getData().get(i).getFormat()); - assertEquals(response.getData().get(i).getState(), recordings.getData().get(i).getState()); - assertEquals(response.getData().get(i).getLegId(), recordings.getData().get(i).getLegId()); - assertEquals(response.getData().get(i).getDuration(), recordings.getData().get(i).getDuration()); - assertEquals(response.getData().get(i).getCreatedAt(), recordings.getData().get(i).getCreatedAt()); - assertEquals(response.getData().get(i).getUpdatedAt(), recordings.getData().get(i).getUpdatedAt()); - assertEquals(response.getData().get(i).getLinks().get("self"), recordings.getLinks().get("self")); - assertEquals(response.getData().get(i).getLinks().get("file"), recordings.getLinks().get("file")); + assertReflectionEquals(response.getData().get(i), recordings.getData().get(i)); } } diff --git a/examples/src/main/java/ExampleDownloadRecording.java b/examples/src/main/java/ExampleDownloadRecording.java index c013dd46..b880967a 100644 --- a/examples/src/main/java/ExampleDownloadRecording.java +++ b/examples/src/main/java/ExampleDownloadRecording.java @@ -7,9 +7,9 @@ public class ExampleDownloadRecording { public static void main(String[] args) { - if (args.length < 5) { - System.out.println("Please specify your access key and call id and leg id and recording id example :" + - " java -jar test_accesskey e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938"); + if (args.length < 4) { + System.out.println("Please specify your access key and call id and leg id and recording id and base path(optional) example :" + + " java -jar test_accesskey e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938 /users/{user}/test"); return; } @@ -24,7 +24,10 @@ public static void main(String[] args) { final String callId = args[1]; final String legId = args[2]; final String recordingId = args[3]; - final String basePath = args[4]; + String basePath = null; + if (args.length > 4) { + basePath = args[4]; + } //Sending call id and leg id and recording id parameters to client final String filePath = messageBirdClient.downloadRecording(callId, legId, recordingId, basePath); if (filePath != null) { diff --git a/examples/src/main/java/ExampleListOfRecording.java b/examples/src/main/java/ExampleListOfRecording.java index d20240e6..ed1fa5a0 100644 --- a/examples/src/main/java/ExampleListOfRecording.java +++ b/examples/src/main/java/ExampleListOfRecording.java @@ -8,8 +8,8 @@ public class ExampleListOfRecording { public static void main(String[] args) { if (args.length < 3) { - System.out.println("Please specify your access key and call id and leg id and recording id example :" + - " java -jar test_accesskey e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938"); + System.out.println("Please specify your access key and call id and leg id example :" + + " java -jar test_accesskey e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938"); return; } From 8e55776b137d19069771441a25103713df818153 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Thu, 10 Oct 2019 11:43:16 +0200 Subject: [PATCH 047/516] Issue #57 was resolved with these changes --- .../java/com/messagebird/MessageBirdClient.java | 4 ++++ .../com/messagebird/objects/VoiceMessage.java | 17 +++++++++++++++++ .../objects/VoiceMessageResponse.java | 10 ++++++++++ 3 files changed, 31 insertions(+) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 5a72f09c..1f0a9d43 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -311,6 +311,10 @@ public MessageResponse viewMessage(final String id) throws UnauthorizedException * @throws GeneralException general exception */ public VoiceMessageResponse sendVoiceMessage(final VoiceMessage voiceMessage) throws UnauthorizedException, GeneralException { + if (voiceMessage.getMachineTimeout() == 0){ + voiceMessage.setMachineTimeout(7000); //default machine timeout value + } + return messageBirdService.sendPayLoad(VOICEMESSAGESPATH, voiceMessage, VoiceMessageResponse.class); } diff --git a/api/src/main/java/com/messagebird/objects/VoiceMessage.java b/api/src/main/java/com/messagebird/objects/VoiceMessage.java index 8d941051..0674851e 100644 --- a/api/src/main/java/com/messagebird/objects/VoiceMessage.java +++ b/api/src/main/java/com/messagebird/objects/VoiceMessage.java @@ -22,6 +22,7 @@ public class VoiceMessage implements MessageBase, Serializable { private VoiceType voice; private Integer repeat; private IfMachineType ifMachine; + private int machineTimeout; private Date scheduledDatetime; public VoiceMessage(String body, List recipients) { @@ -171,6 +172,22 @@ public void setIfMachine(IfMachineType ifMachine) { this.ifMachine = ifMachine; } + /** + * The time (in milliseconds) to analyze if a machine has picked up the phone. + * Used in combination with the delay and hangup values of the ifMachine attribute. + * Minimum: 400, maximum: 10000. Default: 7000 + * @return value of machine timeout + */ + public int getMachineTimeout() { return machineTimeout; } + + /** + * The time (in milliseconds) to analyze if a machine has picked up the phone. + * Used in combination with the delay and hangup values of the ifMachine attribute. + * Minimum: 400, maximum: 10000. Default: 7000 + * @param machineTimeout value of machine timeout + */ + public void setMachineTimeout(int machineTimeout) { this.machineTimeout = machineTimeout; } + @Override public Date getScheduledDatetime() { return scheduledDatetime; diff --git a/api/src/main/java/com/messagebird/objects/VoiceMessageResponse.java b/api/src/main/java/com/messagebird/objects/VoiceMessageResponse.java index fe8d56f1..6563919e 100644 --- a/api/src/main/java/com/messagebird/objects/VoiceMessageResponse.java +++ b/api/src/main/java/com/messagebird/objects/VoiceMessageResponse.java @@ -21,6 +21,7 @@ public class VoiceMessageResponse implements MessageResponseBase, Serializable { private VoiceType voice; private Integer repeat; private IfMachineType ifMachine; + private int machineTimeout; private Date scheduledDatetime; private Date createdDatetime; private MessageResponse.Recipients recipients; @@ -40,6 +41,7 @@ public String toString() { ", voice=" + voice + ", repeat=" + repeat + ", ifMachine=" + ifMachine + + ", machineTimeout=" + machineTimeout + ", scheduledDatetime=" + scheduledDatetime + ", createdDatetime=" + createdDatetime + ", recipients=" + recipients + @@ -114,6 +116,14 @@ public IfMachineType getIfMachine() { return ifMachine; } + /** + * The time (in milliseconds) to analyze if a machine has picked up the phone. + * Used in combination with the delay and hangup values of the ifMachine attribute. + * Minimum: 400, maximum: 10000. Default: 7000 + * @return value of machine timeout + */ + public int getMachineTimeout() { return machineTimeout; } + /** * The scheduled date and time of the message * From 9df25d4d5e3c9c68505838b7e0b64c0b2bea26c5 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Thu, 10 Oct 2019 11:59:17 +0200 Subject: [PATCH 048/516] updated after review --- .../com/messagebird/MessageBirdClient.java | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 1f0a9d43..bdcee58b 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -109,6 +109,9 @@ public class MessageBirdClient { static final String VOICECALLFLOWPATH = "/call-flows"; private static final String VOICELEGS_SUFFIX_PATH = "/legs"; static final String RECORDING_DOWNLOAD_FORMAT = ".wav"; + private static final int DEFAULT_MACHINE_TIMEOUT_VALUE = 7000; + private static final int MIN_MACHINE_TIMEOUT_VALUE = 400; + private static final int MAX_MACHINE_TIMEOUT_VALUE = 10000; private final String DOWNLOADS = "Downloads"; @@ -311,10 +314,8 @@ public MessageResponse viewMessage(final String id) throws UnauthorizedException * @throws GeneralException general exception */ public VoiceMessageResponse sendVoiceMessage(final VoiceMessage voiceMessage) throws UnauthorizedException, GeneralException { - if (voiceMessage.getMachineTimeout() == 0){ - voiceMessage.setMachineTimeout(7000); //default machine timeout value - } - + addDefaultMachineTimeoutValueIfNotExists(voiceMessage); + checkMachineTimeoutValueIsInRange(voiceMessage); return messageBirdService.sendPayLoad(VOICEMESSAGESPATH, voiceMessage, VoiceMessageResponse.class); } @@ -329,6 +330,8 @@ public VoiceMessageResponse sendVoiceMessage(final VoiceMessage voiceMessage) th */ public VoiceMessageResponse sendVoiceMessage(final String body, final List recipients) throws UnauthorizedException, GeneralException { final VoiceMessage message = new VoiceMessage(body, recipients); + addDefaultMachineTimeoutValueIfNotExists(message); + checkMachineTimeoutValueIsInRange(message); return messageBirdService.sendPayLoad(VOICEMESSAGESPATH, message, VoiceMessageResponse.class); } @@ -345,9 +348,23 @@ public VoiceMessageResponse sendVoiceMessage(final String body, final List recipients, final String reference) throws UnauthorizedException, GeneralException { final VoiceMessage message = new VoiceMessage(body, recipients); message.setReference(reference); + addDefaultMachineTimeoutValueIfNotExists(message); + checkMachineTimeoutValueIsInRange(message); return messageBirdService.sendPayLoad(VOICEMESSAGESPATH, message, VoiceMessageResponse.class); } + private void addDefaultMachineTimeoutValueIfNotExists(final VoiceMessage voiceMessage){ + if (voiceMessage.getMachineTimeout() == 0){ + voiceMessage.setMachineTimeout(DEFAULT_MACHINE_TIMEOUT_VALUE); //default machine timeout value + } + } + + private void checkMachineTimeoutValueIsInRange(final VoiceMessage voiceMessage){ + if (voiceMessage.getMachineTimeout() < MIN_MACHINE_TIMEOUT_VALUE || voiceMessage.getMachineTimeout() > MAX_MACHINE_TIMEOUT_VALUE){ + throw new IllegalArgumentException("Please define machine timeout value between " + MIN_MACHINE_TIMEOUT_VALUE + " and " + MAX_MACHINE_TIMEOUT_VALUE); + } + } + /** * Delete a voice message from the Messagebird server * From 39c3fbc9492476f710cca2995a2d400d1807a3e2 Mon Sep 17 00:00:00 2001 From: cemturker Date: Thu, 10 Oct 2019 13:14:20 +0200 Subject: [PATCH 049/516] Adds transaction download and transaction listing. --- .../com/messagebird/MessageBirdClient.java | 128 ++++++++++++++++-- .../messagebird/MessageBirdServiceImpl.java | 8 ++ .../objects/voicecalls/Transcription.java | 26 +++- .../voicecalls/TranscriptionResponse.java | 37 +++++ .../messagebird/MessageBirdClientTest.java | 64 ++++++++- .../java/ExampleDownloadTranscription.java | 43 ++++++ .../main/java/ExampleListTranscriptions.java | 44 ++++++ .../main/java/ExampleViewTranscription.java | 15 +- .../ExampleViewTranscriptionDeprecated.java | 40 ++++++ 9 files changed, 382 insertions(+), 23 deletions(-) create mode 100644 examples/src/main/java/ExampleDownloadTranscription.java create mode 100644 examples/src/main/java/ExampleListTranscriptions.java create mode 100644 examples/src/main/java/ExampleViewTranscriptionDeprecated.java diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 5a72f09c..00461bb9 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -109,6 +109,7 @@ public class MessageBirdClient { static final String VOICECALLFLOWPATH = "/call-flows"; private static final String VOICELEGS_SUFFIX_PATH = "/legs"; static final String RECORDING_DOWNLOAD_FORMAT = ".wav"; + static final String TRANSCRIPTION_DOWNLOAD_FORMAT = ".txt"; private final String DOWNLOADS = "Downloads"; @@ -1246,15 +1247,6 @@ public String downloadRecording(String callID, String legId, String recordingId, throw new IllegalArgumentException("Recording ID must be specified."); } - if (basePath == null) { - String homePath = System.getProperty("user.home"); - //Home path is not existing - if (homePath == null) { - throw new IllegalArgumentException("BasePath must be specified."); - } - basePath = String.format("%s/%s",homePath,DOWNLOADS); - } - String url = String.format( "%s%s/%s%s/%s%s/%s%s", VOICE_CALLS_BASE_URL, @@ -1360,7 +1352,10 @@ public TranscriptionResponse createTranscription(String callID, String legId, St * @return TranscriptionResponseList * @throws UnauthorizedException if client is unauthorized * @throws GeneralException general exception + * + * @deprecated use {@link #listTranscriptions} instead. */ + @Deprecated public TranscriptionResponse viewTranscription(String callID, String legId, String recordingId, Integer page, Integer pageSize) throws UnauthorizedException, GeneralException { if (callID == null) { throw new IllegalArgumentException("Voice call ID must be specified."); @@ -1375,18 +1370,129 @@ public TranscriptionResponse viewTranscription(String callID, String legId, Stri } String url = String.format( - "%s%s/%s%s/%s%s/%s", + "%s%s/%s%s/%s%s/%s%s", VOICE_CALLS_BASE_URL, VOICECALLSPATH, callID, LEGSPATH, legId, RECORDINGPATH, - recordingId); + recordingId, + TRANSCRIPTIONPATH); return messageBirdService.requestList(url, new PagedPaging(page, pageSize), TranscriptionResponse.class); } + /** + * Function to view recording by call id, leg id and recording id + * + * @param callID Voice call ID + * @param legId Leg ID + * @param recordingId Recording ID + * @param transcriptionId Transcription ID + * @return TranscriptionResponseList + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + * @throws NotFoundException If transcription is not found + */ + public TranscriptionResponse viewTranscription(String callID, String legId, String recordingId, String transcriptionId) throws UnauthorizedException, GeneralException, NotFoundException { + if (callID == null) { + throw new IllegalArgumentException("Voice call ID must be specified."); + } + + if (legId == null) { + throw new IllegalArgumentException("Leg ID must be specified."); + } + + if (recordingId == null) { + throw new IllegalArgumentException("Recording ID must be specified."); + } + + String url = String.format( + "%s%s/%s%s/%s%s/%s%s", + VOICE_CALLS_BASE_URL, + VOICECALLSPATH, + callID, + LEGSPATH, + legId, + RECORDINGPATH, + recordingId, + TRANSCRIPTIONPATH); + + return messageBirdService.requestByID(url, transcriptionId, TranscriptionResponse.class); + } + + /** + * + * @param callID + * @param legId + * @param recordingId + * @param page + * @param pageSize + * @return + * @throws UnauthorizedException + * @throws GeneralException + */ + public TranscriptionResponse listTranscriptions(String callID, String legId, String recordingId, Integer page, Integer pageSize) throws UnauthorizedException, GeneralException { + if (callID == null) { + throw new IllegalArgumentException("Voice call ID must be specified."); + } + + if (legId == null) { + throw new IllegalArgumentException("Leg ID must be specified."); + } + + if (recordingId == null) { + throw new IllegalArgumentException("Recording ID must be specified."); + } + + String url = String.format( + "%s%s/%s%s/%s%s/%s%s", + VOICE_CALLS_BASE_URL, + VOICECALLSPATH, + callID, + LEGSPATH, + legId, + RECORDINGPATH, + recordingId, + TRANSCRIPTIONPATH); + + return messageBirdService.requestList(url, new PagedPaging(page, pageSize), TranscriptionResponse.class); + } + + public String downloadTranscription(String callID, String legId, String recordingId, String transcriptionId, String basePath) + throws UnauthorizedException, GeneralException, NotFoundException { + if (callID == null) { + throw new IllegalArgumentException("Voice call ID must be specified."); + } + + if (legId == null) { + throw new IllegalArgumentException("Leg ID must be specified."); + } + + if (recordingId == null) { + throw new IllegalArgumentException("Recording ID must be specified."); + } + + if (transcriptionId == null) { + throw new IllegalArgumentException("Transcription ID must be specified."); + } + String fileName = String.format("%s%s", transcriptionId, TRANSCRIPTION_DOWNLOAD_FORMAT); + String url = String.format( + "%s%s/%s%s/%s%s/%s%s/%s", + VOICE_CALLS_BASE_URL, + VOICECALLSPATH, + callID, + LEGSPATH, + legId, + RECORDINGPATH, + recordingId, + TRANSCRIPTIONPATH, + fileName); + + return messageBirdService.getBinaryData(url, basePath, fileName); + } + /** * Function to create a webhook * diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 45e4030c..a29ae4f5 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -169,6 +169,14 @@ public R sendPayLoad(String method, String request, P payload, Class c @Override public String getBinaryData(String request, String basePath, String fileName) throws GeneralException, UnauthorizedException, NotFoundException { + if (basePath == null) { + String homePath = System.getProperty("user.home"); + //Home path is not existing + if (homePath == null) { + throw new IllegalArgumentException("BasePath must be specified."); + } + basePath = String.format("%s/%s",homePath,"Downloads"); + } File file = new File(basePath); if(!file.exists()) { throw new IllegalArgumentException("basePath must be existed as directory."); diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/Transcription.java b/api/src/main/java/com/messagebird/objects/voicecalls/Transcription.java index 3c6c665e..3a43a98a 100644 --- a/api/src/main/java/com/messagebird/objects/voicecalls/Transcription.java +++ b/api/src/main/java/com/messagebird/objects/voicecalls/Transcription.java @@ -12,6 +12,8 @@ public class Transcription implements Serializable { private String id; private String recordingId; private String error; + private String status; + private String legId; private Date createdAt; private Date updatedAt; @JsonProperty("_links") @@ -45,6 +47,10 @@ public Date getCreatedAt() { return createdAt; } + public static long getSerialVersionUID() { + return serialVersionUID; + } + public void setCreatedAt(Date createdAt) { this.createdAt = createdAt; } @@ -65,15 +71,33 @@ public void setLinks(Map links) { this.links = links; } + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getLegId() { + return legId; + } + + public void setLegId(String legId) { + this.legId = legId; + } + @Override public String toString() { return "Transcription{" + "id='" + id + '\'' + ", recordingId='" + recordingId + '\'' + ", error='" + error + '\'' + + ", status='" + status + '\'' + + ", legId='" + legId + '\'' + ", createdAt=" + createdAt + ", updatedAt=" + updatedAt + - ", links='" + links + '\'' + + ", links=" + links + '}'; } } diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/TranscriptionResponse.java b/api/src/main/java/com/messagebird/objects/voicecalls/TranscriptionResponse.java index a760d915..442c44da 100644 --- a/api/src/main/java/com/messagebird/objects/voicecalls/TranscriptionResponse.java +++ b/api/src/main/java/com/messagebird/objects/voicecalls/TranscriptionResponse.java @@ -1,13 +1,28 @@ package com.messagebird.objects.voicecalls; +import com.fasterxml.jackson.annotation.JsonProperty; + import java.io.Serializable; import java.util.List; +import java.util.Map; public class TranscriptionResponse implements Serializable { private static final long serialVersionUID = -25064223639161201L; private List data; + @JsonProperty("_links") + private Map links; + private Pagination pagination; + + public TranscriptionResponse() {} + + public TranscriptionResponse(List data, Map links, Pagination pagination) { + this.data = data; + this.links = links; + this.pagination = pagination; + } + public List getData() { return data; } @@ -16,10 +31,32 @@ public void setData(List data) { this.data = data; } + public static long getSerialVersionUID() { + return serialVersionUID; + } + + public Map getLinks() { + return links; + } + + public void setLinks(Map links) { + this.links = links; + } + + public Pagination getPagination() { + return pagination; + } + + public void setPagination(Pagination pagination) { + this.pagination = pagination; + } + @Override public String toString() { return "TranscriptionResponse{" + "data=" + data + + ", links=" + links + + ", pagination=" + pagination + '}'; } } diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 779a88f7..1b682069 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -622,13 +622,43 @@ public void testDownloadRecording() throws NotFoundException, GeneralException, assertEquals(downloadPath, response); } + @Test + public void testDownloadTranscription() throws NotFoundException, GeneralException, UnauthorizedException { + String transcriptionId = "123123123"; + String basePath = "test"; + String fileName = String.format("%s%s", transcriptionId, TRANSCRIPTION_DOWNLOAD_FORMAT); + final String downloadPath = TestUtil.createDownloadPath(transcriptionId, basePath); + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + + String url = String.format( + "%s%s/%s%s/%s%s/%s%s/%s", + VOICE_CALLS_BASE_URL, + VOICECALLSPATH, + "ANY_CALL_ID", + LEGSPATH, + "ANY_LEG_ID", + RECORDINGPATH, + "ANY_RECORDING_ID", + TRANSCRIPTIONPATH, + fileName + ); + when(messageBirdServiceMock.getBinaryData(url, basePath, fileName)) + .thenReturn(downloadPath); + final String response = messageBirdClientInjectMock + .downloadTranscription("ANY_CALL_ID", "ANY_LEG_ID", "ANY_RECORDING_ID", transcriptionId, basePath); + verify(messageBirdServiceMock, times(1)).getBinaryData(url, basePath, fileName); + assertNotNull(response); + assertEquals(downloadPath, response); + } + @Test(expected = IllegalArgumentException.class) public void shouldThrowIllegalArgumentExceptionWhenLanguageIsNotSupported() throws UnauthorizedException, GeneralException { messageBirdClient.createTranscription("ANY_CALL_ID", "ANY_LEG_ID", "ANY_ID", "tr-TR"); } @Test - public void testViewTranscription() throws UnauthorizedException, GeneralException { + public void testViewTranscriptionDeprecated() throws UnauthorizedException, GeneralException { final TranscriptionResponse transcriptionResponse = TestUtil.createTranscriptionResponse(); MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); @@ -652,10 +682,36 @@ public void testViewTranscription() throws UnauthorizedException, GeneralExcepti verify(messageBirdServiceMock, times(1)) .requestList(Mockito.eq(url), Mockito.isA(PagedPaging.class), Mockito.eq(TranscriptionResponse.class)); assertNotNull(response); - assertEquals(response.getData().get(0).getId(), transcriptionResponse.getData().get(0).getId()); - assertEquals(response.getData().get(0).getRecordingId(), transcriptionResponse.getData().get(0).getRecordingId()); - assertEquals(response.getData().get(0).getCreatedAt(), transcriptionResponse.getData().get(0).getCreatedAt()); + assertReflectionEquals(response.getData().get(0), transcriptionResponse.getData().get(0)); + } + + @Test + public void testViewTranscription() throws UnauthorizedException, GeneralException, NotFoundException { + final TranscriptionResponse transcriptionResponse = TestUtil.createTranscriptionResponse(); + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + + String url = String.format( + "%s%s/%s%s/%s%s/%s%s", + VOICE_CALLS_BASE_URL, + VOICECALLSPATH, + "ANY_CALL_ID", + LEGSPATH, + "ANY_LEG_ID", + RECORDINGPATH, + "ANY_ID", + TRANSCRIPTIONPATH); + + when(messageBirdServiceMock.requestByID(Mockito.eq(url), Mockito.eq("ANY_TRANSCRIPTION_ID"), Mockito.eq(TranscriptionResponse.class))) + .thenReturn(transcriptionResponse); + final TranscriptionResponse response = messageBirdClientInjectMock + .viewTranscription("ANY_CALL_ID", "ANY_LEG_ID", "ANY_ID", "ANY_TRANSCRIPTION_ID"); + verify(messageBirdServiceMock, times(1)) + .requestByID(Mockito.eq(url), Mockito.eq("ANY_TRANSCRIPTION_ID"), Mockito.eq(TranscriptionResponse.class)); + assertNotNull(response); + assertReflectionEquals(response.getData().get(0), transcriptionResponse.getData().get(0)); } @Test diff --git a/examples/src/main/java/ExampleDownloadTranscription.java b/examples/src/main/java/ExampleDownloadTranscription.java new file mode 100644 index 00000000..ec672fbf --- /dev/null +++ b/examples/src/main/java/ExampleDownloadTranscription.java @@ -0,0 +1,43 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; + +public class ExampleDownloadTranscription { + public static void main(String[] args) { + if (args.length < 5) { + System.out.println("Please specify your access key and call id and leg id and recording id and transcription Id and basePath(optional) example :" + + " java -jar test_accesskey e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938" + + " e8077d803532c0b5937c639b60216938 /users/{user}/test"); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + System.out.println("Getting a transcription file"); + final String callId = args[1]; + final String legId = args[2]; + final String recordingId = args[3]; + final String transcriptionId = args[4]; + String basePath = null; + if (args.length > 5) { + basePath = args[5]; + } + //Sending call id and leg id and recording and transcription id parameters to client + final String filePath = messageBirdClient.downloadTranscription(callId, legId, recordingId, transcriptionId, basePath); + if (filePath != null) { + System.out.println("Transcription file is downloaded to "+filePath); + } + + } catch (GeneralException | NotFoundException | UnauthorizedException exception) { + exception.printStackTrace(); + } + } +} diff --git a/examples/src/main/java/ExampleListTranscriptions.java b/examples/src/main/java/ExampleListTranscriptions.java new file mode 100644 index 00000000..9aee955b --- /dev/null +++ b/examples/src/main/java/ExampleListTranscriptions.java @@ -0,0 +1,44 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.voicecalls.Transcription; +import com.messagebird.objects.voicecalls.TranscriptionResponse; + +public class ExampleListTranscriptions { + public static void main(String[] args) { + if (args.length < 6) { + System.out.println("Please specify your access key and call id and leg id and recording id and page and page size example :" + + " java -jar test_accesskey e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938 1 10"); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + System.out.println("Getting transcriptions"); + final String callId = args[1]; + final String legId = args[2]; + final String recordingId = args[3]; + final Integer page = Integer.valueOf(args[4]); + final Integer pageSize = Integer.valueOf(args[5]); + TranscriptionResponse transcriptions = messageBirdClient.listTranscriptions(callId, legId, recordingId, page, pageSize); + if(transcriptions.getData() == null) { + System.out.println("no transcriptions found"); + return; + } + for (Transcription transcription: transcriptions.getData()) { + System.out.println(transcription.toString()); + System.out.println(); + } + + } catch (GeneralException | UnauthorizedException exception) { + exception.printStackTrace(); + } + } +} diff --git a/examples/src/main/java/ExampleViewTranscription.java b/examples/src/main/java/ExampleViewTranscription.java index 778fcd42..e3dfe6db 100644 --- a/examples/src/main/java/ExampleViewTranscription.java +++ b/examples/src/main/java/ExampleViewTranscription.java @@ -2,15 +2,17 @@ import com.messagebird.MessageBirdService; import com.messagebird.MessageBirdServiceImpl; import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; import com.messagebird.objects.voicecalls.TranscriptionResponse; public class ExampleViewTranscription { public static void main(String[] args) { - if (args.length < 6) { - System.out.println("Please specify your access key, call ID, leg ID, recording ID, page, page size :" + - " java -jar test_accesskey e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938"); + if (args.length < 5) { + System.out.println("Please specify your access key, call ID, leg ID, recording ID and transcriptionId :" + + " java -jar test_accesskey e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938" + + " e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938"); return; } @@ -25,14 +27,13 @@ public static void main(String[] args) { final String callId = args[1]; final String legId = args[2]; final String recordingId = args[3]; - final int page = Integer.valueOf(args[4]); - final int pageSize = Integer.valueOf(args[5]); + final String transactionId = args[4]; // Sending call ID, leg ID, recording ID, page, page size parameters to client - final TranscriptionResponse responseList = messageBirdClient.viewTranscription(callId, legId, recordingId, page, pageSize) ; + final TranscriptionResponse responseList = messageBirdClient.viewTranscription(callId, legId, recordingId, transactionId) ; //Display transcription response System.out.println(responseList.toString()); - } catch (GeneralException | UnauthorizedException exceptions) { + } catch (GeneralException | UnauthorizedException | NotFoundException exceptions) { exceptions.printStackTrace(); } diff --git a/examples/src/main/java/ExampleViewTranscriptionDeprecated.java b/examples/src/main/java/ExampleViewTranscriptionDeprecated.java new file mode 100644 index 00000000..40b975be --- /dev/null +++ b/examples/src/main/java/ExampleViewTranscriptionDeprecated.java @@ -0,0 +1,40 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.voicecalls.TranscriptionResponse; + +public class ExampleViewTranscriptionDeprecated { + + public static void main(String[] args) { + if (args.length < 6) { + System.out.println("Please specify your access key, call ID, leg ID, recording ID, page, page size :" + + " java -jar test_accesskey e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938"); + return; + } + + //First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + //Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + System.out.println("Getting transcription list"); + final String callId = args[1]; + final String legId = args[2]; + final String recordingId = args[3]; + final Integer page = Integer.valueOf(args[4]); + final Integer pageSize = Integer.valueOf(args[5]); + // Sending call ID, leg ID, recording ID, page, page size parameters to client + final TranscriptionResponse responseList = messageBirdClient.viewTranscription(callId, legId, recordingId, page, pageSize) ; + //Display transcription response + System.out.println(responseList.toString()); + + } catch (GeneralException | UnauthorizedException exceptions) { + exceptions.printStackTrace(); + } + + } +} \ No newline at end of file From 8c10aaf96f0f1043b038a645dd610c49afec4b03 Mon Sep 17 00:00:00 2001 From: cemturker Date: Thu, 10 Oct 2019 13:23:19 +0200 Subject: [PATCH 050/516] Unit test is fixed. --- api/src/test/java/com/messagebird/MessageBirdClientTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 1b682069..7044bd8b 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -665,14 +665,15 @@ public void testViewTranscriptionDeprecated() throws UnauthorizedException, Gene MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); String url = String.format( - "%s%s/%s%s/%s%s/%s", + "%s%s/%s%s/%s%s/%s%s", VOICE_CALLS_BASE_URL, VOICECALLSPATH, "ANY_CALL_ID", LEGSPATH, "ANY_LEG_ID", RECORDINGPATH, - "ANY_ID"); + "ANY_ID", + TRANSCRIPTIONPATH); when(messageBirdServiceMock.requestList(Mockito.eq(url), Mockito.isA(PagedPaging.class), Mockito.eq(TranscriptionResponse.class))) .thenReturn(transcriptionResponse); From 10af9d33015e403a8968eccbf7ae754cce974808 Mon Sep 17 00:00:00 2001 From: cemturker Date: Thu, 10 Oct 2019 13:30:36 +0200 Subject: [PATCH 051/516] Documentation is added. --- .../com/messagebird/MessageBirdClient.java | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 0d924cf3..c63601be 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1413,7 +1413,7 @@ public TranscriptionResponse viewTranscription(String callID, String legId, Stri * @param legId Leg ID * @param recordingId Recording ID * @param transcriptionId Transcription ID - * @return TranscriptionResponseList + * @return Transcription * @throws UnauthorizedException if client is unauthorized * @throws GeneralException general exception * @throws NotFoundException If transcription is not found @@ -1446,15 +1446,16 @@ public TranscriptionResponse viewTranscription(String callID, String legId, Stri } /** + * Lists the Transcription of callId, legId and recordId * - * @param callID - * @param legId - * @param recordingId - * @param page - * @param pageSize - * @return - * @throws UnauthorizedException - * @throws GeneralException + * @param callID Voice call ID + * @param legId Leg ID + * @param recordingId Recording ID + * @param page page to fetch (can be null - will return first page), number of first page is 1 + * @param pageSize page size + * @return List of Transcription + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception */ public TranscriptionResponse listTranscriptions(String callID, String legId, String recordingId, Integer page, Integer pageSize) throws UnauthorizedException, GeneralException { if (callID == null) { @@ -1483,6 +1484,20 @@ public TranscriptionResponse listTranscriptions(String callID, String legId, Str return messageBirdService.requestList(url, new PagedPaging(page, pageSize), TranscriptionResponse.class); } + /** + * Downloads the transcription in .txt format by using callId, legId, recordId and transcriptionId and stores to basePath. basePath is not mandatory to set. + * If basePath is not set, default download will be the /Download folder in user group. + * + * @param callID Voice call ID + * @param legId Leg ID + * @param recordingId Recording ID + * @param transcriptionId Transcription ID + * @param basePath store location. It should be directory. Property is Optional if $HOME is accessible + * @return the path that file is stored + * @throws NotFoundException if the recording does not found + * @throws GeneralException general exception + * @throws UnauthorizedException if client is unauthorized + */ public String downloadTranscription(String callID, String legId, String recordingId, String transcriptionId, String basePath) throws UnauthorizedException, GeneralException, NotFoundException { if (callID == null) { From a4866ca2025c78549bc311fec488fe5b7378674f Mon Sep 17 00:00:00 2001 From: cemturker Date: Fri, 11 Oct 2019 08:54:01 +0200 Subject: [PATCH 052/516] Deprecated view Transcription is completely removed. --- .../com/messagebird/MessageBirdClient.java | 40 ------------------- .../messagebird/MessageBirdClientTest.java | 29 -------------- .../ExampleViewTranscriptionDeprecated.java | 40 ------------------- 3 files changed, 109 deletions(-) delete mode 100644 examples/src/main/java/ExampleViewTranscriptionDeprecated.java diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index c63601be..1d664c3e 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1366,46 +1366,6 @@ public TranscriptionResponse createTranscription(String callID, String legId, St return messageBirdService.sendPayLoad(url, language, TranscriptionResponse.class); } - /** - * Function to view recording by call id, leg id and recording id - * - * @param callID Voice call ID - * @param legId Leg ID - * @param recordingId Recording ID - * @return TranscriptionResponseList - * @throws UnauthorizedException if client is unauthorized - * @throws GeneralException general exception - * - * @deprecated use {@link #listTranscriptions} instead. - */ - @Deprecated - public TranscriptionResponse viewTranscription(String callID, String legId, String recordingId, Integer page, Integer pageSize) throws UnauthorizedException, GeneralException { - if (callID == null) { - throw new IllegalArgumentException("Voice call ID must be specified."); - } - - if (legId == null) { - throw new IllegalArgumentException("Leg ID must be specified."); - } - - if (recordingId == null) { - throw new IllegalArgumentException("Recording ID must be specified."); - } - - String url = String.format( - "%s%s/%s%s/%s%s/%s%s", - VOICE_CALLS_BASE_URL, - VOICECALLSPATH, - callID, - LEGSPATH, - legId, - RECORDINGPATH, - recordingId, - TRANSCRIPTIONPATH); - - return messageBirdService.requestList(url, new PagedPaging(page, pageSize), TranscriptionResponse.class); - } - /** * Function to view recording by call id, leg id and recording id * diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 7044bd8b..ef8b2af5 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -657,35 +657,6 @@ public void shouldThrowIllegalArgumentExceptionWhenLanguageIsNotSupported() thro messageBirdClient.createTranscription("ANY_CALL_ID", "ANY_LEG_ID", "ANY_ID", "tr-TR"); } - @Test - public void testViewTranscriptionDeprecated() throws UnauthorizedException, GeneralException { - final TranscriptionResponse transcriptionResponse = TestUtil.createTranscriptionResponse(); - - MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); - MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); - - String url = String.format( - "%s%s/%s%s/%s%s/%s%s", - VOICE_CALLS_BASE_URL, - VOICECALLSPATH, - "ANY_CALL_ID", - LEGSPATH, - "ANY_LEG_ID", - RECORDINGPATH, - "ANY_ID", - TRANSCRIPTIONPATH); - - when(messageBirdServiceMock.requestList(Mockito.eq(url), Mockito.isA(PagedPaging.class), Mockito.eq(TranscriptionResponse.class))) - .thenReturn(transcriptionResponse); - - final TranscriptionResponse response = messageBirdClientInjectMock - .viewTranscription("ANY_CALL_ID", "ANY_LEG_ID", "ANY_ID", 1, 2); - verify(messageBirdServiceMock, times(1)) - .requestList(Mockito.eq(url), Mockito.isA(PagedPaging.class), Mockito.eq(TranscriptionResponse.class)); - assertNotNull(response); - assertReflectionEquals(response.getData().get(0), transcriptionResponse.getData().get(0)); - } - @Test public void testViewTranscription() throws UnauthorizedException, GeneralException, NotFoundException { final TranscriptionResponse transcriptionResponse = TestUtil.createTranscriptionResponse(); diff --git a/examples/src/main/java/ExampleViewTranscriptionDeprecated.java b/examples/src/main/java/ExampleViewTranscriptionDeprecated.java deleted file mode 100644 index 40b975be..00000000 --- a/examples/src/main/java/ExampleViewTranscriptionDeprecated.java +++ /dev/null @@ -1,40 +0,0 @@ -import com.messagebird.MessageBirdClient; -import com.messagebird.MessageBirdService; -import com.messagebird.MessageBirdServiceImpl; -import com.messagebird.exceptions.GeneralException; -import com.messagebird.exceptions.UnauthorizedException; -import com.messagebird.objects.voicecalls.TranscriptionResponse; - -public class ExampleViewTranscriptionDeprecated { - - public static void main(String[] args) { - if (args.length < 6) { - System.out.println("Please specify your access key, call ID, leg ID, recording ID, page, page size :" + - " java -jar test_accesskey e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938 e8077d803532c0b5937c639b60216938"); - return; - } - - //First create your service object - final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); - - //Add the service to the client - final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); - - try { - System.out.println("Getting transcription list"); - final String callId = args[1]; - final String legId = args[2]; - final String recordingId = args[3]; - final Integer page = Integer.valueOf(args[4]); - final Integer pageSize = Integer.valueOf(args[5]); - // Sending call ID, leg ID, recording ID, page, page size parameters to client - final TranscriptionResponse responseList = messageBirdClient.viewTranscription(callId, legId, recordingId, page, pageSize) ; - //Display transcription response - System.out.println(responseList.toString()); - - } catch (GeneralException | UnauthorizedException exceptions) { - exceptions.printStackTrace(); - } - - } -} \ No newline at end of file From 958e80535c2c0765388c61c58c3488a8ca2775fc Mon Sep 17 00:00:00 2001 From: cemturker Date: Fri, 11 Oct 2019 13:04:57 +0200 Subject: [PATCH 053/516] Null check is added for transcriptionId --- api/src/main/java/com/messagebird/MessageBirdClient.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 1d664c3e..8d71bae2 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1391,6 +1391,10 @@ public TranscriptionResponse viewTranscription(String callID, String legId, Stri throw new IllegalArgumentException("Recording ID must be specified."); } + if(transcriptionId == null) { + throw new IllegalArgumentException("Transcription ID must be specified."); + } + String url = String.format( "%s%s/%s%s/%s%s/%s%s", VOICE_CALLS_BASE_URL, From 6b120182e47ca9acaa9f31a00463bbe9fd358c5f Mon Sep 17 00:00:00 2001 From: lukbajmb Date: Thu, 17 Oct 2019 18:17:00 +0200 Subject: [PATCH 054/516] Fixed parsing error due to case sensitivity in ObjectMapper --- .../main/java/com/messagebird/MessageBirdServiceImpl.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index a29ae4f5..4478f0a9 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -15,6 +15,7 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.NotFoundException; @@ -209,7 +210,10 @@ public T getJsonData(final String request, final P payload, final String final ObjectMapper mapper = new ObjectMapper(); // If we as new properties, we don't want the system to fail, we rather want to ignore them - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + // Enable case insensitivity to avoid parsing errors if parameters' case in api response doesn't match sdk's + mapper.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES); + mapper.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS); try { return mapper.readValue(body, clazz); From 38c281d2f46ff5d1a9ae793ff07b8440efd8af61 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 21 Oct 2019 15:06:50 +0200 Subject: [PATCH 055/516] updated for new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 823b264f..0b21bf8e 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.2 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 4478f0a9..23867fb1 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -61,7 +61,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.0.2"; + private final String clientVersion = "3.0.3"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 0a520149..b3837c06 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.2 + 3.0.3 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.2 + 3.0.3 compile From e222a9b7ec0ea70c7a51345dfb54e78fbafdafab Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 21 Oct 2019 15:09:33 +0200 Subject: [PATCH 056/516] [maven-release-plugin] prepare release v3.0.3 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 0b21bf8e..1bc1a532 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.3-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.0.3 From 9aa2e02c2ee6483f3746da8afa65cb81685fc970 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 21 Oct 2019 15:09:41 +0200 Subject: [PATCH 057/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 1bc1a532..987d405a 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.3 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.0.3 + HEAD From 26ea5944ea5068173f11e3cc1959b7261b6a1312 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 21 Oct 2019 15:45:26 +0200 Subject: [PATCH 058/516] updated for new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 987d405a..cd21355b 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.4-SNAPSHOT From 4e862e0dfabfb7451c0949d078a15681060fda8b Mon Sep 17 00:00:00 2001 From: lukbajmb Date: Tue, 22 Oct 2019 17:00:20 +0200 Subject: [PATCH 059/516] Adding getter to ConversationWebhookCreateRequest as JSON parser doesn't pick up the channelId parameter otherwise --- .../conversations/ConversationWebhookCreateRequest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationWebhookCreateRequest.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationWebhookCreateRequest.java index 1b7c3864..24cf7f9a 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationWebhookCreateRequest.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationWebhookCreateRequest.java @@ -28,4 +28,8 @@ protected String getRequestName() { protected String getStringRepresentationOfExtraParameters() { return "channelId='" + channelId; } + + public String getChannelId() { + return channelId; + } } From 845872de470ec9cb0b76bf589f25d3f0a8f7f6e8 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Wed, 30 Oct 2019 09:43:34 +0100 Subject: [PATCH 060/516] fixed balance amount field type --- api/src/main/java/com/messagebird/objects/Balance.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/Balance.java b/api/src/main/java/com/messagebird/objects/Balance.java index 993bcb6c..ddf653cb 100644 --- a/api/src/main/java/com/messagebird/objects/Balance.java +++ b/api/src/main/java/com/messagebird/objects/Balance.java @@ -14,7 +14,7 @@ public class Balance implements Serializable{ private String payment; private String type; - private Integer amount; + private float amount; public Balance() { } @@ -48,7 +48,7 @@ public String getType() { * The amount of balance of the payment type. When postpaid is your payment method, the amount will be 0. * @return */ - public Integer getAmount() { + public float getAmount() { return amount; } } From 82075ca7a79fd0917feffed8404bc51ced164428 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Wed, 30 Oct 2019 10:10:45 +0100 Subject: [PATCH 061/516] updates for the new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index cd21355b..987d405a 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.3 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 23867fb1..8eaf64b6 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -61,7 +61,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.0.3"; + private final String clientVersion = "3.0.4"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index b3837c06..7802e3c9 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.3 + 3.0.4 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.3 + 3.0.4 compile From 04c411cc633127c255a76b600cd346a3949474fe Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Wed, 30 Oct 2019 10:13:27 +0100 Subject: [PATCH 062/516] [maven-release-plugin] prepare release v3.0.4 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 987d405a..35c3f5ce 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.4-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.0.4 From 63a0fca4bb963c78a00071cd1e1785b73c5d92bc Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Wed, 30 Oct 2019 10:13:34 +0100 Subject: [PATCH 063/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 35c3f5ce..31d2c669 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.4 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.0.4 + HEAD From 857198d1dcddbc1dd48cbd0c084eafc86c03bb76 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Wed, 30 Oct 2019 10:46:21 +0100 Subject: [PATCH 064/516] updated --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 31d2c669..c740bb6f 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.5-SNAPSHOT From 89749f3d31a741994aed4be3bbecb884797617f4 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Wed, 30 Oct 2019 12:06:57 +0100 Subject: [PATCH 065/516] updated --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index c740bb6f..fd4d7f04 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.5 From 9340d169f8d5d73c839fa83a264e6369c3c1a525 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Wed, 30 Oct 2019 13:29:55 +0100 Subject: [PATCH 066/516] fixing security vulnerability --- api/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index fd4d7f04..3b13418d 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -83,17 +83,17 @@ com.fasterxml.jackson.core jackson-annotations - 2.9.8 + 2.10.0 com.fasterxml.jackson.core jackson-databind - 2.9.8 + 2.10.0 com.fasterxml.jackson.dataformat jackson-dataformat-csv - 2.9.8 + 2.10.0 junit From bbbdee7cb9dfdbe435802289ff0f872dfb24d35d Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Wed, 30 Oct 2019 13:33:39 +0100 Subject: [PATCH 067/516] update junit version --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 3b13418d..78e11f9b 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -98,7 +98,7 @@ junit junit - 4.11 + 4.12 test From 18d76d42ea0deb201f2256f97b1df8fcf0349336 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Wed, 30 Oct 2019 14:30:10 +0100 Subject: [PATCH 068/516] new relase for critical security vulnerability fix --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 78e11f9b..a0f88dd3 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.4 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 8eaf64b6..d799938a 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -61,7 +61,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.0.4"; + private final String clientVersion = "3.0.5"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 7802e3c9..07060216 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.4 + 3.0.5 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.4 + 3.0.5 compile From fb04431f91cb75c074790c7a6db69ad76a320cd5 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Wed, 30 Oct 2019 14:31:21 +0100 Subject: [PATCH 069/516] [maven-release-plugin] prepare release v3.0.5 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index a0f88dd3..5ca57e66 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.5-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.0.5 From fdd037148e5458e91962b12d7eb889a18cc791d8 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Wed, 30 Oct 2019 14:31:29 +0100 Subject: [PATCH 070/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 5ca57e66..e6df852d 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.5 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.0.5 + HEAD From b6fe3554df2efae4c32e26c63bccc2324ca709af Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Wed, 30 Oct 2019 14:40:30 +0100 Subject: [PATCH 071/516] updated pom --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index e6df852d..c9173c23 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.6-SNAPSHOT From 175ae322c06ec1e58257ba432fa75fbe50d7e410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Mattrat?= Date: Thu, 31 Oct 2019 22:29:58 +0100 Subject: [PATCH 072/516] Fixes incorrect type (string->int) leading to a 400 error when trying to create a step with repeat set in the step option of a call flow. --- .../main/java/com/messagebird/objects/VoiceStepOption.java | 6 +++--- api/src/test/java/com/messagebird/TestUtil.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/VoiceStepOption.java b/api/src/main/java/com/messagebird/objects/VoiceStepOption.java index 51e74962..9e8e1292 100644 --- a/api/src/main/java/com/messagebird/objects/VoiceStepOption.java +++ b/api/src/main/java/com/messagebird/objects/VoiceStepOption.java @@ -10,7 +10,7 @@ public class VoiceStepOption implements Serializable { private String payload; private String language; private String voice; - private String repeat; + private int repeat; private String media; private int length; private int maxLength; @@ -57,11 +57,11 @@ public void setVoice(String voice) { this.voice = voice; } - public String getRepeat() { + public int getRepeat() { return repeat; } - public void setRepeat(String repeat) { + public void setRepeat(int repeat) { this.repeat = repeat; } diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index 7e12d349..5a854b45 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -173,7 +173,7 @@ private static VoiceStepOption createVoiceStepOption() voiceStepOption.setPayload("Test payload Update"); voiceStepOption.setLanguage("en-US"); voiceStepOption.setVoice("female"); - voiceStepOption.setRepeat("5"); + voiceStepOption.setRepeat(5); voiceStepOption.setMedia("test.wav"); voiceStepOption.setLength(10); voiceStepOption.setMaxLength(20); From 612f11982b96b7ea6a3da193fdaa8d4898f4ddab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Mattrat?= Date: Thu, 31 Oct 2019 22:35:19 +0100 Subject: [PATCH 073/516] updates fixtures --- api/src/test/resources/fixtures/call_flow_update_response.json | 2 +- api/src/test/resources/fixtures/call_flow_view.json | 2 +- api/src/test/resources/fixtures/call_flows_list.json | 2 +- api/src/test/resources/fixtures/call_flows_post.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/src/test/resources/fixtures/call_flow_update_response.json b/api/src/test/resources/fixtures/call_flow_update_response.json index 7659ccfa..13663211 100644 --- a/api/src/test/resources/fixtures/call_flow_update_response.json +++ b/api/src/test/resources/fixtures/call_flow_update_response.json @@ -12,7 +12,7 @@ "payload" : "Test payload", "language" : "en-GB", "voice" : "male", - "repeat" : "1", + "repeat" : 1, "media" : "test.mp3", "length" : 1, "maxLength" : 2, diff --git a/api/src/test/resources/fixtures/call_flow_view.json b/api/src/test/resources/fixtures/call_flow_view.json index 8feed38d..247d7cb5 100644 --- a/api/src/test/resources/fixtures/call_flow_view.json +++ b/api/src/test/resources/fixtures/call_flow_view.json @@ -12,7 +12,7 @@ "payload" : "Test payload", "language" : "en-GB", "voice" : "male", - "repeat" : "1", + "repeat" : 1, "media" : "test.mp3", "length" : 1, "maxLength" : 2, diff --git a/api/src/test/resources/fixtures/call_flows_list.json b/api/src/test/resources/fixtures/call_flows_list.json index 0cebcef1..81d57a2d 100644 --- a/api/src/test/resources/fixtures/call_flows_list.json +++ b/api/src/test/resources/fixtures/call_flows_list.json @@ -12,7 +12,7 @@ "payload" : "Test payload", "language" : "en-GB", "voice" : "male", - "repeat" : "1", + "repeat" : 1, "media" : "test.mp3", "length" : 1, "maxLength" : 2, diff --git a/api/src/test/resources/fixtures/call_flows_post.json b/api/src/test/resources/fixtures/call_flows_post.json index 7659ccfa..13663211 100644 --- a/api/src/test/resources/fixtures/call_flows_post.json +++ b/api/src/test/resources/fixtures/call_flows_post.json @@ -12,7 +12,7 @@ "payload" : "Test payload", "language" : "en-GB", "voice" : "male", - "repeat" : "1", + "repeat" : 1, "media" : "test.mp3", "length" : 1, "maxLength" : 2, From 658c8a1599f58709bd27fd2cdcd39dbad257a8c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Mattrat?= Date: Thu, 31 Oct 2019 22:44:41 +0100 Subject: [PATCH 074/516] Fixes test for repeat --- api/src/test/java/com/messagebird/VoiceCallFlowTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/test/java/com/messagebird/VoiceCallFlowTest.java b/api/src/test/java/com/messagebird/VoiceCallFlowTest.java index 46832199..9767e223 100644 --- a/api/src/test/java/com/messagebird/VoiceCallFlowTest.java +++ b/api/src/test/java/com/messagebird/VoiceCallFlowTest.java @@ -236,7 +236,7 @@ private void testVoiceCallFlowAgainstFixture(VoiceCallFlow voiceCallFlow) { assertEquals(voiceStepOption.getPayload(), "Test payload"); assertEquals(voiceStepOption.getLanguage(), "en-GB"); assertEquals(voiceStepOption.getVoice(), "male"); - assertEquals(voiceStepOption.getRepeat(), "1"); + assertEquals(voiceStepOption.getRepeat(), 1); assertEquals(voiceStepOption.getMedia(), "test.mp3"); assertEquals(voiceStepOption.getFinishOnKey(), "1"); assertEquals(voiceStepOption.getTranscribeLanguage(), "en-GB"); From 8ce4189b4154c9da1a585b2d92c989f1b9565308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Mattrat?= Date: Thu, 31 Oct 2019 22:59:36 +0100 Subject: [PATCH 075/516] snapshot --- api/pom.xml | 2 +- examples/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index c9173c23..e6df852d 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.5 diff --git a/examples/pom.xml b/examples/pom.xml index 07060216..48cb2fa4 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.5 + 3.0.6 From ca24edd6a617ea749e5fda6ad5cd8bd8d6cca992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Mattrat?= Date: Thu, 31 Oct 2019 23:02:27 +0100 Subject: [PATCH 076/516] [maven-release-plugin] prepare release messagebird-api-3.0.6 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index e6df852d..bbe555b9 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.6-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + messagebird-api-3.0.6 From 4d46c5a1f63d2ba81308b5b7525a40c3613e620f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Mattrat?= Date: Thu, 31 Oct 2019 23:02:38 +0100 Subject: [PATCH 077/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index bbe555b9..f9fed4e5 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.6 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - messagebird-api-3.0.6 + HEAD From db6955832d07f9f4c51f936d51f686a23bffb43c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Mattrat?= Date: Thu, 31 Oct 2019 23:04:49 +0100 Subject: [PATCH 078/516] set to 3.0.6 --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index f9fed4e5..a4a60174 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.7-SNAPSHOT From 00346f3edc9e09823f5c06a5af1c1ff057b285a3 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 1 Nov 2019 10:04:18 +0100 Subject: [PATCH 079/516] fixed wrong version --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index a4a60174..e6df852d 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.6 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index d799938a..a45a2279 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -61,7 +61,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.0.5"; + private final String clientVersion = "3.0.6"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 48cb2fa4..59e90252 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.5 + 3.0.6 compile From 30e5b947dc5d97e3d82fc3c09618afcea53c8b44 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 1 Nov 2019 10:05:20 +0100 Subject: [PATCH 080/516] [maven-release-plugin] prepare release v3.0.6 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index e6df852d..bbbd6f25 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.6-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.0.6 From 084a743cbfd16d3d1b009bbd12ae58e36032cee0 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 1 Nov 2019 10:05:28 +0100 Subject: [PATCH 081/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index bbbd6f25..f9fed4e5 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.6 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.0.6 + HEAD From 075e2fffea61b9521e1e4894176db8982d02352c Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 1 Nov 2019 11:55:12 +0100 Subject: [PATCH 082/516] updated --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index f9fed4e5..a4a60174 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.7-SNAPSHOT From 6b9fdf403b472273248a5174ea6498f1891367f1 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Wed, 8 Jan 2020 10:05:46 +0100 Subject: [PATCH 083/516] add working example / classes --- .../com/messagebird/MessageBirdClient.java | 15 +++++++- .../com/messagebird/objects/PhoneNumber.java | 36 +++++++++++++++++++ .../objects/PhoneNumberFeature.java | 19 ++++++++++ .../objects/PhoneNumbersResponse.java | 21 +++++++++++ .../java/ExampleListPurchaseableNumbers.java | 29 +++++++++++++++ 5 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 api/src/main/java/com/messagebird/objects/PhoneNumber.java create mode 100644 api/src/main/java/com/messagebird/objects/PhoneNumberFeature.java create mode 100644 api/src/main/java/com/messagebird/objects/PhoneNumbersResponse.java create mode 100644 examples/src/main/java/ExampleListPurchaseableNumbers.java diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 8d71bae2..4f26a414 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -19,6 +19,8 @@ import com.messagebird.objects.MessageResponse; import com.messagebird.objects.MsgType; import com.messagebird.objects.PagedPaging; +import com.messagebird.objects.PhoneNumber; +import com.messagebird.objects.PhoneNumberFeature; import com.messagebird.objects.Verify; import com.messagebird.objects.VerifyRequest; import com.messagebird.objects.VoiceMessage; @@ -58,6 +60,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.EnumSet; /** * Message bird general client @@ -1587,4 +1590,14 @@ private void verifyOffsetAndLimit(Integer offset, Integer limit) { throw new IllegalArgumentException("Limit must be > 0"); } } -} \ No newline at end of file + + public void listNumbersForPurchase(String countryCode) throws IllegalArgumentException { + if (countryCode == null) { + throw new IllegalArgumentException("Country Code must be specified."); + } + final EnumSet features = EnumSet.of(PhoneNumberFeature.SMS); + PhoneNumber phoneNumber = new PhoneNumber("31627132365", "NL", "", features, "mobile"); + System.out.println(String.format("Received Country Code: %s", phoneNumber.toString())); + return; + } +} \ No newline at end of file diff --git a/api/src/main/java/com/messagebird/objects/PhoneNumber.java b/api/src/main/java/com/messagebird/objects/PhoneNumber.java new file mode 100644 index 00000000..f6c4e51c --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/PhoneNumber.java @@ -0,0 +1,36 @@ +package com.messagebird.objects; + +import com.messagebird.objects.PhoneNumberFeature; + +import java.io.Serializable; +import java.util.EnumSet; + +// TODO: Debug or change EnumSet to Array of Strings? +public class PhoneNumber { + private String number; + private String country; + private String region; + private String locality; + private EnumSet features; + private String type; + + public PhoneNumber(String number, String country, String region, EnumSet features, String type) { + this.number = number; + this.country = country; + this.region = region; + this.features = features; + this.type = type; + } + + @Override + public String toString() { + return "PhoneNumber{" + + "number='" + number + "\'" + + ", country='" + country + "\'" + + ", region='" + region + "\'" + + ", locality='" + locality + "\'" + + ", features=" + features + + ", type='" + type + "\'" + + "}"; + } +} diff --git a/api/src/main/java/com/messagebird/objects/PhoneNumberFeature.java b/api/src/main/java/com/messagebird/objects/PhoneNumberFeature.java new file mode 100644 index 00000000..790177c9 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/PhoneNumberFeature.java @@ -0,0 +1,19 @@ +package com.messagebird.objects; + +public enum PhoneNumberFeature { + + SMS("sms"), + MMS("mms"), + VOICE("voice"); + + private String type; + + PhoneNumberFeature(String type) { + this.type = type; + } + + @Override + public String toString() { + return this.type; + } +} \ No newline at end of file diff --git a/api/src/main/java/com/messagebird/objects/PhoneNumbersResponse.java b/api/src/main/java/com/messagebird/objects/PhoneNumbersResponse.java new file mode 100644 index 00000000..e0f91036 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/PhoneNumbersResponse.java @@ -0,0 +1,21 @@ +package com.messagebird.objects; + +import com.messagebird.objects.PhoneNumber; + +import java.io.Serializable; +import java.util.List; + +class PhoneNumbersResponse implements Serializable { + private Number limit; + private Number offset; + private List items; + + @Override + public String toString() { + return "PhoneNumbersResponse{" + + "limit=" + limit + + ", offset=" + offset + + ", items=" + items + + "}"; + } +} \ No newline at end of file diff --git a/examples/src/main/java/ExampleListPurchaseableNumbers.java b/examples/src/main/java/ExampleListPurchaseableNumbers.java new file mode 100644 index 00000000..b5174db0 --- /dev/null +++ b/examples/src/main/java/ExampleListPurchaseableNumbers.java @@ -0,0 +1,29 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; + +public class ExampleListPurchaseableNumbers { + public static void main(String[] args) { + if (args.length < 1) { + System.out.println("Please specify your access key."); + return; + } + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + messageBirdClient.listNumbersForPurchase(args[1]); + return; + // try { + // } catch (UnauthorizedException | GeneralException exception) { + // if (exception.getErrors() != null) { + // System.out.println(exception.getErrors().toString()); + // } + // exception.printStackTrace(); + // } + } +} \ No newline at end of file From eeac7dc95335b925849a7c475d4c86f5342e3ec6 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Wed, 8 Jan 2020 10:10:02 +0100 Subject: [PATCH 084/516] use array, not list --- .../main/java/com/messagebird/objects/PhoneNumbersResponse.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/objects/PhoneNumbersResponse.java b/api/src/main/java/com/messagebird/objects/PhoneNumbersResponse.java index e0f91036..32373301 100644 --- a/api/src/main/java/com/messagebird/objects/PhoneNumbersResponse.java +++ b/api/src/main/java/com/messagebird/objects/PhoneNumbersResponse.java @@ -8,7 +8,7 @@ class PhoneNumbersResponse implements Serializable { private Number limit; private Number offset; - private List items; + private PhoneNumber[] items; @Override public String toString() { From bd0946ceeb1e62723fefb136af451cd3c275880b Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Wed, 8 Jan 2020 11:04:38 +0100 Subject: [PATCH 085/516] refactor to accept user input --- .../main/java/com/messagebird/MessageBirdClient.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 4f26a414..54afc69c 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -21,6 +21,7 @@ import com.messagebird.objects.PagedPaging; import com.messagebird.objects.PhoneNumber; import com.messagebird.objects.PhoneNumberFeature; +import com.messagebird.objects.PhoneNumbersResponse; import com.messagebird.objects.Verify; import com.messagebird.objects.VerifyRequest; import com.messagebird.objects.VoiceMessage; @@ -90,6 +91,7 @@ public class MessageBirdClient { private static final String BASE_URL_CONVERSATIONS_WHATSAPP_SANDBOX = "https://whatsapp-sandbox.messagebird.com/v1"; static final String VOICE_CALLS_BASE_URL = "https://voice.messagebird.com"; + static final String NUMBERS_CALLS_BASE_URL = "https://numbers.messagebird.com"; private static String[] supportedLanguages = {"de-DE", "en-AU", "en-UK", "en-US", "es-ES", "es-LA", "fr-FR", "it-IT", "nl-NL", "pt-BR"}; private static final String BALANCEPATH = "/balance"; @@ -1591,13 +1593,12 @@ private void verifyOffsetAndLimit(Integer offset, Integer limit) { } } - public void listNumbersForPurchase(String countryCode) throws IllegalArgumentException { + public PhoneNumbersResponse listNumbersForPurchase(String countryCode) throws IllegalArgumentException, GeneralException, UnauthorizedException, NotFoundException { if (countryCode == null) { throw new IllegalArgumentException("Country Code must be specified."); } - final EnumSet features = EnumSet.of(PhoneNumberFeature.SMS); - PhoneNumber phoneNumber = new PhoneNumber("31627132365", "NL", "", features, "mobile"); - System.out.println(String.format("Received Country Code: %s", phoneNumber.toString())); - return; + final String url = String.format("%s/v1/available-phone-numbers", NUMBERS_CALLS_BASE_URL); + return messageBirdService.requestByID(url, countryCode, PhoneNumbersResponse.class); } + } \ No newline at end of file From fca204e55af0bd781896e75d3766fd38e137d4a0 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Wed, 8 Jan 2020 11:05:02 +0100 Subject: [PATCH 086/516] add getters --- .../com/messagebird/objects/PhoneNumber.java | 30 ++++++++++++++----- .../objects/PhoneNumbersResponse.java | 23 ++++++++++++-- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/PhoneNumber.java b/api/src/main/java/com/messagebird/objects/PhoneNumber.java index f6c4e51c..5fdda19f 100644 --- a/api/src/main/java/com/messagebird/objects/PhoneNumber.java +++ b/api/src/main/java/com/messagebird/objects/PhoneNumber.java @@ -2,10 +2,8 @@ import com.messagebird.objects.PhoneNumberFeature; -import java.io.Serializable; import java.util.EnumSet; -// TODO: Debug or change EnumSet to Array of Strings? public class PhoneNumber { private String number; private String country; @@ -14,12 +12,28 @@ public class PhoneNumber { private EnumSet features; private String type; - public PhoneNumber(String number, String country, String region, EnumSet features, String type) { - this.number = number; - this.country = country; - this.region = region; - this.features = features; - this.type = type; + public String getNumber() { + return this.number; + } + + public String getCountry() { + return this.country; + } + + public String getRegion() { + return this.region; + } + + public String getLocality() { + return this.locality; + } + + public EnumSet getFeatures() { + return this.features; + } + + public String getType() { + return this.type; } @Override diff --git a/api/src/main/java/com/messagebird/objects/PhoneNumbersResponse.java b/api/src/main/java/com/messagebird/objects/PhoneNumbersResponse.java index 32373301..68e9ef4d 100644 --- a/api/src/main/java/com/messagebird/objects/PhoneNumbersResponse.java +++ b/api/src/main/java/com/messagebird/objects/PhoneNumbersResponse.java @@ -2,14 +2,31 @@ import com.messagebird.objects.PhoneNumber; -import java.io.Serializable; import java.util.List; -class PhoneNumbersResponse implements Serializable { +import java.io.Serializable; + +public class PhoneNumbersResponse implements Serializable { + /** + * + */ + private static final long serialVersionUID = 6177098534499444839L; private Number limit; private Number offset; - private PhoneNumber[] items; + private List items; + + public Number getLimit() { + return this.limit; + } + + public Number getOffset() { + return this.offset; + } + public List getItems() { + return this.items; + } + @Override public String toString() { return "PhoneNumbersResponse{" + From 803a2813b0b0f98430b96364b012c1dc494e947c Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Wed, 8 Jan 2020 11:05:30 +0100 Subject: [PATCH 087/516] improve example --- .../java/ExampleListPurchaseableNumbers.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/examples/src/main/java/ExampleListPurchaseableNumbers.java b/examples/src/main/java/ExampleListPurchaseableNumbers.java index b5174db0..a6b871c7 100644 --- a/examples/src/main/java/ExampleListPurchaseableNumbers.java +++ b/examples/src/main/java/ExampleListPurchaseableNumbers.java @@ -2,6 +2,7 @@ import com.messagebird.MessageBirdService; import com.messagebird.MessageBirdServiceImpl; import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; public class ExampleListPurchaseableNumbers { @@ -11,19 +12,19 @@ public static void main(String[] args) { return; } // First create your service object - final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0], "https://numbers.messagebird.com"); // Add the service to the client final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); - messageBirdClient.listNumbersForPurchase(args[1]); - return; - // try { - // } catch (UnauthorizedException | GeneralException exception) { - // if (exception.getErrors() != null) { - // System.out.println(exception.getErrors().toString()); - // } - // exception.printStackTrace(); - // } + try { + System.out.println(messageBirdClient.listNumbersForPurchase(args[1])); + return; + } catch (UnauthorizedException | GeneralException | NotFoundException exception) { + if (exception.getErrors() != null) { + System.out.println(exception.getErrors().toString()); + } + exception.printStackTrace(); + } } } \ No newline at end of file From 85b9248a18ba3d48bb816567091a00ed6e1a3e10 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Wed, 8 Jan 2020 11:08:20 +0100 Subject: [PATCH 088/516] add method with params --- api/src/main/java/com/messagebird/MessageBirdClient.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 54afc69c..d83957b4 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1601,4 +1601,12 @@ public PhoneNumbersResponse listNumbersForPurchase(String countryCode) throws Il return messageBirdService.requestByID(url, countryCode, PhoneNumbersResponse.class); } + public PhoneNumbersResponse listNumbersForPurchase(String countryCode, LinkedHashMap params) throws IllegalArgumentException, GeneralException, UnauthorizedException, NotFoundException { + if (countryCode == null) { + throw new IllegalArgumentException("Country Code must be specified."); + } + final String url = String.format("%s/v1/available-phone-numbers", NUMBERS_CALLS_BASE_URL); + return messageBirdService.requestByID(url, countryCode, params, PhoneNumbersResponse.class); + } + } \ No newline at end of file From 62b2a7e4f1dac9dac1ef898bfdadb281166e7cdd Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Wed, 8 Jan 2020 11:08:45 +0100 Subject: [PATCH 089/516] rename example --- ...chaseableNumbers.java => ExampleListNumbersForPurchase.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename examples/src/main/java/{ExampleListPurchaseableNumbers.java => ExampleListNumbersForPurchase.java} (96%) diff --git a/examples/src/main/java/ExampleListPurchaseableNumbers.java b/examples/src/main/java/ExampleListNumbersForPurchase.java similarity index 96% rename from examples/src/main/java/ExampleListPurchaseableNumbers.java rename to examples/src/main/java/ExampleListNumbersForPurchase.java index a6b871c7..1e8ce8b9 100644 --- a/examples/src/main/java/ExampleListPurchaseableNumbers.java +++ b/examples/src/main/java/ExampleListNumbersForPurchase.java @@ -5,7 +5,7 @@ import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; -public class ExampleListPurchaseableNumbers { +public class ExampleListNumbersForPurchase { public static void main(String[] args) { if (args.length < 1) { System.out.println("Please specify your access key."); From c0296141f6bf902891b160bf8c9cda1716ecb523 Mon Sep 17 00:00:00 2001 From: Bernhard Breytenbach Date: Wed, 8 Jan 2020 15:22:32 +0100 Subject: [PATCH 090/516] Allow purchasing of new numbers through the numbers API --- .../com/messagebird/MessageBirdClient.java | 11 +++++ .../objects/PurchasedPhoneNumber.java | 43 +++++++++++++++++++ .../java/ExampleListNumbersForPurchase.java | 3 ++ .../src/main/java/ExamplePurchaseNumber.java | 35 +++++++++++++++ 4 files changed, 92 insertions(+) create mode 100644 api/src/main/java/com/messagebird/objects/PurchasedPhoneNumber.java create mode 100644 examples/src/main/java/ExamplePurchaseNumber.java diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index d83957b4..d8fe640e 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -22,6 +22,7 @@ import com.messagebird.objects.PhoneNumber; import com.messagebird.objects.PhoneNumberFeature; import com.messagebird.objects.PhoneNumbersResponse; +import com.messagebird.objects.PurchasedPhoneNumber; import com.messagebird.objects.Verify; import com.messagebird.objects.VerifyRequest; import com.messagebird.objects.VoiceMessage; @@ -1609,4 +1610,14 @@ public PhoneNumbersResponse listNumbersForPurchase(String countryCode, LinkedHas return messageBirdService.requestByID(url, countryCode, params, PhoneNumbersResponse.class); } + public PurchasedPhoneNumber purchaseNumber(String number, String countryCode, int billingIntervalMonths) throws UnauthorizedException, GeneralException { + final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); + + final Map payload = new LinkedHashMap(); + payload.put("number", number); + payload.put("countryCode", countryCode); + payload.put("billingIntervalMonths", billingIntervalMonths); + + return messageBirdService.sendPayLoad(url, payload, PurchasedPhoneNumber.class); + } } \ No newline at end of file diff --git a/api/src/main/java/com/messagebird/objects/PurchasedPhoneNumber.java b/api/src/main/java/com/messagebird/objects/PurchasedPhoneNumber.java new file mode 100644 index 00000000..6be79ece --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/PurchasedPhoneNumber.java @@ -0,0 +1,43 @@ +package com.messagebird.objects; + +import java.util.Date; +import java.util.List; + +public class PurchasedPhoneNumber extends PhoneNumber { + private List tags; + private String status; + private Date createdAt; + private Date renewalAt; + + public List getTags() { + return tags; + } + + public String getStatus() { + return status; + } + + public Date getCreatedAt() { + return createdAt; + } + + public Date getRenewalAt() { + return renewalAt; + } + + @Override + public String toString() { + return "PhoneNumber{" + + "number='" + this.getNumber() + "\'" + + ", country='" + this.getCountry() + "\'" + + ", region='" + this.getRegion() + "\'" + + ", locality='" + this.getLocality() + "\'" + + ", features=" + this.getFeatures() + + ", type='" + this.getType() + "\'" + + ", tags='" + tags + "\'" + + ", status='" + status + "\'" + + ", createdAt='" + createdAt + "\'" + + ", renewalAt='" + renewalAt + "\'" + + "}"; + } +} diff --git a/examples/src/main/java/ExampleListNumbersForPurchase.java b/examples/src/main/java/ExampleListNumbersForPurchase.java index 1e8ce8b9..24ad7f5c 100644 --- a/examples/src/main/java/ExampleListNumbersForPurchase.java +++ b/examples/src/main/java/ExampleListNumbersForPurchase.java @@ -5,6 +5,9 @@ import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; +import java.util.LinkedHashMap; +import java.util.Map; + public class ExampleListNumbersForPurchase { public static void main(String[] args) { if (args.length < 1) { diff --git a/examples/src/main/java/ExamplePurchaseNumber.java b/examples/src/main/java/ExamplePurchaseNumber.java new file mode 100644 index 00000000..4d7bb17a --- /dev/null +++ b/examples/src/main/java/ExamplePurchaseNumber.java @@ -0,0 +1,35 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.PurchasedPhoneNumber; + +import java.util.LinkedHashMap; + +public class ExamplePurchaseNumber { + public static void main(String[] args) { + if (args.length < 4) { + System.out.println("Please specify your access key, number, country code and billing interval months, eg: ExamplePurchaseNumber test_accesskey 3197010240563 NL 1"); + return; + } + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0], "https://numbers.messagebird.com"); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + PurchasedPhoneNumber purchasedPhoneNumber = messageBirdClient.purchaseNumber(args[1], args[2], Integer.parseInt(args[3])); + + System.out.println(purchasedPhoneNumber); + return; + } catch (UnauthorizedException | GeneralException exception) { + if (exception.getErrors() != null) { + System.out.println(exception.getErrors().toString()); + } + exception.printStackTrace(); + } + } +} \ No newline at end of file From 4fdd2172af0a805c2fd339f3bf27757701e11dde Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Wed, 8 Jan 2020 17:08:27 +0100 Subject: [PATCH 091/516] extend method to allow support for iterable values --- .../messagebird/MessageBirdServiceImpl.java | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index a45a2279..c680c919 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -200,7 +200,6 @@ public T getJsonData(final String request, final P payload, final String if (!isURLAbsolute(url)) { url = serviceUrl + url; } - final APIResponse apiResponse = doRequest(requestType, url, payload); final String body = apiResponse.getBody(); @@ -618,6 +617,17 @@ private void saveClose(final InputStream is) { } } + /** + * Encodes a key/value pair with percent encoding. + * + * @param String key + * @param Object value + * @return String + */ + private String encodeKeyValuePair(String key, Object value) throws UnsupportedEncodingException { + return URLEncoder.encode(key, String.valueOf(StandardCharsets.UTF_8)) + "=" + URLEncoder.encode(String.valueOf(value), String.valueOf(StandardCharsets.UTF_8)); + } + /** * Build a path variable for GET requests * @@ -631,7 +641,30 @@ private String getPathVariables(final Map map) { bpath.append("&"); } try { - bpath.append(URLEncoder.encode(param.getKey(), String.valueOf(StandardCharsets.UTF_8))).append("=").append(URLEncoder.encode(String.valueOf(param.getValue()), String.valueOf(StandardCharsets.UTF_8))); + // Check to see if the value is a Collection + if (param.getValue() instanceof Collection) { + // If it is, cast the value as a Collection explicitly + // so it can be iterated over. Its values should be + // appended to the querystring parameters using the + // original key provided (e.g., ?features=sms&features=mms) + Collection col = (Collection) param.getValue(); + Iterator iterator = col.iterator(); + int count = 0; + // While there are still remaining iterables + while (iterator.hasNext()) { + // Append & if not the first iterable + if (count > 0) { + bpath.append("&"); + } + // Append the encoded querystring key/value pair. + // the value is returned from the next() call + bpath.append(encodeKeyValuePair(param.getKey(), iterator.next())); + count++; + } + } else { + // If the value is not a collection, create the querystring value directly. + bpath.append(encodeKeyValuePair(param.getKey(), param.getValue())); + } } catch (UnsupportedEncodingException exception) { // Do nothing } From 50b3644eb533fc722eb34d421a0c5b83fcdf50d5 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Wed, 8 Jan 2020 17:10:55 +0100 Subject: [PATCH 092/516] format request --- api/src/main/java/com/messagebird/MessageBirdClient.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index d83957b4..d4a4eb13 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -19,8 +19,7 @@ import com.messagebird.objects.MessageResponse; import com.messagebird.objects.MsgType; import com.messagebird.objects.PagedPaging; -import com.messagebird.objects.PhoneNumber; -import com.messagebird.objects.PhoneNumberFeature; +import com.messagebird.objects.PhoneNumbersLookup; import com.messagebird.objects.PhoneNumbersResponse; import com.messagebird.objects.Verify; import com.messagebird.objects.VerifyRequest; @@ -61,7 +60,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.EnumSet; /** * Message bird general client @@ -1601,12 +1599,12 @@ public PhoneNumbersResponse listNumbersForPurchase(String countryCode) throws Il return messageBirdService.requestByID(url, countryCode, PhoneNumbersResponse.class); } - public PhoneNumbersResponse listNumbersForPurchase(String countryCode, LinkedHashMap params) throws IllegalArgumentException, GeneralException, UnauthorizedException, NotFoundException { + public PhoneNumbersResponse listNumbersForPurchase(String countryCode, PhoneNumbersLookup params) throws IllegalArgumentException, IllegalAccessException, GeneralException, UnauthorizedException, NotFoundException { if (countryCode == null) { throw new IllegalArgumentException("Country Code must be specified."); } final String url = String.format("%s/v1/available-phone-numbers", NUMBERS_CALLS_BASE_URL); - return messageBirdService.requestByID(url, countryCode, params, PhoneNumbersResponse.class); + return messageBirdService.requestByID(url, countryCode, params.toHashMap(), PhoneNumbersResponse.class); } } \ No newline at end of file From ba0b275776e74a952831b970498b57116451f9dd Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Wed, 8 Jan 2020 17:11:14 +0100 Subject: [PATCH 093/516] remove needless null checking --- api/src/main/java/com/messagebird/MessageBirdClient.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index d4a4eb13..c0e44095 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1592,17 +1592,11 @@ private void verifyOffsetAndLimit(Integer offset, Integer limit) { } public PhoneNumbersResponse listNumbersForPurchase(String countryCode) throws IllegalArgumentException, GeneralException, UnauthorizedException, NotFoundException { - if (countryCode == null) { - throw new IllegalArgumentException("Country Code must be specified."); - } final String url = String.format("%s/v1/available-phone-numbers", NUMBERS_CALLS_BASE_URL); return messageBirdService.requestByID(url, countryCode, PhoneNumbersResponse.class); } public PhoneNumbersResponse listNumbersForPurchase(String countryCode, PhoneNumbersLookup params) throws IllegalArgumentException, IllegalAccessException, GeneralException, UnauthorizedException, NotFoundException { - if (countryCode == null) { - throw new IllegalArgumentException("Country Code must be specified."); - } final String url = String.format("%s/v1/available-phone-numbers", NUMBERS_CALLS_BASE_URL); return messageBirdService.requestByID(url, countryCode, params.toHashMap(), PhoneNumbersResponse.class); } From f08c8011d287d79cc746229cf13916654c566b60 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Wed, 8 Jan 2020 17:11:41 +0100 Subject: [PATCH 094/516] add class to make advanced requests --- .../objects/PhoneNumbersLookup.java | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 api/src/main/java/com/messagebird/objects/PhoneNumbersLookup.java diff --git a/api/src/main/java/com/messagebird/objects/PhoneNumbersLookup.java b/api/src/main/java/com/messagebird/objects/PhoneNumbersLookup.java new file mode 100644 index 00000000..af008d2f --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/PhoneNumbersLookup.java @@ -0,0 +1,81 @@ +package com.messagebird.objects; + +import com.messagebird.objects.PhoneNumberFeature; +import com.messagebird.objects.PhoneNumberType; +import com.messagebird.objects.PhoneNumberSearchPattern;; + +import java.util.EnumSet; +import java.util.HashMap; +import java.lang.reflect.Field; + +public class PhoneNumbersLookup { + + private Number number; + private Number limit; + private EnumSet features; + private PhoneNumberType type; + private PhoneNumberSearchPattern searchPattern; + + public Number getNumber() { + return this.number; + } + + public EnumSet getFeatures() { + return this.features; + } + + public PhoneNumberType getType() { + return this.type; + } + + public Number getLimit() { + return this.limit; + } + + public PhoneNumberSearchPattern getSearchPattern() { + return this.searchPattern; + } + + public void setNumber(Number number) { + this.number = number; + } + + public void setFeatures(EnumSet features) { + this.features = features; + } + + public void setType(PhoneNumberType type) { + this.type = type; + } + + public void setLimit(Number limit) { + this.limit = limit; + } + + public void setSearchPattern(PhoneNumberSearchPattern searchPattern) { + this.searchPattern = searchPattern; + } + + public HashMap toHashMap() throws IllegalAccessException { + final HashMap map = new HashMap(); + for (Field f: getClass().getDeclaredFields()) { + Object value = f.get(this); + String key = f.getName(); + if (value != null) { + map.put(key, value); + } + } + return map; + } + + @Override + public String toString() { + return "PhoneNumbersLookup{" + + " number='" + number + "'" + + ", features='" + features + "'" + + ", type='" + type + "'" + + ", limit='" + limit + "'" + + ", searchPattern='" + searchPattern + "'" + + "}"; + } +} \ No newline at end of file From 952b36d6c5ca3a115508e7891024d1c6806e560d Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Wed, 8 Jan 2020 17:12:11 +0100 Subject: [PATCH 095/516] add phone number option enums --- .../objects/PhoneNumberSearchPattern.java | 18 ++++++++++++++++++ .../messagebird/objects/PhoneNumberType.java | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 api/src/main/java/com/messagebird/objects/PhoneNumberSearchPattern.java create mode 100644 api/src/main/java/com/messagebird/objects/PhoneNumberType.java diff --git a/api/src/main/java/com/messagebird/objects/PhoneNumberSearchPattern.java b/api/src/main/java/com/messagebird/objects/PhoneNumberSearchPattern.java new file mode 100644 index 00000000..cf0b3099 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/PhoneNumberSearchPattern.java @@ -0,0 +1,18 @@ +package com.messagebird.objects; + +public enum PhoneNumberSearchPattern { + START("start"), + ANYWHERE("anywhere"), + END("end"); + + private String type; + + PhoneNumberSearchPattern(String type) { + this.type = type; + } + + @Override + public String toString() { + return this.type; + } +} \ No newline at end of file diff --git a/api/src/main/java/com/messagebird/objects/PhoneNumberType.java b/api/src/main/java/com/messagebird/objects/PhoneNumberType.java new file mode 100644 index 00000000..82908203 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/PhoneNumberType.java @@ -0,0 +1,18 @@ +package com.messagebird.objects; + +public enum PhoneNumberType { + LANDLINE("landline"), + MOBILE("mobile"), + PREMIUM_RATE("premium_rate"); + + private String type; + + PhoneNumberType(String type) { + this.type = type; + } + + @Override + public String toString() { + return this.type; + } +} \ No newline at end of file From bd3e304718a75df9bc5d4327e71e6d9d4d20b582 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Wed, 8 Jan 2020 17:13:23 +0100 Subject: [PATCH 096/516] clean up example --- .../java/ExampleListNumbersForPurchase.java | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/examples/src/main/java/ExampleListNumbersForPurchase.java b/examples/src/main/java/ExampleListNumbersForPurchase.java index 1e8ce8b9..a1122012 100644 --- a/examples/src/main/java/ExampleListNumbersForPurchase.java +++ b/examples/src/main/java/ExampleListNumbersForPurchase.java @@ -4,6 +4,12 @@ import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.PhoneNumberFeature; +import com.messagebird.objects.PhoneNumberType; +import com.messagebird.objects.PhoneNumberSearchPattern; +import com.messagebird.objects.PhoneNumbersLookup; + +import java.util.EnumSet;; public class ExampleListNumbersForPurchase { public static void main(String[] args) { @@ -12,17 +18,31 @@ public static void main(String[] args) { return; } // First create your service object - final MessageBirdService wsr = new MessageBirdServiceImpl(args[0], "https://numbers.messagebird.com"); + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); // Add the service to the client final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); try { - System.out.println(messageBirdClient.listNumbersForPurchase(args[1])); - return; + if (args[1].equalsIgnoreCase("--params")) { + PhoneNumbersLookup options = new PhoneNumbersLookup(); + options.setFeatures(EnumSet.of(PhoneNumberFeature.VOICE, PhoneNumberFeature.SMS)); + options.setType(PhoneNumberType.MOBILE); + options.setLimit(10); + options.setNumber(562); + options.setSearchPattern(PhoneNumberSearchPattern.START); + System.out.print(options.toString()); + try { + System.out.println(String.format("Request Made With Params: %s", messageBirdClient.listNumbersForPurchase("US", options))); + } catch (IllegalAccessException exception) { + System.out.println(exception.toString()); + } + } else { + System.out.println(String.format("Request Made Without Params: %s", messageBirdClient.listNumbersForPurchase("NL"))); + } } catch (UnauthorizedException | GeneralException | NotFoundException exception) { if (exception.getErrors() != null) { - System.out.println(exception.getErrors().toString()); + System.out.println(exception.getErrors().toString()); } exception.printStackTrace(); } From ff46cce45a86795c964817bb17ad4e0f57ecd583 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Wed, 8 Jan 2020 17:32:06 +0100 Subject: [PATCH 097/516] change to general exception --- .../java/com/messagebird/MessageBirdClient.java | 2 +- .../messagebird/objects/PhoneNumbersLookup.java | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index c0e44095..7193a2b0 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1596,7 +1596,7 @@ public PhoneNumbersResponse listNumbersForPurchase(String countryCode) throws Il return messageBirdService.requestByID(url, countryCode, PhoneNumbersResponse.class); } - public PhoneNumbersResponse listNumbersForPurchase(String countryCode, PhoneNumbersLookup params) throws IllegalArgumentException, IllegalAccessException, GeneralException, UnauthorizedException, NotFoundException { + public PhoneNumbersResponse listNumbersForPurchase(String countryCode, PhoneNumbersLookup params) throws IllegalArgumentException, GeneralException, UnauthorizedException, NotFoundException { final String url = String.format("%s/v1/available-phone-numbers", NUMBERS_CALLS_BASE_URL); return messageBirdService.requestByID(url, countryCode, params.toHashMap(), PhoneNumbersResponse.class); } diff --git a/api/src/main/java/com/messagebird/objects/PhoneNumbersLookup.java b/api/src/main/java/com/messagebird/objects/PhoneNumbersLookup.java index af008d2f..48c0ae19 100644 --- a/api/src/main/java/com/messagebird/objects/PhoneNumbersLookup.java +++ b/api/src/main/java/com/messagebird/objects/PhoneNumbersLookup.java @@ -1,5 +1,6 @@ package com.messagebird.objects; +import com.messagebird.exceptions.GeneralException; import com.messagebird.objects.PhoneNumberFeature; import com.messagebird.objects.PhoneNumberType; import com.messagebird.objects.PhoneNumberSearchPattern;; @@ -56,13 +57,17 @@ public void setSearchPattern(PhoneNumberSearchPattern searchPattern) { this.searchPattern = searchPattern; } - public HashMap toHashMap() throws IllegalAccessException { + public HashMap toHashMap() throws GeneralException { final HashMap map = new HashMap(); for (Field f: getClass().getDeclaredFields()) { - Object value = f.get(this); - String key = f.getName(); - if (value != null) { - map.put(key, value); + try { + Object value = f.get(this); + String key = f.getName(); + if (value != null) { + map.put(key, value); + } + } catch (IllegalAccessException exception) { + throw new GeneralException("Error Converting PhoneNumbersLookup Class to HashMap."); } } return map; From df08d40cc1bb7d69038ad1b7e9a0ba461a3fd1e3 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Wed, 8 Jan 2020 17:34:54 +0100 Subject: [PATCH 098/516] remove try/catch --- examples/src/main/java/ExampleListNumbersForPurchase.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/examples/src/main/java/ExampleListNumbersForPurchase.java b/examples/src/main/java/ExampleListNumbersForPurchase.java index a1122012..6d417f2e 100644 --- a/examples/src/main/java/ExampleListNumbersForPurchase.java +++ b/examples/src/main/java/ExampleListNumbersForPurchase.java @@ -32,11 +32,7 @@ public static void main(String[] args) { options.setNumber(562); options.setSearchPattern(PhoneNumberSearchPattern.START); System.out.print(options.toString()); - try { - System.out.println(String.format("Request Made With Params: %s", messageBirdClient.listNumbersForPurchase("US", options))); - } catch (IllegalAccessException exception) { - System.out.println(exception.toString()); - } + System.out.println(String.format("Request Made With Params: %s", messageBirdClient.listNumbersForPurchase("US", options))); } else { System.out.println(String.format("Request Made Without Params: %s", messageBirdClient.listNumbersForPurchase("NL"))); } From 180cd39dc8ddd1ed337fd8cecad8545905ae77b6 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Thu, 9 Jan 2020 10:44:27 +0100 Subject: [PATCH 099/516] add updateNumber method --- .../main/java/com/messagebird/MessageBirdClient.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 1e64580e..0a4780e6 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -19,6 +19,7 @@ import com.messagebird.objects.MessageResponse; import com.messagebird.objects.MsgType; import com.messagebird.objects.PagedPaging; +import com.messagebird.objects.PhoneNumber; import com.messagebird.objects.PhoneNumbersLookup; import com.messagebird.objects.PhoneNumbersResponse; import com.messagebird.objects.PurchasedPhoneNumber; @@ -57,6 +58,7 @@ import java.nio.charset.StandardCharsets; import java.net.URLEncoder; import java.util.Arrays; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; @@ -1612,4 +1614,12 @@ public PurchasedPhoneNumber purchaseNumber(String number, String countryCode, in return messageBirdService.sendPayLoad(url, payload, PurchasedPhoneNumber.class); } + + public PhoneNumber updateNumber(String number, String... tags) throws UnauthorizedException, GeneralException { + final String url = String.format("%s/v1/phone-numbers/%s", NUMBERS_CALLS_BASE_URL, number); + final Map> payload = new HashMap>(); + payload.put("tags", Arrays.asList(tags)); + System.out.println(String.format("Payload: %s", payload.toString())); + return messageBirdService.sendPayLoad("PATCH", url, payload, PhoneNumber.class); + } } \ No newline at end of file From be43389c236e50b7ac44a97ae99f1d75ac1b91c1 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Thu, 9 Jan 2020 10:45:18 +0100 Subject: [PATCH 100/516] add tags to phone number --- api/src/main/java/com/messagebird/objects/PhoneNumber.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/api/src/main/java/com/messagebird/objects/PhoneNumber.java b/api/src/main/java/com/messagebird/objects/PhoneNumber.java index 5fdda19f..3ec63d7d 100644 --- a/api/src/main/java/com/messagebird/objects/PhoneNumber.java +++ b/api/src/main/java/com/messagebird/objects/PhoneNumber.java @@ -3,6 +3,7 @@ import com.messagebird.objects.PhoneNumberFeature; import java.util.EnumSet; +import java.util.List; public class PhoneNumber { private String number; @@ -11,6 +12,7 @@ public class PhoneNumber { private String locality; private EnumSet features; private String type; + private List tags; public String getNumber() { return this.number; @@ -36,6 +38,10 @@ public String getType() { return this.type; } + public List getTags() { + return this.tags; + } + @Override public String toString() { return "PhoneNumber{" + @@ -44,6 +50,7 @@ public String toString() { ", region='" + region + "\'" + ", locality='" + locality + "\'" + ", features=" + features + + ", tags=" + tags + ", type='" + type + "\'" + "}"; } From dea92550714931e6d305a53eac9eb6f7b102bccf Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Thu, 9 Jan 2020 10:45:27 +0100 Subject: [PATCH 101/516] fix example usage --- examples/src/main/java/ExampleListNumbersForPurchase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/src/main/java/ExampleListNumbersForPurchase.java b/examples/src/main/java/ExampleListNumbersForPurchase.java index 58579802..7ab1039c 100644 --- a/examples/src/main/java/ExampleListNumbersForPurchase.java +++ b/examples/src/main/java/ExampleListNumbersForPurchase.java @@ -27,7 +27,7 @@ public static void main(String[] args) { final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); try { - if (args[1].equalsIgnoreCase("--params")) { + if (args.length > 1) { PhoneNumbersLookup options = new PhoneNumbersLookup(); options.setFeatures(EnumSet.of(PhoneNumberFeature.VOICE, PhoneNumberFeature.SMS)); options.setType(PhoneNumberType.MOBILE); From ed8866300dd00281229bfd8820c976dde8d3a59c Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Thu, 9 Jan 2020 10:45:46 +0100 Subject: [PATCH 102/516] add example --- .../src/main/java/ExampleUpdateNumber.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 examples/src/main/java/ExampleUpdateNumber.java diff --git a/examples/src/main/java/ExampleUpdateNumber.java b/examples/src/main/java/ExampleUpdateNumber.java new file mode 100644 index 00000000..b6ab52fc --- /dev/null +++ b/examples/src/main/java/ExampleUpdateNumber.java @@ -0,0 +1,27 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; + +public class ExampleUpdateNumber { + public static void main(String[] args) { + if (args.length < 1) { + System.out.println("Please specify your access key."); + return; + } + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + try { + System.out.println(messageBirdClient.updateNumber(args[1], args[2], args[3], args[4])); + } catch (UnauthorizedException | GeneralException exception) { + if (exception.getErrors() != null) { + System.out.println(exception.getErrors().toString()); + } + exception.printStackTrace(); + } + } +} \ No newline at end of file From 69edee6428286796cd007b0ef649b40499507b1c Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Thu, 9 Jan 2020 10:56:50 +0100 Subject: [PATCH 103/516] cancel a number --- api/src/main/java/com/messagebird/MessageBirdClient.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 1e64580e..2c865d8c 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1612,4 +1612,9 @@ public PurchasedPhoneNumber purchaseNumber(String number, String countryCode, in return messageBirdService.sendPayLoad(url, payload, PurchasedPhoneNumber.class); } + + public void cancelNumber(String number) throws UnauthorizedException, GeneralException, NotFoundException { + final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); + messageBirdService.deleteByID(url, number); + } } \ No newline at end of file From 3ea8e8d9f51aadbb16302d9a10bc9aadacc5a78d Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Thu, 9 Jan 2020 10:56:58 +0100 Subject: [PATCH 104/516] add cancel number example --- .../src/main/java/ExampleCancelNumber.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 examples/src/main/java/ExampleCancelNumber.java diff --git a/examples/src/main/java/ExampleCancelNumber.java b/examples/src/main/java/ExampleCancelNumber.java new file mode 100644 index 00000000..f018c10c --- /dev/null +++ b/examples/src/main/java/ExampleCancelNumber.java @@ -0,0 +1,30 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.exceptions.NotFoundException; + +public class ExampleCancelNumber { + public static void main(String[] args) { + if (args.length < 2) { + System.out.println("Please specify your access key & the number you wish to delete."); + return; + } + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0], "https://numbers.messagebird.com"); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + messageBirdClient.cancelNumber(args[1]); + System.out.println("Number Deleted!"); + } catch (UnauthorizedException | GeneralException | NotFoundException exception) { + if (exception.getErrors() != null) { + System.out.println(exception.getErrors().toString()); + } + exception.printStackTrace(); + } + } +} \ No newline at end of file From c8d5dc372c7efdd66e0b0ee0efe7809ccafad70f Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Thu, 9 Jan 2020 10:58:50 +0100 Subject: [PATCH 105/516] remove needless baseurl instantiation --- examples/src/main/java/ExampleCancelNumber.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/src/main/java/ExampleCancelNumber.java b/examples/src/main/java/ExampleCancelNumber.java index f018c10c..eba1d3d4 100644 --- a/examples/src/main/java/ExampleCancelNumber.java +++ b/examples/src/main/java/ExampleCancelNumber.java @@ -12,7 +12,7 @@ public static void main(String[] args) { return; } // First create your service object - final MessageBirdService wsr = new MessageBirdServiceImpl(args[0], "https://numbers.messagebird.com"); + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); // Add the service to the client final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); From a5890d5cc7f7914bb849f4fab909091b894f70f9 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Thu, 9 Jan 2020 11:00:34 +0100 Subject: [PATCH 106/516] fix error conditions --- examples/src/main/java/ExampleUpdateNumber.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/src/main/java/ExampleUpdateNumber.java b/examples/src/main/java/ExampleUpdateNumber.java index b6ab52fc..1c0ed142 100644 --- a/examples/src/main/java/ExampleUpdateNumber.java +++ b/examples/src/main/java/ExampleUpdateNumber.java @@ -6,8 +6,8 @@ public class ExampleUpdateNumber { public static void main(String[] args) { - if (args.length < 1) { - System.out.println("Please specify your access key."); + if (args.length < 3) { + System.out.println("Please specify your access key, phone number, and the tags you wish to apply to it."); return; } // First create your service object From be4254e6472b6ad228046b5513ea1f672e28d531 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Thu, 9 Jan 2020 11:18:39 +0100 Subject: [PATCH 107/516] rm println --- api/src/main/java/com/messagebird/MessageBirdClient.java | 1 - 1 file changed, 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 0a4780e6..257fa7c9 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1619,7 +1619,6 @@ public PhoneNumber updateNumber(String number, String... tags) throws Unauthoriz final String url = String.format("%s/v1/phone-numbers/%s", NUMBERS_CALLS_BASE_URL, number); final Map> payload = new HashMap>(); payload.put("tags", Arrays.asList(tags)); - System.out.println(String.format("Payload: %s", payload.toString())); return messageBirdService.sendPayLoad("PATCH", url, payload, PhoneNumber.class); } } \ No newline at end of file From 58496b7c97420d6fc57c89cde3df8e9573505f34 Mon Sep 17 00:00:00 2001 From: Bernhard Breytenbach Date: Thu, 9 Jan 2020 11:25:17 +0100 Subject: [PATCH 108/516] Refactor: Import the entire objects folder --- .../com/messagebird/MessageBirdClient.java | 25 +------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 1e64580e..01029b4b 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -3,30 +3,7 @@ import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; -import com.messagebird.objects.Balance; -import com.messagebird.objects.Contact; -import com.messagebird.objects.ContactList; -import com.messagebird.objects.ContactRequest; -import com.messagebird.objects.ErrorReport; -import com.messagebird.objects.Group; -import com.messagebird.objects.GroupList; -import com.messagebird.objects.GroupRequest; -import com.messagebird.objects.Hlr; -import com.messagebird.objects.Lookup; -import com.messagebird.objects.LookupHlr; -import com.messagebird.objects.Message; -import com.messagebird.objects.MessageList; -import com.messagebird.objects.MessageResponse; -import com.messagebird.objects.MsgType; -import com.messagebird.objects.PagedPaging; -import com.messagebird.objects.PhoneNumbersLookup; -import com.messagebird.objects.PhoneNumbersResponse; -import com.messagebird.objects.PurchasedPhoneNumber; -import com.messagebird.objects.Verify; -import com.messagebird.objects.VerifyRequest; -import com.messagebird.objects.VoiceMessage; -import com.messagebird.objects.VoiceMessageList; -import com.messagebird.objects.VoiceMessageResponse; +import com.messagebird.objects.*; import com.messagebird.objects.conversations.Conversation; import com.messagebird.objects.conversations.ConversationList; import com.messagebird.objects.conversations.ConversationMessage; From 40a489a4fccc2bc3f3243153d099324183bd4682 Mon Sep 17 00:00:00 2001 From: Bernhard Breytenbach Date: Thu, 9 Jan 2020 11:28:31 +0100 Subject: [PATCH 109/516] Seperate the base PurchacedNumber from the response Purchasing a number adds extra fields that aren't returned when fetching purchased numbers. This refactor separates the "response" class and the basic information always present in a Purchased number --- .../com/messagebird/MessageBirdClient.java | 4 +-- .../messagebird/objects/PurchasedNumber.java | 31 +++++++++++++++++++ ...va => PurchasedNumberCreatedResponse.java} | 16 ++-------- .../src/main/java/ExamplePurchaseNumber.java | 9 ++---- 4 files changed, 39 insertions(+), 21 deletions(-) create mode 100644 api/src/main/java/com/messagebird/objects/PurchasedNumber.java rename api/src/main/java/com/messagebird/objects/{PurchasedPhoneNumber.java => PurchasedNumberCreatedResponse.java} (70%) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 01029b4b..10f51b58 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1579,7 +1579,7 @@ public PhoneNumbersResponse listNumbersForPurchase(String countryCode, PhoneNumb return messageBirdService.requestByID(url, countryCode, params.toHashMap(), PhoneNumbersResponse.class); } - public PurchasedPhoneNumber purchaseNumber(String number, String countryCode, int billingIntervalMonths) throws UnauthorizedException, GeneralException { + public PurchasedNumberCreatedResponse purchaseNumber(String number, String countryCode, int billingIntervalMonths) throws UnauthorizedException, GeneralException { final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); final Map payload = new LinkedHashMap(); @@ -1587,6 +1587,6 @@ public PurchasedPhoneNumber purchaseNumber(String number, String countryCode, in payload.put("countryCode", countryCode); payload.put("billingIntervalMonths", billingIntervalMonths); - return messageBirdService.sendPayLoad(url, payload, PurchasedPhoneNumber.class); + return messageBirdService.sendPayLoad(url, payload, PurchasedNumberCreatedResponse.class); } } \ No newline at end of file diff --git a/api/src/main/java/com/messagebird/objects/PurchasedNumber.java b/api/src/main/java/com/messagebird/objects/PurchasedNumber.java new file mode 100644 index 00000000..5f82e313 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/PurchasedNumber.java @@ -0,0 +1,31 @@ +package com.messagebird.objects; + +import java.util.Date; +import java.util.List; + +public class PurchasedNumber extends PhoneNumber { + private List tags; + private String status; + + public List getTags() { + return tags; + } + + public String getStatus() { + return status; + } + + @Override + public String toString() { + return "PhoneNumber{" + + "number='" + this.getNumber() + "\'" + + ", country='" + this.getCountry() + "\'" + + ", region='" + this.getRegion() + "\'" + + ", locality='" + this.getLocality() + "\'" + + ", features=" + this.getFeatures() + + ", type='" + this.getType() + "\'" + + ", tags='" + tags + "\'" + + ", status='" + status + "\'" + + "}"; + } +} diff --git a/api/src/main/java/com/messagebird/objects/PurchasedPhoneNumber.java b/api/src/main/java/com/messagebird/objects/PurchasedNumberCreatedResponse.java similarity index 70% rename from api/src/main/java/com/messagebird/objects/PurchasedPhoneNumber.java rename to api/src/main/java/com/messagebird/objects/PurchasedNumberCreatedResponse.java index 6be79ece..da5b7d43 100644 --- a/api/src/main/java/com/messagebird/objects/PurchasedPhoneNumber.java +++ b/api/src/main/java/com/messagebird/objects/PurchasedNumberCreatedResponse.java @@ -3,20 +3,10 @@ import java.util.Date; import java.util.List; -public class PurchasedPhoneNumber extends PhoneNumber { - private List tags; - private String status; +public class PurchasedNumberCreatedResponse extends PurchasedNumber { private Date createdAt; private Date renewalAt; - public List getTags() { - return tags; - } - - public String getStatus() { - return status; - } - public Date getCreatedAt() { return createdAt; } @@ -34,8 +24,8 @@ public String toString() { ", locality='" + this.getLocality() + "\'" + ", features=" + this.getFeatures() + ", type='" + this.getType() + "\'" + - ", tags='" + tags + "\'" + - ", status='" + status + "\'" + + ", tags='" + this.getTags() + "\'" + + ", status='" + this.getStatus() + "\'" + ", createdAt='" + createdAt + "\'" + ", renewalAt='" + renewalAt + "\'" + "}"; diff --git a/examples/src/main/java/ExamplePurchaseNumber.java b/examples/src/main/java/ExamplePurchaseNumber.java index 4d7bb17a..b60bfb7e 100644 --- a/examples/src/main/java/ExamplePurchaseNumber.java +++ b/examples/src/main/java/ExamplePurchaseNumber.java @@ -2,11 +2,8 @@ import com.messagebird.MessageBirdService; import com.messagebird.MessageBirdServiceImpl; import com.messagebird.exceptions.GeneralException; -import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; -import com.messagebird.objects.PurchasedPhoneNumber; - -import java.util.LinkedHashMap; +import com.messagebird.objects.PurchasedNumberCreatedResponse; public class ExamplePurchaseNumber { public static void main(String[] args) { @@ -21,9 +18,9 @@ public static void main(String[] args) { final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); try { - PurchasedPhoneNumber purchasedPhoneNumber = messageBirdClient.purchaseNumber(args[1], args[2], Integer.parseInt(args[3])); + PurchasedNumberCreatedResponse purchasedNumberCreatedResponse = messageBirdClient.purchaseNumber(args[1], args[2], Integer.parseInt(args[3])); - System.out.println(purchasedPhoneNumber); + System.out.println(purchasedNumberCreatedResponse); return; } catch (UnauthorizedException | GeneralException exception) { if (exception.getErrors() != null) { From 719578937155ce59512ef8a5aa95df93691230cb Mon Sep 17 00:00:00 2001 From: Bernhard Breytenbach Date: Thu, 9 Jan 2020 11:30:17 +0100 Subject: [PATCH 110/516] Fetch all Purchased numbers based on a filter --- .../com/messagebird/MessageBirdClient.java | 5 + .../objects/PurchasedNumbersFilter.java | 124 ++++++++++++++++++ .../objects/PurchasedNumbersResponse.java | 42 ++++++ .../java/ExampleListPurchasedNumbers.java | 40 ++++++ 4 files changed, 211 insertions(+) create mode 100644 api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java create mode 100644 api/src/main/java/com/messagebird/objects/PurchasedNumbersResponse.java create mode 100644 examples/src/main/java/ExampleListPurchasedNumbers.java diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 10f51b58..449d8d0b 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1589,4 +1589,9 @@ public PurchasedNumberCreatedResponse purchaseNumber(String number, String count return messageBirdService.sendPayLoad(url, payload, PurchasedNumberCreatedResponse.class); } + + public PurchasedNumbersResponse listPurchasedNumbers(PurchasedNumbersFilter filter) throws UnauthorizedException, GeneralException, NotFoundException { + final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); + return messageBirdService.requestByID(url, null, filter.toHashMap(), PurchasedNumbersResponse.class); + } } \ No newline at end of file diff --git a/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java b/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java new file mode 100644 index 00000000..f4516ce8 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java @@ -0,0 +1,124 @@ +package com.messagebird.objects; + +import com.messagebird.exceptions.GeneralException; + +import java.io.Serializable; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.HashMap; + +public class PurchasedNumbersFilter implements Serializable { + private int limit = 10; + private int offset = 0; + private EnumSet features = EnumSet.noneOf(PhoneNumberFeature.class); + private ArrayList tags = new ArrayList<>(); + private String number; + private String region; + private String locality; + private PhoneNumberType type; + + public int getLimit() { + return limit; + } + + public void setLimit(int limit) { + this.limit = limit; + } + + public int getOffset() { + return offset; + } + + public void setOffset(int offset) { + this.offset = offset; + } + + public EnumSet getFeatures() { + return features; + } + + public void addFeature(PhoneNumberFeature feature) { + this.features.add(feature); + } + + public void removeFeature(PhoneNumberFeature feature) { + this.features.remove(feature); + } + + public ArrayList getTags() { + return tags; + } + + public void addTag(String tag) { + this.tags.add(tag); + } + + public void clearTags() { + this.tags.clear(); + } + + public String getNumber() { + return number; + } + + public void setNumber(String number) { + this.number = number; + } + + public String getRegion() { + return region; + } + + public void setRegion(String region) { + this.region = region; + } + + public String getLocality() { + return locality; + } + + public void setLocality(String locality) { + this.locality = locality; + } + + public PhoneNumberType getType() { + return type; + } + + public void setType(PhoneNumberType type) { + this.type = type; + } + + public HashMap toHashMap() throws GeneralException { + final HashMap map = new HashMap(); + for (Field f: getClass().getDeclaredFields()) { + if (f.canAccess(this)) { + try { + Object value = f.get(this); + String key = f.getName(); + if (value != null) { + map.put(key, value); + } + } catch (IllegalAccessException exception) { + throw new GeneralException("Error converting to HashMap. This should never happen."); + } + } + } + return map; + } + + @Override + public String toString() { + return "PurchasedNumbersFilter{" + + "limit=" + limit + + ", offset=" + offset + + ", features=" + features + + ", tags=" + tags.toString() + + ", number='" + number + '\'' + + ", region='" + region + '\'' + + ", locality='" + locality + '\'' + + ", type='" + type + '\'' + + '}'; + } +} diff --git a/api/src/main/java/com/messagebird/objects/PurchasedNumbersResponse.java b/api/src/main/java/com/messagebird/objects/PurchasedNumbersResponse.java new file mode 100644 index 00000000..b61928ca --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/PurchasedNumbersResponse.java @@ -0,0 +1,42 @@ +package com.messagebird.objects; + +import java.util.List; + +public class PurchasedNumbersResponse { + private int offset; + private int limit; + private int count; + private int totalCount; + private List items; + + public int getOffset() { + return offset; + } + + public int getLimit() { + return limit; + } + + public int getCount() { + return count; + } + + public int getTotalCount() { + return totalCount; + } + + public List getItems() { + return items; + } + + @Override + public String toString() { + return "PurchasedNumbersResponse{" + + "offset=" + offset + + ", limit=" + limit + + ", count=" + count + + ", totalCount=" + totalCount + + ", items=" + items + + '}'; + } +} diff --git a/examples/src/main/java/ExampleListPurchasedNumbers.java b/examples/src/main/java/ExampleListPurchasedNumbers.java new file mode 100644 index 00000000..74010c96 --- /dev/null +++ b/examples/src/main/java/ExampleListPurchasedNumbers.java @@ -0,0 +1,40 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.PhoneNumberFeature; +import com.messagebird.objects.PhoneNumberType; +import com.messagebird.objects.PurchasedNumbersFilter; + +public class ExampleListPurchasedNumbers { + public static void main(String[] args) { + if (args.length < 1) { + System.out.println("Please specify your access key."); + return; + } + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0], "https://numbers.messagebird.com"); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + PurchasedNumbersFilter filter = new PurchasedNumbersFilter(); + + filter.addFeature(PhoneNumberFeature.SMS); + filter.setType(PhoneNumberType.MOBILE); + + filter.setLimit(25); + + try { + System.out.println(messageBirdClient.listPurchasedNumbers(filter)); + return; + } catch (UnauthorizedException | NotFoundException | GeneralException exception) { + if (exception.getErrors() != null) { + System.out.println(exception.getErrors().toString()); + } + exception.printStackTrace(); + } + } +} \ No newline at end of file From 296ce486571d95fc705d248b6844267f936bbefe Mon Sep 17 00:00:00 2001 From: Bernhard Breytenbach Date: Thu, 9 Jan 2020 11:40:24 +0100 Subject: [PATCH 111/516] Add ability to view a single number --- .../com/messagebird/MessageBirdClient.java | 5 +++ .../main/java/ExampleViewPurchasedNumber.java | 33 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 examples/src/main/java/ExampleViewPurchasedNumber.java diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 449d8d0b..de7b825f 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1594,4 +1594,9 @@ public PurchasedNumbersResponse listPurchasedNumbers(PurchasedNumbersFilter filt final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); return messageBirdService.requestByID(url, null, filter.toHashMap(), PurchasedNumbersResponse.class); } + + public PurchasedNumber viewPurchasedNumber(String number) throws UnauthorizedException, GeneralException, NotFoundException { + final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); + return messageBirdService.requestByID(url, number, PurchasedNumber.class); + } } \ No newline at end of file diff --git a/examples/src/main/java/ExampleViewPurchasedNumber.java b/examples/src/main/java/ExampleViewPurchasedNumber.java new file mode 100644 index 00000000..f22b354c --- /dev/null +++ b/examples/src/main/java/ExampleViewPurchasedNumber.java @@ -0,0 +1,33 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.PhoneNumberFeature; +import com.messagebird.objects.PhoneNumberType; +import com.messagebird.objects.PurchasedNumbersFilter; + +public class ExampleViewPurchasedNumber { + public static void main(String[] args) { + if (args.length < 2) { + System.out.println("Please specify your access key and phone number."); + return; + } + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0], "https://numbers.messagebird.com"); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + System.out.println(messageBirdClient.viewPurchasedNumber(args[1])); + return; + } catch (UnauthorizedException | NotFoundException | GeneralException exception) { + if (exception.getErrors() != null) { + System.out.println(exception.getErrors().toString()); + } + exception.printStackTrace(); + } + } +} \ No newline at end of file From f5ca393b413c54ed851f2dd9a7debbbfeb58fb7a Mon Sep 17 00:00:00 2001 From: Bernhard Breytenbach Date: Thu, 9 Jan 2020 12:02:45 +0100 Subject: [PATCH 112/516] Fix exception message --- .../java/com/messagebird/objects/PurchasedNumbersFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java b/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java index f4516ce8..671ea618 100644 --- a/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java +++ b/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java @@ -101,7 +101,7 @@ public HashMap toHashMap() throws GeneralException { map.put(key, value); } } catch (IllegalAccessException exception) { - throw new GeneralException("Error converting to HashMap. This should never happen."); + throw new GeneralException("Error converting to HashMap."); } } } From 1e798acb4c4345db92d00004a550c61c22b56e69 Mon Sep 17 00:00:00 2001 From: Bernhard Breytenbach Date: Fri, 10 Jan 2020 10:39:37 +0100 Subject: [PATCH 113/516] Cleanup toString method --- .../java/com/messagebird/objects/PurchasedNumbersFilter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java b/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java index 671ea618..9fb1d48e 100644 --- a/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java +++ b/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java @@ -114,11 +114,11 @@ public String toString() { "limit=" + limit + ", offset=" + offset + ", features=" + features + - ", tags=" + tags.toString() + + ", tags=" + tags + ", number='" + number + '\'' + ", region='" + region + '\'' + ", locality='" + locality + '\'' + - ", type='" + type + '\'' + + ", type=" + type + '}'; } } From a40433c00299b1f443108e70b758a9f408866977 Mon Sep 17 00:00:00 2001 From: Bernhard Breytenbach Date: Fri, 10 Jan 2020 10:40:04 +0100 Subject: [PATCH 114/516] Allow adding/removing multiple features/tags at a time --- .../objects/PurchasedNumbersFilter.java | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java b/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java index 9fb1d48e..59eabd72 100644 --- a/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java +++ b/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java @@ -38,20 +38,34 @@ public EnumSet getFeatures() { return features; } - public void addFeature(PhoneNumberFeature feature) { - this.features.add(feature); + public void addFeature(PhoneNumberFeature... features) { + for (PhoneNumberFeature feature: features) { + this.features.add(feature); + } } - public void removeFeature(PhoneNumberFeature feature) { - this.features.remove(feature); + public void removeFeature(PhoneNumberFeature... features) { + for (PhoneNumberFeature feature: features) { + this.features.remove(feature); + } } public ArrayList getTags() { return tags; } - public void addTag(String tag) { - this.tags.add(tag); + public void addTag(String... tags) { + for (String tag: tags) { + if (!this.tags.contains(tag)) { + this.tags.add(tag); + } + } + } + + public void removeTag(String... tags) { + for (String tag: tags) { + this.tags.remove(tag); + } } public void clearTags() { From 3612125f538ce6caa182424e4a1ba037742bdbd1 Mon Sep 17 00:00:00 2001 From: Bernhard Breytenbach Date: Fri, 10 Jan 2020 10:40:33 +0100 Subject: [PATCH 115/516] Add unit tests for PurchasedNumbersFilter --- .../PurchasedNumbersFilterTest.java | 213 ++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 api/src/test/java/com/messagebird/PurchasedNumbersFilterTest.java diff --git a/api/src/test/java/com/messagebird/PurchasedNumbersFilterTest.java b/api/src/test/java/com/messagebird/PurchasedNumbersFilterTest.java new file mode 100644 index 00000000..2d9cef72 --- /dev/null +++ b/api/src/test/java/com/messagebird/PurchasedNumbersFilterTest.java @@ -0,0 +1,213 @@ +package com.messagebird; + +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.*; +import org.junit.Test; + +import java.lang.reflect.Array; +import java.util.*; + +import static org.junit.Assert.*; +import static org.junit.Assert.assertNull; + +public class PurchasedNumbersFilterTest { + + @Test + public void testDefaults() { + // Setup + PurchasedNumbersFilter filter = new PurchasedNumbersFilter(); + + // Test + assertEquals(10, filter.getLimit()); + assertEquals(0, filter.getOffset()); + assertEquals(0, filter.getFeatures().size()); + assertEquals(0, filter.getTags().size()); + assertNull(filter.getNumber()); + assertNull(filter.getRegion()); + assertNull(filter.getLocality()); + assertNull(filter.getType()); + } + + @Test + public void testAddingFeatures() { + // Setup + PurchasedNumbersFilter filter = new PurchasedNumbersFilter(); + + assertEquals(EnumSet.noneOf(PhoneNumberFeature.class), filter.getFeatures()); + + // Test can add a feature + filter.addFeature(PhoneNumberFeature.SMS); + assertEquals(EnumSet.of(PhoneNumberFeature.SMS), filter.getFeatures()); + + // Test can have multiple features + filter.addFeature(PhoneNumberFeature.VOICE); + assertEquals(EnumSet.of(PhoneNumberFeature.SMS, PhoneNumberFeature.VOICE), filter.getFeatures()); + + // Test shouldn't have more than one of each + filter.addFeature(PhoneNumberFeature.SMS); + assertEquals(EnumSet.of(PhoneNumberFeature.SMS, PhoneNumberFeature.VOICE), filter.getFeatures()); + + filter.addFeature(PhoneNumberFeature.MMS); + assertEquals(EnumSet.of(PhoneNumberFeature.SMS, PhoneNumberFeature.VOICE, PhoneNumberFeature.MMS), filter.getFeatures()); + } + + @Test + public void testAddingMultipleFeatures() { + // Setup + PurchasedNumbersFilter filter = new PurchasedNumbersFilter(); + + assertEquals(EnumSet.noneOf(PhoneNumberFeature.class), filter.getFeatures()); + + // Test + filter.addFeature(PhoneNumberFeature.SMS, PhoneNumberFeature.VOICE); + assertEquals(EnumSet.of(PhoneNumberFeature.SMS, PhoneNumberFeature.VOICE), filter.getFeatures()); + } + + @Test + public void testRemovingFeatures() { + // Setup + PurchasedNumbersFilter filter = new PurchasedNumbersFilter(); + + // Test + filter.addFeature(PhoneNumberFeature.SMS, PhoneNumberFeature.MMS, PhoneNumberFeature.VOICE); + assertEquals(EnumSet.of(PhoneNumberFeature.SMS, PhoneNumberFeature.VOICE, PhoneNumberFeature.MMS), filter.getFeatures()); + + filter.removeFeature(PhoneNumberFeature.VOICE); + assertEquals(EnumSet.of(PhoneNumberFeature.SMS, PhoneNumberFeature.MMS), filter.getFeatures()); + + filter.removeFeature(PhoneNumberFeature.VOICE); + assertEquals(EnumSet.of(PhoneNumberFeature.SMS, PhoneNumberFeature.MMS), filter.getFeatures()); + + filter.removeFeature(PhoneNumberFeature.SMS, PhoneNumberFeature.MMS); + assertEquals(EnumSet.noneOf(PhoneNumberFeature.class), filter.getFeatures()); + } + + @Test + public void testAddingTags() { + // Setup + PurchasedNumbersFilter filter = new PurchasedNumbersFilter(); + + assertArrayEquals(new String[]{}, filter.getTags().toArray()); + + // Test + filter.addTag("TEST_TAG"); + assertArrayEquals(new String[]{"TEST_TAG"}, filter.getTags().toArray()); + + filter.addTag("Another test tag"); + assertArrayEquals(new String[]{"TEST_TAG", "Another test tag"}, filter.getTags().toArray()); + + filter.addTag("a", "b", "c"); + assertArrayEquals(new String[]{"TEST_TAG", "Another test tag", "a", "b", "c"}, filter.getTags().toArray()); + } + + @Test + public void testAddingDuplicateTags() { + // Setup + PurchasedNumbersFilter filter = new PurchasedNumbersFilter(); + + filter.addTag("a"); + filter.addTag("a"); + filter.addTag("a", "b", "b", "c", "b"); + + assertArrayEquals(new String[]{"a", "b", "c"}, filter.getTags().toArray()); + } + + @Test + public void testRemoveTags() { + // Setup + PurchasedNumbersFilter filter = new PurchasedNumbersFilter(); + + filter.addTag("a", "b", "c", "d"); + assertArrayEquals(new String[]{"a", "b", "c", "d"}, filter.getTags().toArray()); + + // Test + filter.removeTag("b"); + assertArrayEquals(new String[]{"a", "c", "d"}, filter.getTags().toArray()); + + filter.removeTag("d"); + assertArrayEquals(new String[]{"a", "c"}, filter.getTags().toArray()); + + filter.removeTag("b", "c", "d"); + assertArrayEquals(new String[]{"a"}, filter.getTags().toArray()); + } + + @Test + public void testClearTags() { + // Setup + PurchasedNumbersFilter filter = new PurchasedNumbersFilter(); + + filter.addTag("a", "b", "c", "d"); + assertArrayEquals(new String[]{"a", "b", "c", "d"}, filter.getTags().toArray()); + + // Test + filter.clearTags(); + assertArrayEquals(new String[]{}, filter.getTags().toArray()); + } + + @Test + public void testBasicSetters() { + // Setup + PurchasedNumbersFilter filter = new PurchasedNumbersFilter(); + + assertNull(filter.getNumber()); + assertNull(filter.getRegion()); + assertNull(filter.getLocality()); + assertNull(filter.getType()); + + // Test + filter.setLimit(23); + filter.setOffset(5); + filter.setNumber("TEST_NUMBER"); + filter.setRegion("TEST_REGION"); + filter.setLocality("TEST_LOCALITY"); + filter.setType(PhoneNumberType.MOBILE); + + assertEquals(23, filter.getLimit()); + assertEquals(5, filter.getOffset()); + assertEquals("TEST_NUMBER", filter.getNumber()); + assertEquals("TEST_REGION", filter.getRegion()); + assertEquals("TEST_LOCALITY", filter.getLocality()); + assertEquals(PhoneNumberType.MOBILE, filter.getType()); + } + + @Test + public void testToHashMapWithDefaultValues() throws GeneralException { + // Setup + PurchasedNumbersFilter filter = new PurchasedNumbersFilter(); + + HashMap map = filter.toHashMap(); + + assertEquals(10, map.get("limit")); + assertEquals(0, map.get("offset")); + assertEquals(EnumSet.noneOf(PhoneNumberFeature.class), map.get("features")); + assertEquals(new ArrayList(), map.get("tags")); + } + + @Test + public void testToHashMapWithAllValues() throws GeneralException { + // Setup + PurchasedNumbersFilter filter = new PurchasedNumbersFilter(); + + filter.setLimit(42); + filter.setOffset(24); + filter.setNumber("1234567890"); + filter.setRegion("My Region"); + filter.setLocality("My Locality"); + filter.setType(PhoneNumberType.MOBILE); + filter.addFeature(PhoneNumberFeature.SMS, PhoneNumberFeature.VOICE); + filter.addTag("h", "e", "l", "l", "o"); + + HashMap map = filter.toHashMap(); + + assertEquals(42, map.get("limit")); + assertEquals(24, map.get("offset")); + assertEquals("1234567890", map.get("number")); + assertEquals("My Region", map.get("region")); + assertEquals("My Locality", map.get("locality")); + assertEquals("mobile", map.get("type").toString()); + assertArrayEquals(new PhoneNumberFeature[]{PhoneNumberFeature.SMS, PhoneNumberFeature.VOICE}, ((Collection) map.get("features")).toArray()); + + assertArrayEquals(new String[]{"h", "e", "l", "o"}, ((Collection) map.get("tags")).toArray()); + } +} From e0433116b6f3f80a46a505f8c932e1fe1a68330e Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Fri, 10 Jan 2020 10:45:19 +0100 Subject: [PATCH 116/516] add phone number constructor --- .../main/java/com/messagebird/objects/PhoneNumber.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/objects/PhoneNumber.java b/api/src/main/java/com/messagebird/objects/PhoneNumber.java index 96f5d155..26cd2cf0 100644 --- a/api/src/main/java/com/messagebird/objects/PhoneNumber.java +++ b/api/src/main/java/com/messagebird/objects/PhoneNumber.java @@ -3,7 +3,6 @@ import com.messagebird.objects.PhoneNumberFeature; import java.util.EnumSet; -import java.util.List; public class PhoneNumber { private String number; @@ -37,6 +36,15 @@ public String getType() { return this.type; } + public PhoneNumber(String number, String country, String region, String locality, EnumSet features, String type) { + this.number = number; + this.country = country; + this.region = region; + this.locality = locality; + this.features = features; + this.type = type; + } + @Override public String toString() { return "PhoneNumber{" + From 132029144e67f654e5362760c4f2659729e1675d Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Fri, 10 Jan 2020 10:45:34 +0100 Subject: [PATCH 117/516] add more convenient setter --- .../java/com/messagebird/objects/PhoneNumbersLookup.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/objects/PhoneNumbersLookup.java b/api/src/main/java/com/messagebird/objects/PhoneNumbersLookup.java index 48c0ae19..8b8396fa 100644 --- a/api/src/main/java/com/messagebird/objects/PhoneNumbersLookup.java +++ b/api/src/main/java/com/messagebird/objects/PhoneNumbersLookup.java @@ -3,8 +3,9 @@ import com.messagebird.exceptions.GeneralException; import com.messagebird.objects.PhoneNumberFeature; import com.messagebird.objects.PhoneNumberType; -import com.messagebird.objects.PhoneNumberSearchPattern;; +import com.messagebird.objects.PhoneNumberSearchPattern; +import java.util.Arrays; import java.util.EnumSet; import java.util.HashMap; import java.lang.reflect.Field; @@ -44,6 +45,12 @@ public void setNumber(Number number) { public void setFeatures(EnumSet features) { this.features = features; } + + public void setFeatures(PhoneNumberFeature... features) { + EnumSet featuresEnum = EnumSet.noneOf(PhoneNumberFeature.class); + featuresEnum.addAll(Arrays.asList(features)); + this.features = featuresEnum; + } public void setType(PhoneNumberType type) { this.type = type; From 6f21f9baa6a6c111bc42202b21ec457c82be6467 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Fri, 10 Jan 2020 10:45:44 +0100 Subject: [PATCH 118/516] add setters --- .../com/messagebird/objects/PhoneNumbersResponse.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/api/src/main/java/com/messagebird/objects/PhoneNumbersResponse.java b/api/src/main/java/com/messagebird/objects/PhoneNumbersResponse.java index 68e9ef4d..4a37fcaf 100644 --- a/api/src/main/java/com/messagebird/objects/PhoneNumbersResponse.java +++ b/api/src/main/java/com/messagebird/objects/PhoneNumbersResponse.java @@ -26,6 +26,15 @@ public Number getOffset() { public List getItems() { return this.items; } + public void setLimit(Number limit) { + this.limit = limit; + } + public void setOffset(Number offset) { + this.offset = offset; + } + public void setItems(List items) { + this.items = items; + } @Override public String toString() { From e13a31a1a87c47695efd51c3a56c8681f2c91f3b Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Fri, 10 Jan 2020 10:45:59 +0100 Subject: [PATCH 119/516] add tests to list numbers --- .../messagebird/MessageBirdClientTest.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index ef8b2af5..6afe6463 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -769,4 +769,47 @@ public void testDeleteWebhook() throws NotFoundException, GeneralException, Unau messageBirdClientMock.deleteWebhook("id"); verify(messageBirdServiceMock, times(1)).deleteByID(VOICE_CALLS_BASE_URL + WEBHOOKS, "id"); } + + @Test + public void testListNumbersForPurchase() throws IllegalArgumentException, GeneralException, UnauthorizedException, NotFoundException { + final String url = String.format("%s/v1/available-phone-numbers", NUMBERS_CALLS_BASE_URL); + final PhoneNumbersResponse mockedResponse = TestUtil.createPhoneNumbersResponseData(); + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); + + when(messageBirdServiceMock.requestByID(url, "NL", PhoneNumbersResponse.class)) + .thenReturn(mockedResponse); + + final PhoneNumbersResponse response = messageBirdClientMock.listNumbersForPurchase("NL"); + verify(messageBirdServiceMock, times(1)).requestByID(url, "NL", PhoneNumbersResponse.class); + + assertNotNull(response); + assertEquals(response, mockedResponse); + } + + @Test + public void testListNumbersForPurchaseWithParams() throws IllegalArgumentException, GeneralException, UnauthorizedException, NotFoundException { + final String url = String.format("%s/v1/available-phone-numbers", NUMBERS_CALLS_BASE_URL); + final PhoneNumbersResponse mockedResponse = TestUtil.createPhoneNumbersResponseDataWithParams(); + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); + + PhoneNumbersLookup options = new PhoneNumbersLookup(); + options.setFeatures(PhoneNumberFeature.VOICE, PhoneNumberFeature.SMS); + options.setType(PhoneNumberType.MOBILE); + options.setLimit(1); + options.setNumber(562); + options.setSearchPattern(PhoneNumberSearchPattern.START); + + when(messageBirdServiceMock.requestByID(url, "US", options.toHashMap(), PhoneNumbersResponse.class)) + .thenReturn(mockedResponse); + + final PhoneNumbersResponse response = messageBirdClientMock.listNumbersForPurchase("US", options); + verify(messageBirdServiceMock, times(1)).requestByID(url, "US", options.toHashMap(), PhoneNumbersResponse.class); + assertNotNull(response); + assertEquals(response, mockedResponse); + } + } From 2079d5d6c7e991b6cafde4b77253d27e2ae1e090 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Fri, 10 Jan 2020 10:46:07 +0100 Subject: [PATCH 120/516] add sample data --- .../test/java/com/messagebird/TestUtil.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index 5a854b45..fcbbd3fc 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -240,4 +240,24 @@ static ConversationWebhookCreateRequest createConversationWebhookRequest() { ) ); } + + static PhoneNumbersResponse createPhoneNumbersResponseData() { + final PhoneNumber number = new PhoneNumber("31102005195", "NL", "", "Rotterdam", EnumSet.of(PhoneNumberFeature.VOICE), "unknown"); + final List numbers = List.of(number); + final PhoneNumbersResponse phoneNumbersResponseData = new PhoneNumbersResponse(); + phoneNumbersResponseData.setLimit(1); + phoneNumbersResponseData.setOffset(0); + phoneNumbersResponseData.setItems(numbers); + return phoneNumbersResponseData; + } + + static PhoneNumbersResponse createPhoneNumbersResponseDataWithParams() { + final PhoneNumber number = new PhoneNumber("15625267429", "US", "", "", EnumSet.of(PhoneNumberFeature.SMS, PhoneNumberFeature.MMS, PhoneNumberFeature.VOICE), "landline_or_mobile"); + final List numbers = List.of(number); + final PhoneNumbersResponse phoneNumbersResponseData = new PhoneNumbersResponse(); + phoneNumbersResponseData.setLimit(1); + phoneNumbersResponseData.setOffset(0); + phoneNumbersResponseData.setItems(numbers); + return phoneNumbersResponseData; + } } From 720d4aae40c9a471c0318b0b659978aa0d8fc188 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Fri, 10 Jan 2020 10:46:51 +0100 Subject: [PATCH 121/516] use new setter method --- examples/src/main/java/ExampleListNumbersForPurchase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/src/main/java/ExampleListNumbersForPurchase.java b/examples/src/main/java/ExampleListNumbersForPurchase.java index 7ab1039c..f8c6c625 100644 --- a/examples/src/main/java/ExampleListNumbersForPurchase.java +++ b/examples/src/main/java/ExampleListNumbersForPurchase.java @@ -29,7 +29,7 @@ public static void main(String[] args) { try { if (args.length > 1) { PhoneNumbersLookup options = new PhoneNumbersLookup(); - options.setFeatures(EnumSet.of(PhoneNumberFeature.VOICE, PhoneNumberFeature.SMS)); + options.setFeatures(PhoneNumberFeature.VOICE, PhoneNumberFeature.SMS); options.setType(PhoneNumberType.MOBILE); options.setLimit(10); options.setNumber(562); From c8dd3c32a32779d57306f7406d4eac84662f4d44 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Fri, 10 Jan 2020 10:47:02 +0100 Subject: [PATCH 122/516] remove unused imports --- examples/src/main/java/ExampleListNumbersForPurchase.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/examples/src/main/java/ExampleListNumbersForPurchase.java b/examples/src/main/java/ExampleListNumbersForPurchase.java index f8c6c625..96766f2a 100644 --- a/examples/src/main/java/ExampleListNumbersForPurchase.java +++ b/examples/src/main/java/ExampleListNumbersForPurchase.java @@ -9,11 +9,6 @@ import com.messagebird.objects.PhoneNumberSearchPattern; import com.messagebird.objects.PhoneNumbersLookup; -import java.util.EnumSet;; - -import java.util.LinkedHashMap; -import java.util.Map; - public class ExampleListNumbersForPurchase { public static void main(String[] args) { if (args.length < 1) { From 190db370d17d5edfc99db291a14222d9a0b36541 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Fri, 10 Jan 2020 10:47:10 +0100 Subject: [PATCH 123/516] remove unused imports --- examples/src/main/java/ExampleViewPurchasedNumber.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/examples/src/main/java/ExampleViewPurchasedNumber.java b/examples/src/main/java/ExampleViewPurchasedNumber.java index f22b354c..07c88cd2 100644 --- a/examples/src/main/java/ExampleViewPurchasedNumber.java +++ b/examples/src/main/java/ExampleViewPurchasedNumber.java @@ -4,9 +4,6 @@ import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; -import com.messagebird.objects.PhoneNumberFeature; -import com.messagebird.objects.PhoneNumberType; -import com.messagebird.objects.PurchasedNumbersFilter; public class ExampleViewPurchasedNumber { public static void main(String[] args) { From 5279f86c08f16574ff88916edc1fce5aa7de07a7 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Fri, 10 Jan 2020 10:58:39 +0100 Subject: [PATCH 124/516] remove unused import --- .../com/messagebird/objects/PurchasedNumberCreatedResponse.java | 1 - 1 file changed, 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/objects/PurchasedNumberCreatedResponse.java b/api/src/main/java/com/messagebird/objects/PurchasedNumberCreatedResponse.java index da5b7d43..8922db2e 100644 --- a/api/src/main/java/com/messagebird/objects/PurchasedNumberCreatedResponse.java +++ b/api/src/main/java/com/messagebird/objects/PurchasedNumberCreatedResponse.java @@ -1,7 +1,6 @@ package com.messagebird.objects; import java.util.Date; -import java.util.List; public class PurchasedNumberCreatedResponse extends PurchasedNumber { private Date createdAt; From 9c23ae49ee7ad7e41224365d0568ee90334ffa51 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Fri, 10 Jan 2020 13:10:08 +0100 Subject: [PATCH 125/516] update return type --- api/src/main/java/com/messagebird/MessageBirdClient.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index aba660d4..1ecc84f0 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1601,11 +1601,11 @@ public PurchasedNumber viewPurchasedNumber(String number) throws UnauthorizedExc return messageBirdService.requestByID(url, number, PurchasedNumber.class); } - public PurchasedNumbersResponse updateNumber(String number, String... tags) throws UnauthorizedException, GeneralException { + public PurchasedNumber updateNumber(String number, String... tags) throws UnauthorizedException, GeneralException { final String url = String.format("%s/v1/phone-numbers/%s", NUMBERS_CALLS_BASE_URL, number); final Map> payload = new HashMap>(); payload.put("tags", Arrays.asList(tags)); - return messageBirdService.sendPayLoad("PATCH", url, payload, PurchasedNumbersResponse.class); + return messageBirdService.sendPayLoad("PATCH", url, payload, PurchasedNumber.class); } public void cancelNumber(String number) throws UnauthorizedException, GeneralException, NotFoundException { From d97c65a4c456b745f482dcee5d0c997b269a3579 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Fri, 10 Jan 2020 13:10:21 +0100 Subject: [PATCH 126/516] add setters --- .../messagebird/objects/PurchasedNumber.java | 19 ++++++++++++++- .../PurchasedNumberCreatedResponse.java | 13 ++++++++++ .../objects/PurchasedNumbersResponse.java | 24 +++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/objects/PurchasedNumber.java b/api/src/main/java/com/messagebird/objects/PurchasedNumber.java index 5f82e313..23552860 100644 --- a/api/src/main/java/com/messagebird/objects/PurchasedNumber.java +++ b/api/src/main/java/com/messagebird/objects/PurchasedNumber.java @@ -1,9 +1,14 @@ package com.messagebird.objects; -import java.util.Date; +import java.util.EnumSet; import java.util.List; public class PurchasedNumber extends PhoneNumber { + public PurchasedNumber(String number, String country, String region, String locality, + EnumSet features, String type) { + super(number, country, region, locality, features, type); + } + private List tags; private String status; @@ -11,10 +16,22 @@ public List getTags() { return tags; } + public void setTags(List tags) { + this.tags = tags; + } + + public void setTags(String... tags) { + this.tags = List.of(tags); + } + public String getStatus() { return status; } + public void setStatus(String status) { + this.status = status; + } + @Override public String toString() { return "PhoneNumber{" + diff --git a/api/src/main/java/com/messagebird/objects/PurchasedNumberCreatedResponse.java b/api/src/main/java/com/messagebird/objects/PurchasedNumberCreatedResponse.java index 8922db2e..7ec7dcde 100644 --- a/api/src/main/java/com/messagebird/objects/PurchasedNumberCreatedResponse.java +++ b/api/src/main/java/com/messagebird/objects/PurchasedNumberCreatedResponse.java @@ -1,8 +1,14 @@ package com.messagebird.objects; import java.util.Date; +import java.util.EnumSet; public class PurchasedNumberCreatedResponse extends PurchasedNumber { + public PurchasedNumberCreatedResponse(String number, String country, String region, String locality, + EnumSet features, String type) { + super(number, country, region, locality, features, type); + } + private Date createdAt; private Date renewalAt; @@ -14,6 +20,13 @@ public Date getRenewalAt() { return renewalAt; } + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + public void setRenewalAt(Date renewalAt) { + this.renewalAt = renewalAt; + } + @Override public String toString() { return "PhoneNumber{" + diff --git a/api/src/main/java/com/messagebird/objects/PurchasedNumbersResponse.java b/api/src/main/java/com/messagebird/objects/PurchasedNumbersResponse.java index b61928ca..a95e6741 100644 --- a/api/src/main/java/com/messagebird/objects/PurchasedNumbersResponse.java +++ b/api/src/main/java/com/messagebird/objects/PurchasedNumbersResponse.java @@ -29,6 +29,30 @@ public List getItems() { return items; } + public void setOffset(int offset) { + this.offset = offset; + } + + public void setLimit(int limit) { + this.limit = limit; + } + + public void setCount(int count) { + this.count = count; + } + + public void setTotalCount(int totalCount) { + this.totalCount = totalCount; + } + + public void setItems(List items) { + this.items = items; + } + + public void setItems(PurchasedNumber... items) { + this.items = List.of(items); + } + @Override public String toString() { return "PurchasedNumbersResponse{" + From 9699cef44288304fa1f13423b5b92a0b0704db37 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Fri, 10 Jan 2020 13:10:37 +0100 Subject: [PATCH 127/516] add remaining method tests --- .../messagebird/MessageBirdClientTest.java | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 6afe6463..750abbeb 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -12,8 +12,11 @@ import java.io.UnsupportedEncodingException; import java.math.BigInteger; +import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import static com.messagebird.MessageBirdClient.*; @@ -812,4 +815,101 @@ public void testListNumbersForPurchaseWithParams() throws IllegalArgumentExcepti assertEquals(response, mockedResponse); } + @Test + public void testPurchaseNumber() throws UnauthorizedException, GeneralException { + final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); + + PurchasedNumberCreatedResponse purchasedNumberMockData = TestUtil.createPurchaseNumberResponse(); + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); + + final Map payload = new LinkedHashMap(); + payload.put("number", "15625267429"); + payload.put("countryCode", "US"); + payload.put("billingIntervalMonths", 1); + + when(messageBirdServiceMock.sendPayLoad(url, payload, PurchasedNumberCreatedResponse.class)) + .thenReturn(purchasedNumberMockData); + final PurchasedNumberCreatedResponse response = messageBirdClientMock.purchaseNumber("15625267429", "US", 1); + verify(messageBirdServiceMock, times(1)).sendPayLoad(url, payload, PurchasedNumberCreatedResponse.class); + assertNotNull(response); + assertEquals(response, purchasedNumberMockData); + } + + @Test + public void testListPurchasedNumbers() throws UnauthorizedException, GeneralException, NotFoundException { + final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); + + PurchasedNumbersResponse purchasedNumbersMockData = TestUtil.createPurchasedNumbersResponse(); + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); + + PurchasedNumbersFilter filter = new PurchasedNumbersFilter(); + filter.setLimit(1); + filter.addFeature(PhoneNumberFeature.SMS); + filter.setType(PhoneNumberType.MOBILE); + filter.addTag("tag"); + + when(messageBirdServiceMock.requestByID(url, null, filter.toHashMap(), PurchasedNumbersResponse.class)) + .thenReturn(purchasedNumbersMockData); + + final PurchasedNumbersResponse response = messageBirdClientMock.listPurchasedNumbers(filter); + + verify(messageBirdServiceMock, times(1)).requestByID(url, null, filter.toHashMap(), PurchasedNumbersResponse.class); + assertNotNull(response); + assertEquals(response, purchasedNumbersMockData); + } + + @Test + public void testViewPurchasedNumber() throws UnauthorizedException, GeneralException, NotFoundException { + final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); + + PurchasedNumber purchasedNumberMockData = TestUtil.createPurchasedNumberResponse(); + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); + when(messageBirdServiceMock.requestByID(url, "15625267429", PurchasedNumber.class)) + .thenReturn(purchasedNumberMockData); + final PurchasedNumber response = messageBirdClientMock.viewPurchasedNumber("15625267429"); + + verify(messageBirdServiceMock, times(1)).requestByID(url, "15625267429", PurchasedNumber.class); + assertNotNull(response); + assertEquals(response, purchasedNumberMockData); + } + + @Test + public void updatePurchasedNumber() throws UnauthorizedException, GeneralException, NotFoundException { + final String phoneNumber = "15625267429"; + final String url = String.format("%s/v1/phone-numbers/%s", NUMBERS_CALLS_BASE_URL, phoneNumber); + + PurchasedNumber updatedNumberMock = TestUtil.createPurchasedNumberResponse(); + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); + + final Map> payload = new HashMap>(); + payload.put("tags", Arrays.asList("tag")); + + when(messageBirdServiceMock.sendPayLoad("PATCH", url, payload, PurchasedNumber.class)) + .thenReturn(updatedNumberMock); + final PurchasedNumber response = messageBirdClientMock.updateNumber(phoneNumber, "tag"); + verify(messageBirdServiceMock, times(1)).sendPayLoad("PATCH", url, payload, PurchasedNumber.class); + assertNotNull(response); + assertEquals(response, updatedNumberMock); + } + + @Test + public void deletePurchasedNumber() throws UnauthorizedException, GeneralException, NotFoundException { + final String phoneNumber = "15625267429"; + final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); + + messageBirdClientMock.cancelNumber(phoneNumber); + verify(messageBirdServiceMock, times(1)).deleteByID(url, phoneNumber); + } + } From 9e5c5a730745329fc6c4e41c6c87182dce79bafa Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Fri, 10 Jan 2020 13:10:46 +0100 Subject: [PATCH 128/516] add mocks --- .../test/java/com/messagebird/TestUtil.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index fcbbd3fc..fe9f3718 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -260,4 +260,35 @@ static PhoneNumbersResponse createPhoneNumbersResponseDataWithParams() { phoneNumbersResponseData.setItems(numbers); return phoneNumbersResponseData; } + + static PurchasedNumberCreatedResponse createPurchaseNumberResponse() { + final PurchasedNumberCreatedResponse response = new PurchasedNumberCreatedResponse("15625267429", + "US", "", "", EnumSet.of(PhoneNumberFeature.SMS, PhoneNumberFeature.MMS, PhoneNumberFeature.VOICE), "landline_or_mobile"); + response.setCreatedAt(new Date()); + response.setRenewalAt(new Date()); + return response; + } + + static PurchasedNumbersResponse createPurchasedNumbersResponse() { + final PurchasedNumber number = new PurchasedNumber("15625267429", "US", + "", "", EnumSet.of(PhoneNumberFeature.SMS, PhoneNumberFeature.MMS, PhoneNumberFeature.VOICE), "landline_or_mobile"); + number.setTags("tag"); + number.setStatus("active"); + PurchasedNumbersResponse response = new PurchasedNumbersResponse(); + response.setItems(number); + response.setCount(1); + response.setLimit(1); + response.setTotalCount(1); + response.setOffset(0); + return response; + } + + static PurchasedNumber createPurchasedNumberResponse() { + final PurchasedNumber number = new PurchasedNumber("15625267429", "US", + "", "", EnumSet.of(PhoneNumberFeature.SMS, PhoneNumberFeature.MMS, PhoneNumberFeature.VOICE), "landline_or_mobile"); + number.setTags("tag"); + number.setStatus("active"); + return number; + } + } From 6e236c6831387ed7e84db0c9894f97d0432bcbfc Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Fri, 10 Jan 2020 13:27:55 +0100 Subject: [PATCH 129/516] simplify based on feedback --- .../com/messagebird/objects/PhoneNumber.java | 9 ---- .../objects/PhoneNumbersResponse.java | 9 ---- .../messagebird/objects/PurchasedNumber.java | 17 ------- .../PurchasedNumberCreatedResponse.java | 12 ----- .../objects/PurchasedNumbersResponse.java | 24 --------- .../messagebird/MessageBirdClientTest.java | 12 ++--- .../test/java/com/messagebird/TestUtil.java | 50 ------------------- 7 files changed, 6 insertions(+), 127 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/PhoneNumber.java b/api/src/main/java/com/messagebird/objects/PhoneNumber.java index 26cd2cf0..5fdda19f 100644 --- a/api/src/main/java/com/messagebird/objects/PhoneNumber.java +++ b/api/src/main/java/com/messagebird/objects/PhoneNumber.java @@ -36,15 +36,6 @@ public String getType() { return this.type; } - public PhoneNumber(String number, String country, String region, String locality, EnumSet features, String type) { - this.number = number; - this.country = country; - this.region = region; - this.locality = locality; - this.features = features; - this.type = type; - } - @Override public String toString() { return "PhoneNumber{" + diff --git a/api/src/main/java/com/messagebird/objects/PhoneNumbersResponse.java b/api/src/main/java/com/messagebird/objects/PhoneNumbersResponse.java index 4a37fcaf..68e9ef4d 100644 --- a/api/src/main/java/com/messagebird/objects/PhoneNumbersResponse.java +++ b/api/src/main/java/com/messagebird/objects/PhoneNumbersResponse.java @@ -26,15 +26,6 @@ public Number getOffset() { public List getItems() { return this.items; } - public void setLimit(Number limit) { - this.limit = limit; - } - public void setOffset(Number offset) { - this.offset = offset; - } - public void setItems(List items) { - this.items = items; - } @Override public String toString() { diff --git a/api/src/main/java/com/messagebird/objects/PurchasedNumber.java b/api/src/main/java/com/messagebird/objects/PurchasedNumber.java index 23552860..4ee60edf 100644 --- a/api/src/main/java/com/messagebird/objects/PurchasedNumber.java +++ b/api/src/main/java/com/messagebird/objects/PurchasedNumber.java @@ -1,13 +1,8 @@ package com.messagebird.objects; -import java.util.EnumSet; import java.util.List; public class PurchasedNumber extends PhoneNumber { - public PurchasedNumber(String number, String country, String region, String locality, - EnumSet features, String type) { - super(number, country, region, locality, features, type); - } private List tags; private String status; @@ -16,22 +11,10 @@ public List getTags() { return tags; } - public void setTags(List tags) { - this.tags = tags; - } - - public void setTags(String... tags) { - this.tags = List.of(tags); - } - public String getStatus() { return status; } - public void setStatus(String status) { - this.status = status; - } - @Override public String toString() { return "PhoneNumber{" + diff --git a/api/src/main/java/com/messagebird/objects/PurchasedNumberCreatedResponse.java b/api/src/main/java/com/messagebird/objects/PurchasedNumberCreatedResponse.java index 7ec7dcde..0b4b6bdb 100644 --- a/api/src/main/java/com/messagebird/objects/PurchasedNumberCreatedResponse.java +++ b/api/src/main/java/com/messagebird/objects/PurchasedNumberCreatedResponse.java @@ -4,11 +4,6 @@ import java.util.EnumSet; public class PurchasedNumberCreatedResponse extends PurchasedNumber { - public PurchasedNumberCreatedResponse(String number, String country, String region, String locality, - EnumSet features, String type) { - super(number, country, region, locality, features, type); - } - private Date createdAt; private Date renewalAt; @@ -20,13 +15,6 @@ public Date getRenewalAt() { return renewalAt; } - public void setCreatedAt(Date createdAt) { - this.createdAt = createdAt; - } - public void setRenewalAt(Date renewalAt) { - this.renewalAt = renewalAt; - } - @Override public String toString() { return "PhoneNumber{" + diff --git a/api/src/main/java/com/messagebird/objects/PurchasedNumbersResponse.java b/api/src/main/java/com/messagebird/objects/PurchasedNumbersResponse.java index a95e6741..b61928ca 100644 --- a/api/src/main/java/com/messagebird/objects/PurchasedNumbersResponse.java +++ b/api/src/main/java/com/messagebird/objects/PurchasedNumbersResponse.java @@ -29,30 +29,6 @@ public List getItems() { return items; } - public void setOffset(int offset) { - this.offset = offset; - } - - public void setLimit(int limit) { - this.limit = limit; - } - - public void setCount(int count) { - this.count = count; - } - - public void setTotalCount(int totalCount) { - this.totalCount = totalCount; - } - - public void setItems(List items) { - this.items = items; - } - - public void setItems(PurchasedNumber... items) { - this.items = List.of(items); - } - @Override public String toString() { return "PurchasedNumbersResponse{" + diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 750abbeb..08aa9bd8 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -776,7 +776,7 @@ public void testDeleteWebhook() throws NotFoundException, GeneralException, Unau @Test public void testListNumbersForPurchase() throws IllegalArgumentException, GeneralException, UnauthorizedException, NotFoundException { final String url = String.format("%s/v1/available-phone-numbers", NUMBERS_CALLS_BASE_URL); - final PhoneNumbersResponse mockedResponse = TestUtil.createPhoneNumbersResponseData(); + final PhoneNumbersResponse mockedResponse = new PhoneNumbersResponse(); MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); @@ -794,7 +794,7 @@ public void testListNumbersForPurchase() throws IllegalArgumentException, Genera @Test public void testListNumbersForPurchaseWithParams() throws IllegalArgumentException, GeneralException, UnauthorizedException, NotFoundException { final String url = String.format("%s/v1/available-phone-numbers", NUMBERS_CALLS_BASE_URL); - final PhoneNumbersResponse mockedResponse = TestUtil.createPhoneNumbersResponseDataWithParams(); + final PhoneNumbersResponse mockedResponse = new PhoneNumbersResponse(); MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); @@ -819,7 +819,7 @@ public void testListNumbersForPurchaseWithParams() throws IllegalArgumentExcepti public void testPurchaseNumber() throws UnauthorizedException, GeneralException { final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); - PurchasedNumberCreatedResponse purchasedNumberMockData = TestUtil.createPurchaseNumberResponse(); + PurchasedNumberCreatedResponse purchasedNumberMockData = new PurchasedNumberCreatedResponse(); MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); @@ -841,7 +841,7 @@ public void testPurchaseNumber() throws UnauthorizedException, GeneralException public void testListPurchasedNumbers() throws UnauthorizedException, GeneralException, NotFoundException { final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); - PurchasedNumbersResponse purchasedNumbersMockData = TestUtil.createPurchasedNumbersResponse(); + PurchasedNumbersResponse purchasedNumbersMockData = new PurchasedNumbersResponse(); MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); @@ -866,7 +866,7 @@ public void testListPurchasedNumbers() throws UnauthorizedException, GeneralExce public void testViewPurchasedNumber() throws UnauthorizedException, GeneralException, NotFoundException { final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); - PurchasedNumber purchasedNumberMockData = TestUtil.createPurchasedNumberResponse(); + PurchasedNumber purchasedNumberMockData = new PurchasedNumber(); MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); @@ -884,7 +884,7 @@ public void updatePurchasedNumber() throws UnauthorizedException, GeneralExcept final String phoneNumber = "15625267429"; final String url = String.format("%s/v1/phone-numbers/%s", NUMBERS_CALLS_BASE_URL, phoneNumber); - PurchasedNumber updatedNumberMock = TestUtil.createPurchasedNumberResponse(); + PurchasedNumber updatedNumberMock = new PurchasedNumber(); MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index fe9f3718..1ccca584 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -241,54 +241,4 @@ static ConversationWebhookCreateRequest createConversationWebhookRequest() { ); } - static PhoneNumbersResponse createPhoneNumbersResponseData() { - final PhoneNumber number = new PhoneNumber("31102005195", "NL", "", "Rotterdam", EnumSet.of(PhoneNumberFeature.VOICE), "unknown"); - final List numbers = List.of(number); - final PhoneNumbersResponse phoneNumbersResponseData = new PhoneNumbersResponse(); - phoneNumbersResponseData.setLimit(1); - phoneNumbersResponseData.setOffset(0); - phoneNumbersResponseData.setItems(numbers); - return phoneNumbersResponseData; - } - - static PhoneNumbersResponse createPhoneNumbersResponseDataWithParams() { - final PhoneNumber number = new PhoneNumber("15625267429", "US", "", "", EnumSet.of(PhoneNumberFeature.SMS, PhoneNumberFeature.MMS, PhoneNumberFeature.VOICE), "landline_or_mobile"); - final List numbers = List.of(number); - final PhoneNumbersResponse phoneNumbersResponseData = new PhoneNumbersResponse(); - phoneNumbersResponseData.setLimit(1); - phoneNumbersResponseData.setOffset(0); - phoneNumbersResponseData.setItems(numbers); - return phoneNumbersResponseData; - } - - static PurchasedNumberCreatedResponse createPurchaseNumberResponse() { - final PurchasedNumberCreatedResponse response = new PurchasedNumberCreatedResponse("15625267429", - "US", "", "", EnumSet.of(PhoneNumberFeature.SMS, PhoneNumberFeature.MMS, PhoneNumberFeature.VOICE), "landline_or_mobile"); - response.setCreatedAt(new Date()); - response.setRenewalAt(new Date()); - return response; - } - - static PurchasedNumbersResponse createPurchasedNumbersResponse() { - final PurchasedNumber number = new PurchasedNumber("15625267429", "US", - "", "", EnumSet.of(PhoneNumberFeature.SMS, PhoneNumberFeature.MMS, PhoneNumberFeature.VOICE), "landline_or_mobile"); - number.setTags("tag"); - number.setStatus("active"); - PurchasedNumbersResponse response = new PurchasedNumbersResponse(); - response.setItems(number); - response.setCount(1); - response.setLimit(1); - response.setTotalCount(1); - response.setOffset(0); - return response; - } - - static PurchasedNumber createPurchasedNumberResponse() { - final PurchasedNumber number = new PurchasedNumber("15625267429", "US", - "", "", EnumSet.of(PhoneNumberFeature.SMS, PhoneNumberFeature.MMS, PhoneNumberFeature.VOICE), "landline_or_mobile"); - number.setTags("tag"); - number.setStatus("active"); - return number; - } - } From a6210f6573a06cf678e81e118a089b6039ce1d1a Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Fri, 10 Jan 2020 13:28:38 +0100 Subject: [PATCH 130/516] rm --- api/src/test/java/com/messagebird/TestUtil.java | 1 - 1 file changed, 1 deletion(-) diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index 1ccca584..5a854b45 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -240,5 +240,4 @@ static ConversationWebhookCreateRequest createConversationWebhookRequest() { ) ); } - } From b67b843fdfbed2805d35642760852ed51818c1c3 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Fri, 10 Jan 2020 13:29:18 +0100 Subject: [PATCH 131/516] remove whitespace --- api/src/main/java/com/messagebird/objects/PurchasedNumber.java | 1 - 1 file changed, 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/objects/PurchasedNumber.java b/api/src/main/java/com/messagebird/objects/PurchasedNumber.java index 4ee60edf..fb07a686 100644 --- a/api/src/main/java/com/messagebird/objects/PurchasedNumber.java +++ b/api/src/main/java/com/messagebird/objects/PurchasedNumber.java @@ -3,7 +3,6 @@ import java.util.List; public class PurchasedNumber extends PhoneNumber { - private List tags; private String status; From 41bacb07845d6202eda6b7f52b04f9883bf7b6d8 Mon Sep 17 00:00:00 2001 From: Bernhard Breytenbach Date: Fri, 10 Jan 2020 14:03:48 +0100 Subject: [PATCH 132/516] Add type MMS to MsgType --- api/src/main/java/com/messagebird/objects/MsgType.java | 1 + 1 file changed, 1 insertion(+) diff --git a/api/src/main/java/com/messagebird/objects/MsgType.java b/api/src/main/java/com/messagebird/objects/MsgType.java index dc9af724..bfc421c8 100644 --- a/api/src/main/java/com/messagebird/objects/MsgType.java +++ b/api/src/main/java/com/messagebird/objects/MsgType.java @@ -7,6 +7,7 @@ */ public enum MsgType { sms("sms"), + mms("mms"), binary("binary"), premium("premium"), flash("flash"); From c2ae15ef8ef725345e910007e733ac7fb84612fa Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Mon, 13 Jan 2020 15:48:06 +0100 Subject: [PATCH 133/516] use explicit imports --- .../com/messagebird/MessageBirdClient.java | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 1ecc84f0..10c4af11 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -3,7 +3,33 @@ import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; -import com.messagebird.objects.*; +import com.messagebird.objects.Balance; +import com.messagebird.objects.Contact; +import com.messagebird.objects.ContactList; +import com.messagebird.objects.ContactRequest; +import com.messagebird.objects.ErrorReport; +import com.messagebird.objects.Group; +import com.messagebird.objects.GroupList; +import com.messagebird.objects.GroupRequest; +import com.messagebird.objects.Hlr; +import com.messagebird.objects.Lookup; +import com.messagebird.objects.LookupHlr; +import com.messagebird.objects.Message; +import com.messagebird.objects.MessageList; +import com.messagebird.objects.MessageResponse; +import com.messagebird.objects.MsgType; +import com.messagebird.objects.PagedPaging; +import com.messagebird.objects.PhoneNumbersLookup; +import com.messagebird.objects.PhoneNumbersResponse; +import com.messagebird.objects.PurchasedNumber; +import com.messagebird.objects.PurchasedNumberCreatedResponse; +import com.messagebird.objects.PurchasedNumbersResponse; +import com.messagebird.objects.PurchasedNumbersFilter; +import com.messagebird.objects.Verify; +import com.messagebird.objects.VerifyRequest; +import com.messagebird.objects.VoiceMessage; +import com.messagebird.objects.VoiceMessageList; +import com.messagebird.objects.VoiceMessageResponse; import com.messagebird.objects.conversations.Conversation; import com.messagebird.objects.conversations.ConversationList; import com.messagebird.objects.conversations.ConversationMessage; From 288d5a200f64e608c16aceafec05e171606e0ecc Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Mon, 13 Jan 2020 15:58:31 +0100 Subject: [PATCH 134/516] annotate methods --- .../com/messagebird/MessageBirdClient.java | 61 ++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 10c4af11..07fcc7cc 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1596,16 +1596,41 @@ private void verifyOffsetAndLimit(Integer offset, Integer limit) { } } - public PhoneNumbersResponse listNumbersForPurchase(String countryCode) throws IllegalArgumentException, GeneralException, UnauthorizedException, NotFoundException { + /** + * Lists Numbers that are available to purchase in a particular country code, without any filters. + * + * @param countryCode The country code in which the Number should be purchased. + * @throws GeneralException general exception + * @throws UnauthorizedException if client is unauthorized + * @throws NotFoundException if the resource is missing + */ + public PhoneNumbersResponse listNumbersForPurchase(String countryCode) throws GeneralException, UnauthorizedException, NotFoundException { final String url = String.format("%s/v1/available-phone-numbers", NUMBERS_CALLS_BASE_URL); return messageBirdService.requestByID(url, countryCode, PhoneNumbersResponse.class); } - public PhoneNumbersResponse listNumbersForPurchase(String countryCode, PhoneNumbersLookup params) throws IllegalArgumentException, GeneralException, UnauthorizedException, NotFoundException { + /** + * Lists Numbers that are available to purchase in a particular country code, according to specified search criteria. + * + * @param countryCode The country code in which the Number should be purchased. + * @param params Parameters to filter the resulting phone numbers returned. + * @throws GeneralException general exception + * @throws UnauthorizedException if client is unauthorized + * @throws NotFoundException if the resource is missing + */ + public PhoneNumbersResponse listNumbersForPurchase(String countryCode, PhoneNumbersLookup params) throws GeneralException, UnauthorizedException, NotFoundException { final String url = String.format("%s/v1/available-phone-numbers", NUMBERS_CALLS_BASE_URL); return messageBirdService.requestByID(url, countryCode, params.toHashMap(), PhoneNumbersResponse.class); } + /** + * Purchases a phone number. To be used in conjunction with listNumbersForPurchase to identify available numbers. + * + * @param number The number to purchase. + * @param countryCode The country code in which the Number should be purchased. + * @throws GeneralException general exception + * @throws UnauthorizedException if client is unauthorized + */ public PurchasedNumberCreatedResponse purchaseNumber(String number, String countryCode, int billingIntervalMonths) throws UnauthorizedException, GeneralException { final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); @@ -1617,16 +1642,40 @@ public PurchasedNumberCreatedResponse purchaseNumber(String number, String count return messageBirdService.sendPayLoad(url, payload, PurchasedNumberCreatedResponse.class); } + /** + * Lists Numbers that were purchased using the account credentials that the client was initialized with. + * + * @param filter Filters the list of purchased numbers according to search criteria. + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + * @throws NotFoundException if the resource is missing + */ public PurchasedNumbersResponse listPurchasedNumbers(PurchasedNumbersFilter filter) throws UnauthorizedException, GeneralException, NotFoundException { final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); return messageBirdService.requestByID(url, null, filter.toHashMap(), PurchasedNumbersResponse.class); } + /** + * Returns a Number that has already been purchased on the initialized account. + * + * @param number The number whose data should be returned. + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + * @throws NotFoundException if the Number is missing + */ public PurchasedNumber viewPurchasedNumber(String number) throws UnauthorizedException, GeneralException, NotFoundException { final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); return messageBirdService.requestByID(url, number, PurchasedNumber.class); } + /** + * Updates tags on a particular existing Number. Any number of parameters after the number can be given to apply multiple tags. + * + * @param number The number to update. + * @param tags A tag to apply to the number. + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + */ public PurchasedNumber updateNumber(String number, String... tags) throws UnauthorizedException, GeneralException { final String url = String.format("%s/v1/phone-numbers/%s", NUMBERS_CALLS_BASE_URL, number); final Map> payload = new HashMap>(); @@ -1634,6 +1683,14 @@ public PurchasedNumber updateNumber(String number, String... tags) throws Unauth return messageBirdService.sendPayLoad("PATCH", url, payload, PurchasedNumber.class); } + /** + * Cancels a particular number. + * + * @param nummber The number to cancel. + * @throws GeneralException general exception + * @throws UnauthorizedException if client is unauthorized + * @throws NotFoundException if the resource is missing + */ public void cancelNumber(String number) throws UnauthorizedException, GeneralException, NotFoundException { final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); messageBirdService.deleteByID(url, number); From 3e314dbc92f69ffd63ca2810320a7db63b9613b8 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Mon, 13 Jan 2020 16:01:13 +0100 Subject: [PATCH 135/516] update base URL --- .../java/com/messagebird/MessageBirdClient.java | 16 ++++++++-------- .../com/messagebird/MessageBirdClientTest.java | 14 +++++++------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 07fcc7cc..773d2742 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -94,7 +94,7 @@ public class MessageBirdClient { private static final String BASE_URL_CONVERSATIONS_WHATSAPP_SANDBOX = "https://whatsapp-sandbox.messagebird.com/v1"; static final String VOICE_CALLS_BASE_URL = "https://voice.messagebird.com"; - static final String NUMBERS_CALLS_BASE_URL = "https://numbers.messagebird.com"; + static final String NUMBERS_CALLS_BASE_URL = "https://numbers.messagebird.com/v1"; private static String[] supportedLanguages = {"de-DE", "en-AU", "en-UK", "en-US", "es-ES", "es-LA", "fr-FR", "it-IT", "nl-NL", "pt-BR"}; private static final String BALANCEPATH = "/balance"; @@ -1605,7 +1605,7 @@ private void verifyOffsetAndLimit(Integer offset, Integer limit) { * @throws NotFoundException if the resource is missing */ public PhoneNumbersResponse listNumbersForPurchase(String countryCode) throws GeneralException, UnauthorizedException, NotFoundException { - final String url = String.format("%s/v1/available-phone-numbers", NUMBERS_CALLS_BASE_URL); + final String url = String.format("%s/available-phone-numbers", NUMBERS_CALLS_BASE_URL); return messageBirdService.requestByID(url, countryCode, PhoneNumbersResponse.class); } @@ -1619,7 +1619,7 @@ public PhoneNumbersResponse listNumbersForPurchase(String countryCode) throws Ge * @throws NotFoundException if the resource is missing */ public PhoneNumbersResponse listNumbersForPurchase(String countryCode, PhoneNumbersLookup params) throws GeneralException, UnauthorizedException, NotFoundException { - final String url = String.format("%s/v1/available-phone-numbers", NUMBERS_CALLS_BASE_URL); + final String url = String.format("%s/available-phone-numbers", NUMBERS_CALLS_BASE_URL); return messageBirdService.requestByID(url, countryCode, params.toHashMap(), PhoneNumbersResponse.class); } @@ -1632,7 +1632,7 @@ public PhoneNumbersResponse listNumbersForPurchase(String countryCode, PhoneNumb * @throws UnauthorizedException if client is unauthorized */ public PurchasedNumberCreatedResponse purchaseNumber(String number, String countryCode, int billingIntervalMonths) throws UnauthorizedException, GeneralException { - final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); + final String url = String.format("%s/phone-numbers", NUMBERS_CALLS_BASE_URL); final Map payload = new LinkedHashMap(); payload.put("number", number); @@ -1651,7 +1651,7 @@ public PurchasedNumberCreatedResponse purchaseNumber(String number, String count * @throws NotFoundException if the resource is missing */ public PurchasedNumbersResponse listPurchasedNumbers(PurchasedNumbersFilter filter) throws UnauthorizedException, GeneralException, NotFoundException { - final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); + final String url = String.format("%s/phone-numbers", NUMBERS_CALLS_BASE_URL); return messageBirdService.requestByID(url, null, filter.toHashMap(), PurchasedNumbersResponse.class); } @@ -1664,7 +1664,7 @@ public PurchasedNumbersResponse listPurchasedNumbers(PurchasedNumbersFilter filt * @throws NotFoundException if the Number is missing */ public PurchasedNumber viewPurchasedNumber(String number) throws UnauthorizedException, GeneralException, NotFoundException { - final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); + final String url = String.format("%s/phone-numbers", NUMBERS_CALLS_BASE_URL); return messageBirdService.requestByID(url, number, PurchasedNumber.class); } @@ -1677,7 +1677,7 @@ public PurchasedNumber viewPurchasedNumber(String number) throws UnauthorizedExc * @throws GeneralException general exception */ public PurchasedNumber updateNumber(String number, String... tags) throws UnauthorizedException, GeneralException { - final String url = String.format("%s/v1/phone-numbers/%s", NUMBERS_CALLS_BASE_URL, number); + final String url = String.format("%s/phone-numbers/%s", NUMBERS_CALLS_BASE_URL, number); final Map> payload = new HashMap>(); payload.put("tags", Arrays.asList(tags)); return messageBirdService.sendPayLoad("PATCH", url, payload, PurchasedNumber.class); @@ -1692,7 +1692,7 @@ public PurchasedNumber updateNumber(String number, String... tags) throws Unauth * @throws NotFoundException if the resource is missing */ public void cancelNumber(String number) throws UnauthorizedException, GeneralException, NotFoundException { - final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); + final String url = String.format("%s/phone-numbers", NUMBERS_CALLS_BASE_URL); messageBirdService.deleteByID(url, number); } } \ No newline at end of file diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 08aa9bd8..f350af06 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -775,7 +775,7 @@ public void testDeleteWebhook() throws NotFoundException, GeneralException, Unau @Test public void testListNumbersForPurchase() throws IllegalArgumentException, GeneralException, UnauthorizedException, NotFoundException { - final String url = String.format("%s/v1/available-phone-numbers", NUMBERS_CALLS_BASE_URL); + final String url = String.format("%s/available-phone-numbers", NUMBERS_CALLS_BASE_URL); final PhoneNumbersResponse mockedResponse = new PhoneNumbersResponse(); MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); @@ -793,7 +793,7 @@ public void testListNumbersForPurchase() throws IllegalArgumentException, Genera @Test public void testListNumbersForPurchaseWithParams() throws IllegalArgumentException, GeneralException, UnauthorizedException, NotFoundException { - final String url = String.format("%s/v1/available-phone-numbers", NUMBERS_CALLS_BASE_URL); + final String url = String.format("%s/available-phone-numbers", NUMBERS_CALLS_BASE_URL); final PhoneNumbersResponse mockedResponse = new PhoneNumbersResponse(); MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); @@ -817,7 +817,7 @@ public void testListNumbersForPurchaseWithParams() throws IllegalArgumentExcepti @Test public void testPurchaseNumber() throws UnauthorizedException, GeneralException { - final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); + final String url = String.format("%s/phone-numbers", NUMBERS_CALLS_BASE_URL); PurchasedNumberCreatedResponse purchasedNumberMockData = new PurchasedNumberCreatedResponse(); @@ -839,7 +839,7 @@ public void testPurchaseNumber() throws UnauthorizedException, GeneralException @Test public void testListPurchasedNumbers() throws UnauthorizedException, GeneralException, NotFoundException { - final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); + final String url = String.format("%s/phone-numbers", NUMBERS_CALLS_BASE_URL); PurchasedNumbersResponse purchasedNumbersMockData = new PurchasedNumbersResponse(); @@ -864,7 +864,7 @@ public void testListPurchasedNumbers() throws UnauthorizedException, GeneralExce @Test public void testViewPurchasedNumber() throws UnauthorizedException, GeneralException, NotFoundException { - final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); + final String url = String.format("%s/phone-numbers", NUMBERS_CALLS_BASE_URL); PurchasedNumber purchasedNumberMockData = new PurchasedNumber(); @@ -882,7 +882,7 @@ public void testViewPurchasedNumber() throws UnauthorizedException, GeneralExce @Test public void updatePurchasedNumber() throws UnauthorizedException, GeneralException, NotFoundException { final String phoneNumber = "15625267429"; - final String url = String.format("%s/v1/phone-numbers/%s", NUMBERS_CALLS_BASE_URL, phoneNumber); + final String url = String.format("%s/phone-numbers/%s", NUMBERS_CALLS_BASE_URL, phoneNumber); PurchasedNumber updatedNumberMock = new PurchasedNumber(); @@ -903,7 +903,7 @@ public void updatePurchasedNumber() throws UnauthorizedException, GeneralExcept @Test public void deletePurchasedNumber() throws UnauthorizedException, GeneralException, NotFoundException { final String phoneNumber = "15625267429"; - final String url = String.format("%s/v1/phone-numbers", NUMBERS_CALLS_BASE_URL); + final String url = String.format("%s/phone-numbers", NUMBERS_CALLS_BASE_URL); MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); From 6e56c18e0451fda063e5bad57c396f60510eef58 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Mon, 13 Jan 2020 16:18:41 +0100 Subject: [PATCH 136/516] rm needless returns --- examples/src/main/java/ExampleListPurchasedNumbers.java | 1 - examples/src/main/java/ExamplePurchaseNumber.java | 1 - examples/src/main/java/ExampleViewPurchasedNumber.java | 1 - 3 files changed, 3 deletions(-) diff --git a/examples/src/main/java/ExampleListPurchasedNumbers.java b/examples/src/main/java/ExampleListPurchasedNumbers.java index 74010c96..4dbd0425 100644 --- a/examples/src/main/java/ExampleListPurchasedNumbers.java +++ b/examples/src/main/java/ExampleListPurchasedNumbers.java @@ -29,7 +29,6 @@ public static void main(String[] args) { try { System.out.println(messageBirdClient.listPurchasedNumbers(filter)); - return; } catch (UnauthorizedException | NotFoundException | GeneralException exception) { if (exception.getErrors() != null) { System.out.println(exception.getErrors().toString()); diff --git a/examples/src/main/java/ExamplePurchaseNumber.java b/examples/src/main/java/ExamplePurchaseNumber.java index b60bfb7e..3c71017c 100644 --- a/examples/src/main/java/ExamplePurchaseNumber.java +++ b/examples/src/main/java/ExamplePurchaseNumber.java @@ -21,7 +21,6 @@ public static void main(String[] args) { PurchasedNumberCreatedResponse purchasedNumberCreatedResponse = messageBirdClient.purchaseNumber(args[1], args[2], Integer.parseInt(args[3])); System.out.println(purchasedNumberCreatedResponse); - return; } catch (UnauthorizedException | GeneralException exception) { if (exception.getErrors() != null) { System.out.println(exception.getErrors().toString()); diff --git a/examples/src/main/java/ExampleViewPurchasedNumber.java b/examples/src/main/java/ExampleViewPurchasedNumber.java index 07c88cd2..34af8301 100644 --- a/examples/src/main/java/ExampleViewPurchasedNumber.java +++ b/examples/src/main/java/ExampleViewPurchasedNumber.java @@ -19,7 +19,6 @@ public static void main(String[] args) { try { System.out.println(messageBirdClient.viewPurchasedNumber(args[1])); - return; } catch (UnauthorizedException | NotFoundException | GeneralException exception) { if (exception.getErrors() != null) { System.out.println(exception.getErrors().toString()); From 79a81d4174f4081538da0f92af1b094e3e6cb501 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Mon, 13 Jan 2020 16:26:49 +0100 Subject: [PATCH 137/516] use singleton list --- api/src/test/java/com/messagebird/MessageBirdClientTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index f350af06..64deb9f2 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -890,7 +890,7 @@ public void updatePurchasedNumber() throws UnauthorizedException, GeneralExcept MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); final Map> payload = new HashMap>(); - payload.put("tags", Arrays.asList("tag")); + payload.put("tags", Collections.singletonList("tag")); when(messageBirdServiceMock.sendPayLoad("PATCH", url, payload, PurchasedNumber.class)) .thenReturn(updatedNumberMock); From 5f0f63dd4e8ef126613ccdc82b2b5d82556614bb Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Mon, 13 Jan 2020 16:26:59 +0100 Subject: [PATCH 138/516] remove unused imports --- .../test/java/com/messagebird/PurchasedNumbersFilterTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/api/src/test/java/com/messagebird/PurchasedNumbersFilterTest.java b/api/src/test/java/com/messagebird/PurchasedNumbersFilterTest.java index 2d9cef72..0a70c9ba 100644 --- a/api/src/test/java/com/messagebird/PurchasedNumbersFilterTest.java +++ b/api/src/test/java/com/messagebird/PurchasedNumbersFilterTest.java @@ -1,11 +1,9 @@ package com.messagebird; import com.messagebird.exceptions.GeneralException; -import com.messagebird.exceptions.UnauthorizedException; import com.messagebird.objects.*; import org.junit.Test; -import java.lang.reflect.Array; import java.util.*; import static org.junit.Assert.*; From e1103dee5cb98cf991f95905fc5fc6218639d16f Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Mon, 13 Jan 2020 16:29:15 +0100 Subject: [PATCH 139/516] correct annotation --- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index d42ef4d1..3c8a2da9 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -620,8 +620,8 @@ private void saveClose(final InputStream is) { /** * Encodes a key/value pair with percent encoding. * - * @param String key - * @param Object value + * @param key the key name to be used + * @param value the value to be assigned to that key * @return String */ private String encodeKeyValuePair(String key, Object value) throws UnsupportedEncodingException { From a63346530cbbb57ab105849c3bae092bec13fa61 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Mon, 13 Jan 2020 16:31:52 +0100 Subject: [PATCH 140/516] use addAll method --- .../java/com/messagebird/objects/PurchasedNumbersFilter.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java b/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java index 59eabd72..21bd670e 100644 --- a/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java +++ b/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java @@ -5,6 +5,7 @@ import java.io.Serializable; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; @@ -39,9 +40,7 @@ public EnumSet getFeatures() { } public void addFeature(PhoneNumberFeature... features) { - for (PhoneNumberFeature feature: features) { - this.features.add(feature); - } + Collections.addAll(this.features, features); } public void removeFeature(PhoneNumberFeature... features) { From 3bfab36dce728fd43879f2c497f9551070b21322 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Mon, 13 Jan 2020 16:32:19 +0100 Subject: [PATCH 141/516] remove unused import --- .../com/messagebird/objects/PurchasedNumberCreatedResponse.java | 1 - 1 file changed, 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/objects/PurchasedNumberCreatedResponse.java b/api/src/main/java/com/messagebird/objects/PurchasedNumberCreatedResponse.java index 0b4b6bdb..8922db2e 100644 --- a/api/src/main/java/com/messagebird/objects/PurchasedNumberCreatedResponse.java +++ b/api/src/main/java/com/messagebird/objects/PurchasedNumberCreatedResponse.java @@ -1,7 +1,6 @@ package com.messagebird.objects; import java.util.Date; -import java.util.EnumSet; public class PurchasedNumberCreatedResponse extends PurchasedNumber { private Date createdAt; From 2d48650ae87ab6edcd1d1e96d34fb8096ead0dba Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Mon, 13 Jan 2020 17:32:41 +0100 Subject: [PATCH 142/516] simplify example --- examples/src/main/java/ExampleListNumbersForPurchase.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/src/main/java/ExampleListNumbersForPurchase.java b/examples/src/main/java/ExampleListNumbersForPurchase.java index 96766f2a..6c289b5a 100644 --- a/examples/src/main/java/ExampleListNumbersForPurchase.java +++ b/examples/src/main/java/ExampleListNumbersForPurchase.java @@ -11,8 +11,8 @@ public class ExampleListNumbersForPurchase { public static void main(String[] args) { - if (args.length < 1) { - System.out.println("Please specify your access key."); + if (args.length < 2) { + System.out.println("Please specify your access key and a country code to test."); return; } // First create your service object @@ -22,7 +22,7 @@ public static void main(String[] args) { final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); try { - if (args.length > 1) { + if (args.length > 2) { PhoneNumbersLookup options = new PhoneNumbersLookup(); options.setFeatures(PhoneNumberFeature.VOICE, PhoneNumberFeature.SMS); options.setType(PhoneNumberType.MOBILE); @@ -32,7 +32,7 @@ public static void main(String[] args) { System.out.print(options.toString()); System.out.println(String.format("Request Made With Params: %s", messageBirdClient.listNumbersForPurchase("US", options))); } else { - System.out.println(String.format("Request Made Without Params: %s", messageBirdClient.listNumbersForPurchase("NL"))); + System.out.println(String.format("Request Made Without Params: %s", messageBirdClient.listNumbersForPurchase(args[1]))); } } catch (UnauthorizedException | GeneralException | NotFoundException exception) { if (exception.getErrors() != null) { From 6065a9a49e846adc73883e5e36dfa85455d90de2 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Mon, 13 Jan 2020 17:32:47 +0100 Subject: [PATCH 143/516] remove filters --- examples/src/main/java/ExampleListPurchasedNumbers.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/examples/src/main/java/ExampleListPurchasedNumbers.java b/examples/src/main/java/ExampleListPurchasedNumbers.java index 4dbd0425..a065ba88 100644 --- a/examples/src/main/java/ExampleListPurchasedNumbers.java +++ b/examples/src/main/java/ExampleListPurchasedNumbers.java @@ -5,7 +5,6 @@ import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; import com.messagebird.objects.PhoneNumberFeature; -import com.messagebird.objects.PhoneNumberType; import com.messagebird.objects.PurchasedNumbersFilter; public class ExampleListPurchasedNumbers { @@ -15,16 +14,12 @@ public static void main(String[] args) { return; } // First create your service object - final MessageBirdService wsr = new MessageBirdServiceImpl(args[0], "https://numbers.messagebird.com"); + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); // Add the service to the client final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); PurchasedNumbersFilter filter = new PurchasedNumbersFilter(); - - filter.addFeature(PhoneNumberFeature.SMS); - filter.setType(PhoneNumberType.MOBILE); - filter.setLimit(25); try { From 6b29856f31d5046f779b0777082aa1ba7f8a5e98 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Mon, 13 Jan 2020 17:33:35 +0100 Subject: [PATCH 144/516] validate parameters --- .../com/messagebird/MessageBirdClient.java | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 773d2742..dedc97e3 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -64,6 +64,7 @@ import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; +import java.util.Locale; import java.util.Map; /** @@ -1596,6 +1597,20 @@ private void verifyOffsetAndLimit(Integer offset, Integer limit) { } } + /** + * Checks whether a particular country code is a recognized ISO Country. + * + * @param countryCode The country code in which the Number should be purchased. + * @throws IllegalArgumentException + */ + private Boolean countryCodeIsValid(String countryCode) throws IllegalArgumentException { + final Boolean isValid = Arrays.asList(Locale.getISOCountries()).contains(countryCode); + if (!isValid) { + throw new IllegalArgumentException("Invalid Country Code Provided."); + } + return true; + } + /** * Lists Numbers that are available to purchase in a particular country code, without any filters. * @@ -1603,8 +1618,10 @@ private void verifyOffsetAndLimit(Integer offset, Integer limit) { * @throws GeneralException general exception * @throws UnauthorizedException if client is unauthorized * @throws NotFoundException if the resource is missing + * @throws IllegalArgumentException if the country code provided is invalid */ - public PhoneNumbersResponse listNumbersForPurchase(String countryCode) throws GeneralException, UnauthorizedException, NotFoundException { + public PhoneNumbersResponse listNumbersForPurchase(String countryCode) throws GeneralException, UnauthorizedException, NotFoundException, IllegalArgumentException { + countryCodeIsValid(countryCode); final String url = String.format("%s/available-phone-numbers", NUMBERS_CALLS_BASE_URL); return messageBirdService.requestByID(url, countryCode, PhoneNumbersResponse.class); } @@ -1617,8 +1634,10 @@ public PhoneNumbersResponse listNumbersForPurchase(String countryCode) throws Ge * @throws GeneralException general exception * @throws UnauthorizedException if client is unauthorized * @throws NotFoundException if the resource is missing + * @throws IllegalArgumentException if the country code provided is invalid */ - public PhoneNumbersResponse listNumbersForPurchase(String countryCode, PhoneNumbersLookup params) throws GeneralException, UnauthorizedException, NotFoundException { + public PhoneNumbersResponse listNumbersForPurchase(String countryCode, PhoneNumbersLookup params) throws GeneralException, UnauthorizedException, NotFoundException, IllegalArgumentException { + countryCodeIsValid(countryCode); final String url = String.format("%s/available-phone-numbers", NUMBERS_CALLS_BASE_URL); return messageBirdService.requestByID(url, countryCode, params.toHashMap(), PhoneNumbersResponse.class); } @@ -1630,13 +1649,17 @@ public PhoneNumbersResponse listNumbersForPurchase(String countryCode, PhoneNumb * @param countryCode The country code in which the Number should be purchased. * @throws GeneralException general exception * @throws UnauthorizedException if client is unauthorized + * @throws IllegalArgumentException if the country code provided is invalid */ - public PurchasedNumberCreatedResponse purchaseNumber(String number, String countryCode, int billingIntervalMonths) throws UnauthorizedException, GeneralException { + public PurchasedNumberCreatedResponse purchaseNumber(String number, String countryCode, int billingIntervalMonths) throws UnauthorizedException, GeneralException, IllegalArgumentException { + countryCodeIsValid(countryCode); final String url = String.format("%s/phone-numbers", NUMBERS_CALLS_BASE_URL); - final Map payload = new LinkedHashMap(); payload.put("number", number); payload.put("countryCode", countryCode); + if (!Arrays.asList(1, 3, 6, 9).contains(billingIntervalMonths)) { + throw new IllegalArgumentException("Billing Interval Must Be Either 1, 3, 6, or 9."); + } payload.put("billingIntervalMonths", billingIntervalMonths); return messageBirdService.sendPayLoad(url, payload, PurchasedNumberCreatedResponse.class); From 2ef8df95731501bdc0c5d833c1b78c3808675765 Mon Sep 17 00:00:00 2001 From: Ben Sweeney Date: Mon, 13 Jan 2020 17:45:32 +0100 Subject: [PATCH 145/516] remove exception --- api/src/test/java/com/messagebird/MessageBirdClientTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 64deb9f2..a3d99cab 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -880,7 +880,7 @@ public void testViewPurchasedNumber() throws UnauthorizedException, GeneralExce } @Test - public void updatePurchasedNumber() throws UnauthorizedException, GeneralException, NotFoundException { + public void updatePurchasedNumber() throws UnauthorizedException, GeneralException { final String phoneNumber = "15625267429"; final String url = String.format("%s/phone-numbers/%s", NUMBERS_CALLS_BASE_URL, phoneNumber); From a91829e75ff4f0bf9fe40d79a77b9e4205c93fcc Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 14 Jan 2020 14:21:00 +0100 Subject: [PATCH 146/516] returned void in countryCodeIsValid --- api/src/main/java/com/messagebird/MessageBirdClient.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index dedc97e3..1d845555 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1601,14 +1601,13 @@ private void verifyOffsetAndLimit(Integer offset, Integer limit) { * Checks whether a particular country code is a recognized ISO Country. * * @param countryCode The country code in which the Number should be purchased. - * @throws IllegalArgumentException + * @throws IllegalArgumentException for invalid country code */ - private Boolean countryCodeIsValid(String countryCode) throws IllegalArgumentException { - final Boolean isValid = Arrays.asList(Locale.getISOCountries()).contains(countryCode); + private void countryCodeIsValid(String countryCode) throws IllegalArgumentException { + final boolean isValid = Arrays.asList(Locale.getISOCountries()).contains(countryCode); if (!isValid) { throw new IllegalArgumentException("Invalid Country Code Provided."); } - return true; } /** @@ -1709,7 +1708,7 @@ public PurchasedNumber updateNumber(String number, String... tags) throws Unauth /** * Cancels a particular number. * - * @param nummber The number to cancel. + * @param number The number to cancel. * @throws GeneralException general exception * @throws UnauthorizedException if client is unauthorized * @throws NotFoundException if the resource is missing From 031fa7482b2458469e13157e7b7d04107bdc975c Mon Sep 17 00:00:00 2001 From: Bernhard Breytenbach Date: Tue, 14 Jan 2020 13:36:55 +0100 Subject: [PATCH 147/516] Bugfix: #87 Webhook URL and Token not set correctly --- .../objects/voicecalls/VoiceCall.java | 37 ++++++++++++++----- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCall.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCall.java index ea7bff21..8ece36ec 100644 --- a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCall.java +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCall.java @@ -1,5 +1,6 @@ package com.messagebird.objects.voicecalls; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.messagebird.objects.MessageBase; import java.io.Serializable; @@ -12,9 +13,7 @@ public class VoiceCall implements MessageBase, Serializable { private String source; private String destination; private VoiceCallFlow callFlow; - - private String webhookUrl; - private String webhookToken; + private Webhook webhook = new Webhook(); @Override public String getBody() { @@ -60,20 +59,41 @@ public void setCallFlow(VoiceCallFlow callFlow) { this.callFlow = callFlow; } + public Webhook getWebhook() { + return webhook; + } + + public void setWebhook(String url) { + this.setWebhook(url, null); + } + + public void setWebhook(String url, String token) { + this.webhook.setUrl(url); + this.webhook.setToken(token); + } + + @JsonIgnore + @Deprecated public String getWebhookUrl() { - return webhookUrl; + return webhook.getUrl(); } + @JsonIgnore + @Deprecated public void setWebhookUrl(String webhookUrl) { - this.webhookUrl = webhookUrl; + this.webhook.setUrl(webhookUrl); } + @JsonIgnore + @Deprecated public String getWebhookToken() { - return webhookToken; + return webhook.getToken(); } + @JsonIgnore + @Deprecated public void setWebhookToken(String webhookToken) { - this.webhookToken = webhookToken; + this.webhook.setToken(webhookToken); } @Override @@ -82,8 +102,7 @@ public String toString() { "source='" + source + '\'' + ", destination='" + destination + '\'' + ", callFlow=" + callFlow + - ", webhookUrl='" + webhookUrl + '\'' + - ", webhookToken='" + webhookToken + '\'' + + ", webhook=" + webhook + '}'; } } From 60fa27af79ae34645e7bbad97c4cfc1e60636e24 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 14 Jan 2020 14:43:47 +0100 Subject: [PATCH 148/516] added auto in datacodingtype --- api/src/main/java/com/messagebird/objects/DataCodingType.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/objects/DataCodingType.java b/api/src/main/java/com/messagebird/objects/DataCodingType.java index 986cea4a..3f78d21d 100644 --- a/api/src/main/java/com/messagebird/objects/DataCodingType.java +++ b/api/src/main/java/com/messagebird/objects/DataCodingType.java @@ -7,7 +7,8 @@ */ public enum DataCodingType { plain("plain"), - unicode("unicode"); + unicode("unicode"), + auto("auto"); final String value; From 909cf8b7a1568ae20853581d6a57acea35353bc4 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 14 Jan 2020 15:02:54 +0100 Subject: [PATCH 149/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index a4a60174..f9fed4e5 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.6 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 3c8a2da9..1e6faa11 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -61,7 +61,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.0.6"; + private final String clientVersion = "3.0.7"; private final String userAgentString; private Proxy proxy = null; From 47603f70e6ddc8a9266340f06489be5597afc3d9 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 14 Jan 2020 15:03:40 +0100 Subject: [PATCH 150/516] updated pom --- examples/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/pom.xml b/examples/pom.xml index 59e90252..fa3009d8 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.6 + 3.0.7 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.6 + 3.0.7 compile From 300b671eb4610730c95d3bb73423082d7449d27c Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 14 Jan 2020 15:06:06 +0100 Subject: [PATCH 151/516] [maven-release-plugin] prepare release v3.0.7 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index f9fed4e5..4f71a62f 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.7-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.0.7 From cced820b3c7f96cf8749d5d73348642a2c84e1f3 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 14 Jan 2020 15:06:14 +0100 Subject: [PATCH 152/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 4f71a62f..47d8de51 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.7 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.0.7 + HEAD From 4abc2c6f3511adb615cecde3471c29f06721e4c7 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 14 Jan 2020 16:43:42 +0100 Subject: [PATCH 153/516] updated version --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 47d8de51..919b15d5 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.8-SNAPSHOT From 6f73a458c78f36779a41fd047c1db27141edc191 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Sun, 19 Jan 2020 13:04:38 +0100 Subject: [PATCH 154/516] added message field --- .../com/messagebird/objects/ErrorReport.java | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/ErrorReport.java b/api/src/main/java/com/messagebird/objects/ErrorReport.java index 00c74aa9..e5665dbe 100644 --- a/api/src/main/java/com/messagebird/objects/ErrorReport.java +++ b/api/src/main/java/com/messagebird/objects/ErrorReport.java @@ -1,32 +1,40 @@ package com.messagebird.objects; +import com.fasterxml.jackson.annotation.JsonInclude; /** * When MessageBird returns a 4xx, you will find a list of any error codes in your return dataset. * you will receive a list of errors from the API in such case. * * Created by rvt on 1/5/15. */ +@JsonInclude(JsonInclude.Include.NON_EMPTY) public class ErrorReport { private Integer code; private String description; private String parameter; + private String message; public ErrorReport() { } - public ErrorReport(Integer code, String description, String parameter) { + public ErrorReport(Integer code, String description, String parameter, String message) { this.code = code; this.description = description; this.parameter = parameter; + this.message = message; } @Override public String toString() { - return "ErrorReport{" + - "code=" + code + - ", description='" + description + '\'' + - ", parameter='" + parameter + '\'' + - '}'; + String str = "ErrorReport{code=" + code; + if (message != null) { + str = str.concat(", message='" + message + "'"); + } else { + str = str.concat(", description=''" + description + "'"); + str = str.concat(", parameter='" + parameter + "'"); + } + str = str.concat("}"); + return str; } /** @@ -53,4 +61,11 @@ public String getParameter() { return parameter; } + /** + * message not null for only voice API response + * @return + */ + public String getMessage() { + return message; + } } From 9f01d3d767890510a0768480e97ab7f55663e74f Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Sun, 19 Jan 2020 13:12:06 +0100 Subject: [PATCH 155/516] fixing typo --- api/src/main/java/com/messagebird/objects/ErrorReport.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/objects/ErrorReport.java b/api/src/main/java/com/messagebird/objects/ErrorReport.java index e5665dbe..d538dd5d 100644 --- a/api/src/main/java/com/messagebird/objects/ErrorReport.java +++ b/api/src/main/java/com/messagebird/objects/ErrorReport.java @@ -30,7 +30,7 @@ public String toString() { if (message != null) { str = str.concat(", message='" + message + "'"); } else { - str = str.concat(", description=''" + description + "'"); + str = str.concat(", description='" + description + "'"); str = str.concat(", parameter='" + parameter + "'"); } str = str.concat("}"); From 768fe954ac7677d078891e6834f98804f933b82a Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Sun, 19 Jan 2020 13:21:38 +0100 Subject: [PATCH 156/516] fixed after review --- api/src/main/java/com/messagebird/objects/ErrorReport.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/objects/ErrorReport.java b/api/src/main/java/com/messagebird/objects/ErrorReport.java index d538dd5d..d0d63d5a 100644 --- a/api/src/main/java/com/messagebird/objects/ErrorReport.java +++ b/api/src/main/java/com/messagebird/objects/ErrorReport.java @@ -27,7 +27,7 @@ public ErrorReport(Integer code, String description, String parameter, String me @Override public String toString() { String str = "ErrorReport{code=" + code; - if (message != null) { + if (message != null && !message.isEmpty()) { str = str.concat(", message='" + message + "'"); } else { str = str.concat(", description='" + description + "'"); From 15d237a25585bbea17cbc0eff6124e4f8d1b7541 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 20 Jan 2020 18:35:02 +0100 Subject: [PATCH 157/516] updated version --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 919b15d5..47d8de51 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.7 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 1e6faa11..e909a080 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -61,7 +61,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.0.7"; + private final String clientVersion = "3.0.8"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index fa3009d8..733a1b35 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.7 + 3.0.8 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.7 + 3.0.8 compile From 25d13c5836574712d2f408cdaa8764414cfc2946 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 20 Jan 2020 18:36:25 +0100 Subject: [PATCH 158/516] [maven-release-plugin] prepare release v3.0.8 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 47d8de51..d9081cd1 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.8-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.0.8 From 5c92f98ba10006a149074a14e96321baac43a1c9 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 20 Jan 2020 18:36:34 +0100 Subject: [PATCH 159/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index d9081cd1..25a0d8b6 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.8 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.0.8 + HEAD From 9520405314f80cf9f6c4514464ebf8535779d915 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 21 Jan 2020 07:37:29 +0100 Subject: [PATCH 160/516] updated version --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 25a0d8b6..c0a542f6 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.9-SNAPSHOT From d70c6c5f87556c7a92311ff73fd6377ea6719500 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 14 Feb 2020 11:04:43 +0100 Subject: [PATCH 161/516] updated voice call status --- .../com/messagebird/objects/voicecalls/VoiceCallStatus.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallStatus.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallStatus.java index e46c32d9..6806b8e7 100644 --- a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallStatus.java +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallStatus.java @@ -5,7 +5,10 @@ public enum VoiceCallStatus { queued("queued"), starting("starting"), ongoing("ongoing"), - ended("ended"); + ended("ended"), + failed("failed"), + busy("busy"), + no_answer("no_answer"); final String value; From 018c9ef796e02764d1c9c90bd5517143c9b79685 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 14 Feb 2020 11:38:19 +0100 Subject: [PATCH 162/516] new version --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index c0a542f6..25a0d8b6 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.8 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index e909a080..091277b0 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -61,7 +61,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.0.8"; + private final String clientVersion = "3.0.9"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 733a1b35..b2e9094f 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.8 + 3.0.9 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.8 + 3.0.9 compile From 747ef88fac032f81212c809ee2a7e576ab78608f Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 14 Feb 2020 11:40:03 +0100 Subject: [PATCH 163/516] [maven-release-plugin] prepare release v3.0.9 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 25a0d8b6..39095ee0 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.9-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.0.9 From 2e96531981bae2fc43a4fda63cd3c77652fc1254 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 14 Feb 2020 11:40:11 +0100 Subject: [PATCH 164/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 39095ee0..a6005097 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.9 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.0.9 + HEAD From 295964a8ef5a74a6410fe368132ea6dbe6d0d26f Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 14 Feb 2020 14:52:14 +0100 Subject: [PATCH 165/516] updated --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index a6005097..858e8dbd 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.10-SNAPSHOT From a4c5a6ec926c82ce1e31bd90a21a4c34d0b5519a Mon Sep 17 00:00:00 2001 From: cemturker Date: Sun, 1 Mar 2020 23:40:44 +0100 Subject: [PATCH 166/516] Support java version 1.8 --- api/pom.xml | 9 ++++++--- .../objects/PurchasedNumbersFilter.java | 16 +++++++--------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 858e8dbd..6160988d 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -67,7 +67,7 @@ disable-doclint - [11,) + [1.8,11,) none @@ -149,6 +149,9 @@ + + none + @@ -177,8 +180,8 @@ maven-compiler-plugin 3.7.0 - 11 - 11 + 1.8 + 1.8 diff --git a/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java b/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java index 21bd670e..40c6dcd9 100644 --- a/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java +++ b/api/src/main/java/com/messagebird/objects/PurchasedNumbersFilter.java @@ -106,16 +106,14 @@ public void setType(PhoneNumberType type) { public HashMap toHashMap() throws GeneralException { final HashMap map = new HashMap(); for (Field f: getClass().getDeclaredFields()) { - if (f.canAccess(this)) { - try { - Object value = f.get(this); - String key = f.getName(); - if (value != null) { - map.put(key, value); - } - } catch (IllegalAccessException exception) { - throw new GeneralException("Error converting to HashMap."); + try { + Object value = f.get(this); + String key = f.getName(); + if (value != null) { + map.put(key, value); } + } catch (IllegalAccessException exception) { + throw new GeneralException("Error converting to HashMap."); } } return map; From 3a4e3f9d357c16da1788d28a1172c2256da4a69d Mon Sep 17 00:00:00 2001 From: cemturker Date: Sun, 1 Mar 2020 23:42:54 +0100 Subject: [PATCH 167/516] Support java version 1.8 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index c71a5afe..9e3235b4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,3 +5,4 @@ script: mvn test -Ptest -DskipTests=false -Dhttps.protocols=TLSv1.2 -DmessageBir jdk: - oraclejdk11 - openjdk11 + - openjdk8 From 2cf73db9649415d529e48294118d4d0f42fd36a6 Mon Sep 17 00:00:00 2001 From: cemturker Date: Mon, 2 Mar 2020 11:18:21 +0100 Subject: [PATCH 168/516] Support java version 1.8 --- examples/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/pom.xml b/examples/pom.xml index b2e9094f..ab8d5346 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -50,8 +50,8 @@ maven-compiler-plugin 3.1 - 11 - 11 + 1.8 + 1.8 From d18aa09b10b87473fb15832a6911fcdc88054b8c Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 2 Mar 2020 13:07:14 +0100 Subject: [PATCH 169/516] updated a new version --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 6160988d..b226e8cc 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.9 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 091277b0..686f1e2e 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -61,7 +61,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.0.9"; + private final String clientVersion = "3.0.10"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index ab8d5346..44fb0fdc 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.9 + 3.0.10 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.9 + 3.0.10 compile From 131e919e4f111554b65f37895a42dbf778d0046a Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 2 Mar 2020 13:38:29 +0100 Subject: [PATCH 170/516] updated --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index b226e8cc..19d36bf2 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -67,7 +67,7 @@ disable-doclint - [1.8,11,) + [8,11,) none From d35f12ff82bf0d000411eb306752fa9b30c3de86 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 2 Mar 2020 17:02:58 +0100 Subject: [PATCH 171/516] [maven-release-plugin] prepare release v3.0.10 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 19d36bf2..7df21b2c 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.10-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.0.10 From 46a22eaf61393f6477700d4980da910274652fba Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 2 Mar 2020 17:03:06 +0100 Subject: [PATCH 172/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 7df21b2c..c1d02a47 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.10 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.0.10 + HEAD From 5d878e80ed9b14c145d5470e51548bd891ca2b2f Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 3 Mar 2020 12:54:55 +0100 Subject: [PATCH 173/516] updated pom --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index c1d02a47..dbe144a6 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.11-SNAPSHOT From f14c506eab5ddf33df0f54f2293fb27a99a4245b Mon Sep 17 00:00:00 2001 From: Andrey Romancev Date: Tue, 3 Mar 2020 15:33:28 +0100 Subject: [PATCH 174/516] Add listScheduledMessages method --- .../java/com/messagebird/MessageBirdClient.java | 9 +++++++++ .../java/com/messagebird/MessageBirdService.java | 16 ++++++++++++++++ .../com/messagebird/MessageBirdServiceImpl.java | 11 +++++++++++ .../com/messagebird/MessageBirdClientTest.java | 9 +++++++++ 4 files changed, 45 insertions(+) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 1d845555..96855ea4 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -118,6 +118,8 @@ public class MessageBirdClient { static final String VOICECALLFLOWPATH = "/call-flows"; private static final String VOICELEGS_SUFFIX_PATH = "/legs"; static final String RECORDING_DOWNLOAD_FORMAT = ".wav"; + private static final String MESSAGE_STATUS = "status"; + private static final String MESSAGE_STATUS_SCHEDULED = "scheduled"; static final String TRANSCRIPTION_DOWNLOAD_FORMAT = ".txt"; @@ -284,6 +286,13 @@ public MessageList listMessages(final Integer offset, final Integer limit) throw return messageBirdService.requestList(MESSAGESPATH, offset, limit, MessageList.class); } + public MessageList listScheduledMessages(final Integer offset, final Integer limit) throws UnauthorizedException, GeneralException { + verifyOffsetAndLimit(offset, limit); + Map params = new LinkedHashMap<>(); + params.put(MESSAGE_STATUS, MESSAGE_STATUS_SCHEDULED); + return messageBirdService.requestList(MESSAGESPATH, params, offset, limit, MessageList.class); + } + /** * Delete a message from the Messagebird server * diff --git a/api/src/main/java/com/messagebird/MessageBirdService.java b/api/src/main/java/com/messagebird/MessageBirdService.java index c100da10..68cf1f56 100644 --- a/api/src/main/java/com/messagebird/MessageBirdService.java +++ b/api/src/main/java/com/messagebird/MessageBirdService.java @@ -51,6 +51,22 @@ public interface MessageBirdService { */ R requestList(String request, Integer offset, Integer limit, Class clazz) throws UnauthorizedException, GeneralException; + /** + * Request a List 'of' object. + * Allow to request a listMessage or listViewMessages objects. + * @see com.messagebird.objects.MessageList + * + * @param request request from client + * @param params additional query params + * @param offset offset of data to return + * @param limit limit number of objects, incase you notice you pass in '1' a lot, please consider using requestByID if you know the ID of the message + * @param clazz object type to return + * @return base class + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + */ + R requestList(String request, Map params, Integer offset, Integer limit, Class clazz) throws UnauthorizedException, GeneralException; + /** * Request a List 'of' object. * Allow to request a listMessage or listViewMessages objects. diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 091277b0..4cc6c7a9 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -137,6 +137,17 @@ public R requestList(String request, Integer offset, Integer limit, Class } } + @Override + public R requestList(String request, Map params, Integer offset, Integer limit, Class clazz) throws UnauthorizedException, GeneralException { + if (offset != null) params.put("offset", String.valueOf(offset)); + if (limit != null) params.put("limit", String.valueOf(limit)); + try { + return getJsonData(request + "?" + getPathVariables(params), null, "GET", clazz); + } catch (NotFoundException e) { + throw new GeneralException(e); + } + } + @Override public R requestList(String request, PagedPaging pagedPaging, Class clazz) throws UnauthorizedException, GeneralException { Map map = new LinkedHashMap<>(); diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index a3d99cab..57c4e56e 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -108,6 +108,15 @@ public void testDeleteMessage() throws Exception { messageBirdClient.deleteMessage("Foo"); } + @Test + public void testListScheduledMessages() throws Exception { + final MessageList list = messageBirdClient.listScheduledMessages(null, null); + assertNotNull(list.getOffset()); + assertNotNull(list.getLinks()); + assertNotNull(list.getTotalCount()); + assertNotNull(list.getLinks()); + } + /*********************************************************************/ /** Test message system **/ /*********************************************************************/ From fda9d52c1dfc4f8abb966fda7ea10514c305e7a9 Mon Sep 17 00:00:00 2001 From: Andrey Romancev Date: Tue, 3 Mar 2020 16:34:03 +0100 Subject: [PATCH 175/516] Replace listScheduledMessages with a broader listMessagesFiltered with custom filters. --- .../main/java/com/messagebird/MessageBirdClient.java | 10 +++------- .../java/com/messagebird/MessageBirdClientTest.java | 4 +++- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 96855ea4..fe8e9140 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -118,9 +118,7 @@ public class MessageBirdClient { static final String VOICECALLFLOWPATH = "/call-flows"; private static final String VOICELEGS_SUFFIX_PATH = "/legs"; static final String RECORDING_DOWNLOAD_FORMAT = ".wav"; - private static final String MESSAGE_STATUS = "status"; - private static final String MESSAGE_STATUS_SCHEDULED = "scheduled"; - + static final String TRANSCRIPTION_DOWNLOAD_FORMAT = ".txt"; private static final int DEFAULT_MACHINE_TIMEOUT_VALUE = 7000; @@ -286,11 +284,9 @@ public MessageList listMessages(final Integer offset, final Integer limit) throw return messageBirdService.requestList(MESSAGESPATH, offset, limit, MessageList.class); } - public MessageList listScheduledMessages(final Integer offset, final Integer limit) throws UnauthorizedException, GeneralException { + public MessageList listMessagesFiltered(final Integer offset, final Integer limit, final Map filters) throws UnauthorizedException, GeneralException { verifyOffsetAndLimit(offset, limit); - Map params = new LinkedHashMap<>(); - params.put(MESSAGE_STATUS, MESSAGE_STATUS_SCHEDULED); - return messageBirdService.requestList(MESSAGESPATH, params, offset, limit, MessageList.class); + return messageBirdService.requestList(MESSAGESPATH, filters, offset, limit, MessageList.class); } /** diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 57c4e56e..0fef3c39 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -110,7 +110,9 @@ public void testDeleteMessage() throws Exception { @Test public void testListScheduledMessages() throws Exception { - final MessageList list = messageBirdClient.listScheduledMessages(null, null); + Map filters = new LinkedHashMap<>(); + filters.put("status", "scheduled"); + final MessageList list = messageBirdClient.listMessagesFiltered(null, null, filters); assertNotNull(list.getOffset()); assertNotNull(list.getLinks()); assertNotNull(list.getTotalCount()); From 6f84878ea2d275ae1d0a2243bd729ac84cce9559 Mon Sep 17 00:00:00 2001 From: Andrey Romancev Date: Tue, 3 Mar 2020 16:34:18 +0100 Subject: [PATCH 176/516] Add listMessagesFiltered example. --- .../java/ExampleListMessagesFiltered.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 examples/src/main/java/ExampleListMessagesFiltered.java diff --git a/examples/src/main/java/ExampleListMessagesFiltered.java b/examples/src/main/java/ExampleListMessagesFiltered.java new file mode 100644 index 00000000..ea5e03ce --- /dev/null +++ b/examples/src/main/java/ExampleListMessagesFiltered.java @@ -0,0 +1,42 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.MessageList; + + +public class ExampleListMessagesFiltered { + public static void main(String[] args) { + + if (args.length == 0) { + System.out.println("Please specify your access key example : java -jar test_accesskey"); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + // Get list of messages with offset and limit + System.out.println("Retrieving message list"); + + // Create filters + Map filters = new LinkedHashMap<>(); + filters.put("status", "scheduled"); + + final MessageList messageList = messageBirdClient.listMessagesFiltered(3, null, filters); + + // Display messages + System.out.println(messageList.toString()); + } catch (UnauthorizedException | GeneralException exception) { + if (exception.getErrors() != null) { + System.out.println(exception.getErrors().toString()); + } + exception.printStackTrace(); + } + } +} From c67a9ac4394c7b513c2e2f8514f0d198772ecc57 Mon Sep 17 00:00:00 2001 From: Andrey Romancev Date: Wed, 4 Mar 2020 09:59:47 +0100 Subject: [PATCH 177/516] Fix imports for the ListMessagesFiltered example. --- examples/src/main/java/ExampleListMessagesFiltered.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/src/main/java/ExampleListMessagesFiltered.java b/examples/src/main/java/ExampleListMessagesFiltered.java index ea5e03ce..4a6c94ea 100644 --- a/examples/src/main/java/ExampleListMessagesFiltered.java +++ b/examples/src/main/java/ExampleListMessagesFiltered.java @@ -4,6 +4,8 @@ import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.UnauthorizedException; import com.messagebird.objects.MessageList; +import java.util.LinkedHashMap; +import java.util.Map; public class ExampleListMessagesFiltered { From dec60b48a19ccef24a126d3ab15e386fc342c18e Mon Sep 17 00:00:00 2001 From: Andrey Romancev Date: Wed, 4 Mar 2020 10:00:24 +0100 Subject: [PATCH 178/516] Assert returned response in the test. --- .../com/messagebird/MessageBirdClientTest.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 0fef3c39..e8117b13 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -110,13 +110,20 @@ public void testDeleteMessage() throws Exception { @Test public void testListScheduledMessages() throws Exception { + final MessageList mockedResponse = new MessageList(); + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); + Map filters = new LinkedHashMap<>(); filters.put("status", "scheduled"); - final MessageList list = messageBirdClient.listMessagesFiltered(null, null, filters); - assertNotNull(list.getOffset()); - assertNotNull(list.getLinks()); - assertNotNull(list.getTotalCount()); - assertNotNull(list.getLinks()); + + when(messageBirdServiceMock.requestList("/messages", filters, null, null, MessageList.class)) + .thenReturn(mockedResponse); + + final MessageList response = messageBirdClientMock.listMessagesFiltered(null, null, filters); + assertNotNull(response); + assertEquals(response, mockedResponse); } /*********************************************************************/ From 49acf9760f0278b8dd9bd6262b70378970d3b807 Mon Sep 17 00:00:00 2001 From: Andrey Romancev Date: Wed, 4 Mar 2020 10:27:12 +0100 Subject: [PATCH 179/516] Add filter check to listMessagesFiltered. --- .../main/java/com/messagebird/MessageBirdClient.java | 12 ++++++++++++ .../java/com/messagebird/MessageBirdClientTest.java | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index fe8e9140..13212279 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -66,6 +66,8 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; +import java.util.HashSet; /** * Message bird general client @@ -125,6 +127,9 @@ public class MessageBirdClient { private static final int MIN_MACHINE_TIMEOUT_VALUE = 400; private static final int MAX_MACHINE_TIMEOUT_VALUE = 10000; + private static final String[] MESSAGE_LIST_FILTERS_VALS = {"originator", "recipient", "direction", "limit", "offset", "searchterm", "type", "contact_id", "status", "from", "until"}; + private static final Set MESSAGE_LIST_FILTERS = new HashSet<>(Arrays.asList(MESSAGE_LIST_FILTERS_VALS)); + private final String DOWNLOADS = "Downloads"; private MessageBirdService messageBirdService; @@ -286,6 +291,13 @@ public MessageList listMessages(final Integer offset, final Integer limit) throw public MessageList listMessagesFiltered(final Integer offset, final Integer limit, final Map filters) throws UnauthorizedException, GeneralException { verifyOffsetAndLimit(offset, limit); + + for (String filter : filters.keySet()) { + if (!MESSAGE_LIST_FILTERS.contains(filter)) { + throw new IllegalArgumentException("Invalid filter name: " + filter); + } + } + return messageBirdService.requestList(MESSAGESPATH, filters, offset, limit, MessageList.class); } diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index e8117b13..66cdca53 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -126,6 +126,14 @@ public void testListScheduledMessages() throws Exception { assertEquals(response, mockedResponse); } + @Test(expected = IllegalArgumentException.class) + public void testListScheduledMessagesWrongFilter() throws Exception { + Map filters = new LinkedHashMap<>(); + filters.put("does not exist", null); + + messageBirdClient.listMessagesFiltered(null, null, filters); + } + /*********************************************************************/ /** Test message system **/ /*********************************************************************/ From 950fb99384a1b6eb68732c80bb92fc3376e7bd0d Mon Sep 17 00:00:00 2001 From: Andrey Romancev Date: Wed, 4 Mar 2020 13:43:27 +0100 Subject: [PATCH 180/516] Remove limit and offset from allowed filters. --- api/src/main/java/com/messagebird/MessageBirdClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 13212279..62d158aa 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -127,7 +127,7 @@ public class MessageBirdClient { private static final int MIN_MACHINE_TIMEOUT_VALUE = 400; private static final int MAX_MACHINE_TIMEOUT_VALUE = 10000; - private static final String[] MESSAGE_LIST_FILTERS_VALS = {"originator", "recipient", "direction", "limit", "offset", "searchterm", "type", "contact_id", "status", "from", "until"}; + private static final String[] MESSAGE_LIST_FILTERS_VALS = {"originator", "recipient", "direction", "searchterm", "type", "contact_id", "status", "from", "until"}; private static final Set MESSAGE_LIST_FILTERS = new HashSet<>(Arrays.asList(MESSAGE_LIST_FILTERS_VALS)); private final String DOWNLOADS = "Downloads"; From 826954134ba80de49de9af111a971ec16d45e111 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Wed, 4 Mar 2020 16:56:48 +0100 Subject: [PATCH 181/516] updated list creation --- .../java/ExampleStartConversationsWithWhatsAppSandbox.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/src/main/java/ExampleStartConversationsWithWhatsAppSandbox.java b/examples/src/main/java/ExampleStartConversationsWithWhatsAppSandbox.java index 08e82f33..6039ac18 100644 --- a/examples/src/main/java/ExampleStartConversationsWithWhatsAppSandbox.java +++ b/examples/src/main/java/ExampleStartConversationsWithWhatsAppSandbox.java @@ -4,6 +4,8 @@ import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.UnauthorizedException; import com.messagebird.objects.conversations.*; + +import java.util.ArrayList; import java.util.List; public class ExampleStartConversationsWithWhatsAppSandbox { @@ -17,9 +19,11 @@ public static void main(String[] args) { //First create your service object final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + List features = new ArrayList<>(); + features.add(MessageBirdClient.Feature.ENABLE_CONVERSATION_API_WHATSAPP_SANDBOX); //Add the service to the client - final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr, List.of(MessageBirdClient.Feature.ENABLE_CONVERSATION_API_WHATSAPP_SANDBOX)); //Create client with WhatsApp Sandbox enabled + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr, features); //Create client with WhatsApp Sandbox enabled ConversationContent conversationContent = new ConversationContent(); conversationContent.setText("Hello world from java sdk"); From 967421c3d8e2c3fc68416682f7432917871eb1c6 Mon Sep 17 00:00:00 2001 From: Katherine ChengLi Date: Thu, 19 Mar 2020 09:07:41 -0700 Subject: [PATCH 182/516] Adding the ReportURL Parameter for ConversationStartRequest and ConversationMessageRequest --- .../conversations/ConversationMessageRequest.java | 10 ++++++++++ .../conversations/ConversationStartRequest.java | 10 ++++++++++ .../java/com/messagebird/ConversationMessagesTest.java | 1 + .../test/java/com/messagebird/ConversationsTest.java | 1 + 4 files changed, 22 insertions(+) diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageRequest.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageRequest.java index 5607c147..486589dc 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageRequest.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageRequest.java @@ -8,6 +8,7 @@ public class ConversationMessageRequest { private ConversationContentType type; private ConversationContent content; private String channelId; + private String reportUrl; public ConversationContentType getType() { return type; @@ -33,12 +34,21 @@ public void setChannelId(String channelId) { this.channelId = channelId; } + public String getReportUrl() { + return reportUrl; + } + + public void setReportUrl(String reportUrl) { + this.reportUrl = reportUrl; + } + @Override public String toString() { return "ConversationMessageRequest{" + "type=" + type + ", content=" + content + ", channelId='" + channelId + '\'' + + ", reportUrl='" + reportUrl + '\'' + '}'; } } diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationStartRequest.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationStartRequest.java index 9779bf5c..cd2151a7 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationStartRequest.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationStartRequest.java @@ -9,6 +9,7 @@ public class ConversationStartRequest { private ConversationContentType type; private ConversationContent content; private String channelId; + private String reportUrl; public ConversationStartRequest( final String to, @@ -58,6 +59,14 @@ public void setChannelId(final String channelId) { this.channelId = channelId; } + public String getReportUrl() { + return reportUrl; + } + + public void setReportUrl(final String reportUrl) { + this.reportUrl = reportUrl; + } + @Override public String toString() { return "ConversationStartRequest{" + @@ -65,6 +74,7 @@ public String toString() { ", type=" + type + ", content=" + content + ", channelId='" + channelId + '\'' + + ", reportUrl='" + reportUrl + '\'' + '}'; } } diff --git a/api/src/test/java/com/messagebird/ConversationMessagesTest.java b/api/src/test/java/com/messagebird/ConversationMessagesTest.java index dab6e41f..dcadd1da 100644 --- a/api/src/test/java/com/messagebird/ConversationMessagesTest.java +++ b/api/src/test/java/com/messagebird/ConversationMessagesTest.java @@ -52,6 +52,7 @@ public void testSendConversationMessage() throws GeneralException, UnauthorizedE conversationMessageRequest.setChannelId("aChannelIdentifier"); conversationMessageRequest.setType(ConversationContentType.VIDEO); conversationMessageRequest.setContent(conversationContent); + conversationMessageRequest.setReportUrl("https://example.com/reportUrl"); MessageBirdService messageBirdService = SpyService .expects("POST", "conversations/convid/messages", conversationMessageRequest) diff --git a/api/src/test/java/com/messagebird/ConversationsTest.java b/api/src/test/java/com/messagebird/ConversationsTest.java index 2f3834d1..b91b498d 100644 --- a/api/src/test/java/com/messagebird/ConversationsTest.java +++ b/api/src/test/java/com/messagebird/ConversationsTest.java @@ -50,6 +50,7 @@ public void testStartConversation() throws GeneralException, UnauthorizedExcepti conversationContent, "chanid" ); + request.setReportUrl("https://example.com/reportUrl"); MessageBirdService messageBirdService = SpyService .expects("POST", "conversations/start", request) From b555b903b1ca07add5e4cea46b2a4f6b43faa5fb Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 20 Mar 2020 14:51:53 +0100 Subject: [PATCH 183/516] delete voice recording --- .../com/messagebird/MessageBirdClient.java | 32 +++++++++++++++++ .../messagebird/MessageBirdClientTest.java | 16 +++++++++ .../src/main/java/ExampleDeleteRecording.java | 35 +++++++++++++++++++ .../src/main/java/ExampleSendVoiceCall.java | 1 + 4 files changed, 84 insertions(+) create mode 100644 examples/src/main/java/ExampleDeleteRecording.java diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 62d158aa..8a55acf1 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1345,6 +1345,38 @@ public RecordingResponse listRecordings(String callID, String legId, final Integ return messageBirdService.requestList(url, offset, limit, RecordingResponse.class); } + /** + * Deletes a voice recording + * + * @param callID Voice call ID + * @param legID Leg ID + * @param recordingID Recording ID + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + */ + public void deleteRecording(final String callID, final String legID, final String recordingID) + throws NotFoundException, GeneralException, UnauthorizedException { + if (callID == null) { + throw new IllegalArgumentException("Call ID must be specified."); + } + if (legID == null) { + throw new IllegalArgumentException("Leg ID must be specified."); + } + if (recordingID == null) { + throw new IllegalArgumentException("Recording ID must be specified."); + } + String url = String.format( + "%s%s/%s%s/%s%s", + VOICE_CALLS_BASE_URL, + VOICECALLSPATH, + callID, + LEGSPATH, + legID, + RECORDINGPATH + ); + messageBirdService.deleteByID(url, recordingID); + } + /** * Function to view recording by call id , leg id and recording id * diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 66cdca53..031aa16e 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -938,4 +938,20 @@ public void deletePurchasedNumber() throws UnauthorizedException, GeneralExcept verify(messageBirdServiceMock, times(1)).deleteByID(url, phoneNumber); } + @Test + public void testDeleteRecording() throws NotFoundException, GeneralException, UnauthorizedException { + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); + String url = String.format( + "%s%s/%s%s/%s%s", + VOICE_CALLS_BASE_URL, + VOICECALLSPATH, + "ANY_CALL_ID", + LEGSPATH, + "ANY_LEG_ID", + RECORDINGPATH + ); + messageBirdClientMock.deleteRecording("ANY_CALL_ID", "ANY_LEG_ID","recordingID"); + verify(messageBirdServiceMock, times(1)).deleteByID(url , "recordingID"); + } } diff --git a/examples/src/main/java/ExampleDeleteRecording.java b/examples/src/main/java/ExampleDeleteRecording.java new file mode 100644 index 00000000..39ff9dc6 --- /dev/null +++ b/examples/src/main/java/ExampleDeleteRecording.java @@ -0,0 +1,35 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; + +public class ExampleDeleteRecording { + public static void main(String[] args) { + + if (args.length < 3) { + System.out.println("Please specify your access key and a call_id, leg_id, and recording_id to delete: java -jar " ); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + // Deleting message by id + System.out.println("Delete recording:"); + messageBirdClient.deleteRecording(args[1],args[2],args[3]); + System.out.println("Recording ID ["+args[3]+"] deleted."); + + } catch (UnauthorizedException | GeneralException | NotFoundException exception) { + if (exception.getErrors() != null) { + System.out.println(exception.getErrors().toString()); + } + exception.printStackTrace(); + } + } +} diff --git a/examples/src/main/java/ExampleSendVoiceCall.java b/examples/src/main/java/ExampleSendVoiceCall.java index d327a78c..64617a47 100644 --- a/examples/src/main/java/ExampleSendVoiceCall.java +++ b/examples/src/main/java/ExampleSendVoiceCall.java @@ -31,6 +31,7 @@ public static void main(String[] args) { final VoiceCall voiceCall = new VoiceCall(); voiceCall.setSource("31644556677"); voiceCall.setDestination(args[1]); + voiceCall.setWebhook("https://example.com/","foobar"); //Title and steps are required fields for creating callFlow final VoiceCallFlow voiceCallFlow = new VoiceCallFlow(); From b94f6a1bca0ee4095046084e15236929fa1bfec5 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 20 Mar 2020 15:06:44 +0100 Subject: [PATCH 184/516] updates for a new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index dbe144a6..c1d02a47 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.10 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index f2f7df5f..a6ea54e4 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -61,7 +61,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.0.10"; + private final String clientVersion = "3.0.11"; private final String userAgentString; private Proxy proxy = null; From 6664466119319c69459e532b9950ef700dcfff4c Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 20 Mar 2020 15:11:12 +0100 Subject: [PATCH 185/516] updated --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index c1d02a47..ec28ce76 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.0.11 From e16b08fa23c4d315057e09e4bce2078afc3b1aae Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 20 Mar 2020 15:11:48 +0100 Subject: [PATCH 186/516] [maven-release-plugin] prepare release v3.0.11 --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index ec28ce76..8e69b4fc 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.11-SNAPSHOT From 67af8169a69979531ccb2c651e3c554d1de92d0d Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 20 Mar 2020 15:11:57 +0100 Subject: [PATCH 187/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 8e69b4fc..cda871d5 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.11 From dd87e6140b9f5710b1ef95d9865f19f3fedd5244 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 20 Mar 2020 15:13:52 +0100 Subject: [PATCH 188/516] updated --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index cda871d5..ec28ce76 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.12-SNAPSHOT From 89dce3c4ce08d4a64f7c499fc4ca3c37892c9403 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 20 Mar 2020 15:14:48 +0100 Subject: [PATCH 189/516] [maven-release-plugin] prepare release v3.0.11 --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index ec28ce76..8e69b4fc 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.11-SNAPSHOT From d992522d4f78ae0b0c914d76ffc253b7b3679717 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 20 Mar 2020 15:20:09 +0100 Subject: [PATCH 190/516] updated --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 8e69b4fc..ec28ce76 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.11 From e720993005444c3e5fbc633a55fc95f0cc4fde4b Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 20 Mar 2020 15:20:43 +0100 Subject: [PATCH 191/516] [maven-release-plugin] prepare release v3.0.11 --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index ec28ce76..8e69b4fc 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.11-SNAPSHOT From a52e6384907703f7134cd9564285be1207df4a69 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 20 Mar 2020 15:23:35 +0100 Subject: [PATCH 192/516] updated version --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 8e69b4fc..ec28ce76 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.11 From 19d8ecdae8fb274776ec554d3ca2f95c509fc595 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 20 Mar 2020 15:24:21 +0100 Subject: [PATCH 193/516] [maven-release-plugin] prepare release messagebird-api-3.0.11 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index ec28ce76..6bb0bc0f 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.11-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.0.11 + messagebird-api-3.0.11 From 94813a88da4eb0e828a3161c1815bb173ad98e4c Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 20 Mar 2020 15:24:29 +0100 Subject: [PATCH 194/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 6bb0bc0f..cda871d5 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.11 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - messagebird-api-3.0.11 + v3.0.11 From 792b69c018c39b11ccca74c468efd9b3562458d5 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 20 Mar 2020 19:27:35 +0100 Subject: [PATCH 195/516] updated --- api/pom.xml | 2 +- examples/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index cda871d5..8e69b4fc 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.12-SNAPSHOT diff --git a/examples/pom.xml b/examples/pom.xml index 44fb0fdc..909cdca4 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.10 + 3.0.11 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.10 + 3.0.11 compile From 0221144e1772c2c864e61efa03bb048f4befb370 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 20 Mar 2020 19:32:26 +0100 Subject: [PATCH 196/516] updated --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 8e69b4fc..cb2ad70c 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.0.11 + HEAD From fd637799dbdffe78ed6f2f247b6e6b601eff2da4 Mon Sep 17 00:00:00 2001 From: cemturker Date: Tue, 24 Mar 2020 00:29:17 +0100 Subject: [PATCH 197/516] Media caption is added for conversation --- .../ConversationContentMedia.java | 15 ++++++ .../java/ExampleSendConversationMessage.java | 47 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 examples/src/main/java/ExampleSendConversationMessage.java diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationContentMedia.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationContentMedia.java index b2d1e4ca..7ac29e8f 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationContentMedia.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationContentMedia.java @@ -7,6 +7,12 @@ public class ConversationContentMedia { private String url; + private String caption; + + public ConversationContentMedia(final String url, final String caption) { + this.url = url; + this.caption = caption; + } public ConversationContentMedia(final String url) { this.url = url; @@ -24,10 +30,19 @@ public void setUrl(final String url) { this.url = url; } + public String getCaption() { + return caption; + } + + public void setCaption(String caption) { + this.caption = caption; + } + @Override public String toString() { return "ConversationContentMedia{" + "url='" + url + '\'' + + ", caption='" + caption + '\'' + '}'; } } diff --git a/examples/src/main/java/ExampleSendConversationMessage.java b/examples/src/main/java/ExampleSendConversationMessage.java new file mode 100644 index 00000000..f653980a --- /dev/null +++ b/examples/src/main/java/ExampleSendConversationMessage.java @@ -0,0 +1,47 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.MessageResponse; +import com.messagebird.objects.conversations.*; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by rvt on 1/7/15. + */ +public class ExampleSendConversationMessage { + + public static void main(String[] args) { + if (args.length < 3) { + System.out.println("Please specify your access key, one ore more phone numbers and a message body example : java -jar test_accesskey 31612345678,3161112233 \"My message to be send\""); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl("l3EUyX1zFVkzGQTAa5O7l4OvG"); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + ConversationMessageRequest request = new ConversationMessageRequest(); + request.setChannelId(args[1]); + ConversationContent content = new ConversationContent(); + ConversationContentMedia media = new ConversationContentMedia("https://example.com/photo.png", "example"); + content.setImage(media); + request.setContent(content); + request.setType(ConversationContentType.IMAGE); + try { + final ConversationMessage response = messageBirdClient.sendConversationMessage(args[2], request); + //Display message response + System.out.println(response.toString()); + } catch (UnauthorizedException | GeneralException exception) { + if (exception.getErrors() != null) { + System.out.println(exception.getErrors().toString()); + } + exception.printStackTrace(); + } + } +} From 7cd9644b500b4afd1902819a781bb976c1719900 Mon Sep 17 00:00:00 2001 From: cemturker Date: Tue, 24 Mar 2020 00:33:55 +0100 Subject: [PATCH 198/516] Media caption is added for conversation --- examples/src/main/java/ExampleSendConversationMessage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/src/main/java/ExampleSendConversationMessage.java b/examples/src/main/java/ExampleSendConversationMessage.java index f653980a..c8c457fd 100644 --- a/examples/src/main/java/ExampleSendConversationMessage.java +++ b/examples/src/main/java/ExampleSendConversationMessage.java @@ -22,7 +22,7 @@ public static void main(String[] args) { } // First create your service object - final MessageBirdService wsr = new MessageBirdServiceImpl("l3EUyX1zFVkzGQTAa5O7l4OvG"); + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); // Add the service to the client final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); From 27b8ae82fbd2b980afe59e9636a0bd3e7e0811a3 Mon Sep 17 00:00:00 2001 From: cemturker Date: Tue, 24 Mar 2020 10:05:31 +0100 Subject: [PATCH 199/516] Unused imports are removed --- .../src/main/java/ExampleSendConversationMessage.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/examples/src/main/java/ExampleSendConversationMessage.java b/examples/src/main/java/ExampleSendConversationMessage.java index c8c457fd..378c3ae3 100644 --- a/examples/src/main/java/ExampleSendConversationMessage.java +++ b/examples/src/main/java/ExampleSendConversationMessage.java @@ -1,17 +1,11 @@ import com.messagebird.MessageBirdClient; -import com.messagebird.MessageBirdService; import com.messagebird.MessageBirdServiceImpl; import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.UnauthorizedException; -import com.messagebird.objects.MessageResponse; import com.messagebird.objects.conversations.*; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; - /** - * Created by rvt on 1/7/15. + * Created by olimpias on 24/3/20. */ public class ExampleSendConversationMessage { From 62ab6033dc5652c6a52633eba85e6e285827a7a3 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 24 Mar 2020 15:51:44 +0100 Subject: [PATCH 200/516] new version --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index cb2ad70c..62f2949d 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.11 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index a6ea54e4..9fc6c4db 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -61,7 +61,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.0.11"; + private final String clientVersion = "3.0.12"; private final String userAgentString; private Proxy proxy = null; From 72af24cfb59e9967ba5d09313a8148a64743d12c Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 24 Mar 2020 15:53:08 +0100 Subject: [PATCH 201/516] [maven-release-plugin] prepare release v3.0.12 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 62f2949d..120beef6 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.12-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.0.12 From efea221a0c3c6edf9079d0ae8025e307b28f18a6 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 24 Mar 2020 15:53:16 +0100 Subject: [PATCH 202/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 120beef6..7552a1fb 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.12 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.0.12 + HEAD From c5aa3e0269d695dbf15bd7420c02ba67f2c0d1c7 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 24 Mar 2020 17:53:24 +0100 Subject: [PATCH 203/516] new version --- api/pom.xml | 2 +- examples/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 7552a1fb..27dd0069 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.13-SNAPSHOT diff --git a/examples/pom.xml b/examples/pom.xml index 909cdca4..778b3947 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.11 + 3.0.12 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.11 + 3.0.12 compile From db95f162d4d85834edc3c36ee428276c4fc0b200 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 24 Mar 2020 18:08:50 +0100 Subject: [PATCH 204/516] fixed import --- examples/src/main/java/ExampleSendConversationMessage.java | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/src/main/java/ExampleSendConversationMessage.java b/examples/src/main/java/ExampleSendConversationMessage.java index 378c3ae3..e5915057 100644 --- a/examples/src/main/java/ExampleSendConversationMessage.java +++ b/examples/src/main/java/ExampleSendConversationMessage.java @@ -1,4 +1,5 @@ import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; import com.messagebird.MessageBirdServiceImpl; import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.UnauthorizedException; From b5aef3ea8a1a0e552196c95d00487c2545871e72 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 9 Jun 2020 17:37:03 +0200 Subject: [PATCH 205/516] updated libs regardings #109Issue --- api/pom.xml | 9 ++------- .../main/java/com/messagebird/objects/MClassType.java | 1 - 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 27dd0069..cbae5182 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -83,17 +83,12 @@ com.fasterxml.jackson.core jackson-annotations - 2.10.0 + 2.11.0 com.fasterxml.jackson.core jackson-databind - 2.10.0 - - - com.fasterxml.jackson.dataformat - jackson-dataformat-csv - 2.10.0 + 2.11.0 junit diff --git a/api/src/main/java/com/messagebird/objects/MClassType.java b/api/src/main/java/com/messagebird/objects/MClassType.java index 1f566703..4474b15e 100644 --- a/api/src/main/java/com/messagebird/objects/MClassType.java +++ b/api/src/main/java/com/messagebird/objects/MClassType.java @@ -30,7 +30,6 @@ public Integer toJson() { return getValue(); } - @JsonCreator public static MClassType forValue(String value) { if ("0".equals(value)) { return flash; From 6a11add5db5e7e9b592318332fd82312b7f483b8 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 9 Jun 2020 17:44:27 +0200 Subject: [PATCH 206/516] new relase --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index cbae5182..3cf09107 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.12 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 9fc6c4db..f26f2e9b 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -61,7 +61,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.0.12"; + private final String clientVersion = "3.0.13"; private final String userAgentString; private Proxy proxy = null; From 96cbf2b35024a93fb121c4b00f7177174cd0e820 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 9 Jun 2020 17:45:46 +0200 Subject: [PATCH 207/516] [maven-release-plugin] prepare release v3.0.13 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 3cf09107..8b7aa346 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.13-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.0.13 From 8d8174da344ac885cdc7765d62f2cc09fe937883 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 9 Jun 2020 17:49:40 +0200 Subject: [PATCH 208/516] for the new release --- api/pom.xml | 2 +- examples/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 8b7aa346..c0019b5d 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.13 diff --git a/examples/pom.xml b/examples/pom.xml index 778b3947..352e1198 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.12 + 3.0.13 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.12 + 3.0.13 compile From e2779dea1a150b24d8c9c92f7733fecce8e67e8b Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 9 Jun 2020 17:50:45 +0200 Subject: [PATCH 209/516] [maven-release-plugin] prepare release v3.0.13 --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index c0019b5d..8b7aa346 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.13-SNAPSHOT From b24a8ec928ccc90d93f7d0e4bc54f84928de7199 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 9 Jun 2020 17:50:53 +0200 Subject: [PATCH 210/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 8b7aa346..e5f7a1d6 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.13 From 9cb6838452076c1524b34908ec1f29dcbcc50876 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 9 Jun 2020 21:19:04 +0200 Subject: [PATCH 211/516] related new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index e5f7a1d6..8b7aa346 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.14-SNAPSHOT From f5ef126737c471a4719e66b2ae30562bbea2441f Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 9 Jun 2020 21:22:26 +0200 Subject: [PATCH 212/516] updated tag --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 8b7aa346..47ab5199 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.0.13 + HEAD From bd3918d056e480f76a9fc65f42bf8d4854988d57 Mon Sep 17 00:00:00 2001 From: Jeff Jung Date: Fri, 7 Aug 2020 08:21:30 +0900 Subject: [PATCH 213/516] Reuse ObjectMapper --- .../messagebird/MessageBirdServiceImpl.java | 35 ++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index f26f2e9b..86a3d209 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -65,6 +65,8 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String userAgentString; private Proxy proxy = null; + private final ObjectMapper mapper; + public MessageBirdServiceImpl(final String accessKey, final String serviceUrl) { if (accessKey == null) { throw new IllegalArgumentException(ACCESS_KEY_MUST_BE_SPECIFIED); @@ -75,6 +77,17 @@ public MessageBirdServiceImpl(final String accessKey, final String serviceUrl) { this.accessKey = accessKey; this.serviceUrl = serviceUrl; this.userAgentString = determineUserAgentString(); + + this.mapper = new ObjectMapper() + // If we as new properties, we don't want the system to fail, we rather want to ignore them + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + // Enable case insensitivity to avoid parsing errors if parameters' case in api response doesn't match sdk's + .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS) + .setSerializationInclusion(Include.NON_NULL) + // Specifically set the date format for POST requests so scheduled + // messages and other things relying on specific date formats don't + // fail when sending. + .setDateFormat(getDateFormat()); } private String determineUserAgentString() { @@ -217,14 +230,6 @@ public T getJsonData(final String request, final P payload, final String final int status = apiResponse.getStatus(); if (status == HttpURLConnection.HTTP_OK || status == HttpURLConnection.HTTP_CREATED) { - final ObjectMapper mapper = new ObjectMapper(); - - // If we as new properties, we don't want the system to fail, we rather want to ignore them - mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); - // Enable case insensitivity to avoid parsing errors if parameters' case in api response doesn't match sdk's - mapper.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES); - mapper.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS); - try { return mapper.readValue(body, clazz); } catch (IOException ioe) { @@ -477,14 +482,6 @@ public

HttpURLConnection getConnection(final String serviceUrl, final P body connection.setRequestMethod(requestType); connection.setDoOutput(true); connection.setRequestProperty("Content-Type", "application/json"); - ObjectMapper mapper = new ObjectMapper(); - mapper.setSerializationInclusion(Include.NON_NULL); - - // Specifically set the date format for POST requests so scheduled - // messages and other things relying on specific date formats don't - // fail when sending. - DateFormat df = getDateFormat(); - mapper.setDateFormat(df); final String json = mapper.writeValueAsString(body); connection.getOutputStream().write(json.getBytes(String.valueOf(StandardCharsets.UTF_8))); @@ -538,11 +535,9 @@ private double getVersion() throws GeneralException { * @return Error report, or null if the body can not be deserialized. */ private List getErrorReportOrNull(final String body) { - ObjectMapper objectMapper = new ObjectMapper(); - try { - JsonNode jsonNode = objectMapper.readValue(body, JsonNode.class); - ErrorReport[] errors = objectMapper.readValue(jsonNode.get("errors").toString(), ErrorReport[].class); + JsonNode jsonNode = mapper.readValue(body, JsonNode.class); + ErrorReport[] errors = mapper.readValue(jsonNode.get("errors").toString(), ErrorReport[].class); List result = Arrays.asList(errors); From d3c2cb328f53e7ddf7aeb8632ad00d441d439022 Mon Sep 17 00:00:00 2001 From: cemturker Date: Sat, 8 Aug 2020 09:57:36 +0200 Subject: [PATCH 214/516] check if `errors` field exists in json --- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index f26f2e9b..a01f2479 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -542,6 +542,10 @@ private List getErrorReportOrNull(final String body) { try { JsonNode jsonNode = objectMapper.readValue(body, JsonNode.class); + if(!jsonNode.has("errors")) { + return null; + } + ErrorReport[] errors = objectMapper.readValue(jsonNode.get("errors").toString(), ErrorReport[].class); List result = Arrays.asList(errors); From a2b0ed9f21e3f1f13b591065b5af044af2c4b15d Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 10 Aug 2020 16:40:57 +0200 Subject: [PATCH 215/516] added options for sendKeys action --- .../messagebird/objects/VoiceStepOption.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/objects/VoiceStepOption.java b/api/src/main/java/com/messagebird/objects/VoiceStepOption.java index 9e8e1292..70c0670b 100644 --- a/api/src/main/java/com/messagebird/objects/VoiceStepOption.java +++ b/api/src/main/java/com/messagebird/objects/VoiceStepOption.java @@ -24,6 +24,9 @@ public class VoiceStepOption implements Serializable { private int machineTimeout; private String onFinish; private boolean mask; + private String keys; + private int duration; + private int interval; public String getDestination() { return destination; @@ -169,6 +172,18 @@ public void setMask(boolean mask) { this.mask = mask; } + public String getKeys() { return keys; } + + public void setKeys(String keys) { this.keys = keys; } + + public int getDuration() { return duration; } + + public void setDuration(int duration) { this.duration = duration; } + + public int getInterval() { return interval; } + + public void setInterval(int interval) { this.interval = interval; } + @Override public String toString() { return "VoiceStepOption{" + @@ -189,7 +204,10 @@ public String toString() { ", ifMachine='" + ifMachine + '\'' + ", machineTimeout=" + machineTimeout + ", onFinish='" + onFinish + '\'' + - ", mask=" + mask + + ", mask=" + mask + '\'' + + ", keys='" + keys + '\'' + + ", interval='" + interval + '\'' + + ", duration='" + duration + '}'; } } From 0d621909be866573ebd3611027116af08bb243c2 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 10 Aug 2020 17:22:18 +0200 Subject: [PATCH 216/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 47ab5199..8a94d7c2 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.13 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 9617d465..44cdbd94 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -61,7 +61,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.0.13"; + private final String clientVersion = "3.0.14"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 352e1198..8957bb26 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.13 + 3.0.14 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.13 + 3.0.14 compile From f0f7b8bb072b475f1d24f320148634847572b736 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 10 Aug 2020 17:26:35 +0200 Subject: [PATCH 217/516] updated version --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 8a94d7c2..2a4cc18e 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.0.14 From 714e97d3a711ac820b1d8af8191587c081ccb6ec Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 10 Aug 2020 17:27:34 +0200 Subject: [PATCH 218/516] [maven-release-plugin] prepare release v3.0.14 --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 2a4cc18e..1baa8a5c 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.14-SNAPSHOT From d2135b8b611c1eec7d6fca3d0e88008cd07ec99d Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 10 Aug 2020 17:27:43 +0200 Subject: [PATCH 219/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 1baa8a5c..6ec1d8ec 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.14 From 709f8fb2853dad7d3988aad5a743d9f24f0ca0dd Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 10 Aug 2020 21:06:30 +0200 Subject: [PATCH 220/516] updated --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 6ec1d8ec..1baa8a5c 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.15-SNAPSHOT From 2be87f3702ffe4929964dd9283cf971c8949bb63 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 10 Aug 2020 21:08:20 +0200 Subject: [PATCH 221/516] updated --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 1baa8a5c..9ff62ded 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.0.14 + HEAD From df1a77881908af770cdb0647efd3968657873fab Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Thu, 13 Aug 2020 11:56:07 +0200 Subject: [PATCH 222/516] reverted reuse of objectmapper --- .../messagebird/MessageBirdServiceImpl.java | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 44cdbd94..694093b4 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -65,8 +65,6 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String userAgentString; private Proxy proxy = null; - private final ObjectMapper mapper; - public MessageBirdServiceImpl(final String accessKey, final String serviceUrl) { if (accessKey == null) { throw new IllegalArgumentException(ACCESS_KEY_MUST_BE_SPECIFIED); @@ -78,16 +76,6 @@ public MessageBirdServiceImpl(final String accessKey, final String serviceUrl) { this.serviceUrl = serviceUrl; this.userAgentString = determineUserAgentString(); - this.mapper = new ObjectMapper() - // If we as new properties, we don't want the system to fail, we rather want to ignore them - .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) - // Enable case insensitivity to avoid parsing errors if parameters' case in api response doesn't match sdk's - .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS) - .setSerializationInclusion(Include.NON_NULL) - // Specifically set the date format for POST requests so scheduled - // messages and other things relying on specific date formats don't - // fail when sending. - .setDateFormat(getDateFormat()); } private String determineUserAgentString() { @@ -231,6 +219,13 @@ public T getJsonData(final String request, final P payload, final String if (status == HttpURLConnection.HTTP_OK || status == HttpURLConnection.HTTP_CREATED) { try { + final ObjectMapper mapper = new ObjectMapper(); + // If we as new properties, we don't want the system to fail, we rather want to ignore them + mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + // Enable case insensitivity to avoid parsing errors if parameters' case in api response doesn't match sdk's + mapper.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES); + mapper.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS); + return mapper.readValue(body, clazz); } catch (IOException ioe) { throw new GeneralException(ioe); @@ -482,6 +477,13 @@ public

HttpURLConnection getConnection(final String serviceUrl, final P body connection.setRequestMethod(requestType); connection.setDoOutput(true); connection.setRequestProperty("Content-Type", "application/json"); + ObjectMapper mapper = new ObjectMapper(); + mapper.setSerializationInclusion(Include.NON_NULL); + // Specifically set the date format for POST requests so scheduled + // messages and other things relying on specific date formats don't + // fail when sending. + DateFormat df = getDateFormat(); + mapper.setDateFormat(df); final String json = mapper.writeValueAsString(body); connection.getOutputStream().write(json.getBytes(String.valueOf(StandardCharsets.UTF_8))); @@ -535,13 +537,14 @@ private double getVersion() throws GeneralException { * @return Error report, or null if the body can not be deserialized. */ private List getErrorReportOrNull(final String body) { + ObjectMapper objectMapper = new ObjectMapper(); try { - JsonNode jsonNode = mapper.readValue(body, JsonNode.class); + JsonNode jsonNode = objectMapper.readValue(body, JsonNode.class); if(!jsonNode.has("errors")) { return null; } - ErrorReport[] errors = mapper.readValue(jsonNode.get("errors").toString(), ErrorReport[].class); + ErrorReport[] errors = objectMapper.readValue(jsonNode.get("errors").toString(), ErrorReport[].class); List result = Arrays.asList(errors); From 615ad82961595fd1d118d17447035042b3fbe2e8 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Thu, 13 Aug 2020 12:26:20 +0200 Subject: [PATCH 223/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 9ff62ded..030bb910 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.14 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 694093b4..d1089dcb 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -61,7 +61,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.0.14"; + private final String clientVersion = "3.0.15"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 8957bb26..c8486973 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.14 + 3.0.15 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.14 + 3.0.15 compile From 010ce6bde1cf6c4496675b5d724f75b604badce2 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Thu, 13 Aug 2020 12:27:21 +0200 Subject: [PATCH 224/516] [maven-release-plugin] prepare release v3.0.15 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 030bb910..05bd743f 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.15-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.0.15 From 8035e460670053a687965633bd3e73669dcae12b Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Thu, 13 Aug 2020 12:27:29 +0200 Subject: [PATCH 225/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 05bd743f..a6e80153 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.15 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.0.15 + HEAD From 5c2bcda4923797597313a4554484d39ad9176cd4 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Thu, 13 Aug 2020 21:03:02 +0200 Subject: [PATCH 226/516] updated version --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index a6e80153..28376709 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.16-SNAPSHOT From 79e8a9fefdfedb7ea97f9129b12ed1cdd9d1fff6 Mon Sep 17 00:00:00 2001 From: cemturker Date: Thu, 3 Sep 2020 18:51:59 +0200 Subject: [PATCH 227/516] Add support for fallback messages and add v1/send conversation end point --- .../com/messagebird/MessageBirdClient.java | 15 ++++ .../messagebird/MessageBirdServiceImpl.java | 2 +- .../ConversationFallbackOption.java | 38 +++++++++ .../ConversationSendRequest.java | 85 +++++++++++++++++++ .../ConversationSendResponse.java | 60 +++++++++++++ .../java/ExampleConversationSendMessage.java | 51 +++++++++++ 6 files changed, 250 insertions(+), 1 deletion(-) create mode 100644 api/src/main/java/com/messagebird/objects/conversations/ConversationFallbackOption.java create mode 100644 api/src/main/java/com/messagebird/objects/conversations/ConversationSendRequest.java create mode 100644 api/src/main/java/com/messagebird/objects/conversations/ConversationSendResponse.java create mode 100644 examples/src/main/java/ExampleConversationSendMessage.java diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 8a55acf1..eccdf85a 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -35,6 +35,8 @@ import com.messagebird.objects.conversations.ConversationMessage; import com.messagebird.objects.conversations.ConversationMessageList; import com.messagebird.objects.conversations.ConversationMessageRequest; +import com.messagebird.objects.conversations.ConversationSendRequest; +import com.messagebird.objects.conversations.ConversationSendResponse; import com.messagebird.objects.conversations.ConversationStartRequest; import com.messagebird.objects.conversations.ConversationStatus; import com.messagebird.objects.conversations.ConversationWebhook; @@ -110,6 +112,7 @@ public class MessageBirdClient { private static final String VERIFYPATH = "/verify"; private static final String VOICEMESSAGESPATH = "/voicemessages"; private static final String CONVERSATION_PATH = "/conversations"; + private static final String CONVERSATION_SEND_PATH = "/send"; private static final String CONVERSATION_MESSAGE_PATH = "/messages"; private static final String CONVERSATION_WEBHOOK_PATH = "/webhooks"; static final String VOICECALLSPATH = "/calls"; @@ -951,6 +954,18 @@ public Conversation startConversation(ConversationStartRequest request) return messageBirdService.sendPayLoad(url, request, Conversation.class); } + /** + * sendMessage allows you to send message to users over any communication platform supported by Programmable Conversations + * + * @param request Data for this request. + * @return The created Message in ConversationSendResponse object. + */ + public ConversationSendResponse sendMessage(ConversationSendRequest request) + throws UnauthorizedException, GeneralException { + String url = String.format("%s%s", this.conversationsBaseUrl, CONVERSATION_SEND_PATH); + return messageBirdService.sendPayLoad(url, request, ConversationSendResponse.class); + } + /** * Gets a ConversationMessage listing with specified pagination options. * diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index d1089dcb..94fc8634 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -217,7 +217,7 @@ public T getJsonData(final String request, final P payload, final String final String body = apiResponse.getBody(); final int status = apiResponse.getStatus(); - if (status == HttpURLConnection.HTTP_OK || status == HttpURLConnection.HTTP_CREATED) { + if (status == HttpURLConnection.HTTP_OK || status == HttpURLConnection.HTTP_CREATED || status == HttpURLConnection.HTTP_ACCEPTED) { try { final ObjectMapper mapper = new ObjectMapper(); // If we as new properties, we don't want the system to fail, we rather want to ignore them diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationFallbackOption.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationFallbackOption.java new file mode 100644 index 00000000..0048de12 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationFallbackOption.java @@ -0,0 +1,38 @@ +package com.messagebird.objects.conversations; + +public class ConversationFallbackOption { + private String from; + private String after; + + public ConversationFallbackOption() { + } + + public ConversationFallbackOption(String from, String after) { + this.from = from; + this.after = after; + } + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public String getAfter() { + return after; + } + + public void setAfter(String after) { + this.after = after; + } + + @Override + public String toString() { + return "ConversationFallbackOption{" + + "from='" + from + '\'' + + ", after='" + after + '\'' + + '}'; + } +} diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationSendRequest.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationSendRequest.java new file mode 100644 index 00000000..479edfdd --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationSendRequest.java @@ -0,0 +1,85 @@ +package com.messagebird.objects.conversations; + +public class ConversationSendRequest { + private String to; + private ConversationContentType type; + private ConversationContent content; + private String from; + private String reportUrl; + private ConversationFallbackOption fallback; + + public ConversationSendRequest(String to, ConversationContentType type, ConversationContent content, String from, String reportUrl, ConversationFallbackOption fallback) { + this.to = to; + this.type = type; + this.content = content; + this.from = from; + this.reportUrl = reportUrl; + this.fallback = fallback; + } + + public ConversationSendRequest() { + } + + + public String getTo() { + return to; + } + + public void setTo(String to) { + this.to = to; + } + + public ConversationContentType getType() { + return type; + } + + public void setType(ConversationContentType type) { + this.type = type; + } + + public ConversationContent getContent() { + return content; + } + + public void setContent(ConversationContent content) { + this.content = content; + } + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public String getReportUrl() { + return reportUrl; + } + + public void setReportUrl(String reportUrl) { + this.reportUrl = reportUrl; + } + + public ConversationFallbackOption getFallback() { + return fallback; + } + + public void setFallback(ConversationFallbackOption fallback) { + this.fallback = fallback; + } + + @Override + public String toString() { + return "ConversationSendRequest{" + + "to='" + to + '\'' + + ", type=" + type + + ", content=" + content + + ", from='" + from + '\'' + + ", reportUrl='" + reportUrl + '\'' + + ", fallback=" + fallback + + '}'; + } +} + + diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationSendResponse.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationSendResponse.java new file mode 100644 index 00000000..8d928df6 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationSendResponse.java @@ -0,0 +1,60 @@ +package com.messagebird.objects.conversations; + +public class ConversationSendResponse { + private String id; //messageID + private String status; + private FallbackOptionResponse fallback; + + public static class FallbackOptionResponse{ + private String id; + + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Override + public String toString() { + return "FallbackOptionResponse{" + + "id='" + id + '\'' + + '}'; + } + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public FallbackOptionResponse getFallback() { + return fallback; + } + + public void setFallback(FallbackOptionResponse fallback) { + this.fallback = fallback; + } + + @Override + public String toString() { + return "ConversationSendResponse{" + + "id='" + id + '\'' + + ", status='" + status + '\'' + + ", fallback=" + fallback + + '}'; + } +} diff --git a/examples/src/main/java/ExampleConversationSendMessage.java b/examples/src/main/java/ExampleConversationSendMessage.java new file mode 100644 index 00000000..83ed2c3a --- /dev/null +++ b/examples/src/main/java/ExampleConversationSendMessage.java @@ -0,0 +1,51 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.conversations.ConversationContent; +import com.messagebird.objects.conversations.ConversationContentType; +import com.messagebird.objects.conversations.ConversationFallbackOption; +import com.messagebird.objects.conversations.ConversationSendRequest; +import com.messagebird.objects.conversations.ConversationSendResponse; + +public class ExampleConversationSendMessage { + + public static void main(String[] args) { + if (args.length < 4) { + System.out.println("Please at least specify your access key, the channel id and destination address.\n" + + "Usage : java -jar test_accesskey(Required) channel_id(Required) to(Required) fallback_channel_id(optional)"); + return; + } + + //First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + //Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); //Create client with WhatsApp Sandbox enabled + + + + ConversationFallbackOption fallbackOption = null; + if (args.length == 4) { + fallbackOption = new ConversationFallbackOption(args[3], "5m"); + } + ConversationContent conversationContent = new ConversationContent(); + conversationContent.setText("Hello world from java sdk"); + + ConversationSendRequest request = new ConversationSendRequest( + args[1], + ConversationContentType.TEXT, + conversationContent, + args[2], + "", + fallbackOption); + + try { + ConversationSendResponse sendResponse = messageBirdClient.sendMessage(request); + System.out.println(sendResponse.toString());//Prints messageID + + } catch (GeneralException | UnauthorizedException exception) { + exception.printStackTrace(); + } + } +} From 13aec94b99cba554db7a720793636a2180f3cec0 Mon Sep 17 00:00:00 2001 From: cemturker Date: Thu, 3 Sep 2020 18:54:57 +0200 Subject: [PATCH 228/516] Small fix --- examples/src/main/java/ExampleConversationSendMessage.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/src/main/java/ExampleConversationSendMessage.java b/examples/src/main/java/ExampleConversationSendMessage.java index 83ed2c3a..d63be671 100644 --- a/examples/src/main/java/ExampleConversationSendMessage.java +++ b/examples/src/main/java/ExampleConversationSendMessage.java @@ -12,7 +12,7 @@ public class ExampleConversationSendMessage { public static void main(String[] args) { - if (args.length < 4) { + if (args.length < 3) { System.out.println("Please at least specify your access key, the channel id and destination address.\n" + "Usage : java -jar test_accesskey(Required) channel_id(Required) to(Required) fallback_channel_id(optional)"); return; @@ -42,7 +42,7 @@ public static void main(String[] args) { try { ConversationSendResponse sendResponse = messageBirdClient.sendMessage(request); - System.out.println(sendResponse.toString());//Prints messageID + System.out.println(sendResponse.toString()); } catch (GeneralException | UnauthorizedException exception) { exception.printStackTrace(); From 694ce8b9a18b6bb89e445ae219df686266cab165 Mon Sep 17 00:00:00 2001 From: cemturker Date: Thu, 3 Sep 2020 18:58:58 +0200 Subject: [PATCH 229/516] Remove the comment --- examples/src/main/java/ExampleConversationSendMessage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/src/main/java/ExampleConversationSendMessage.java b/examples/src/main/java/ExampleConversationSendMessage.java index d63be671..927fbad0 100644 --- a/examples/src/main/java/ExampleConversationSendMessage.java +++ b/examples/src/main/java/ExampleConversationSendMessage.java @@ -21,7 +21,7 @@ public static void main(String[] args) { //First create your service object final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); //Add the service to the client - final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); //Create client with WhatsApp Sandbox enabled + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); From 459d82b7c05a5e89a6ce2fb6fb7881a69d776baf Mon Sep 17 00:00:00 2001 From: cemturker Date: Fri, 4 Sep 2020 17:14:07 +0200 Subject: [PATCH 230/516] Add unit test for sendMessage in conversation tests --- .../messagebird/ConversationMessagesTest.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/api/src/test/java/com/messagebird/ConversationMessagesTest.java b/api/src/test/java/com/messagebird/ConversationMessagesTest.java index dcadd1da..76f61d8b 100644 --- a/api/src/test/java/com/messagebird/ConversationMessagesTest.java +++ b/api/src/test/java/com/messagebird/ConversationMessagesTest.java @@ -22,6 +22,7 @@ public class ConversationMessagesTest { private static final String JSON_CONVERSATION_MESSAGE_LOCATION = "{\"id\": \"mesid\",\"conversationId\": \"convid\",\"channelId\": \"chanid\",\"status\": \"received\",\"type\": \"location\",\"direction\": \"received\",\"content\": {\"location\": { \"latitude\": 52.344263, \"longitude\": 4.911627 } },\"createdDatetime\": \"2018-08-29T11:49:16Z\",\"updatedDatetime\": \"2018-08-29T11:49:16Z\"}"; private static final String JSON_CONVERSATION_MESSAGE_TEXT = "{\"id\": \"mesid\",\"conversationId\": \"convid\",\"channelId\": \"chanid\",\"status\": \"received\",\"type\": \"text\",\"direction\": \"received\",\"content\": {\"text\": \"Hello\"},\"createdDatetime\": \"2018-08-29T11:49:16Z\",\"updatedDatetime\": \"2018-08-29T11:49:16Z\"}"; private static final String JSON_CONVERSATION_MESSAGE_VIDEO = "{\"id\": \"mesid\",\"conversationId\": \"convid\",\"channelId\": \"chanid\",\"status\": \"received\",\"type\": \"video\",\"direction\": \"received\",\"content\": {\"video\": { \"url\": \"https://example.com/video.mp4\" } },\"createdDatetime\": \"2018-08-29T11:49:16Z\",\"updatedDatetime\": \"2018-08-29T11:49:16Z\"}"; + private static final String JSON_CONVERSATION_SEND_MESSAGE_RESPONSE = "{\"id\":\"mesid\",\"status\":\"accepted\",\"fallback\":{\"id\":\"mesid\"}}"; /** * Epsilon to use when checking two latitudes or longitudes for equality. @@ -66,6 +67,31 @@ public void testSendConversationMessage() throws GeneralException, UnauthorizedE assertEquals(ConversationContentType.VIDEO, conversationMessage.getType()); } + @Test + public void testSendMessage() throws GeneralException, UnauthorizedException { + ConversationContent conversationContent = new ConversationContent(); + conversationContent.setText("test"); + + ConversationSendRequest sendRequest = new ConversationSendRequest(); + sendRequest.setChannelId("aChannelIdentifier"); + sendRequest.setType(ConversationContentType.TEXT); + sendRequest.setContent(conversationContent); + sendRequest.setReportUrl("https://example.com/reportUrl"); + + MessageBirdService messageBirdService = SpyService + .expects("POST", "conversations/send", sendRequest) + .withConversationsAPIBaseURL() + .andReturns(new APIResponse(JSON_CONVERSATION_SEND_MESSAGE_RESPONSE)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + + ConversationSendResponse conversationMessage + = messageBirdClient.sendMessage(sendRequest); + + assertEquals("mesid", conversationMessage.getId()); + assertEquals("accepted", conversationMessage.getStatus()); + assertEquals("mesid", conversationMessage.getFallback().getId()); + } + @Test public void testViewConversationMessageAudio() throws GeneralException, NotFoundException, UnauthorizedException { MessageBirdService messageBirdService = SpyService From 09a9b1240cff097afd66111197a0cfa243d80d7e Mon Sep 17 00:00:00 2001 From: cemturker Date: Fri, 4 Sep 2020 17:26:46 +0200 Subject: [PATCH 231/516] Fix the test --- api/src/test/java/com/messagebird/ConversationMessagesTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/test/java/com/messagebird/ConversationMessagesTest.java b/api/src/test/java/com/messagebird/ConversationMessagesTest.java index 76f61d8b..5df2a039 100644 --- a/api/src/test/java/com/messagebird/ConversationMessagesTest.java +++ b/api/src/test/java/com/messagebird/ConversationMessagesTest.java @@ -73,7 +73,7 @@ public void testSendMessage() throws GeneralException, UnauthorizedException { conversationContent.setText("test"); ConversationSendRequest sendRequest = new ConversationSendRequest(); - sendRequest.setChannelId("aChannelIdentifier"); + sendRequest.setFrom("aChannelIdentifier"); sendRequest.setType(ConversationContentType.TEXT); sendRequest.setContent(conversationContent); sendRequest.setReportUrl("https://example.com/reportUrl"); From 1afb1098dc0856cb0a53b624d69f6f28fa2256d0 Mon Sep 17 00:00:00 2001 From: cemturker Date: Fri, 4 Sep 2020 17:29:41 +0200 Subject: [PATCH 232/516] fix url --- api/src/test/java/com/messagebird/ConversationMessagesTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/test/java/com/messagebird/ConversationMessagesTest.java b/api/src/test/java/com/messagebird/ConversationMessagesTest.java index 5df2a039..d1e8aad3 100644 --- a/api/src/test/java/com/messagebird/ConversationMessagesTest.java +++ b/api/src/test/java/com/messagebird/ConversationMessagesTest.java @@ -79,7 +79,7 @@ public void testSendMessage() throws GeneralException, UnauthorizedException { sendRequest.setReportUrl("https://example.com/reportUrl"); MessageBirdService messageBirdService = SpyService - .expects("POST", "conversations/send", sendRequest) + .expects("POST", "/send", sendRequest) .withConversationsAPIBaseURL() .andReturns(new APIResponse(JSON_CONVERSATION_SEND_MESSAGE_RESPONSE)); MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); From a92a267338657ad7e5928dc8e636542faa396123 Mon Sep 17 00:00:00 2001 From: cemturker Date: Fri, 4 Sep 2020 17:38:42 +0200 Subject: [PATCH 233/516] Fix the url --- api/src/test/java/com/messagebird/ConversationMessagesTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/test/java/com/messagebird/ConversationMessagesTest.java b/api/src/test/java/com/messagebird/ConversationMessagesTest.java index d1e8aad3..81357f88 100644 --- a/api/src/test/java/com/messagebird/ConversationMessagesTest.java +++ b/api/src/test/java/com/messagebird/ConversationMessagesTest.java @@ -79,7 +79,7 @@ public void testSendMessage() throws GeneralException, UnauthorizedException { sendRequest.setReportUrl("https://example.com/reportUrl"); MessageBirdService messageBirdService = SpyService - .expects("POST", "/send", sendRequest) + .expects("POST", "send", sendRequest) .withConversationsAPIBaseURL() .andReturns(new APIResponse(JSON_CONVERSATION_SEND_MESSAGE_RESPONSE)); MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); From 0f3f2e88bb1e3d757a13c944ea78554eaffeeadd Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 4 Sep 2020 17:51:16 +0200 Subject: [PATCH 234/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 28376709..a6e80153 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.15 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 94fc8634..9f2419ae 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -61,7 +61,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.0.15"; + private final String clientVersion = "3.0.16"; private final String userAgentString; private Proxy proxy = null; From 66670a87d4715b5a094330be1787cba65d028244 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 4 Sep 2020 17:52:10 +0200 Subject: [PATCH 235/516] [maven-release-plugin] prepare release v3.0.16 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index a6e80153..2fde0c5c 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.16-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.0.16 From 145e2f4d32bb7cc398207ac496d6ca4375b73555 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 4 Sep 2020 17:52:18 +0200 Subject: [PATCH 236/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 2fde0c5c..e568025f 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.16 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.0.16 + HEAD From 94eb05faa167723154759e0594271ad46a1e503e Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Fri, 4 Sep 2020 19:19:00 +0200 Subject: [PATCH 237/516] new version release --- api/pom.xml | 2 +- examples/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index e568025f..a196969b 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.17-SNAPSHOT diff --git a/examples/pom.xml b/examples/pom.xml index c8486973..ceff5ec5 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.15 + 3.0.16 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.15 + 3.0.16 compile From da9ba6632b5a002a78e6b18af15bac4d7063c6a0 Mon Sep 17 00:00:00 2001 From: "Mehmet M. Inanc" Date: Tue, 29 Sep 2020 14:40:29 +0200 Subject: [PATCH 238/516] Updates conversations API with recent features. --- api/pom.xml | 22 +--------- .../com/messagebird/objects/ListBase.java | 2 +- .../messagebird/objects/MessageReference.java | 6 +++ .../conversations/ConversationChannel.java | 11 +++++ .../conversations/ConversationMessage.java | 11 +++++ .../conversations/ConversationMessageTag.java | 41 +++++++++++++++++++ .../ConversationPlatformConstants.java | 33 +++++++++++++++ .../ConversationSendRequest.java | 29 +++++++++++-- .../ConversationStartRequest.java | 28 ++++++++++++- .../com/messagebird/ConversationsTest.java | 12 +++++- .../java/ExampleConversationSendMessage.java | 12 +++++- ...StartConversationsWithWhatsAppSandbox.java | 11 +++-- 12 files changed, 187 insertions(+), 31 deletions(-) create mode 100644 api/src/main/java/com/messagebird/objects/conversations/ConversationMessageTag.java create mode 100644 api/src/main/java/com/messagebird/objects/conversations/ConversationPlatformConstants.java diff --git a/api/pom.xml b/api/pom.xml index a196969b..def28274 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -52,26 +52,6 @@ true - true - - - UTF-8 - - - - test - - false - - - - disable-doclint - - [8,11,) - - - none - true UTF-8 @@ -203,7 +183,7 @@ maven-surefire-plugin 2.21.0 - ${skipTests} + false ${messageBirdAccessKey} ${messageBirdMSISDN} diff --git a/api/src/main/java/com/messagebird/objects/ListBase.java b/api/src/main/java/com/messagebird/objects/ListBase.java index 354eafa1..da54e709 100644 --- a/api/src/main/java/com/messagebird/objects/ListBase.java +++ b/api/src/main/java/com/messagebird/objects/ListBase.java @@ -13,6 +13,7 @@ public class ListBase { private Integer limit; private Integer totalCount; private Links links; + private List items; public ListBase() { } @@ -28,7 +29,6 @@ public String toString() { '}'; } - private List items; public Integer getOffset() { return offset; diff --git a/api/src/main/java/com/messagebird/objects/MessageReference.java b/api/src/main/java/com/messagebird/objects/MessageReference.java index da5fb596..26778292 100644 --- a/api/src/main/java/com/messagebird/objects/MessageReference.java +++ b/api/src/main/java/com/messagebird/objects/MessageReference.java @@ -4,6 +4,7 @@ public class MessageReference { private String href; private int totalCount; + private String lastMessageId; public String getHREF() { return href; @@ -21,11 +22,16 @@ public void setTotalCount(int totalCount) { this.totalCount = totalCount; } + public String getLastMessageId() { + return lastMessageId; + } + @Override public String toString() { return "MessageReference{" + "href='" + href + '\'' + ", totalCount=" + totalCount + + ", lastMessageId='" + lastMessageId + '\'' + '}'; } } diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationChannel.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationChannel.java index 32db29e6..2c2bd06e 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationChannel.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationChannel.java @@ -11,6 +11,8 @@ public class ConversationChannel { private String id; private String name; + // See: ConversationPlatformConstants + private String platformId; private ConversationChannelStatus status; private Date createdDatetime; private Date updatedDatetime; @@ -55,11 +57,20 @@ public void setUpdatedDatetime(final Date updatedDatetime) { this.updatedDatetime = updatedDatetime; } + public String getPlatformId() { + return platformId; + } + + public void setPlatformId(String platformId) { + this.platformId = platformId; + } + @Override public String toString() { return "ConversationChannel{" + "id='" + id + '\'' + ", name='" + name + '\'' + + ", platformId=" + platformId + ", status=" + status + ", createdDatetime=" + createdDatetime + ", updatedDatetime=" + updatedDatetime + diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessage.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessage.java index 43b2c275..7ad53882 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessage.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessage.java @@ -1,6 +1,7 @@ package com.messagebird.objects.conversations; import java.util.Date; +import java.util.Map; /** * Response object that represents a conversation's message. Messages can be @@ -18,6 +19,7 @@ public class ConversationMessage { private ConversationContent content; private Date createdDatetime; private Date updatedDatetime; + private Map source; public String getId() { return id; @@ -91,6 +93,14 @@ public void setUpdatedDatetime(Date updatedDatetime) { this.updatedDatetime = updatedDatetime; } + public Map getSource() { + return source; + } + + public void setSource(Map source) { + this.source = source; + } + @Override public String toString() { return "ConversationMessage{" + @@ -103,6 +113,7 @@ public String toString() { ", content=" + content + ", createdDatetime=" + createdDatetime + ", updatedDatetime=" + updatedDatetime + + ", source=" + source + '}'; } } diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageTag.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageTag.java new file mode 100644 index 00000000..49314b3c --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageTag.java @@ -0,0 +1,41 @@ +package com.messagebird.objects.conversations; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * These allow tagging a message based on Facebook tags. + * For more information visit: https://developers.facebook.com/docs/messenger-platform/send-messages/message-tags/ + */ +public enum ConversationMessageTag { + EventUpdate("event.update"), + PurchaseUpdate("purchase.update"), + AccountUpdate("account.update"), + HumanAgent("human_agent"); + + @JsonValue + private final String tag; + + ConversationMessageTag(String tag) { + this.tag = tag; + } + + @JsonCreator + public static ConversationMessageTag forValue(final String value) { + for (ConversationMessageTag tag : ConversationMessageTag.values()) { + if (tag.getTag().equals(value)) { + return tag; + } + } + return null; + } + + public String getTag() { + return tag; + } + + @Override + public String toString() { + return tag; + } +} diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationPlatformConstants.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationPlatformConstants.java new file mode 100644 index 00000000..b9c02f49 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationPlatformConstants.java @@ -0,0 +1,33 @@ +package com.messagebird.objects.conversations; + +/** + * Platforms are communication channels that a conversation can communicate through. + */ +public class ConversationPlatformConstants { + // PlatformSMS identifies the MessageBird SMS platform. + public static final String SMS = "sms"; + + // PlatformWhatsApp identifies the WhatsApp platform. + public static final String WHATSAPP = "whatsapp"; + + // PlatformFacebook identifies the Facebook platform. + public static final String FACEBOOK = "facebook"; + + // PlatformTelegram identifies the Telegram platform. + public static final String TELEGRAM = "telegram"; + + // PlatformLine identifies the LINE platform. + public static final String LINE = "line"; + + // PlatformWeChat identifies the WeChat platform. + public static final String WECHAT = "wechat"; + + // PlatformEmail identifies the Email platform. + public static final String EMAIL = "email"; + + // PlatformEvents identifies the Events platform + public static final String EVENTS = "events"; + + // PlatformWhatsAppSandbox identified the WhatsApp sandbox platform. + public static final String WHATSAPP_SANDBOX = "whatsapp_sandbox"; +} \ No newline at end of file diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationSendRequest.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationSendRequest.java index 479edfdd..f0f9fd5c 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationSendRequest.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationSendRequest.java @@ -1,5 +1,7 @@ package com.messagebird.objects.conversations; +import java.util.Map; + public class ConversationSendRequest { private String to; private ConversationContentType type; @@ -7,20 +9,23 @@ public class ConversationSendRequest { private String from; private String reportUrl; private ConversationFallbackOption fallback; + private Map source; + private ConversationMessageTag tag; - public ConversationSendRequest(String to, ConversationContentType type, ConversationContent content, String from, String reportUrl, ConversationFallbackOption fallback) { + public ConversationSendRequest(String to, ConversationContentType type, ConversationContent content, String from, String reportUrl, ConversationFallbackOption fallback, Map source, ConversationMessageTag tag) { this.to = to; this.type = type; this.content = content; this.from = from; this.reportUrl = reportUrl; this.fallback = fallback; + this.source = source; + this.tag = tag; } public ConversationSendRequest() { } - public String getTo() { return to; } @@ -69,6 +74,22 @@ public void setFallback(ConversationFallbackOption fallback) { this.fallback = fallback; } + public Map getSource() { + return source; + } + + public void setSource(Map source) { + this.source = source; + } + + public ConversationMessageTag getTag() { + return tag; + } + + public void setTag(ConversationMessageTag tag) { + this.tag = tag; + } + @Override public String toString() { return "ConversationSendRequest{" + @@ -77,7 +98,9 @@ public String toString() { ", content=" + content + ", from='" + from + '\'' + ", reportUrl='" + reportUrl + '\'' + - ", fallback=" + fallback + + ", fallback=" + fallback + '\'' + + ", tags=" + tag + + ", source='" + source + '\'' + '}'; } } diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationStartRequest.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationStartRequest.java index cd2151a7..36ebc68a 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationStartRequest.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationStartRequest.java @@ -1,5 +1,7 @@ package com.messagebird.objects.conversations; +import java.util.Map; + /** * Request object used for starting a conversation. */ @@ -8,6 +10,8 @@ public class ConversationStartRequest { private String to; private ConversationContentType type; private ConversationContent content; + private Map source; + private ConversationMessageTag tag; private String channelId; private String reportUrl; @@ -15,12 +19,16 @@ public ConversationStartRequest( final String to, final ConversationContentType type, final ConversationContent content, - final String channelId + final String channelId, + final Map source, + final ConversationMessageTag tag ) { this.to = to; this.type = type; this.content = content; this.channelId = channelId; + this.source = source; + this.tag = tag; } public ConversationStartRequest() { @@ -67,12 +75,30 @@ public void setReportUrl(final String reportUrl) { this.reportUrl = reportUrl; } + public Map getSource() { + return source; + } + + public void setSource(Map source) { + this.source = source; + } + + public ConversationMessageTag getTag() { + return tag; + } + + public void setTag(ConversationMessageTag tag) { + this.tag = tag; + } + @Override public String toString() { return "ConversationStartRequest{" + "to='" + to + '\'' + ", type=" + type + ", content=" + content + + ", source=" + source + + ", tag=" + tag + ", channelId='" + channelId + '\'' + ", reportUrl='" + reportUrl + '\'' + '}'; diff --git a/api/src/test/java/com/messagebird/ConversationsTest.java b/api/src/test/java/com/messagebird/ConversationsTest.java index b91b498d..81095dc3 100644 --- a/api/src/test/java/com/messagebird/ConversationsTest.java +++ b/api/src/test/java/com/messagebird/ConversationsTest.java @@ -6,6 +6,10 @@ import com.messagebird.objects.conversations.*; import org.junit.Test; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + import static org.junit.Assert.*; public class ConversationsTest { @@ -44,11 +48,17 @@ public void testStartConversation() throws GeneralException, UnauthorizedExcepti ConversationContent conversationContent = new ConversationContent(); conversationContent.setText("Hello world"); + Map source = new HashMap<>(); + source.put("agentId", "abc123"); + source.put("userId", Arrays.asList(1, 2, 3)); + ConversationStartRequest request = new ConversationStartRequest( "31612345678", ConversationContentType.TEXT, conversationContent, - "chanid" + "chanid", + source, + ConversationMessageTag.AccountUpdate ); request.setReportUrl("https://example.com/reportUrl"); diff --git a/examples/src/main/java/ExampleConversationSendMessage.java b/examples/src/main/java/ExampleConversationSendMessage.java index 927fbad0..84b3ca65 100644 --- a/examples/src/main/java/ExampleConversationSendMessage.java +++ b/examples/src/main/java/ExampleConversationSendMessage.java @@ -9,6 +9,10 @@ import com.messagebird.objects.conversations.ConversationSendRequest; import com.messagebird.objects.conversations.ConversationSendResponse; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + public class ExampleConversationSendMessage { public static void main(String[] args) { @@ -32,13 +36,19 @@ public static void main(String[] args) { ConversationContent conversationContent = new ConversationContent(); conversationContent.setText("Hello world from java sdk"); + // Optional source parameter, that identifies the actor making the request. + Map source = new HashMap<>(); + source.put("Salesman", "Sir. John Doe"); + ConversationSendRequest request = new ConversationSendRequest( args[1], ConversationContentType.TEXT, conversationContent, args[2], "", - fallbackOption); + fallbackOption, + source, + null); try { ConversationSendResponse sendResponse = messageBirdClient.sendMessage(request); diff --git a/examples/src/main/java/ExampleStartConversationsWithWhatsAppSandbox.java b/examples/src/main/java/ExampleStartConversationsWithWhatsAppSandbox.java index 6039ac18..5c9d0e66 100644 --- a/examples/src/main/java/ExampleStartConversationsWithWhatsAppSandbox.java +++ b/examples/src/main/java/ExampleStartConversationsWithWhatsAppSandbox.java @@ -5,8 +5,7 @@ import com.messagebird.exceptions.UnauthorizedException; import com.messagebird.objects.conversations.*; -import java.util.ArrayList; -import java.util.List; +import java.util.*; public class ExampleStartConversationsWithWhatsAppSandbox { @@ -28,11 +27,17 @@ public static void main(String[] args) { ConversationContent conversationContent = new ConversationContent(); conversationContent.setText("Hello world from java sdk"); + // Optional source parameter, that identifies the actor making the request. + Map source = new HashMap<>(); + source.put("agentId", "abc123"); + ConversationStartRequest request = new ConversationStartRequest( args[2], ConversationContentType.TEXT, conversationContent, - args[1] + args[1], + source, + null ); try { Conversation conversation = messageBirdClient.startConversation(request); From cc2499befa45d923959aa6e38f64b0fa529a1ea5 Mon Sep 17 00:00:00 2001 From: "Mehmet M. Inanc" Date: Fri, 2 Oct 2020 12:05:31 +0200 Subject: [PATCH 239/516] * Adds Conversations email content. * Some minor fixes over the last commit. --- .../messagebird/objects/MessageReference.java | 2 + .../conversations/ConversationContent.java | 10 +++ .../ConversationContentEmail.java | 21 ++++++ .../ConversationEmailAttachment.java | 60 ++++++++++++++++ .../ConversationEmailContent.java | 30 ++++++++ .../ConversationEmailInlineImage.java | 70 +++++++++++++++++++ .../ConversationEmailRecipient.java | 42 +++++++++++ .../ConversationEmailTracking.java | 30 ++++++++ .../conversations/ConversationMessage.java | 23 ++++++ .../ConversationMessageRequest.java | 12 ++++ 10 files changed, 300 insertions(+) create mode 100644 api/src/main/java/com/messagebird/objects/conversations/ConversationContentEmail.java create mode 100644 api/src/main/java/com/messagebird/objects/conversations/ConversationEmailAttachment.java create mode 100644 api/src/main/java/com/messagebird/objects/conversations/ConversationEmailContent.java create mode 100644 api/src/main/java/com/messagebird/objects/conversations/ConversationEmailInlineImage.java create mode 100644 api/src/main/java/com/messagebird/objects/conversations/ConversationEmailRecipient.java create mode 100644 api/src/main/java/com/messagebird/objects/conversations/ConversationEmailTracking.java diff --git a/api/src/main/java/com/messagebird/objects/MessageReference.java b/api/src/main/java/com/messagebird/objects/MessageReference.java index 26778292..6d15b4c6 100644 --- a/api/src/main/java/com/messagebird/objects/MessageReference.java +++ b/api/src/main/java/com/messagebird/objects/MessageReference.java @@ -1,5 +1,7 @@ package com.messagebird.objects; +import com.sun.istack.internal.Nullable; + public class MessageReference { private String href; diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationContent.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationContent.java index 2edfb5b3..9ba82bd8 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationContent.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationContent.java @@ -11,6 +11,7 @@ public class ConversationContent { private ConversationContentHsm hsm; private ConversationContentMedia image; private ConversationContentLocation location; + private ConversationContentEmail email; private String text; private ConversationContentMedia video; @@ -70,6 +71,14 @@ public void setVideo(ConversationContentMedia video) { this.video = video; } + public ConversationContentEmail getEmail() { + return email; + } + + public void setEmail(ConversationContentEmail email) { + this.email = email; + } + @Override public String toString() { return "ConversationContent{" + @@ -78,6 +87,7 @@ public String toString() { ", hsm=" + hsm + ", image=" + image + ", location=" + location + + ", email=" + email + ", text='" + text + '\'' + ", video=" + video + '}'; diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationContentEmail.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationContentEmail.java new file mode 100644 index 00000000..541b1423 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationContentEmail.java @@ -0,0 +1,21 @@ +package com.messagebird.objects.conversations; + +import com.messagebird.objects.MessageResponse; + +import java.util.List; +import java.util.Map; + +public class ConversationContentEmail { + private String id; + private ConversationEmailRecipient from; + private List to; + private String subject; + private ConversationEmailContent content; + private String replyTo; + private String returnPath; + private Map headers; + private ConversationEmailTracking tracking; + private boolean performSubstitutions; + private List attachments; + private List inlineImages; +} diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationEmailAttachment.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationEmailAttachment.java new file mode 100644 index 00000000..82e1a48a --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationEmailAttachment.java @@ -0,0 +1,60 @@ +package com.messagebird.objects.conversations; + +public class ConversationEmailAttachment { + private String id; + private String name; + private String type; + private String URL; + private String length; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getURL() { + return URL; + } + + public void setURL(String URL) { + this.URL = URL; + } + + public String getLength() { + return length; + } + + public void setLength(String length) { + this.length = length; + } + + @Override + public String toString() { + return "ConversationEmailAttachment{" + + "id='" + id + '\'' + + ", name='" + name + '\'' + + ", type='" + type + '\'' + + ", URL='" + URL + '\'' + + ", length='" + length + '\'' + + '}'; + } +} diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationEmailContent.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationEmailContent.java new file mode 100644 index 00000000..7127b104 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationEmailContent.java @@ -0,0 +1,30 @@ +package com.messagebird.objects.conversations; + +public class ConversationEmailContent { + private String html; + private String text; + + public String getHtml() { + return html; + } + + public void setHtml(String html) { + this.html = html; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + @Override + public String toString() { + return "ConversationEmailContent{" + + "html='" + html + '\'' + + ", text='" + text + '\'' + + '}'; + } +} diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationEmailInlineImage.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationEmailInlineImage.java new file mode 100644 index 00000000..a7318216 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationEmailInlineImage.java @@ -0,0 +1,70 @@ +package com.messagebird.objects.conversations; + +public class ConversationEmailInlineImage { + private String id; + private String name; + private String type; + private String URL; + private int length; + private String contentId; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getURL() { + return URL; + } + + public void setURL(String URL) { + this.URL = URL; + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } + + public String getContentId() { + return contentId; + } + + public void setContentId(String contentId) { + this.contentId = contentId; + } + + @Override + public String toString() { + return "ConversationEmailInlineImage{" + + "id='" + id + '\'' + + ", name='" + name + '\'' + + ", type='" + type + '\'' + + ", URL='" + URL + '\'' + + ", length=" + length + + ", contentId='" + contentId + '\'' + + '}'; + } +} diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationEmailRecipient.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationEmailRecipient.java new file mode 100644 index 00000000..bae92bfa --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationEmailRecipient.java @@ -0,0 +1,42 @@ +package com.messagebird.objects.conversations; + +import java.util.Map; + +public class ConversationEmailRecipient { + private String email; + private String name; + private Map variables; + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Map getVariables() { + return variables; + } + + public void setVariables(Map variables) { + this.variables = variables; + } + + @Override + public String toString() { + return "ConversationEmailRecipient{" + + "email='" + email + '\'' + + ", name='" + name + '\'' + + ", variables=" + variables + + '}'; + } +} diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationEmailTracking.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationEmailTracking.java new file mode 100644 index 00000000..b8861d14 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationEmailTracking.java @@ -0,0 +1,30 @@ +package com.messagebird.objects.conversations; + +public class ConversationEmailTracking { + private boolean open; + private boolean click; + + public boolean isOpen() { + return open; + } + + public void setOpen(boolean open) { + this.open = open; + } + + public boolean isClick() { + return click; + } + + public void setClick(boolean click) { + this.click = click; + } + + @Override + public String toString() { + return "ConversationEmailTracking{" + + "open=" + open + + ", click=" + click + + '}'; + } +} diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessage.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessage.java index 7ad53882..82c935dd 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessage.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessage.java @@ -20,6 +20,11 @@ public class ConversationMessage { private Date createdDatetime; private Date updatedDatetime; private Map source; + private ConversationMessageTag tag; + /** + * See: {@link ConversationPlatformConstants} + */ + private String platform; public String getId() { return id; @@ -101,6 +106,22 @@ public void setSource(Map source) { this.source = source; } + public ConversationMessageTag getTag() { + return tag; + } + + public void setTag(ConversationMessageTag tag) { + this.tag = tag; + } + + public String getPlatform() { + return platform; + } + + public void setPlatform(String platform) { + this.platform = platform; + } + @Override public String toString() { return "ConversationMessage{" + @@ -114,6 +135,8 @@ public String toString() { ", createdDatetime=" + createdDatetime + ", updatedDatetime=" + updatedDatetime + ", source=" + source + + ", tag=" + tag + + ", platform='" + platform + '\'' + '}'; } } diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageRequest.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageRequest.java index 486589dc..626e6075 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageRequest.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageRequest.java @@ -1,5 +1,7 @@ package com.messagebird.objects.conversations; +import java.util.Map; + /** * Request object that is used to send new messages over a channel. */ @@ -9,6 +11,7 @@ public class ConversationMessageRequest { private ConversationContent content; private String channelId; private String reportUrl; + private Map source; public ConversationContentType getType() { return type; @@ -42,6 +45,14 @@ public void setReportUrl(String reportUrl) { this.reportUrl = reportUrl; } + public Map getSource() { + return source; + } + + public void setSource(Map source) { + this.source = source; + } + @Override public String toString() { return "ConversationMessageRequest{" + @@ -49,6 +60,7 @@ public String toString() { ", content=" + content + ", channelId='" + channelId + '\'' + ", reportUrl='" + reportUrl + '\'' + + ", source=" + source + '}'; } } From b1b94f905468f8bb09470c8c3cc7902f32f2723d Mon Sep 17 00:00:00 2001 From: "Mehmet M. Inanc" Date: Thu, 8 Oct 2020 19:38:36 +0200 Subject: [PATCH 240/516] * Removes some extra imports. * Adds accessor and toString to ConversationContentEmail. --- .../messagebird/objects/MessageReference.java | 2 - .../ConversationContentEmail.java | 118 +++++++++++++++++- 2 files changed, 115 insertions(+), 5 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/MessageReference.java b/api/src/main/java/com/messagebird/objects/MessageReference.java index 6d15b4c6..26778292 100644 --- a/api/src/main/java/com/messagebird/objects/MessageReference.java +++ b/api/src/main/java/com/messagebird/objects/MessageReference.java @@ -1,7 +1,5 @@ package com.messagebird.objects; -import com.sun.istack.internal.Nullable; - public class MessageReference { private String href; diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationContentEmail.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationContentEmail.java index 541b1423..3ba8b2d8 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationContentEmail.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationContentEmail.java @@ -1,7 +1,5 @@ package com.messagebird.objects.conversations; -import com.messagebird.objects.MessageResponse; - import java.util.List; import java.util.Map; @@ -12,10 +10,124 @@ public class ConversationContentEmail { private String subject; private ConversationEmailContent content; private String replyTo; - private String returnPath; + private String returnPath; private Map headers; private ConversationEmailTracking tracking; private boolean performSubstitutions; private List attachments; private List inlineImages; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public ConversationEmailRecipient getFrom() { + return from; + } + + public void setFrom(ConversationEmailRecipient from) { + this.from = from; + } + + public List getTo() { + return to; + } + + public void setTo(List to) { + this.to = to; + } + + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject; + } + + public ConversationEmailContent getContent() { + return content; + } + + public void setContent(ConversationEmailContent content) { + this.content = content; + } + + public String getReplyTo() { + return replyTo; + } + + public void setReplyTo(String replyTo) { + this.replyTo = replyTo; + } + + public String getReturnPath() { + return returnPath; + } + + public void setReturnPath(String returnPath) { + this.returnPath = returnPath; + } + + public Map getHeaders() { + return headers; + } + + public void setHeaders(Map headers) { + this.headers = headers; + } + + public ConversationEmailTracking getTracking() { + return tracking; + } + + public void setTracking(ConversationEmailTracking tracking) { + this.tracking = tracking; + } + + public boolean isPerformSubstitutions() { + return performSubstitutions; + } + + public void setPerformSubstitutions(boolean performSubstitutions) { + this.performSubstitutions = performSubstitutions; + } + + public List getAttachments() { + return attachments; + } + + public void setAttachments(List attachments) { + this.attachments = attachments; + } + + public List getInlineImages() { + return inlineImages; + } + + public void setInlineImages(List inlineImages) { + this.inlineImages = inlineImages; + } + + @Override + public String toString() { + return "ConversationContentEmail{" + + "id='" + id + '\'' + + ", from=" + from + + ", to=" + to + + ", subject='" + subject + '\'' + + ", content=" + content + + ", replyTo='" + replyTo + '\'' + + ", returnPath='" + returnPath + '\'' + + ", headers=" + headers + + ", tracking=" + tracking + + ", performSubstitutions=" + performSubstitutions + + ", attachments=" + attachments + + ", inlineImages=" + inlineImages + + '}'; + } } From 0d2137d8c4ce3c16d96d28cd032c1333037592e3 Mon Sep 17 00:00:00 2001 From: "Mehmet M. Inanc" Date: Thu, 8 Oct 2020 19:42:04 +0200 Subject: [PATCH 241/516] * Reverts pom.xml changes. --- api/pom.xml | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index def28274..cfa0f21f 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + HEAD @@ -52,6 +52,26 @@ true + true + + + UTF-8 + + + + test + + false + + + + disable-doclint + + [8,11,) + + + none + true UTF-8 @@ -183,7 +203,7 @@ maven-surefire-plugin 2.21.0 - false + ${skipTests} ${messageBirdAccessKey} ${messageBirdMSISDN} From 9e0717886452b3300fccbe42ac5a63dae72cd1f9 Mon Sep 17 00:00:00 2001 From: cemturker Date: Fri, 9 Oct 2020 19:59:47 +0200 Subject: [PATCH 242/516] Add an example for Send Email and some bug fix --- .../ConversationContentType.java | 3 +- .../ConversationEmailRecipient.java | 12 +-- .../ExampleConversationSendEmailMessage.java | 75 +++++++++++++++++++ .../java/ExampleConversationSendMessage.java | 5 +- .../java/ExampleSendConversationMessage.java | 6 +- 5 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 examples/src/main/java/ExampleConversationSendEmailMessage.java diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationContentType.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationContentType.java index 93f6bb4f..3dec398a 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationContentType.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationContentType.java @@ -15,7 +15,8 @@ public enum ConversationContentType { IMAGE("image"), LOCATION("location"), TEXT("text"), - VIDEO("video"); + VIDEO("video"), + EMAIL("email"); private final String type; diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationEmailRecipient.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationEmailRecipient.java index bae92bfa..f5bbdfb9 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationEmailRecipient.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationEmailRecipient.java @@ -3,16 +3,16 @@ import java.util.Map; public class ConversationEmailRecipient { - private String email; + private String address; private String name; private Map variables; - public String getEmail() { - return email; + public String getAddress() { + return address; } - public void setEmail(String email) { - this.email = email; + public void setAddress(String address) { + this.address = address; } public String getName() { @@ -34,7 +34,7 @@ public void setVariables(Map variables) { @Override public String toString() { return "ConversationEmailRecipient{" + - "email='" + email + '\'' + + "address='" + address + '\'' + ", name='" + name + '\'' + ", variables=" + variables + '}'; diff --git a/examples/src/main/java/ExampleConversationSendEmailMessage.java b/examples/src/main/java/ExampleConversationSendEmailMessage.java new file mode 100644 index 00000000..9a8f4021 --- /dev/null +++ b/examples/src/main/java/ExampleConversationSendEmailMessage.java @@ -0,0 +1,75 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.conversations.ConversationContent; +import com.messagebird.objects.conversations.ConversationContentEmail; +import com.messagebird.objects.conversations.ConversationContentType; +import com.messagebird.objects.conversations.ConversationEmailContent; +import com.messagebird.objects.conversations.ConversationEmailRecipient; +import com.messagebird.objects.conversations.ConversationSendRequest; +import com.messagebird.objects.conversations.ConversationSendResponse; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +public class ExampleConversationSendEmailMessage { + + public static void main(String[] args) { + + if (args.length < 4) { + System.out.println("Please at least specify your access key, the channel id and destination address.\n" + + "Usage : java -jar test_accesskey(Required) channel_id(Required) to(Required) from(Required)"); + return; + } + + //First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + //Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + ConversationEmailRecipient fromRecipient = new ConversationEmailRecipient(); + fromRecipient.setAddress(args[2]); + ConversationEmailRecipient toRecipient = new ConversationEmailRecipient(); + toRecipient.setAddress(args[3]); + ConversationEmailContent content = new ConversationEmailContent(); + content.setHtml("

HTML Ipsum Presents

\n" + + "\n" + + "

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. " + + "Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget " + + "tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis.

\n" + + "\n" + + "

Header Level 2

"); + ConversationContentEmail emailContent = new ConversationContentEmail(); + emailContent.setContent(content); + emailContent.setFrom(fromRecipient); + emailContent.setTo(Arrays.asList(toRecipient)); + emailContent.setSubject("Greetings From Messagebird"); + ConversationContent conversationContent = new ConversationContent(); + conversationContent.setEmail(emailContent); + + // Optional source parameter, that identifies the actor making the request. + Map source = new HashMap<>(); + source.put("Salesman", "Sir. John Doe"); + + ConversationSendRequest request = new ConversationSendRequest( + args[2], + ConversationContentType.EMAIL, + conversationContent, + args[1], + "", + null, + source, + null); + + try { + ConversationSendResponse sendResponse = messageBirdClient.sendMessage(request); + System.out.println(sendResponse.toString()); + + } catch (GeneralException | UnauthorizedException exception) { + exception.printStackTrace(); + } + } +} diff --git a/examples/src/main/java/ExampleConversationSendMessage.java b/examples/src/main/java/ExampleConversationSendMessage.java index 84b3ca65..01d91dc7 100644 --- a/examples/src/main/java/ExampleConversationSendMessage.java +++ b/examples/src/main/java/ExampleConversationSendMessage.java @@ -9,7 +9,6 @@ import com.messagebird.objects.conversations.ConversationSendRequest; import com.messagebird.objects.conversations.ConversationSendResponse; -import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -41,10 +40,10 @@ public static void main(String[] args) { source.put("Salesman", "Sir. John Doe"); ConversationSendRequest request = new ConversationSendRequest( - args[1], + args[2], ConversationContentType.TEXT, conversationContent, - args[2], + args[1], "", fallbackOption, source, diff --git a/examples/src/main/java/ExampleSendConversationMessage.java b/examples/src/main/java/ExampleSendConversationMessage.java index e5915057..549bf897 100644 --- a/examples/src/main/java/ExampleSendConversationMessage.java +++ b/examples/src/main/java/ExampleSendConversationMessage.java @@ -3,7 +3,11 @@ import com.messagebird.MessageBirdServiceImpl; import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.UnauthorizedException; -import com.messagebird.objects.conversations.*; +import com.messagebird.objects.conversations.ConversationContent; +import com.messagebird.objects.conversations.ConversationContentMedia; +import com.messagebird.objects.conversations.ConversationContentType; +import com.messagebird.objects.conversations.ConversationMessage; +import com.messagebird.objects.conversations.ConversationMessageRequest; /** * Created by olimpias on 24/3/20. From 247b3be720829335eee90c2cc571ef2d3a6b0b9c Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 12 Oct 2020 10:07:02 +0200 Subject: [PATCH 243/516] changes for a new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index cfa0f21f..ff859d81 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.16 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 9f2419ae..bbc11c5b 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -61,7 +61,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.0.16"; + private final String clientVersion = "3.0.17"; private final String userAgentString; private Proxy proxy = null; From d98350525db76cee4459331143133e7b1fd891cd Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 12 Oct 2020 10:07:58 +0200 Subject: [PATCH 244/516] [maven-release-plugin] prepare release v3.0.17 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index ff859d81..b28dc3c6 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.17-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.0.17 From 88ac576a7d80bdb9cd20b2d274cf2b37d853a812 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 12 Oct 2020 10:08:07 +0200 Subject: [PATCH 245/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index b28dc3c6..70f2e04e 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.17 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.0.17 + HEAD From 0903ab2eba49609816331ff467d01fbad4120cec Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 12 Oct 2020 15:08:46 +0200 Subject: [PATCH 246/516] updated for a new release --- api/pom.xml | 2 +- examples/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 70f2e04e..a6de214c 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.18-SNAPSHOT diff --git a/examples/pom.xml b/examples/pom.xml index ceff5ec5..3b366968 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.16 + 3.0.17 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.16 + 3.0.17 compile From 7c171eabc52ddd2deae254d0f7e8b73f02de64d2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Oct 2020 09:06:44 +0000 Subject: [PATCH 247/516] Bump junit from 4.12 to 4.13.1 in /api Bumps [junit](https://github.com/junit-team/junit4) from 4.12 to 4.13.1. - [Release notes](https://github.com/junit-team/junit4/releases) - [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.12.md) - [Commits](https://github.com/junit-team/junit4/compare/r4.12...r4.13.1) Signed-off-by: dependabot[bot] --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index a6de214c..466d43e9 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -93,7 +93,7 @@ junit junit - 4.12 + 4.13.1 test From b434e9a8e8aad5427376786e83aaa819ca8810db Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 27 Oct 2020 18:28:01 +0100 Subject: [PATCH 248/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 466d43e9..8e28da47 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.17 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index bbc11c5b..c105edac 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -61,7 +61,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.0.17"; + private final String clientVersion = "3.0.18"; private final String userAgentString; private Proxy proxy = null; From 18888898603159fc0604a82d4ea9f35b838651c1 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 27 Oct 2020 18:28:30 +0100 Subject: [PATCH 249/516] new release changes --- examples/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/pom.xml b/examples/pom.xml index 3b366968..9b63d0ed 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.17 + 3.0.18 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.17 + 3.0.18 compile From b4493bc3fb055e50b2da83a2284fd91a5de0d7ff Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 27 Oct 2020 18:29:44 +0100 Subject: [PATCH 250/516] [maven-release-plugin] prepare release v3.0.18 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 8e28da47..92297366 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.18-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.0.18 From 653d6cb2584ea1ad33fad4fe036458d080183c9a Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 27 Oct 2020 18:29:53 +0100 Subject: [PATCH 251/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 92297366..25b170d9 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.18 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.0.18 + HEAD From a7d961a1e9d96d611cef0d85670bef39a26e77ad Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 27 Oct 2020 20:54:01 +0100 Subject: [PATCH 252/516] updated for the new version --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 25b170d9..b7156a96 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.19-SNAPSHOT From d7027b78d46288e4b941b3ba47170c259a29e520 Mon Sep 17 00:00:00 2001 From: Raymond Jelierse Date: Fri, 13 Nov 2020 16:40:38 +0100 Subject: [PATCH 253/516] Revert "Merge pull request #65 from mariuspot/master" This reverts commit 163eb3a0422bf6a5fd93d4993614d4f8a044763b, reversing changes made to bfa4071439d0cd6e9e4413083295a22435edb046. --- README.md | 10 ---- .../com/messagebird/MessageBirdClient.java | 44 ++++++---------- ...StartConversationsWithWhatsAppSandbox.java | 51 ------------------- 3 files changed, 15 insertions(+), 90 deletions(-) delete mode 100644 examples/src/main/java/ExampleStartConversationsWithWhatsAppSandbox.java diff --git a/README.md b/README.md index 39d62596..fbacf4fe 100644 --- a/README.md +++ b/README.md @@ -115,16 +115,6 @@ If you server doesn't have a direct connection to the internet you can setup a p messageBirdService.setProxy(proxy); ``` -##### Conversations WhatsApp Sandbox -To use the whatsapp sandbox you need to add `MessageBirdClient.ENABLE_CONVERSATION_API_WHATSAPP_SANDBOX` to the list of features you want enabled. Don't forget to replace `YOUR_ACCESS_KEY` with your actual access key. - -```java - // Create a MessageBirdService - final MessageBirdService messageBirdService = new MessageBirdServiceImpl("YOUR_ACCESS_KEY"); - // Add the service to the client - final MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService, List.of(MessageBirdClient.Feature.ENABLE_CONVERSATION_API_WHATSAPP_SANDBOX)); -``` - Documentation ------------- Complete documentation, instructions, and examples are available at: diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index eccdf85a..101d3e4d 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -95,9 +95,7 @@ public class MessageBirdClient { * can, however, override this behaviour by providing absolute URLs * ourselves. */ - private static final String BASE_URL_CONVERSATIONS = "https://conversations.messagebird.com/v1"; - private static final String BASE_URL_CONVERSATIONS_WHATSAPP_SANDBOX = "https://whatsapp-sandbox.messagebird.com/v1"; - + private static final String CONVERSATIONS_BASE_URL = "https://conversations.messagebird.com/v1"; static final String VOICE_CALLS_BASE_URL = "https://voice.messagebird.com"; static final String NUMBERS_CALLS_BASE_URL = "https://numbers.messagebird.com/v1"; private static String[] supportedLanguages = {"de-DE", "en-AU", "en-UK", "en-US", "es-ES", "es-LA", "fr-FR", "it-IT", "nl-NL", "pt-BR"}; @@ -136,23 +134,11 @@ public class MessageBirdClient { private final String DOWNLOADS = "Downloads"; private MessageBirdService messageBirdService; - private String conversationsBaseUrl; - - public enum Feature { - ENABLE_CONVERSATION_API_WHATSAPP_SANDBOX - } public MessageBirdClient(final MessageBirdService messageBirdService) { this.messageBirdService = messageBirdService; - this.conversationsBaseUrl = BASE_URL_CONVERSATIONS; } - public MessageBirdClient(final MessageBirdService messageBirdService, List features) { - this(messageBirdService); - if(features.indexOf(Feature.ENABLE_CONVERSATION_API_WHATSAPP_SANDBOX) >= 0) { - this.conversationsBaseUrl = BASE_URL_CONVERSATIONS_WHATSAPP_SANDBOX; - } - } /****************************************************************************************************/ /** Balance and HRL methods **/ /****************************************************************************************************/ @@ -897,7 +883,7 @@ public Conversation viewConversation(final String id) throws NotFoundException, if (id == null) { throw new IllegalArgumentException("Id must be specified"); } - String url = this.conversationsBaseUrl + CONVERSATION_PATH; + String url = CONVERSATIONS_BASE_URL + CONVERSATION_PATH; return messageBirdService.requestByID(url, id, Conversation.class); } @@ -913,7 +899,7 @@ public Conversation updateConversation(final String id, final ConversationStatus if (id == null) { throw new IllegalArgumentException("Id must be specified."); } - String url = String.format("%s%s/%s", this.conversationsBaseUrl, CONVERSATION_PATH, id); + String url = String.format("%s%s/%s", CONVERSATIONS_BASE_URL, CONVERSATION_PATH, id); return messageBirdService.sendPayLoad("PATCH", url, status, Conversation.class); } @@ -926,7 +912,7 @@ public Conversation updateConversation(final String id, final ConversationStatus */ public ConversationList listConversations(final int offset, final int limit) throws UnauthorizedException, GeneralException { - String url = this.conversationsBaseUrl + CONVERSATION_PATH; + String url = CONVERSATIONS_BASE_URL + CONVERSATION_PATH; return messageBirdService.requestList(url, offset, limit, ConversationList.class); } @@ -950,7 +936,7 @@ public ConversationList listConversations() throws UnauthorizedException, Genera */ public Conversation startConversation(ConversationStartRequest request) throws UnauthorizedException, GeneralException { - String url = String.format("%s%s/start", this.conversationsBaseUrl, CONVERSATION_PATH); + String url = String.format("%s%s/start", CONVERSATIONS_BASE_URL, CONVERSATION_PATH); return messageBirdService.sendPayLoad(url, request, Conversation.class); } @@ -962,7 +948,7 @@ public Conversation startConversation(ConversationStartRequest request) */ public ConversationSendResponse sendMessage(ConversationSendRequest request) throws UnauthorizedException, GeneralException { - String url = String.format("%s%s", this.conversationsBaseUrl, CONVERSATION_SEND_PATH); + String url = String.format("%s%s", CONVERSATIONS_BASE_URL, CONVERSATION_SEND_PATH); return messageBirdService.sendPayLoad(url, request, ConversationSendResponse.class); } @@ -981,7 +967,7 @@ public ConversationMessageList listConversationMessages( ) throws UnauthorizedException, GeneralException { String url = String.format( "%s%s/%s%s", - this.conversationsBaseUrl, + CONVERSATIONS_BASE_URL, CONVERSATION_PATH, conversationId, CONVERSATION_MESSAGE_PATH @@ -1012,7 +998,7 @@ public ConversationMessageList listConversationMessages( */ public ConversationMessage viewConversationMessage(final String messageId) throws NotFoundException, GeneralException, UnauthorizedException { - String url = this.conversationsBaseUrl + CONVERSATION_MESSAGE_PATH; + String url = CONVERSATIONS_BASE_URL + CONVERSATION_MESSAGE_PATH; return messageBirdService.requestByID(url, messageId, ConversationMessage.class); } @@ -1029,7 +1015,7 @@ public ConversationMessage sendConversationMessage( ) throws UnauthorizedException, GeneralException { String url = String.format( "%s%s/%s%s", - this.conversationsBaseUrl, + CONVERSATIONS_BASE_URL, CONVERSATION_PATH, conversationId, CONVERSATION_MESSAGE_PATH @@ -1044,7 +1030,7 @@ public ConversationMessage sendConversationMessage( */ public void deleteConversationWebhook(final String webhookId) throws NotFoundException, GeneralException, UnauthorizedException { - String url = this.conversationsBaseUrl + CONVERSATION_WEBHOOK_PATH; + String url = CONVERSATIONS_BASE_URL + CONVERSATION_WEBHOOK_PATH; messageBirdService.deleteByID(url, webhookId); } @@ -1056,7 +1042,7 @@ public void deleteConversationWebhook(final String webhookId) */ public ConversationWebhook sendConversationWebhook(final ConversationWebhookCreateRequest request) throws UnauthorizedException, GeneralException { - String url = this.conversationsBaseUrl + CONVERSATION_WEBHOOK_PATH; + String url = CONVERSATIONS_BASE_URL + CONVERSATION_WEBHOOK_PATH; return messageBirdService.sendPayLoad(url, request, ConversationWebhook.class); } @@ -1071,7 +1057,7 @@ public ConversationWebhook updateConversationWebhook(final String id, final Conv throw new IllegalArgumentException("Conversation webhook ID must be specified."); } - String url = this.conversationsBaseUrl + CONVERSATION_WEBHOOK_PATH + "/" + id; + String url = CONVERSATIONS_BASE_URL + CONVERSATION_WEBHOOK_PATH + "/" + id; return messageBirdService.sendPayLoad("PATCH", url, request, ConversationWebhook.class); } @@ -1082,7 +1068,7 @@ public ConversationWebhook updateConversationWebhook(final String id, final Conv * @return The retrieved webhook. */ public ConversationWebhook viewConversationWebhook(final String webhookId) throws NotFoundException, GeneralException, UnauthorizedException { - String url = this.conversationsBaseUrl + CONVERSATION_WEBHOOK_PATH; + String url = CONVERSATIONS_BASE_URL + CONVERSATION_WEBHOOK_PATH; return messageBirdService.requestByID(url, webhookId, ConversationWebhook.class); } @@ -1095,7 +1081,7 @@ public ConversationWebhook viewConversationWebhook(final String webhookId) throw */ public ConversationWebhookList listConversationWebhooks(final int offset, final int limit) throws UnauthorizedException, GeneralException { - String url = this.conversationsBaseUrl + CONVERSATION_WEBHOOK_PATH; + String url = CONVERSATIONS_BASE_URL + CONVERSATION_WEBHOOK_PATH; return messageBirdService.requestList(url, offset, limit, ConversationWebhookList.class); } @@ -1781,4 +1767,4 @@ public void cancelNumber(String number) throws UnauthorizedException, GeneralExc final String url = String.format("%s/phone-numbers", NUMBERS_CALLS_BASE_URL); messageBirdService.deleteByID(url, number); } -} \ No newline at end of file +} diff --git a/examples/src/main/java/ExampleStartConversationsWithWhatsAppSandbox.java b/examples/src/main/java/ExampleStartConversationsWithWhatsAppSandbox.java deleted file mode 100644 index 5c9d0e66..00000000 --- a/examples/src/main/java/ExampleStartConversationsWithWhatsAppSandbox.java +++ /dev/null @@ -1,51 +0,0 @@ -import com.messagebird.MessageBirdClient; -import com.messagebird.MessageBirdService; -import com.messagebird.MessageBirdServiceImpl; -import com.messagebird.exceptions.GeneralException; -import com.messagebird.exceptions.UnauthorizedException; -import com.messagebird.objects.conversations.*; - -import java.util.*; - -public class ExampleStartConversationsWithWhatsAppSandbox { - - public static void main(String[] args) { - if (args.length != 3) { - System.out.println("Please at least specify your access key, the channel id and destination address.\n" + - "Usage : java -jar test_accesskey(Required) channel_id(Required) to(Required)"); - return; - } - - //First create your service object - final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); - List features = new ArrayList<>(); - features.add(MessageBirdClient.Feature.ENABLE_CONVERSATION_API_WHATSAPP_SANDBOX); - - //Add the service to the client - final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr, features); //Create client with WhatsApp Sandbox enabled - - ConversationContent conversationContent = new ConversationContent(); - conversationContent.setText("Hello world from java sdk"); - - // Optional source parameter, that identifies the actor making the request. - Map source = new HashMap<>(); - source.put("agentId", "abc123"); - - ConversationStartRequest request = new ConversationStartRequest( - args[2], - ConversationContentType.TEXT, - conversationContent, - args[1], - source, - null - ); - try { - Conversation conversation = messageBirdClient.startConversation(request); - // assertEquals("convid", conversation.getId()); - System.out.println(conversation.getId()); - - } catch (GeneralException | UnauthorizedException exception) { - exception.printStackTrace(); - } - } -} From f61587a3da9293c15a2273b8cf221299df2309b5 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Tue, 17 Nov 2020 11:56:45 +0100 Subject: [PATCH 254/516] src/main/java/com/messagebird/MessageBirdServiceImpl.java --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index b7156a96..25b170d9 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.18 From 53c6892443f0446962a2eb87c618c0e3aac0e65c Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Tue, 17 Nov 2020 11:57:10 +0100 Subject: [PATCH 255/516] updated for a new release --- examples/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/pom.xml b/examples/pom.xml index 9b63d0ed..96c5e146 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.18 + 3.0.19 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.18 + 3.0.19 compile From 05921ddeb5feb73f0e221511caf3f814e7273477 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Tue, 17 Nov 2020 11:58:09 +0100 Subject: [PATCH 256/516] updated for the new release --- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index c105edac..7f7ddad5 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -61,7 +61,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.0.18"; + private final String clientVersion = "3.0.19"; private final String userAgentString; private Proxy proxy = null; From cfd581197607bb469e95b4fb57683f0f2eec4447 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Tue, 17 Nov 2020 11:59:14 +0100 Subject: [PATCH 257/516] [maven-release-plugin] prepare release v3.0.19 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 25b170d9..33866347 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.19-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.0.19 From a9e1782f37cd7ad53911ddc63725a493c21cd73d Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Tue, 17 Nov 2020 12:02:09 +0100 Subject: [PATCH 258/516] version update --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 33866347..f9e778a2 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.19 From 8d1606e03d0964f340cf19c570cb27296e7ce964 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Tue, 17 Nov 2020 12:02:57 +0100 Subject: [PATCH 259/516] [maven-release-plugin] prepare release v3.0.19 --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index f9e778a2..33866347 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.19-SNAPSHOT From 540646175a23efc96beea4fafd9791c06f9447fe Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Tue, 17 Nov 2020 12:03:06 +0100 Subject: [PATCH 260/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 33866347..50e15bc5 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.19 From 119eea05f9ad357b451d996e8009d9fffc472b39 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Tue, 17 Nov 2020 15:26:08 +0100 Subject: [PATCH 261/516] updated --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 50e15bc5..e55f3388 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.20-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.0.19 + HEAD From 4e780885c491ef1ea65ca1c7e3766bf39be253a3 Mon Sep 17 00:00:00 2001 From: cemturker Date: Sun, 3 Jan 2021 23:30:25 +0100 Subject: [PATCH 262/516] Move gpg plugin to profile --- api/pom.xml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/api/pom.xml b/api/pom.xml index e55f3388..23903830 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -77,6 +77,33 @@ UTF-8
+ + release-sign-artifacts + + + performRelease + true + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + + +
From f4a77603f896f903a971cec0370f7838aaa239ac Mon Sep 17 00:00:00 2001 From: cemturker Date: Sun, 3 Jan 2021 23:32:56 +0100 Subject: [PATCH 263/516] remove maven-gpg-plugin from build in plugins --- api/pom.xml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 23903830..19536f48 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -183,20 +183,6 @@ - - org.apache.maven.plugins - maven-gpg-plugin - 1.6 - - - sign-artifacts - verify - - sign - - - - org.apache.maven.plugins maven-compiler-plugin From f7808173522a6d66cddfef2265c7ba0ba36af3d5 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 4 Jan 2021 17:30:04 +0100 Subject: [PATCH 264/516] Revert "Move gpg plugin to profiles" --- api/pom.xml | 41 ++++++++++++++--------------------------- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 19536f48..e55f3388 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -77,33 +77,6 @@ UTF-8 - - release-sign-artifacts - - - performRelease - true - - - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.6 - - - sign-artifacts - verify - - sign - - - - - - -
@@ -183,6 +156,20 @@ + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + org.apache.maven.plugins maven-compiler-plugin From 46b19c98ec12ef00383a994d6c1a19f2b56988b5 Mon Sep 17 00:00:00 2001 From: cemturker Date: Wed, 6 Jan 2021 12:14:59 +0100 Subject: [PATCH 265/516] Fix wrong printing for email example --- examples/src/main/java/ExampleConversationSendEmailMessage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/src/main/java/ExampleConversationSendEmailMessage.java b/examples/src/main/java/ExampleConversationSendEmailMessage.java index 9a8f4021..63734bb8 100644 --- a/examples/src/main/java/ExampleConversationSendEmailMessage.java +++ b/examples/src/main/java/ExampleConversationSendEmailMessage.java @@ -21,7 +21,7 @@ public static void main(String[] args) { if (args.length < 4) { System.out.println("Please at least specify your access key, the channel id and destination address.\n" + - "Usage : java -jar test_accesskey(Required) channel_id(Required) to(Required) from(Required)"); + "Usage : java -jar test_accesskey(Required) channel_id(Required) from(Required) to(Required)"); return; } From 10c2c413815c75e9bfbd08a29698d1f8177297f3 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Thu, 8 Apr 2021 11:02:31 +0200 Subject: [PATCH 266/516] added price field on message response --- .../messagebird/objects/MessageResponse.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/api/src/main/java/com/messagebird/objects/MessageResponse.java b/api/src/main/java/com/messagebird/objects/MessageResponse.java index be132d4f..689981f3 100644 --- a/api/src/main/java/com/messagebird/objects/MessageResponse.java +++ b/api/src/main/java/com/messagebird/objects/MessageResponse.java @@ -1,5 +1,7 @@ package com.messagebird.objects; +import com.sun.istack.internal.Nullable; + import java.io.Serializable; import java.math.BigInteger; import java.util.Date; @@ -260,6 +262,8 @@ static public class Items implements Serializable { private BigInteger recipient; private String status; private Date statusDatetime; + @Nullable + private Price price; public Items() { } @@ -270,6 +274,7 @@ public String toString() { "recipient=" + recipient + ", status='" + status + '\'' + ", statusDatetime=" + statusDatetime + + ", price=" + price + "}"; } @@ -300,6 +305,41 @@ public Date getStatusDatetime() { return statusDatetime; } + public Price getPrice() { + return price; + } + + } + + /** + * Response price of items + */ + static public class Price implements Serializable { + + private static final long serialVersionUID = -4104837036540050532L; + + private float amount; + private String currency; + + public Price() { + } + + @Override + public String toString() { + return "Price{" + + "amount=" + amount + + ", currency=" + currency + + "}"; + } + + public float getAmount() { + return amount; + } + + public String getCurrency() { + return currency; + } + } } From 646db06a65bda7bf9cb258367d44051da5ba3548 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Thu, 8 Apr 2021 11:15:58 +0200 Subject: [PATCH 267/516] fixed import --- api/pom.xml | 5 +++++ .../main/java/com/messagebird/objects/MessageResponse.java | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index e55f3388..8ddfc765 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -108,6 +108,11 @@ 2.21.0 test + + org.jetbrains + annotations + 13.0 + diff --git a/api/src/main/java/com/messagebird/objects/MessageResponse.java b/api/src/main/java/com/messagebird/objects/MessageResponse.java index 689981f3..8b480e25 100644 --- a/api/src/main/java/com/messagebird/objects/MessageResponse.java +++ b/api/src/main/java/com/messagebird/objects/MessageResponse.java @@ -1,6 +1,6 @@ package com.messagebird.objects; -import com.sun.istack.internal.Nullable; +import org.jetbrains.annotations.Nullable; import java.io.Serializable; import java.math.BigInteger; From ba5ec65833e258b382fb892e06e5851755493696 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Thu, 8 Apr 2021 14:29:55 +0200 Subject: [PATCH 268/516] release to fix an issue --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 8ddfc765..9fd86d3f 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.19 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 7f7ddad5..2f0b5e89 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -61,7 +61,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.0.19"; + private final String clientVersion = "3.0.21"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 96c5e146..3c9ce43c 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.19 + 3.0.21 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.19 + 3.0.21 compile From 2122e423ca5a8db76f34944a9a939d73d29a5d47 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Thu, 8 Apr 2021 14:31:01 +0200 Subject: [PATCH 269/516] [maven-release-plugin] prepare release v3.0.21 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 9fd86d3f..3fabc413 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.21-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.0.21 From 124636ba8396d196bb104c57830c5083187d10cb Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Thu, 8 Apr 2021 14:31:07 +0200 Subject: [PATCH 270/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 3fabc413..6f9f1985 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.21 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.0.21 + HEAD From 630c2d310f55b160441b7d28271c3b0bfa66485f Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Thu, 8 Apr 2021 16:42:49 +0200 Subject: [PATCH 271/516] new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 6f9f1985..ad6ae2d6 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.22-SNAPSHOT From 31c80d270cd1ab62207103b1268ee520950a56da Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Thu, 8 Apr 2021 16:43:38 +0200 Subject: [PATCH 272/516] new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index ad6ae2d6..ce907d78 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.22 From 19b05e5a9a8cdaf805fe2bd318f4d4487bb44f38 Mon Sep 17 00:00:00 2001 From: Rafe Arnold Date: Fri, 23 Apr 2021 15:46:32 +0100 Subject: [PATCH 273/516] Fix code parameter in ConversationHsmLocalizableParameterCurrency constructor. --- .../ConversationHsmLocalizableParameterCurrency.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationHsmLocalizableParameterCurrency.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationHsmLocalizableParameterCurrency.java index b17ecbce..708938ee 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationHsmLocalizableParameterCurrency.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationHsmLocalizableParameterCurrency.java @@ -11,10 +11,10 @@ public class ConversationHsmLocalizableParameterCurrency { /** * Instantiates a localizable parameter for currencies. * - * @param code ISO 4217 compliant currency code. + * @param currencyCode ISO 4217 compliant currency code. * @param amount Amount multiplied by 1000. E.g. 12.34 becomes 12340. */ - public ConversationHsmLocalizableParameterCurrency(final String code, final int amount) { + public ConversationHsmLocalizableParameterCurrency(final String currencyCode, final int amount) { this.currencyCode = currencyCode; this.amount = amount; } From ef55a9400b84ad0f3871d48d6030e1a838d66d82 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Thu, 6 May 2021 14:03:36 +0200 Subject: [PATCH 274/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index ce907d78..6f9f1985 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.21 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 2f0b5e89..fcf1e63f 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -61,7 +61,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.0.21"; + private final String clientVersion = "3.0.22"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 3c9ce43c..eefe48cc 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.21 + 3.0.22 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.21 + 3.0.22 compile From 6f5cc09fb9c59d4a078ef86e17a8d71c819b0e25 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Thu, 6 May 2021 14:06:29 +0200 Subject: [PATCH 275/516] new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 6f9f1985..98ddd433 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.0.22 From 72273530114e84f47550ae029135ff7b88af725f Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Thu, 6 May 2021 14:07:14 +0200 Subject: [PATCH 276/516] [maven-release-plugin] prepare release v3.0.22 --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 98ddd433..9d17ee81 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.22-SNAPSHOT From 6f9466ceaae97353825d176956b027a4a7b742ee Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Thu, 6 May 2021 14:10:09 +0200 Subject: [PATCH 277/516] a new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 9d17ee81..98ddd433 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.22 From 30a7bb56ee6706817cfecd65883a6e88dfea0b1a Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Thu, 6 May 2021 14:11:21 +0200 Subject: [PATCH 278/516] [maven-release-plugin] prepare release v3.0.22 --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 98ddd433..9d17ee81 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.22-SNAPSHOT From 1fde3e929110c8e540f7e3451e1da45b955f0bf0 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Thu, 6 May 2021 14:11:27 +0200 Subject: [PATCH 279/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 9d17ee81..3c9e212b 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.22 From e4d50efe301bb15306c2b34408a0ace6a3eaf537 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Fri, 7 May 2021 09:25:11 +0200 Subject: [PATCH 280/516] new release is created --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 3c9e212b..9d17ee81 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.23-SNAPSHOT From 70bac920fcba0c1353ab43de30e44d4b76f6a6b1 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Fri, 7 May 2021 09:27:09 +0200 Subject: [PATCH 281/516] tag update --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 9d17ee81..ad6ae2d6 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.0.22 + HEAD From 748a409fa78f17d60379094bc9e2f2aa7b76d9b9 Mon Sep 17 00:00:00 2001 From: Rafe Arnold Date: Tue, 18 May 2021 12:51:49 +0100 Subject: [PATCH 282/516] Implement file upload and download in MessageBirdClient. --- .../com/messagebird/MessageBirdClient.java | 54 +++++++++++ .../com/messagebird/MessageBirdService.java | 14 +++ .../messagebird/MessageBirdServiceImpl.java | 54 +++++++++-- .../objects/FileUploadResponse.java | 21 +++++ .../messagebird/MessageBirdClientTest.java | 92 ++++++++++++++++++- .../test/java/com/messagebird/SpyService.java | 4 +- 6 files changed, 230 insertions(+), 9 deletions(-) create mode 100644 api/src/main/java/com/messagebird/objects/FileUploadResponse.java diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 101d3e4d..4bbe6ff4 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -8,6 +8,7 @@ import com.messagebird.objects.ContactList; import com.messagebird.objects.ContactRequest; import com.messagebird.objects.ErrorReport; +import com.messagebird.objects.FileUploadResponse; import com.messagebird.objects.Group; import com.messagebird.objects.GroupList; import com.messagebird.objects.GroupRequest; @@ -98,6 +99,7 @@ public class MessageBirdClient { private static final String CONVERSATIONS_BASE_URL = "https://conversations.messagebird.com/v1"; static final String VOICE_CALLS_BASE_URL = "https://voice.messagebird.com"; static final String NUMBERS_CALLS_BASE_URL = "https://numbers.messagebird.com/v1"; + static final String MESSAGING_BASE_URL = "https://messaging.messagebird.com/v1"; private static String[] supportedLanguages = {"de-DE", "en-AU", "en-UK", "en-US", "es-ES", "es-LA", "fr-FR", "it-IT", "nl-NL", "pt-BR"}; private static final String BALANCEPATH = "/balance"; @@ -120,6 +122,8 @@ public class MessageBirdClient { static final String WEBHOOKS = "/webhooks"; static final String VOICECALLFLOWPATH = "/call-flows"; private static final String VOICELEGS_SUFFIX_PATH = "/legs"; + static final String FILES_PATH = "/files"; + static final String RECORDING_DOWNLOAD_FORMAT = ".wav"; static final String TRANSCRIPTION_DOWNLOAD_FORMAT = ".txt"; @@ -1767,4 +1771,54 @@ public void cancelNumber(String number) throws UnauthorizedException, GeneralExc final String url = String.format("%s/phone-numbers", NUMBERS_CALLS_BASE_URL); messageBirdService.deleteByID(url, number); } + + /** + * Uploads a file and returns the assigned ID. + * + * @param binary the bytes of the file to upload. + * @param contentType the content type of the file (e.g. "image/png"). + * @return FileUploadResponse + * @throws GeneralException general exception + * @throws UnauthorizedException if client is unauthorized + * @see #downloadFile + */ + public FileUploadResponse uploadFile(byte[] binary, String contentType) throws GeneralException, UnauthorizedException { + if (binary == null) { + throw new IllegalArgumentException("File binary must be specified."); + } + if (contentType == null) { + throw new IllegalArgumentException("Content type must be specified."); + } + + final String url = MESSAGING_BASE_URL + FILES_PATH; + final Map headers = new HashMap<>(); + headers.put("Content-Type", contentType); + return messageBirdService.sendPayLoad("POST", url, headers, binary, FileUploadResponse.class); + } + + /** + * Downloads a file and stores it with the provided filename in the basePath directory. The + * basePath may be null. If basePath is null, the default download directory will be the + * /Download folder in the user home directory. + * + * @param id the ID of the file, provided when the file was uploaded + * @param basePath store location. It should be a directory. Property is nullable if $HOME is accessible + * @param filename the name of the file to download to. + * @return the path where the downloaded file is stored + * @throws NotFoundException if the file does not exist + * @throws GeneralException general exception + * @throws UnauthorizedException if client is unauthorized + * @see #uploadFile + */ + public String downloadFile(String id, String filename, String basePath) throws GeneralException, UnauthorizedException, NotFoundException { + if (id == null) { + throw new IllegalArgumentException("File ID must be specified."); + } + if (filename == null) { + throw new IllegalArgumentException("Filename must be specified."); + } + + final String url = String.format("%s%s/%s", MESSAGING_BASE_URL, FILES_PATH, id); + return messageBirdService.getBinaryData(url, basePath, filename); + } } diff --git a/api/src/main/java/com/messagebird/MessageBirdService.java b/api/src/main/java/com/messagebird/MessageBirdService.java index 68cf1f56..fdbf6f43 100644 --- a/api/src/main/java/com/messagebird/MessageBirdService.java +++ b/api/src/main/java/com/messagebird/MessageBirdService.java @@ -107,6 +107,20 @@ public interface MessageBirdService { */ R sendPayLoad(String method, String request, P payload, Class clazz) throws UnauthorizedException, GeneralException; + /** + * Send a payload with the provided method and headers and receive a payload object. + * + * @param method HTTP method to use for the request + * @param request path to the request, for example "/messages" + * @param headers additional headers to set on the request + * @param payload payload to send to the server + * @param clazz object type to return + * @return base class + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + */ + R sendPayLoad(String method, String request, Map headers, P payload, Class clazz) throws UnauthorizedException, GeneralException; + /** * Gets the data from the request URL and stores it to basePath/fileName * diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index fcf1e63f..bb512fd4 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -169,12 +169,17 @@ public R sendPayLoad(String request, P payload, Class clazz) throws Un @Override public R sendPayLoad(String method, String request, P payload, Class clazz) throws UnauthorizedException, GeneralException { + return sendPayLoad(method, request, new HashMap<>(), payload, clazz); + } + + @Override + public R sendPayLoad(String method, String request, Map headers, P payload, Class clazz) throws UnauthorizedException, GeneralException { if (!REQUEST_METHODS_WITH_PAYLOAD.contains(method)) { throw new IllegalArgumentException(String.format(REQUEST_METHOD_NOT_ALLOWED, method)); } try { - return getJsonData(request, payload, method, clazz); + return getJsonData(request, payload, method, headers, clazz); } catch (NotFoundException e) { throw new GeneralException(e); } @@ -204,6 +209,10 @@ public String getBinaryData(String request, String basePath, String fileName) th public T getJsonData(final String request, final P payload, final String requestType, final Class clazz) throws UnauthorizedException, GeneralException, NotFoundException { + return getJsonData(request, payload, requestType, new HashMap<>(), clazz); + } + + public T getJsonData(final String request, final P payload, final String requestType, final Map headers, final Class clazz) throws UnauthorizedException, GeneralException, NotFoundException { if (request == null) { throw new IllegalArgumentException(REQUEST_VALUE_MUST_BE_SPECIFIED); } @@ -212,7 +221,7 @@ public T getJsonData(final String request, final P payload, final String if (!isURLAbsolute(url)) { url = serviceUrl + url; } - final APIResponse apiResponse = doRequest(requestType, url, payload); + final APIResponse apiResponse = doRequest(requestType, url, headers, payload); final String body = apiResponse.getBody(); final int status = apiResponse.getStatus(); @@ -256,11 +265,12 @@ private void handleHttpFailStatuses(final int status, String body) throws Unauth * * @param method HTTP method. * @param url Absolute URL. + * @param headers additional headers to set on the request. * @param payload Payload to JSON encode for the request body. May be null. * @param

Type of the payload. * @return APIResponse containing the response's body and status. */ -

APIResponse doRequest(final String method, final String url, final P payload) throws GeneralException { +

APIResponse doRequest(final String method, final String url, final Map headers, final P payload) throws GeneralException { HttpURLConnection connection = null; InputStream inputStream = null; @@ -275,7 +285,7 @@

APIResponse doRequest(final String method, final String url, final P payload } try { - connection = getConnection(url, payload, method); + connection = getConnection(url, payload, method, headers); int status = connection.getResponseCode(); if (APIResponse.isSuccessStatus(status)) { @@ -450,6 +460,20 @@ private boolean isURLAbsolute(String url) { * @throws IOException io exception */ public

HttpURLConnection getConnection(final String serviceUrl, final P body, final String requestType) throws IOException { + return getConnection(serviceUrl, body, requestType, new HashMap<>()); + } + + /** + * Create a HttpURLConnection connection object + * + * @param serviceUrl URL that needs to be requested + * @param body body could not be empty for POST or PUT requests + * @param requestType Request type POST requests without a payload will generate a exception + * @param headers additional headers to set on the request + * @return base class + * @throws IOException io exception + */ + public

HttpURLConnection getConnection(final String serviceUrl, final P body, final String requestType, final Map headers) throws IOException { if (requestType == null || !REQUEST_METHODS.contains(requestType)) { throw new IllegalArgumentException(String.format(REQUEST_METHOD_NOT_ALLOWED, requestType)); } @@ -485,22 +509,40 @@ public

HttpURLConnection getConnection(final String serviceUrl, final P body DateFormat df = getDateFormat(); mapper.setDateFormat(df); - final String json = mapper.writeValueAsString(body); - connection.getOutputStream().write(json.getBytes(String.valueOf(StandardCharsets.UTF_8))); + setAdditionalHeaders(connection, headers); + + byte[] bodyBytes; + if (body instanceof byte[]) { + bodyBytes = (byte[]) body; + } else { + final String json = mapper.writeValueAsString(body); + bodyBytes = json.getBytes(StandardCharsets.UTF_8); + } + connection.getOutputStream().write(bodyBytes); } else if ("DELETE".equals(requestType)) { // could have just used rquestType as it is connection.setDoOutput(false); connection.setRequestMethod("DELETE"); connection.setRequestProperty("Content-Type", "text/plain"); + + setAdditionalHeaders(connection, headers); } else { connection.setDoOutput(false); connection.setRequestMethod("GET"); connection.setRequestProperty("Content-Type", "text/plain"); + + setAdditionalHeaders(connection, headers); } return connection; } + private void setAdditionalHeaders(HttpURLConnection connection, Map headers) { + for (Map.Entry header : headers.entrySet()) { + connection.setRequestProperty(header.getKey(), header.getValue()); + } + } + private DateFormat getDateFormat() { double javaVersion = DEFAULT_JAVA_VERSION; try { diff --git a/api/src/main/java/com/messagebird/objects/FileUploadResponse.java b/api/src/main/java/com/messagebird/objects/FileUploadResponse.java new file mode 100644 index 00000000..29155a63 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/FileUploadResponse.java @@ -0,0 +1,21 @@ +package com.messagebird.objects; + +public class FileUploadResponse { + + private String id; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Override + public String toString() { + return "FileUploadResponse{" + + "id='" + id + '\'' + + '}'; + } +} diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 031aa16e..ff7c6d94 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -10,9 +10,8 @@ import org.junit.Test; import org.mockito.Mockito; -import java.io.UnsupportedEncodingException; +import java.io.*; import java.math.BigInteger; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; @@ -954,4 +953,93 @@ public void testDeleteRecording() throws NotFoundException, GeneralException, Un messageBirdClientMock.deleteRecording("ANY_CALL_ID", "ANY_LEG_ID","recordingID"); verify(messageBirdServiceMock, times(1)).deleteByID(url , "recordingID"); } + + @Test + public void testMockUploadFile() throws GeneralException, UnauthorizedException { + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdServiceMock); + byte[] binary = {1, 2, 3, 4, 5, 6}; + String contentType = "image/png"; + messageBirdClient.uploadFile(binary, contentType); + String url = MESSAGING_BASE_URL + FILES_PATH; + final Map headers = new HashMap<>(); + headers.put("Content-Type", contentType); + verify(messageBirdServiceMock, times(1)).sendPayLoad("POST", url, headers, binary, FileUploadResponse.class); + } + + @Test + public void testUploadFileWithNullBinary() { + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdServiceMock); + String contentType = "image/png"; + assertThrows(IllegalArgumentException.class, () -> messageBirdClient.uploadFile(null, contentType)); + } + + @Test + public void testUploadFileWithNullContentType() { + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdServiceMock); + byte[] binary = {1, 2, 3, 4, 5, 6}; + assertThrows(IllegalArgumentException.class, () -> messageBirdClient.uploadFile(binary, null)); + } + + @Test + public void testMockDownloadFile() throws GeneralException, UnauthorizedException, NotFoundException { + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdServiceMock); + String id = "8144d3bf-6228-4b0e-903f-022d8917f297"; + String filename = "file.png"; + String basePath = "/base/path"; + messageBirdClient.downloadFile(id, filename, basePath); + String url = MESSAGING_BASE_URL + FILES_PATH + "/" + id; + verify(messageBirdServiceMock, times(1)).getBinaryData(url, basePath, filename); + } + + @Test + public void testDownloadFileWithNullId() { + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdServiceMock); + String filename = "file.png"; + String basePath = "/base/path"; + assertThrows(IllegalArgumentException.class, () -> messageBirdClient.downloadFile(null, filename, basePath)); + } + + @Test + public void testDownloadFileWithNullFilename() { + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdServiceMock); + String id = "8144d3bf-6228-4b0e-903f-022d8917f297"; + String basePath = "/base/path"; + assertThrows(IllegalArgumentException.class, () -> messageBirdClient.downloadFile(id, null, basePath)); + } + + @Test + public void testDownloadFileWithNullBasePath() throws GeneralException, UnauthorizedException, NotFoundException { + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdServiceMock); + String id = "8144d3bf-6228-4b0e-903f-022d8917f297"; + String filename = "file.png"; + messageBirdClient.downloadFile(id, filename, null); + String url = MESSAGING_BASE_URL + FILES_PATH + "/" + id; + verify(messageBirdServiceMock, times(1)).getBinaryData(url, null, filename); + } + + @Test + public void testUploadAndDownloadFile() throws GeneralException, UnauthorizedException, NotFoundException, IOException { + byte[] binary = {1, 2, 3, 4, 5, 6}; + String contentType = "image/png"; + FileUploadResponse response = messageBirdClient.uploadFile(binary, contentType); + assertNotNull(response.getId()); + String filepath = messageBirdClient.downloadFile(response.getId(), "file.png", null); + File file = new File(filepath); + assertTrue(file.exists()); + InputStream inputStream = new FileInputStream(file); + byte[] output = new byte[binary.length]; + assertEquals(binary.length, inputStream.read(output)); + for (int i = 0; i < output.length; i++) { + assertEquals(binary[i], output[i]); + } + inputStream.close(); + file.deleteOnExit(); + } } diff --git a/api/src/test/java/com/messagebird/SpyService.java b/api/src/test/java/com/messagebird/SpyService.java index ec7a03fe..7b741e9f 100644 --- a/api/src/test/java/com/messagebird/SpyService.java +++ b/api/src/test/java/com/messagebird/SpyService.java @@ -2,6 +2,8 @@ import com.messagebird.exceptions.GeneralException; +import java.util.HashMap; + import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; @@ -147,7 +149,7 @@ MessageBirdService andReturns(final APIResponse apiResponse) throws GeneralExcep } MessageBirdServiceImpl messageBirdService = spy(new MessageBirdServiceImpl(getAccessKey())); - doReturn(apiResponse).when(messageBirdService).doRequest(method, url, payload); + doReturn(apiResponse).when(messageBirdService).doRequest(method, url, new HashMap<>(), payload); return messageBirdService; } From a8807c0737fd17db6f9e9a34393e96b0589df225 Mon Sep 17 00:00:00 2001 From: Rafe Arnold Date: Wed, 26 May 2021 10:33:13 +0100 Subject: [PATCH 283/516] Add optional filename parameter to MessageBirdClient.uploadFile method. --- .../com/messagebird/MessageBirdClient.java | 6 ++++- .../messagebird/MessageBirdClientTest.java | 25 ++++++++++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 4bbe6ff4..cac344fb 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1777,12 +1777,13 @@ public void cancelNumber(String number) throws UnauthorizedException, GeneralExc * * @param binary the bytes of the file to upload. * @param contentType the content type of the file (e.g. "image/png"). + * @param filename optional filename to set in the upload request headers. * @return FileUploadResponse * @throws GeneralException general exception * @throws UnauthorizedException if client is unauthorized * @see #downloadFile */ - public FileUploadResponse uploadFile(byte[] binary, String contentType) throws GeneralException, UnauthorizedException { + public FileUploadResponse uploadFile(byte[] binary, String contentType, String filename) throws GeneralException, UnauthorizedException { if (binary == null) { throw new IllegalArgumentException("File binary must be specified."); } @@ -1793,6 +1794,9 @@ public FileUploadResponse uploadFile(byte[] binary, String contentType) throws G final String url = MESSAGING_BASE_URL + FILES_PATH; final Map headers = new HashMap<>(); headers.put("Content-Type", contentType); + if (filename != null) { + headers.put("filename", filename); + } return messageBirdService.sendPayLoad("POST", url, headers, binary, FileUploadResponse.class); } diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index ff7c6d94..1221749d 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -960,10 +960,12 @@ public void testMockUploadFile() throws GeneralException, UnauthorizedException MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdServiceMock); byte[] binary = {1, 2, 3, 4, 5, 6}; String contentType = "image/png"; - messageBirdClient.uploadFile(binary, contentType); + String filename = "filename.png"; + messageBirdClient.uploadFile(binary, contentType, filename); String url = MESSAGING_BASE_URL + FILES_PATH; final Map headers = new HashMap<>(); headers.put("Content-Type", contentType); + headers.put("filename", filename); verify(messageBirdServiceMock, times(1)).sendPayLoad("POST", url, headers, binary, FileUploadResponse.class); } @@ -972,7 +974,8 @@ public void testUploadFileWithNullBinary() { MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdServiceMock); String contentType = "image/png"; - assertThrows(IllegalArgumentException.class, () -> messageBirdClient.uploadFile(null, contentType)); + String filename = "filename.png"; + assertThrows(IllegalArgumentException.class, () -> messageBirdClient.uploadFile(null, contentType, filename)); } @Test @@ -980,7 +983,21 @@ public void testUploadFileWithNullContentType() { MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdServiceMock); byte[] binary = {1, 2, 3, 4, 5, 6}; - assertThrows(IllegalArgumentException.class, () -> messageBirdClient.uploadFile(binary, null)); + String filename = "filename.png"; + assertThrows(IllegalArgumentException.class, () -> messageBirdClient.uploadFile(binary, null, filename)); + } + + @Test + public void testUploadFileWithNullFilename() throws GeneralException, UnauthorizedException { + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdServiceMock); + byte[] binary = {1, 2, 3, 4, 5, 6}; + String contentType = "image/png"; + messageBirdClient.uploadFile(binary, contentType, null); + String url = MESSAGING_BASE_URL + FILES_PATH; + final Map headers = new HashMap<>(); + headers.put("Content-Type", contentType); + verify(messageBirdServiceMock, times(1)).sendPayLoad("POST", url, headers, binary, FileUploadResponse.class); } @Test @@ -1028,7 +1045,7 @@ public void testDownloadFileWithNullBasePath() throws GeneralException, Unauthor public void testUploadAndDownloadFile() throws GeneralException, UnauthorizedException, NotFoundException, IOException { byte[] binary = {1, 2, 3, 4, 5, 6}; String contentType = "image/png"; - FileUploadResponse response = messageBirdClient.uploadFile(binary, contentType); + FileUploadResponse response = messageBirdClient.uploadFile(binary, contentType, null); assertNotNull(response.getId()); String filepath = messageBirdClient.downloadFile(response.getId(), "file.png", null); File file = new File(filepath); From 5a352145c4c554a58ec5dba708d83351b11a149f Mon Sep 17 00:00:00 2001 From: Rafe Arnold Date: Wed, 26 May 2021 10:39:30 +0100 Subject: [PATCH 284/516] Allow null filename parameter in MessageBirdClient.downloadFile method. --- api/src/main/java/com/messagebird/MessageBirdClient.java | 6 ++++-- .../test/java/com/messagebird/MessageBirdClientTest.java | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index cac344fb..d9e7261c 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1803,7 +1803,8 @@ public FileUploadResponse uploadFile(byte[] binary, String contentType, String f /** * Downloads a file and stores it with the provided filename in the basePath directory. The * basePath may be null. If basePath is null, the default download directory will be the - * /Download folder in the user home directory. + * /Download folder in the user home directory. The filename may be null. If filename is null, + * the provided id will be used as the filename instead. * * @param id the ID of the file, provided when the file was uploaded * @param basePath store location. It should be a directory. Property is nullable if $HOME is accessible @@ -1818,8 +1819,9 @@ public String downloadFile(String id, String filename, String basePath) throws G if (id == null) { throw new IllegalArgumentException("File ID must be specified."); } + if (filename == null) { - throw new IllegalArgumentException("Filename must be specified."); + filename = id; } final String url = String.format("%s%s/%s", MESSAGING_BASE_URL, FILES_PATH, id); diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 1221749d..83ac4ae9 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -1022,12 +1022,14 @@ public void testDownloadFileWithNullId() { } @Test - public void testDownloadFileWithNullFilename() { + public void testDownloadFileWithNullFilename() throws GeneralException, UnauthorizedException, NotFoundException { MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdServiceMock); String id = "8144d3bf-6228-4b0e-903f-022d8917f297"; String basePath = "/base/path"; - assertThrows(IllegalArgumentException.class, () -> messageBirdClient.downloadFile(id, null, basePath)); + messageBirdClient.downloadFile(id, null, basePath); + String url = MESSAGING_BASE_URL + FILES_PATH + "/" + id; + verify(messageBirdServiceMock, times(1)).getBinaryData(url, basePath, id); } @Test From 672f87e26da4583510653a395a4d5ebd635d8346 Mon Sep 17 00:00:00 2001 From: Rafe Arnold Date: Wed, 26 May 2021 12:58:22 +0100 Subject: [PATCH 285/516] Remove end-to-end test for file upload and download. --- .../messagebird/MessageBirdClientTest.java | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 83ac4ae9..956b177b 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -1042,23 +1042,4 @@ public void testDownloadFileWithNullBasePath() throws GeneralException, Unauthor String url = MESSAGING_BASE_URL + FILES_PATH + "/" + id; verify(messageBirdServiceMock, times(1)).getBinaryData(url, null, filename); } - - @Test - public void testUploadAndDownloadFile() throws GeneralException, UnauthorizedException, NotFoundException, IOException { - byte[] binary = {1, 2, 3, 4, 5, 6}; - String contentType = "image/png"; - FileUploadResponse response = messageBirdClient.uploadFile(binary, contentType, null); - assertNotNull(response.getId()); - String filepath = messageBirdClient.downloadFile(response.getId(), "file.png", null); - File file = new File(filepath); - assertTrue(file.exists()); - InputStream inputStream = new FileInputStream(file); - byte[] output = new byte[binary.length]; - assertEquals(binary.length, inputStream.read(output)); - for (int i = 0; i < output.length; i++) { - assertEquals(binary[i], output[i]); - } - inputStream.close(); - file.deleteOnExit(); - } } From f165aa286de3f6cb046a9f968720fcf331485c21 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Wed, 26 May 2021 17:41:13 +0200 Subject: [PATCH 286/516] updated ErrorReport class --- .../main/java/com/messagebird/objects/ErrorReport.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/objects/ErrorReport.java b/api/src/main/java/com/messagebird/objects/ErrorReport.java index d0d63d5a..afd7dcf9 100644 --- a/api/src/main/java/com/messagebird/objects/ErrorReport.java +++ b/api/src/main/java/com/messagebird/objects/ErrorReport.java @@ -1,6 +1,9 @@ package com.messagebird.objects; import com.fasterxml.jackson.annotation.JsonInclude; + +import java.io.Serializable; + /** * When MessageBird returns a 4xx, you will find a list of any error codes in your return dataset. * you will receive a list of errors from the API in such case. @@ -8,7 +11,10 @@ * Created by rvt on 1/5/15. */ @JsonInclude(JsonInclude.Include.NON_EMPTY) -public class ErrorReport { +public class ErrorReport implements Serializable { + + private static final long serialVersionUID = -8611665867089703268L; + private Integer code; private String description; private String parameter; From c146c0976c6a0991878aa6f176f9813882ce37a6 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Wed, 26 May 2021 18:04:49 +0200 Subject: [PATCH 287/516] changes for the new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index ad6ae2d6..242eeb9d 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.0.22 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index bb512fd4..952881e4 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -61,7 +61,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.0.22"; + private final String clientVersion = "3.1.0"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index eefe48cc..bc49e7d2 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.0.22 + 3.1.0 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.0.22 + 3.1.0 compile From cf68ef3da0ff59944286896513c20fdf6ab3dc96 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Wed, 26 May 2021 18:05:39 +0200 Subject: [PATCH 288/516] [maven-release-plugin] prepare release v3.1.0 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 242eeb9d..5efdb982 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.0-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.1.0 From de449a6980f8ae58bee7a033c9be29b23d74eeed Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Wed, 26 May 2021 18:05:45 +0200 Subject: [PATCH 289/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 5efdb982..4dd1ee64 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.0 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.1.0 + HEAD From b2c8c3b8ad50cef04220c45692e3d117884193b3 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Thu, 27 May 2021 09:43:47 +0200 Subject: [PATCH 290/516] new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 4dd1ee64..77123e78 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.1-SNAPSHOT From 20ca0793a99e3032f0381bdf3c49f36248a0a4ee Mon Sep 17 00:00:00 2001 From: Rafe Arnold Date: Mon, 21 Jun 2021 12:21:41 +0100 Subject: [PATCH 291/516] Fix MessageBirdClient.updateConversation method. --- .../com/messagebird/MessageBirdClient.java | 7 ++++- .../ConversationUpdateRequest.java | 29 +++++++++++++++++++ .../com/messagebird/ConversationsTest.java | 2 +- 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 api/src/main/java/com/messagebird/objects/conversations/ConversationUpdateRequest.java diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index d9e7261c..4315e313 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -40,6 +40,7 @@ import com.messagebird.objects.conversations.ConversationSendResponse; import com.messagebird.objects.conversations.ConversationStartRequest; import com.messagebird.objects.conversations.ConversationStatus; +import com.messagebird.objects.conversations.ConversationUpdateRequest; import com.messagebird.objects.conversations.ConversationWebhook; import com.messagebird.objects.conversations.ConversationWebhookCreateRequest; import com.messagebird.objects.conversations.ConversationWebhookList; @@ -903,8 +904,12 @@ public Conversation updateConversation(final String id, final ConversationStatus if (id == null) { throw new IllegalArgumentException("Id must be specified."); } + if (status == null) { + throw new IllegalArgumentException("An updated conversation status must be specified"); + } + ConversationUpdateRequest payload = new ConversationUpdateRequest(status); String url = String.format("%s%s/%s", CONVERSATIONS_BASE_URL, CONVERSATION_PATH, id); - return messageBirdService.sendPayLoad("PATCH", url, status, Conversation.class); + return messageBirdService.sendPayLoad("PATCH", url, payload, Conversation.class); } /** diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationUpdateRequest.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationUpdateRequest.java new file mode 100644 index 00000000..9a67a516 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationUpdateRequest.java @@ -0,0 +1,29 @@ +package com.messagebird.objects.conversations; + +import java.util.Objects; + +public class ConversationUpdateRequest { + + private final ConversationStatus status; + + public ConversationUpdateRequest(ConversationStatus status) { + this.status = status; + } + + public ConversationStatus getStatus() { + return status; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ConversationUpdateRequest that = (ConversationUpdateRequest) o; + return status == that.status; + } + + @Override + public int hashCode() { + return Objects.hash(status); + } +} diff --git a/api/src/test/java/com/messagebird/ConversationsTest.java b/api/src/test/java/com/messagebird/ConversationsTest.java index 81095dc3..4e7624e8 100644 --- a/api/src/test/java/com/messagebird/ConversationsTest.java +++ b/api/src/test/java/com/messagebird/ConversationsTest.java @@ -76,7 +76,7 @@ public void testStartConversation() throws GeneralException, UnauthorizedExcepti @Test public void testUpdateConversation() throws GeneralException, UnauthorizedException { MessageBirdService messageBirdService = SpyService - .expects("PATCH", "conversations/convid", ConversationStatus.ARCHIVED) + .expects("PATCH", "conversations/convid", new ConversationUpdateRequest(ConversationStatus.ARCHIVED)) .withConversationsAPIBaseURL() .andReturns(new APIResponse(JSON_CONVERSATION)); MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); From bf6714881dd660c875fcb11caa3997c406959ab5 Mon Sep 17 00:00:00 2001 From: Rafe Arnold Date: Mon, 21 Jun 2021 15:12:04 +0100 Subject: [PATCH 292/516] Add example for updating conversation. --- .../main/java/ExampleUpdateConversation.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 examples/src/main/java/ExampleUpdateConversation.java diff --git a/examples/src/main/java/ExampleUpdateConversation.java b/examples/src/main/java/ExampleUpdateConversation.java new file mode 100644 index 00000000..0dc58be3 --- /dev/null +++ b/examples/src/main/java/ExampleUpdateConversation.java @@ -0,0 +1,34 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.conversations.*; + +public class ExampleUpdateConversation { + + public static void main(String[] args) { + if (args.length < 3) { + System.out.println("Please specify your access key, the ID of a conversation and the status to update the conversation to." + + " Example : java -jar test_accesskey test_conversationId archived"); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + final ConversationStatus newStatus = ConversationStatus.forValue(args[2]); + try { + final Conversation response = messageBirdClient.updateConversation(args[1], newStatus); + // Display message response + System.out.println(response.toString()); + } catch (UnauthorizedException | GeneralException exception) { + if (exception.getErrors() != null) { + System.out.println(exception.getErrors().toString()); + } + exception.printStackTrace(); + } + } +} From 0531ab6f7335f0c249ca345d02a36b9bbf108b61 Mon Sep 17 00:00:00 2001 From: Leandro Pinto Date: Wed, 23 Jun 2021 00:05:05 +0200 Subject: [PATCH 293/516] Adding support to new functionality from Verify which enables Email as a channel to be used for sending OTP messages --- .../com/messagebird/MessageBirdClient.java | 20 ++++++++ .../messagebird/objects/VerifyMessage.java | 35 +++++++++++++ .../messagebird/objects/VerifyRequest.java | 13 +++++ .../com/messagebird/objects/VerifyType.java | 3 +- .../test/java/com/messagebird/VerifyTest.java | 22 ++++++++- .../src/main/java/ExampleVerifyEmail.java | 49 +++++++++++++++++++ .../src/main/java/ExampleVerifyToken.java | 44 ----------------- 7 files changed, 139 insertions(+), 47 deletions(-) create mode 100644 api/src/main/java/com/messagebird/objects/VerifyMessage.java create mode 100644 examples/src/main/java/ExampleVerifyEmail.java delete mode 100644 examples/src/main/java/ExampleVerifyToken.java diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index d9e7261c..48f9a157 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -27,6 +27,7 @@ import com.messagebird.objects.PurchasedNumbersResponse; import com.messagebird.objects.PurchasedNumbersFilter; import com.messagebird.objects.Verify; +import com.messagebird.objects.VerifyMessage; import com.messagebird.objects.VerifyRequest; import com.messagebird.objects.VoiceMessage; import com.messagebird.objects.VoiceMessageList; @@ -110,6 +111,7 @@ public class MessageBirdClient { private static final String LOOKUPPATH = "/lookup"; private static final String MESSAGESPATH = "/messages"; private static final String VERIFYPATH = "/verify"; + private static final String VERIFYEMAILPATH = "/verify/messages/email"; private static final String VOICEMESSAGESPATH = "/voicemessages"; private static final String CONVERSATION_PATH = "/conversations"; private static final String CONVERSATION_SEND_PATH = "/send"; @@ -492,6 +494,24 @@ Verify getVerifyObject(String id) throws NotFoundException, GeneralException, Un return messageBirdService.requestByID(VERIFYPATH, id, Verify.class); } + /** + * + * This method can be used to retrieve a Verify Email Message + * + * @param id id is for the email message part of a verify object + * @return Verify object + * @throws NotFoundException if id is not found + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + */ + public VerifyMessage getVerifyEmailMessage(String messageId) throws UnauthorizedException, GeneralException, NotFoundException { + // TODO Auto-generated method stub + if (messageId == null || messageId.isEmpty()) { + throw new IllegalArgumentException("ID cannot be empty for verify email message"); + } + return messageBirdService.requestByID(VERIFYEMAILPATH, messageId, VerifyMessage.class); + } + /** * @param id id for deleting verify object * @throws NotFoundException if id is not found diff --git a/api/src/main/java/com/messagebird/objects/VerifyMessage.java b/api/src/main/java/com/messagebird/objects/VerifyMessage.java new file mode 100644 index 00000000..b2929f11 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/VerifyMessage.java @@ -0,0 +1,35 @@ +package com.messagebird.objects; + +import java.io.Serializable; + +/** + * Created by leandro.pinto on 22/06/15. + */ +public class VerifyMessage implements Serializable { + + private String id; + private String status; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String toString() { + return "VerifyMessage {" + " " + + "id=" + this.id + " " + + "status=" + this.status + " " + + "}"; + } +} diff --git a/api/src/main/java/com/messagebird/objects/VerifyRequest.java b/api/src/main/java/com/messagebird/objects/VerifyRequest.java index 45a6b194..e08f095e 100644 --- a/api/src/main/java/com/messagebird/objects/VerifyRequest.java +++ b/api/src/main/java/com/messagebird/objects/VerifyRequest.java @@ -17,6 +17,7 @@ public class VerifyRequest implements Serializable { private Integer tokenLength; private Gender voice; private Language language; + private String subject; public VerifyRequest(String recipient) { this.recipient = recipient; @@ -54,6 +55,11 @@ public void setType(VerifyType type) { this.type = type; } + public void setType(String type) { + this.type = VerifyType.valueOf(type.toUpperCase()); + } + + /** * The datacoding used by the template. * @@ -112,4 +118,11 @@ public void setLanguage(Language language) { this.language = language; } + public void setSubject(String subject) { + this.subject = subject; + } + + public String getSubject() { + return subject; + } } diff --git a/api/src/main/java/com/messagebird/objects/VerifyType.java b/api/src/main/java/com/messagebird/objects/VerifyType.java index 8965e7a2..630e8e53 100644 --- a/api/src/main/java/com/messagebird/objects/VerifyType.java +++ b/api/src/main/java/com/messagebird/objects/VerifyType.java @@ -9,7 +9,8 @@ public enum VerifyType { FLASH("flash"), SMS("sms"), - TTS("tts"); + TTS("tts"), + EMAIL("email"); final String value; diff --git a/api/src/test/java/com/messagebird/VerifyTest.java b/api/src/test/java/com/messagebird/VerifyTest.java index 6a3d1a80..7ec8565e 100644 --- a/api/src/test/java/com/messagebird/VerifyTest.java +++ b/api/src/test/java/com/messagebird/VerifyTest.java @@ -12,8 +12,9 @@ public class VerifyTest { - private static final String VERIFY_SMS_RESPONSE = "{\"id\": \"verify-id-sms\",\"href\": \"https://rest.messagebird.com/verify/verify-id-sms\",\"recipient\": 31612345678,\"reference\": null,\"messages\": {\"href\": \"https://rest.messagebird.com/messages/5958c0d5e2df41de8154e5e88bfeb5bc\"},\"status\": \"sent\",\"createdDatetime\": \"2018-09-25T14:38:12+00:00\",\"validUntilDatetime\": \"2018-09-25T14:38:42+00:00\"}"; - private static final String VERIFY_TTS_RESPONSE = "{\"id\": \"verify-id-tts\",\"href\": \"https://rest.messagebird.com/verify/verify-id-tts\",\"recipient\": 31612345678,\"reference\": null,\"messages\": {\"href\": \"https://rest.messagebird.com/voicemessages/c043ab473f8e4f2590ab9a16d25f2899\"},\"status\": \"sent\",\"createdDatetime\": \"2018-09-25T14:35:10+00:00\",\"validUntilDatetime\": \"2018-09-25T14:35:40+00:00\"}"; + private static final String VERIFY_SMS_RESPONSE = "{\"id\": \"verify-id-sms\",\"href\": \"https://rest.messagebird.com/verify/verify-id-sms\",\"recipient\": 31612345678,\"reference\": null,\"messages\": {\"href\": \"https://rest.messagebird.com/messages/5958c0d5e2df41de8154e5e88bfeb5bc\"},\"status\": \"sent\",\"createdDatetime\": \"2018-09-25T14:38:12+00:00\",\"validUntilDatetime\": \"2018-09-25T14:38:42+00:00\"}"; + private static final String VERIFY_TTS_RESPONSE = "{\"id\": \"verify-id-tts\",\"href\": \"https://rest.messagebird.com/verify/verify-id-tts\",\"recipient\": 31612345678,\"reference\": null,\"messages\": {\"href\": \"https://rest.messagebird.com/voicemessages/c043ab473f8e4f2590ab9a16d25f2899\"},\"status\": \"sent\",\"createdDatetime\": \"2018-09-25T14:35:10+00:00\",\"validUntilDatetime\": \"2018-09-25T14:35:40+00:00\"}"; + private static final String VERIFY_EMAIL_RESPONSE = "{\"id\": \"verify-id-email\",\"href\": \"https://rest.messagebird.com/verify/verify-id-email\",\"recipient\": \"test@mb.com\",\"reference\": null,\"messages\": {\"href\": \"https://rest.messagebird.com/verify/messages/email/c043ab473f8e4f2590ab9a16d25f2899\"},\"status\": \"sent\",\"createdDatetime\": \"2018-09-25T14:35:10+00:00\",\"validUntilDatetime\": \"2018-09-25T14:35:40+00:00\"}"; @Test public void testSendVerifyTokenSms() throws GeneralException, UnauthorizedException { @@ -47,11 +48,28 @@ public void testSendVerifyTokenTts() throws GeneralException, UnauthorizedExcept assertEquals("verify-id-tts", verify.getId()); } + @Test + public void testSendVerifyTokenEmail() throws GeneralException, UnauthorizedException { + VerifyRequest verifyRequest = new VerifyRequest("rec@mb.com"); + verifyRequest.setType(VerifyType.EMAIL); + + MessageBirdService messageBirdService = SpyService + .expects("POST", "verify", verifyRequest) + .withRestAPIBaseURL() + .andReturns(new APIResponse(VERIFY_EMAIL_RESPONSE, 200)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + + Verify verify = messageBirdClient.sendVerifyToken(verifyRequest); + + assertEquals("verify-id-email", verify.getId()); + } + @Test public void testVerifyTypeValue() { // Important for generating proper JSON payloads... assertEquals("flash", VerifyType.FLASH.getValue()); assertEquals("sms", VerifyType.SMS.getValue()); assertEquals("tts", VerifyType.TTS.getValue()); + assertEquals("email", VerifyType.EMAIL.getValue()); } } diff --git a/examples/src/main/java/ExampleVerifyEmail.java b/examples/src/main/java/ExampleVerifyEmail.java new file mode 100644 index 00000000..8ea3f4cc --- /dev/null +++ b/examples/src/main/java/ExampleVerifyEmail.java @@ -0,0 +1,49 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.Verify; +import com.messagebird.objects.VerifyMessage; +import com.messagebird.objects.VerifyRequest; + +/** + * Created by faizan on 10/12/15. + */ +public class ExampleVerifyEmail { + + public static void main(String[] args) throws UnauthorizedException, GeneralException, NotFoundException { + + final String ACCESS_KEY = args[0]; + final String METHOD = args[1]; + + final MessageBirdService wsr = new MessageBirdServiceImpl(ACCESS_KEY); + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + if("send".equals(METHOD)) { + VerifyRequest request = new VerifyRequest(""); + request.setType("email"); + request.setOriginator(""); + request.setSubject(""); + request.setTimeout(300); + + + Verify verify = messageBirdClient.sendVerifyToken(request); + System.out.println(verify.toString()); + } + else if("verify".equals(METHOD)) { + final String VERIFY_ID = args[2]; + final String TOKEN = args[3]; + + Verify verify = messageBirdClient.verifyToken(VERIFY_ID, TOKEN); + System.out.println(verify.toString()); + } + else if("view".equals(METHOD)) { + final String MESSAGE_ID = args[2]; + VerifyMessage verify = messageBirdClient.getVerifyEmailMessage(MESSAGE_ID); + System.out.println(verify.toString()); + } + } +} diff --git a/examples/src/main/java/ExampleVerifyToken.java b/examples/src/main/java/ExampleVerifyToken.java deleted file mode 100644 index 41eb28f8..00000000 --- a/examples/src/main/java/ExampleVerifyToken.java +++ /dev/null @@ -1,44 +0,0 @@ -import com.messagebird.MessageBirdClient; -import com.messagebird.MessageBirdService; -import com.messagebird.MessageBirdServiceImpl; -import com.messagebird.exceptions.GeneralException; -import com.messagebird.exceptions.NotFoundException; -import com.messagebird.exceptions.UnauthorizedException; -import com.messagebird.objects.Verify; - -/** - * Created by faizan on 10/12/15. - */ -public class ExampleVerifyToken { - - public static void main(String[] args) { - if (args.length < 3) { - System.out.println("Please specify your access key, verifyId and a token : java -jar test_accessKey verifyId token"); - return; - } - - // First create your service object - final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); - - // Add the service to the client - final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); - - - try { - // Send verify token - final String verifyId = args[1]; - final String token = args[2]; - - System.out.println("verifying token request: " + token); - //Sending token to verify - final Verify verify = messageBirdClient.verifyToken(verifyId, token); - //Display result - System.out.println(verify.toString()); - } catch (UnauthorizedException | GeneralException | NotFoundException exception) { - if (exception.getErrors() != null) { - System.out.println(exception.getErrors().toString()); - } - exception.printStackTrace(); - } - } -} From 0509dbc348d6f436949d61ce84998108643e02b5 Mon Sep 17 00:00:00 2001 From: Rafe Arnold Date: Mon, 21 Jun 2021 12:21:41 +0100 Subject: [PATCH 294/516] Fix MessageBirdClient.updateConversation method. --- .../com/messagebird/MessageBirdClient.java | 7 ++++- .../ConversationUpdateRequest.java | 29 +++++++++++++++++++ .../com/messagebird/ConversationsTest.java | 2 +- 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 api/src/main/java/com/messagebird/objects/conversations/ConversationUpdateRequest.java diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 48f9a157..51ea0c03 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -41,6 +41,7 @@ import com.messagebird.objects.conversations.ConversationSendResponse; import com.messagebird.objects.conversations.ConversationStartRequest; import com.messagebird.objects.conversations.ConversationStatus; +import com.messagebird.objects.conversations.ConversationUpdateRequest; import com.messagebird.objects.conversations.ConversationWebhook; import com.messagebird.objects.conversations.ConversationWebhookCreateRequest; import com.messagebird.objects.conversations.ConversationWebhookList; @@ -923,8 +924,12 @@ public Conversation updateConversation(final String id, final ConversationStatus if (id == null) { throw new IllegalArgumentException("Id must be specified."); } + if (status == null) { + throw new IllegalArgumentException("An updated conversation status must be specified"); + } + ConversationUpdateRequest payload = new ConversationUpdateRequest(status); String url = String.format("%s%s/%s", CONVERSATIONS_BASE_URL, CONVERSATION_PATH, id); - return messageBirdService.sendPayLoad("PATCH", url, status, Conversation.class); + return messageBirdService.sendPayLoad("PATCH", url, payload, Conversation.class); } /** diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationUpdateRequest.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationUpdateRequest.java new file mode 100644 index 00000000..9a67a516 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationUpdateRequest.java @@ -0,0 +1,29 @@ +package com.messagebird.objects.conversations; + +import java.util.Objects; + +public class ConversationUpdateRequest { + + private final ConversationStatus status; + + public ConversationUpdateRequest(ConversationStatus status) { + this.status = status; + } + + public ConversationStatus getStatus() { + return status; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ConversationUpdateRequest that = (ConversationUpdateRequest) o; + return status == that.status; + } + + @Override + public int hashCode() { + return Objects.hash(status); + } +} diff --git a/api/src/test/java/com/messagebird/ConversationsTest.java b/api/src/test/java/com/messagebird/ConversationsTest.java index 81095dc3..4e7624e8 100644 --- a/api/src/test/java/com/messagebird/ConversationsTest.java +++ b/api/src/test/java/com/messagebird/ConversationsTest.java @@ -76,7 +76,7 @@ public void testStartConversation() throws GeneralException, UnauthorizedExcepti @Test public void testUpdateConversation() throws GeneralException, UnauthorizedException { MessageBirdService messageBirdService = SpyService - .expects("PATCH", "conversations/convid", ConversationStatus.ARCHIVED) + .expects("PATCH", "conversations/convid", new ConversationUpdateRequest(ConversationStatus.ARCHIVED)) .withConversationsAPIBaseURL() .andReturns(new APIResponse(JSON_CONVERSATION)); MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); From c914197601e0f871be4a18ef375fa402569965df Mon Sep 17 00:00:00 2001 From: Rafe Arnold Date: Mon, 21 Jun 2021 15:12:04 +0100 Subject: [PATCH 295/516] Add example for updating conversation. --- .../main/java/ExampleUpdateConversation.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 examples/src/main/java/ExampleUpdateConversation.java diff --git a/examples/src/main/java/ExampleUpdateConversation.java b/examples/src/main/java/ExampleUpdateConversation.java new file mode 100644 index 00000000..0dc58be3 --- /dev/null +++ b/examples/src/main/java/ExampleUpdateConversation.java @@ -0,0 +1,34 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.conversations.*; + +public class ExampleUpdateConversation { + + public static void main(String[] args) { + if (args.length < 3) { + System.out.println("Please specify your access key, the ID of a conversation and the status to update the conversation to." + + " Example : java -jar test_accesskey test_conversationId archived"); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + final ConversationStatus newStatus = ConversationStatus.forValue(args[2]); + try { + final Conversation response = messageBirdClient.updateConversation(args[1], newStatus); + // Display message response + System.out.println(response.toString()); + } catch (UnauthorizedException | GeneralException exception) { + if (exception.getErrors() != null) { + System.out.println(exception.getErrors().toString()); + } + exception.printStackTrace(); + } + } +} From 79aa0fef00f7b100f1499ad8f14727f654c599e0 Mon Sep 17 00:00:00 2001 From: Leandro Pinto Date: Wed, 23 Jun 2021 11:38:15 +0200 Subject: [PATCH 296/516] Some adjustems to incorporate feedback from the initial PR --- .../com/messagebird/MessageBirdClient.java | 4 -- .../messagebird/objects/VerifyRequest.java | 17 +++--- .../src/main/java/ExampleVerifyEmail.java | 58 ++++++++++--------- 3 files changed, 38 insertions(+), 41 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 51ea0c03..0bff2580 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -496,9 +496,6 @@ Verify getVerifyObject(String id) throws NotFoundException, GeneralException, Un } /** - * - * This method can be used to retrieve a Verify Email Message - * * @param id id is for the email message part of a verify object * @return Verify object * @throws NotFoundException if id is not found @@ -506,7 +503,6 @@ Verify getVerifyObject(String id) throws NotFoundException, GeneralException, Un * @throws GeneralException general exception */ public VerifyMessage getVerifyEmailMessage(String messageId) throws UnauthorizedException, GeneralException, NotFoundException { - // TODO Auto-generated method stub if (messageId == null || messageId.isEmpty()) { throw new IllegalArgumentException("ID cannot be empty for verify email message"); } diff --git a/api/src/main/java/com/messagebird/objects/VerifyRequest.java b/api/src/main/java/com/messagebird/objects/VerifyRequest.java index e08f095e..70de2591 100644 --- a/api/src/main/java/com/messagebird/objects/VerifyRequest.java +++ b/api/src/main/java/com/messagebird/objects/VerifyRequest.java @@ -55,10 +55,9 @@ public void setType(VerifyType type) { this.type = type; } - public void setType(String type) { + public void setType(String type) { this.type = VerifyType.valueOf(type.toUpperCase()); - } - + } /** * The datacoding used by the template. @@ -118,11 +117,11 @@ public void setLanguage(Language language) { this.language = language; } - public void setSubject(String subject) { - this.subject = subject; - } + public void setSubject(String subject) { + this.subject = subject; + } - public String getSubject() { - return subject; - } + public String getSubject() { + return subject; + } } diff --git a/examples/src/main/java/ExampleVerifyEmail.java b/examples/src/main/java/ExampleVerifyEmail.java index 8ea3f4cc..b2ab99bf 100644 --- a/examples/src/main/java/ExampleVerifyEmail.java +++ b/examples/src/main/java/ExampleVerifyEmail.java @@ -9,41 +9,43 @@ import com.messagebird.objects.VerifyRequest; /** - * Created by faizan on 10/12/15. + * Created by leandro.pinto on 23/06/21. */ public class ExampleVerifyEmail { public static void main(String[] args) throws UnauthorizedException, GeneralException, NotFoundException { - - final String ACCESS_KEY = args[0]; - final String METHOD = args[1]; - + + final String ACCESS_KEY = args[0]; + final String METHOD = args[1]; + final MessageBirdService wsr = new MessageBirdServiceImpl(ACCESS_KEY); - // Add the service to the client final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + Verify verify = null; + + switch (METHOD) { + case "send": + VerifyRequest request = new VerifyRequest(""); + request.setType("email"); + request.setOriginator(""); + request.setSubject(""); + request.setTimeout(300); + + verify = messageBirdClient.sendVerifyToken(request); + System.out.println(verify.toString()); + + break; + case "verify": + final String VERIFY_ID = args[2]; + final String TOKEN = args[3]; - if("send".equals(METHOD)) { - VerifyRequest request = new VerifyRequest(""); - request.setType("email"); - request.setOriginator(""); - request.setSubject(""); - request.setTimeout(300); - - - Verify verify = messageBirdClient.sendVerifyToken(request); - System.out.println(verify.toString()); - } - else if("verify".equals(METHOD)) { - final String VERIFY_ID = args[2]; - final String TOKEN = args[3]; - - Verify verify = messageBirdClient.verifyToken(VERIFY_ID, TOKEN); + verify = messageBirdClient.verifyToken(VERIFY_ID, TOKEN); System.out.println(verify.toString()); - } - else if("view".equals(METHOD)) { - final String MESSAGE_ID = args[2]; - VerifyMessage verify = messageBirdClient.getVerifyEmailMessage(MESSAGE_ID); - System.out.println(verify.toString()); - } + break; + case "view": + final String MESSAGE_ID = args[2]; + VerifyMessage verifyMessage = messageBirdClient.getVerifyEmailMessage(MESSAGE_ID); + System.out.println(verifyMessage.toString()); + break; + } } } From 104f337a8c8c85f9ef5e4c368f77f18f4ddca3ea Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Wed, 23 Jun 2021 12:10:48 +0200 Subject: [PATCH 297/516] updated for the new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 77123e78..4dd1ee64 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.0 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 952881e4..e31187b4 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -61,7 +61,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.1.0"; + private final String clientVersion = "3.1.1"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index bc49e7d2..6839c044 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.1.0 + 3.1.1 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.1.0 + 3.1.1 compile From 84d8eb6c56be3d42fb040375dcc71e2c96b81b1f Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Wed, 23 Jun 2021 12:12:20 +0200 Subject: [PATCH 298/516] [maven-release-plugin] prepare release v3.1.1 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 4dd1ee64..7d3ccde6 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.1-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.1.1 From af4a4079c19df87e66096fd8dc819f272b67c571 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Wed, 23 Jun 2021 12:12:27 +0200 Subject: [PATCH 299/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 7d3ccde6..e9239997 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.1 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.1.1 + HEAD From 86849ab5b55a82d492f6a2382e4b14ff731051ec Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Wed, 23 Jun 2021 17:24:09 +0200 Subject: [PATCH 300/516] new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index e9239997..e45af6f7 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.2-SNAPSHOT From 26501ca469ada2cc7fff849358ed30f001fd57cb Mon Sep 17 00:00:00 2001 From: "khanh.nguyen" Date: Fri, 16 Jul 2021 10:21:51 +0200 Subject: [PATCH 301/516] Add support to new JWT signature --- api/pom.xml | 5 + api/src/main/java/com/messagebird/Base64.java | 496 ------------------ .../main/java/com/messagebird/Request.java | 55 -- .../java/com/messagebird/RequestSigner.java | 118 ----- .../com/messagebird/RequestValidator.java | 83 +++ .../exceptions/RequestSigningException.java | 18 - .../RequestValidationException.java | 22 + .../com/messagebird/RequestSignerTest.java | 110 ---- .../com/messagebird/RequestValidatorTest.java | 165 ++++++ 9 files changed, 275 insertions(+), 797 deletions(-) delete mode 100644 api/src/main/java/com/messagebird/Base64.java delete mode 100644 api/src/main/java/com/messagebird/Request.java delete mode 100644 api/src/main/java/com/messagebird/RequestSigner.java create mode 100644 api/src/main/java/com/messagebird/RequestValidator.java delete mode 100644 api/src/main/java/com/messagebird/exceptions/RequestSigningException.java create mode 100644 api/src/main/java/com/messagebird/exceptions/RequestValidationException.java delete mode 100644 api/src/test/java/com/messagebird/RequestSignerTest.java create mode 100644 api/src/test/java/com/messagebird/RequestValidatorTest.java diff --git a/api/pom.xml b/api/pom.xml index e45af6f7..0f0ef660 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -90,6 +90,11 @@ jackson-databind 2.11.0 + + com.auth0 + java-jwt + 3.17.0 + junit junit diff --git a/api/src/main/java/com/messagebird/Base64.java b/api/src/main/java/com/messagebird/Base64.java deleted file mode 100644 index 876beeb0..00000000 --- a/api/src/main/java/com/messagebird/Base64.java +++ /dev/null @@ -1,496 +0,0 @@ -package com.messagebird; - -/** - * Cutted version of iharder's base64 implementation - * @todo replace with actual library on next major bump - * - *

Encodes and decodes to and from Base64 notation.

- *

Homepage: http://iharder.net/base64.

- * - *

- * I am placing this code in the Public Domain. Do with it as you will. - * This software comes with no guarantees or warranties but with - * plenty of well-wishing instead! - * Please visit http://iharder.net/base64 - * periodically to check for updates or to contribute improvements. - *

- * - * @author Robert Harder - * @author rob@iharder.net - * @version 2.3.7 - */ -class Base64 { - -/* ******** P U B L I C F I E L D S ******** */ - - - /** No options specified. Value is zero. */ - public final static int NO_OPTIONS = 0; - - /** Specify that gzipped data should not be automatically gunzipped. */ - public final static int DONT_GUNZIP = 4; - - /** - * Encode using Base64-like encoding that is URL- and Filename-safe as described - * in Section 4 of RFC3548: - * http://www.faqs.org/rfcs/rfc3548.html. - * It is important to note that data encoded this way is not officially valid Base64, - * or at the very least should not be called Base64 without also specifying that is - * was encoded using the URL- and Filename-safe dialect. - */ - public final static int URL_SAFE = 16; - - - /** - * Encode using the special "ordered" dialect of Base64 described here: - * http://www.faqs.org/qa/rfcc-1940.html. - */ - public final static int ORDERED = 32; - - -/* ******** P R I V A T E F I E L D S ******** */ - - - /** The equals sign (=) as a byte. */ - private final static byte EQUALS_SIGN = (byte)'='; - - - /** Preferred encoding. */ - private final static String PREFERRED_ENCODING = "US-ASCII"; - - - private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding - private final static byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding - - -/* ******** S T A N D A R D B A S E 6 4 A L P H A B E T ******** */ - - /** - * Translates a Base64 value to either its 6-bit reconstruction value - * or a negative number indicating some other meaning. - **/ - private final static byte[] _STANDARD_DECODABET = { - -9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 0 - 8 - -5,-5, // Whitespace: Tab and Linefeed - -9,-9, // Decimal 11 - 12 - -5, // Whitespace: Carriage Return - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 14 - 26 - -9,-9,-9,-9,-9, // Decimal 27 - 31 - -5, // Whitespace: Space - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 33 - 42 - 62, // Plus sign at decimal 43 - -9,-9,-9, // Decimal 44 - 46 - 63, // Slash at decimal 47 - 52,53,54,55,56,57,58,59,60,61, // Numbers zero through nine - -9,-9,-9, // Decimal 58 - 60 - -1, // Equals sign at decimal 61 - -9,-9,-9, // Decimal 62 - 64 - 0,1,2,3,4,5,6,7,8,9,10,11,12,13, // Letters 'A' through 'N' - 14,15,16,17,18,19,20,21,22,23,24,25, // Letters 'O' through 'Z' - -9,-9,-9,-9,-9,-9, // Decimal 91 - 96 - 26,27,28,29,30,31,32,33,34,35,36,37,38, // Letters 'a' through 'm' - 39,40,41,42,43,44,45,46,47,48,49,50,51, // Letters 'n' through 'z' - -9,-9,-9,-9,-9 // Decimal 123 - 127 - ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 - }; - - -/* ******** U R L S A F E B A S E 6 4 A L P H A B E T ******** */ - - /** - * Used in decoding URL- and Filename-safe dialects of Base64. - */ - private final static byte[] _URL_SAFE_DECODABET = { - -9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 0 - 8 - -5,-5, // Whitespace: Tab and Linefeed - -9,-9, // Decimal 11 - 12 - -5, // Whitespace: Carriage Return - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 14 - 26 - -9,-9,-9,-9,-9, // Decimal 27 - 31 - -5, // Whitespace: Space - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 33 - 42 - -9, // Plus sign at decimal 43 - -9, // Decimal 44 - 62, // Minus sign at decimal 45 - -9, // Decimal 46 - -9, // Slash at decimal 47 - 52,53,54,55,56,57,58,59,60,61, // Numbers zero through nine - -9,-9,-9, // Decimal 58 - 60 - -1, // Equals sign at decimal 61 - -9,-9,-9, // Decimal 62 - 64 - 0,1,2,3,4,5,6,7,8,9,10,11,12,13, // Letters 'A' through 'N' - 14,15,16,17,18,19,20,21,22,23,24,25, // Letters 'O' through 'Z' - -9,-9,-9,-9, // Decimal 91 - 94 - 63, // Underscore at decimal 95 - -9, // Decimal 96 - 26,27,28,29,30,31,32,33,34,35,36,37,38, // Letters 'a' through 'm' - 39,40,41,42,43,44,45,46,47,48,49,50,51, // Letters 'n' through 'z' - -9,-9,-9,-9,-9 // Decimal 123 - 127 - ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 - }; - - - -/* ******** O R D E R E D B A S E 6 4 A L P H A B E T ******** */ - - /** - * Used in decoding the "ordered" dialect of Base64. - */ - private final static byte[] _ORDERED_DECODABET = { - -9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 0 - 8 - -5,-5, // Whitespace: Tab and Linefeed - -9,-9, // Decimal 11 - 12 - -5, // Whitespace: Carriage Return - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 14 - 26 - -9,-9,-9,-9,-9, // Decimal 27 - 31 - -5, // Whitespace: Space - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 33 - 42 - -9, // Plus sign at decimal 43 - -9, // Decimal 44 - 0, // Minus sign at decimal 45 - -9, // Decimal 46 - -9, // Slash at decimal 47 - 1,2,3,4,5,6,7,8,9,10, // Numbers zero through nine - -9,-9,-9, // Decimal 58 - 60 - -1, // Equals sign at decimal 61 - -9,-9,-9, // Decimal 62 - 64 - 11,12,13,14,15,16,17,18,19,20,21,22,23, // Letters 'A' through 'M' - 24,25,26,27,28,29,30,31,32,33,34,35,36, // Letters 'N' through 'Z' - -9,-9,-9,-9, // Decimal 91 - 94 - 37, // Underscore at decimal 95 - -9, // Decimal 96 - 38,39,40,41,42,43,44,45,46,47,48,49,50, // Letters 'a' through 'm' - 51,52,53,54,55,56,57,58,59,60,61,62,63, // Letters 'n' through 'z' - -9,-9,-9,-9,-9 // Decimal 123 - 127 - ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 - }; - - -/* ******** D E T E R M I N E W H I C H A L H A B E T ******** */ - - /** - * Returns one of the _SOMETHING_DECODABET byte arrays depending on - * the options specified. - * It's possible, though silly, to specify ORDERED and URL_SAFE - * in which case one of them will be picked, though there is - * no guarantee as to which one will be picked. - */ - private final static byte[] getDecodabet( int options ) { - if( (options & URL_SAFE) == URL_SAFE) { - return _URL_SAFE_DECODABET; - } else if ((options & ORDERED) == ORDERED) { - return _ORDERED_DECODABET; - } else { - return _STANDARD_DECODABET; - } - } // end getAlphabet - - - - /** Defeats instantiation. */ - private Base64(){} - - - -/* ******** D E C O D I N G M E T H O D S ******** */ - - - /** - * Decodes four bytes from array source - * and writes the resulting bytes (up to three of them) - * to destination. - * The source and destination arrays can be manipulated - * anywhere along their length by specifying - * srcOffset and destOffset. - * This method does not check to make sure your arrays - * are large enough to accomodate srcOffset + 4 for - * the source array or destOffset + 3 for - * the destination array. - * This method returns the actual number of bytes that - * were converted from the Base64 encoding. - *

This is the lowest level of the decoding methods with - * all possible parameters.

- * - * - * @param source the array to convert - * @param srcOffset the index where conversion begins - * @param destination the array to hold the conversion - * @param destOffset the index where output will be put - * @param options alphabet type is pulled from this (standard, url-safe, ordered) - * @return the number of decoded bytes converted - * @throws NullPointerException if source or destination arrays are null - * @throws IllegalArgumentException if srcOffset or destOffset are invalid - * or there is not enough room in the array. - * @since 1.3 - */ - private static int decode4to3( - byte[] source, int srcOffset, - byte[] destination, int destOffset, int options ) { - - // Lots of error checking and exception throwing - if( source == null ){ - throw new NullPointerException( "Source array was null." ); - } // end if - if( destination == null ){ - throw new NullPointerException( "Destination array was null." ); - } // end if - if( srcOffset < 0 || srcOffset + 3 >= source.length ){ - throw new IllegalArgumentException( String.format( - "Source array with length %d cannot have offset of %d and still process four bytes.", source.length, srcOffset ) ); - } // end if - if( destOffset < 0 || destOffset +2 >= destination.length ){ - throw new IllegalArgumentException( String.format( - "Destination array with length %d cannot have offset of %d and still store three bytes.", destination.length, destOffset ) ); - } // end if - - - byte[] DECODABET = getDecodabet( options ); - - // Example: Dk== - if( source[ srcOffset + 2] == EQUALS_SIGN ) { - // Two ways to do the same thing. Don't know which way I like best. - //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) - // | ( ( DECODABET[ source[ srcOffset + 1] ] << 24 ) >>> 12 ); - int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) - | ( ( DECODABET[ source[ srcOffset + 1] ] & 0xFF ) << 12 ); - - destination[ destOffset ] = (byte)( outBuff >>> 16 ); - return 1; - } - - // Example: DkL= - else if( source[ srcOffset + 3 ] == EQUALS_SIGN ) { - // Two ways to do the same thing. Don't know which way I like best. - //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) - // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) - // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ); - int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) - | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 ) - | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6 ); - - destination[ destOffset ] = (byte)( outBuff >>> 16 ); - destination[ destOffset + 1 ] = (byte)( outBuff >>> 8 ); - return 2; - } - - // Example: DkLE - else { - // Two ways to do the same thing. Don't know which way I like best. - //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) - // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) - // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ) - // | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 ); - int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) - | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 ) - | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6) - | ( ( DECODABET[ source[ srcOffset + 3 ] ] & 0xFF ) ); - - - destination[ destOffset ] = (byte)( outBuff >> 16 ); - destination[ destOffset + 1 ] = (byte)( outBuff >> 8 ); - destination[ destOffset + 2 ] = (byte)( outBuff ); - - return 3; - } - } // end decodeToBytes - - - - - /** - * Low-level access to decoding ASCII characters in - * the form of a byte array. Ignores GUNZIP option, if - * it's set. This is not generally a recommended method, - * although it is used internally as part of the decoding process. - * Special case: if len = 0, an empty array is returned. Still, - * if you need more speed and reduced memory footprint (and aren't - * gzipping), consider this method. - * - * @param source The Base64 encoded data - * @param off The offset of where to begin decoding - * @param len The length of characters to decode - * @param options Can specify options such as alphabet type to use - * @return decoded data - * @throws java.io.IOException If bogus characters exist in source data - * @since 1.3 - */ - public static byte[] decode( byte[] source, int off, int len, int options ) - throws java.io.IOException { - - // Lots of error checking and exception throwing - if( source == null ){ - throw new NullPointerException( "Cannot decode null source array." ); - } // end if - if( off < 0 || off + len > source.length ){ - throw new IllegalArgumentException( String.format( - "Source array with length %d cannot have offset of %d and process %d bytes.", source.length, off, len ) ); - } // end if - - if( len == 0 ){ - return new byte[0]; - }else if( len < 4 ){ - throw new IllegalArgumentException( - "Base64-encoded string must have at least four characters, but length specified was " + len ); - } // end if - - byte[] DECODABET = getDecodabet( options ); - - int len34 = len * 3 / 4; // Estimate on array size - byte[] outBuff = new byte[ len34 ]; // Upper limit on size of output - int outBuffPosn = 0; // Keep track of where we're writing - - byte[] b4 = new byte[4]; // Four byte buffer from source, eliminating white space - int b4Posn = 0; // Keep track of four byte input buffer - int i = 0; // Source array counter - byte sbiDecode = 0; // Special value from DECODABET - - for( i = off; i < off+len; i++ ) { // Loop through source - - sbiDecode = DECODABET[ source[i]&0xFF ]; - - // White space, Equals sign, or legit Base64 character - // Note the values such as -5 and -9 in the - // DECODABETs at the top of the file. - if( sbiDecode >= WHITE_SPACE_ENC ) { - if( sbiDecode >= EQUALS_SIGN_ENC ) { - b4[ b4Posn++ ] = source[i]; // Save non-whitespace - if( b4Posn > 3 ) { // Time to decode? - outBuffPosn += decode4to3( b4, 0, outBuff, outBuffPosn, options ); - b4Posn = 0; - - // If that was the equals sign, break out of 'for' loop - if( source[i] == EQUALS_SIGN ) { - break; - } // end if: equals sign - } // end if: quartet built - } // end if: equals sign or better - } // end if: white space, equals sign or better - else { - // There's a bad input character in the Base64 stream. - throw new java.io.IOException( String.format( - "Bad Base64 input character decimal %d in array position %d", ((int)source[i])&0xFF, i ) ); - } // end else: - } // each input character - - byte[] out = new byte[ outBuffPosn ]; - System.arraycopy( outBuff, 0, out, 0, outBuffPosn ); - return out; - } // end decode - - - - - /** - * Decodes data from Base64 notation, automatically - * detecting gzip-compressed data and decompressing it. - * - * @param s the string to decode - * @return the decoded data - * @throws java.io.IOException If there is a problem - * @since 1.4 - */ - public static byte[] decode( String s ) throws java.io.IOException { - return decode( s, NO_OPTIONS ); - } - - - - /** - * Decodes data from Base64 notation, automatically - * detecting gzip-compressed data and decompressing it. - * - * @param s the string to decode - * @param options encode options such as URL_SAFE - * @return the decoded data - * @throws java.io.IOException if there is an error - * @throws NullPointerException if s is null - * @since 1.4 - */ - public static byte[] decode( String s, int options ) throws java.io.IOException { - - if( s == null ){ - throw new NullPointerException( "Input string was null." ); - } // end if - - byte[] bytes; - try { - bytes = s.getBytes( PREFERRED_ENCODING ); - } // end try - catch( java.io.UnsupportedEncodingException uee ) { - bytes = s.getBytes(); - } // end catch - // - - // Decode - bytes = decode( bytes, 0, bytes.length, options ); - - // Check to see if it's gzip-compressed - // GZIP Magic Two-Byte Number: 0x8b1f (35615) - boolean dontGunzip = (options & DONT_GUNZIP) != 0; - if( (bytes != null) && (bytes.length >= 4) && (!dontGunzip) ) { - - int head = ((int)bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00); - if( java.util.zip.GZIPInputStream.GZIP_MAGIC == head ) { - java.io.ByteArrayInputStream bais = null; - java.util.zip.GZIPInputStream gzis = null; - java.io.ByteArrayOutputStream baos = null; - byte[] buffer = new byte[2048]; - int length = 0; - - try { - baos = new java.io.ByteArrayOutputStream(); - bais = new java.io.ByteArrayInputStream( bytes ); - gzis = new java.util.zip.GZIPInputStream( bais ); - - while( ( length = gzis.read( buffer ) ) >= 0 ) { - baos.write(buffer,0,length); - } // end while: reading input - - // No error? Get new bytes. - bytes = baos.toByteArray(); - - } // end try - catch( java.io.IOException e ) { - e.printStackTrace(); - // Just return originally-decoded bytes - } // end catch - finally { - try{ baos.close(); } catch( Exception e ){} - try{ gzis.close(); } catch( Exception e ){} - try{ bais.close(); } catch( Exception e ){} - } // end finally - - } // end if: gzipped - } // end if: bytes.length >= 2 - - return bytes; - } // end decode - -} // end class Base64 diff --git a/api/src/main/java/com/messagebird/Request.java b/api/src/main/java/com/messagebird/Request.java deleted file mode 100644 index 41d9283b..00000000 --- a/api/src/main/java/com/messagebird/Request.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.messagebird; - -import java.util.Arrays; - -/** - * Holds request data needed to calculate a signature hash for incoming - * webhooks. - */ -public class Request { - - private final String timestamp; - private final String queryParameters; - private final byte[] data; - - private final static String QUERY_PARAMETERS_DELIMITER = "&"; - - /** - * Constructs a new request instance. - * - * @param timestamp Timestamp provided in the MessageBird-Request-Timestamp - * header. - * @param queryParameters Query parameters in abc=foo&def=ghi format. - * @param data Raw body of this request. - */ - public Request(String timestamp, String queryParameters, byte[] data) { - if (timestamp == null || timestamp.isEmpty()) { - throw new IllegalArgumentException("Timestamp can not be null or empty"); - } - - this.timestamp = timestamp; - this.queryParameters = queryParameters; - this.data = data; - } - - String getTimestamp() { - return timestamp; - } - - String getSortedQueryParameters() { - String[] params = queryParameters.split(QUERY_PARAMETERS_DELIMITER); - Arrays.sort(params); - StringBuilder sortedParamsAccumulator = new StringBuilder(); - for (int i = 0, paramsLength = params.length; i < paramsLength; i++) { - sortedParamsAccumulator.append(params[i]); - if (i < paramsLength - 1) { - sortedParamsAccumulator.append(QUERY_PARAMETERS_DELIMITER); - } - } - return sortedParamsAccumulator.toString(); - } - - byte[] getData() { - return data; - } -} diff --git a/api/src/main/java/com/messagebird/RequestSigner.java b/api/src/main/java/com/messagebird/RequestSigner.java deleted file mode 100644 index e2f91d93..00000000 --- a/api/src/main/java/com/messagebird/RequestSigner.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.messagebird; - -import com.messagebird.exceptions.RequestSigningException; - -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; -import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.security.InvalidKeyException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; - -/** - * RequestSigner is used to verify HTTP requests and is an implementation of: - * https://developers.messagebird.com/docs/verify-http-requests. Retrieve your - * signing key at https://dashboard.messagebird.com/developers/settings. - */ -public class RequestSigner { - - private static final String ALGORITHM_SHA256 = "SHA-256"; - private static final String ALGORITHM_HMAC_SHA256 = "HmacSHA256"; - private static final Charset CHARSET_UTF8 = StandardCharsets.UTF_8; - - private SecretKeySpec secret; - - /** - * Constructs a new RequestSigner instance. - * - * @param key Signing key. Can be retrieved through - * https://dashboard.messagebird.com/developers/settings. This - * is NOT your API key. - */ - public RequestSigner(byte[] key) { - this.secret = new SecretKeySpec(key, ALGORITHM_HMAC_SHA256); - } - - /** - * Computes the signature for the provided request and determines whether - * it matches the expected signature (from the raw MessageBird-Signature header). - * - * @param expectedSignature Signature from the MessageBird-Signature - * header in its original base64 encoded state. - * @param request Request containing the values from the incoming webhook. - * @return True if the computed signature matches the expected signature. - */ - public boolean isMatch(String expectedSignature, Request request) { - try { - return isMatch(Base64.decode(expectedSignature), request); - } catch (IOException e) { - throw new RequestSigningException(e); - } - } - - /** - * Computes the signature for the provided request and determines whether - * it matches the expected signature - * - * @param expectedSignature Decoded (with base64) signature - * from the MessageBird-Signature header - * @param request Request containing the values from the incoming webhook. - * @return True if the computed signature matches the expected signature. - */ - public boolean isMatch(byte[] expectedSignature, Request request) { - return Arrays.equals(computeSignature(request), expectedSignature); - } - - /** - * Computes the signature for a request instance. - * - * @param request Request to compute signature for. - * @return HMAC-SHA2556 signature for the provided request. - */ - private byte[] computeSignature(Request request) { - String timestampAndQuery = request.getTimestamp() + '\n' + - request.getSortedQueryParameters() + '\n'; - - byte[] timestampAndQueryBytes = timestampAndQuery.getBytes(CHARSET_UTF8); - byte[] bodyHashBytes = getSha256Hash(request.getData()); - - return getHmacSha256Signature(appendArrays(timestampAndQueryBytes, bodyHashBytes)); - } - - private byte[] getSha256Hash(byte[] bytes) { - try { - return MessageDigest.getInstance(ALGORITHM_SHA256).digest(bytes); - } catch (NoSuchAlgorithmException e) { - throw new RequestSigningException(e); - } - } - - /** - * Stitches the two arrays together and returns a new one. - * - * @param first Start of the new array. - * @param second End of the new array. - * @return New array based on first and second. - */ - private byte[] appendArrays(byte[] first, byte[] second) { - byte[] result = new byte[first.length + second.length]; - System.arraycopy(first, 0, result, 0, first.length); - System.arraycopy(second, 0, result, first.length, second.length); - - return result; - } - - private byte[] getHmacSha256Signature(byte[] bytes) { - try { - Mac mac = Mac.getInstance(ALGORITHM_HMAC_SHA256); - mac.init(secret); - - return mac.doFinal(bytes); - } catch (InvalidKeyException | NoSuchAlgorithmException e) { - throw new RequestSigningException(e); - } - } -} diff --git a/api/src/main/java/com/messagebird/RequestValidator.java b/api/src/main/java/com/messagebird/RequestValidator.java new file mode 100644 index 00000000..f585cf55 --- /dev/null +++ b/api/src/main/java/com/messagebird/RequestValidator.java @@ -0,0 +1,83 @@ +package com.messagebird; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.JWTVerifier.BaseVerification; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.exceptions.JWTVerificationException; +import com.auth0.jwt.exceptions.SignatureVerificationException; +import com.auth0.jwt.interfaces.Clock; +import com.auth0.jwt.interfaces.DecodedJWT; +import com.auth0.jwt.interfaces.JWTVerifier; +import com.messagebird.exceptions.RequestValidationException; + +/** + * RequestValidator + */ +public class RequestValidator { + + public static final String SIGNATURE_HEADER = "MessageBird-Signature-JWT"; + private static final String ALGORITHM_SHA256 = "SHA-256"; + public static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', + 'f' }; + + private String signatureKey; + + public RequestValidator(String signatureKey) { + this.signatureKey = signatureKey; + } + + DecodedJWT validateSignature(Clock clock, String signature, String url, byte[] requestBody) + throws RequestValidationException { + Algorithm algorithmHS = Algorithm.HMAC256(this.signatureKey); + DecodedJWT jwt = JWT.decode(signature); + BaseVerification builder = (BaseVerification) JWT.require(algorithmHS).withIssuer("MessageBird").acceptLeeway(1) + .withClaim("url_hash", calculateSha256(url.getBytes())); + + if (requestBody != null && requestBody.length > 0) { + builder.withClaim("payload_hash", calculateSha256(requestBody)); + } else if (!jwt.getClaim("payload_hash").isNull()) { + throw new RequestValidationException("The Claim 'payload_hash' was set but no payload value."); + } + + JWTVerifier verifier; + if (clock == null) { + verifier = builder.build(); + } else { + verifier = builder.build(clock); + } + + try { + return verifier.verify(jwt); + } catch (SignatureVerificationException e) { + throw new RequestValidationException("Signature is invalid.", e); + } catch (JWTVerificationException e) { + throw new RequestValidationException(e.getMessage()); + } + } + + public DecodedJWT validateSignature(String signature, String url, byte[] requestBody) + throws RequestValidationException { + return validateSignature(null, signature, url, requestBody); + } + + private static String calculateSha256(byte[] bytes) { + try { + return encodeHex(MessageDigest.getInstance(ALGORITHM_SHA256).digest(bytes)); + } catch (NoSuchAlgorithmException e) { + throw new RequestValidationException(e); + } + } + + private static String encodeHex(final byte[] data) { + final int l = data.length; + final char[] out = new char[l << 1]; + for (int i = 0, j = 0; i < l; i++) { + out[j++] = HEX_DIGITS[(0xF0 & data[i]) >>> 4]; + out[j++] = HEX_DIGITS[0x0F & data[i]]; + } + return new String(out); + } +} \ No newline at end of file diff --git a/api/src/main/java/com/messagebird/exceptions/RequestSigningException.java b/api/src/main/java/com/messagebird/exceptions/RequestSigningException.java deleted file mode 100644 index 9f993375..00000000 --- a/api/src/main/java/com/messagebird/exceptions/RequestSigningException.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.messagebird.exceptions; - -/** - * Thrown if an error occurs during request signing. - */ -public class RequestSigningException extends RuntimeException { - - public RequestSigningException() { - } - - public RequestSigningException(String message) { - super(message); - } - - public RequestSigningException(Throwable cause) { - super(cause); - } -} diff --git a/api/src/main/java/com/messagebird/exceptions/RequestValidationException.java b/api/src/main/java/com/messagebird/exceptions/RequestValidationException.java new file mode 100644 index 00000000..f759b211 --- /dev/null +++ b/api/src/main/java/com/messagebird/exceptions/RequestValidationException.java @@ -0,0 +1,22 @@ +package com.messagebird.exceptions; + +/** + * Thrown if an error occurs during request signing. + */ +public class RequestValidationException extends RuntimeException { + + public RequestValidationException() { + } + + public RequestValidationException(String message) { + super(message); + } + + public RequestValidationException(Throwable cause) { + super(cause); + } + + public RequestValidationException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/api/src/test/java/com/messagebird/RequestSignerTest.java b/api/src/test/java/com/messagebird/RequestSignerTest.java deleted file mode 100644 index 435ef1ce..00000000 --- a/api/src/test/java/com/messagebird/RequestSignerTest.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.messagebird; - -import org.junit.Test; - -import java.nio.charset.StandardCharsets; - -import static org.junit.Assert.*; - -public class RequestSignerTest { - - /** - * Helper to get the bytes the provided UTF-8 encoded string represents. - */ - private static byte[] getBytes(String s) { - return s.getBytes(StandardCharsets.UTF_8); - } - - @Test - public void testIsMatchEmptyQueryParamsAndEmptyData() { - RequestSigner requestSigner = new RequestSigner(getBytes("secret")); - String expectedSignature = "LISw4Je7n0/MkYDgVSzTJm8dW6BkytKTXMZZk1IElMs="; - Request request = new Request("1544544948", "", getBytes("")); - - assertTrue(requestSigner.isMatch(expectedSignature, request)); - } - - @Test - public void testIsMatchWithData() { - RequestSigner requestSigner = new RequestSigner(getBytes("secret")); - String expectedSignature = "p2e20OtAg39DEmz1ORHpjQ556U4o1ZaH4NWbM9Q8Qjk="; - Request request = new Request("1544544948", "", getBytes("{\"a key\":\"some value\"}")); - - assertTrue(requestSigner.isMatch(expectedSignature, request)); - } - - @Test - public void testIsMatchWithQueryParams() { - RequestSigner requestSigner = new RequestSigner(getBytes("secret")); - String expectedSignature = "Tfn+nRUBsn6lQgf6IpxBMS1j9lm7XsGjt5xh47M3jCk="; - Request request = new Request("1544544948", "abc=foo&def=bar", getBytes("")); - - assertTrue(requestSigner.isMatch(expectedSignature, request)); - } - - @Test - public void testIsMatchWithShuffledQueryParams() { - RequestSigner requestSigner = new RequestSigner(getBytes("secret")); - String expectedSignature = "Tfn+nRUBsn6lQgf6IpxBMS1j9lm7XsGjt5xh47M3jCk="; - Request request = new Request("1544544948", "def=bar&abc=foo", getBytes("")); - - assertTrue(requestSigner.isMatch(expectedSignature, request)); - } - - @Test - public void testIsMatchWithDataAndQueryParams() { - RequestSigner requestSigner = new RequestSigner(getBytes("other-secret")); - String expectedSignature = "orb0adPhRCYND1WCAvPBr+qjm4STGtyvNDIDNBZ4Ir4="; - Request request = new Request("1544544948", "abc=foo&def=bar", getBytes("{\"a key\":\"some value\"}")); - - assertTrue(requestSigner.isMatch(expectedSignature, request)); - } - - @Test - public void testIsNotMatch() { - RequestSigner requestSigner = new RequestSigner(getBytes("secret")); - String expectedSignature = ""; - Request request = new Request("1544544948", "abc=foo&def=bar", getBytes("{\"a key\":\"some value\"}")); - - assertFalse(requestSigner.isMatch(expectedSignature, request)); - } - - @Test - public void testWithRealSignature() { - /* - * Here we use real signature from MessageBird webhook call - */ - - RequestSigner requestSigner = new RequestSigner(getBytes("Wb3N9gKeFf8ZoCzlOb5lJSic7bHLUcSu")); - String requestSignature = "5Jha9Yyhwgc1nTsgJ9WyzeHilsuUumydICdf4LuIZE8="; - String requestTimestamp = "1547036603"; - String requestParams = "id=57db52e04e2f4001b555f79813a0f503&mccmnc=20409&ported=0&recipient=31667788880&reference=curl&status=delivered&statusDatetime=2019-01-09T12%3A23%3A23%2B00%3A00"; - byte[] requestBody = new byte[0]; - - String spoiledSignature = "5Jha9Yyhwgc1nTsgJ9WyzeHilsuUumydICdf4LUIZE8="; - String spoiledTimestamp = "1547036605"; - String spoiledParams = "id=57db52e04e2f4001b555f79813a0f503&mccmnc=20409&ported=0&recipient=31667788880&reference=curvy&status=delivered&statusDatetime=2019-01-09T12%3A23%3A23%2B00%3A00"; - byte[] spoiledBody = getBytes("get shit spoiled"); - - assertTrue( - "Definitely valid signature is threaten as invalid", - requestSigner.isMatch(requestSignature, new Request(requestTimestamp, requestParams, requestBody)) - ); - assertFalse( - "Invalid signature is threaten as invalid", - requestSigner.isMatch(spoiledSignature, new Request(requestTimestamp, requestParams, requestBody)) - ); - assertFalse( - "Signature is still valid with replaced timestamp", - requestSigner.isMatch(requestSignature, new Request(spoiledTimestamp, requestParams, requestBody)) - ); - assertFalse( - "Signature is still valid with replaced params", - requestSigner.isMatch(requestSignature, new Request(requestTimestamp, spoiledParams, requestBody)) - ); - assertFalse( - "Signature is still valid with replaced body", - requestSigner.isMatch(requestSignature, new Request(requestTimestamp, requestParams, spoiledBody)) - ); - } -} diff --git a/api/src/test/java/com/messagebird/RequestValidatorTest.java b/api/src/test/java/com/messagebird/RequestValidatorTest.java new file mode 100644 index 00000000..6c19fde4 --- /dev/null +++ b/api/src/test/java/com/messagebird/RequestValidatorTest.java @@ -0,0 +1,165 @@ +package com.messagebird; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import java.nio.charset.Charset; +import java.time.OffsetDateTime; +import java.util.Date; + +import com.auth0.jwt.interfaces.Clock; +import com.messagebird.exceptions.RequestValidationException; + +import org.junit.Test; + +public class RequestValidatorTest { + + private static final String TEST_SIGNATURE_KEY = "hunter2"; + + private static final String TEST_BASE_URL = "https://example.com"; + + @Test + public void testValidWithNoParamsBody() { + String signature = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE"; + String signatureKey = TEST_SIGNATURE_KEY; + String receivedAt = "2021-07-05T12:00:00+02:00"; + String requestParams = ""; + String requestPayload = ""; + + runTestValidateSignature(signature, signatureKey, receivedAt, requestParams, requestPayload); + } + + @Test + public void testValidWithParamsAndWithoutBody() { + String signature = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJjOTQ2YWY3Ny1lMTgyLTRlYWEtYjJmZi0xYTU0NWI1ZTk5MWEiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAifQ.wUeGukU50HcPIr8d-zcCpttlGnPE-W57ujVb36AbAYw"; + String signatureKey = TEST_SIGNATURE_KEY; + String receivedAt = "2021-07-05T12:00:00+02:00"; + String requestParams = "/path?bar=1&foo=2"; + String requestPayload = ""; + + runTestValidateSignature(signature, signatureKey, receivedAt, requestParams, requestPayload); + } + + @Test + public void testValidWithParamsAndBody() { + String signature = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI5M2U1NTAwNi1hMGU4LTQ1MjYtYTE5MC1mYTVmZjAwZWExMTYiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAiLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.K6HyLDRdYgQBKN2tBcu0dOSxsfb_lOLaWby3un4rxIc"; + String signatureKey = TEST_SIGNATURE_KEY; + String receivedAt = "2021-07-05T12:00:00+02:00"; + String requestParams = "/path?bar=1&foo=2"; + String requestPayload = "Hello, World!"; + + runTestValidateSignature(signature, signatureKey, receivedAt, requestParams, requestPayload); + } + + @Test + public void testInvalidTokenReceivedBeforeIssued() { + String signature = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ4MjgwMCwiZXhwIjoxNjI1NDgyODYwLCJqdGkiOiJmOWY4YzM4Mi0yNDQ5LTQzMTEtYjcyYi0xZGY3MTY4NzkzMWUiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._59NNTg0j5YVXCRHgyeJAj8n6rTg1gwTh_I_coe7RDQ"; + String signatureKey = TEST_SIGNATURE_KEY; + String receivedAt = "2021-07-05T12:00:00+02:00"; + String requestParams = ""; + String requestPayload = ""; + + RequestValidationException e = assertThrows(RequestValidationException.class, + () -> runTestValidateSignature(signature, signatureKey, receivedAt, requestParams, requestPayload)); + assertTrue(e.getMessage().contains("The Token can't be used before")); + } + + @Test + public void testInvalidTokenReceivedAfterExpired() { + String signature = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3NTYwMCwiZXhwIjoxNjI1NDc1NjYwLCJqdGkiOiI1ZjAyZjUyMi02MDMwLTQ2YzgtYjVhMy0wMTI0NjQ3OGQ4YmMiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.iGUCLsYVQG4iYWe2MkRoLQBBMzq7p_bLy4u0mhC3Jfc"; + String signatureKey = TEST_SIGNATURE_KEY; + String receivedAt = "2021-07-05T12:00:00+02:00"; + String requestParams = ""; + String requestPayload = ""; + + RequestValidationException e = assertThrows(RequestValidationException.class, + () -> runTestValidateSignature(signature, signatureKey, receivedAt, requestParams, requestPayload)); + assertTrue(e.getMessage().contains("The Token has expired")); + } + + @Test + public void testInvalidTokenReceivedOnDifferentURL() { + String signature = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJhNzVjOTA5Ni1lODIzLTQ0MmItODVmMi03ZDNjOWQ5YjcyNmIiLCJ1cmxfaGFzaCI6IjlmZGExZmNkYzc0YjEwMzUzNjhlNWY2NjhmNTdjOTFlOTk0MTJmZjU5Y2YwM2E0NmNlYjk1YWVhNWU2YjU4ZmQifQ.G4lpxrDOxZs75G1vIJ6J1jVbYS19tx2yq-lkIE-oETY"; + String signatureKey = TEST_SIGNATURE_KEY; + String receivedAt = "2021-07-05T12:00:00+02:00"; + String requestParams = ""; + String requestPayload = ""; + + RequestValidationException e = assertThrows(RequestValidationException.class, + () -> runTestValidateSignature(signature, signatureKey, receivedAt, requestParams, requestPayload)); + assertEquals("The Claim 'url_hash' value doesn't match the required one.", e.getMessage()); + } + + @Test + public void testInvalidPayloadNotMatch() { + String signature = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiIzMjRjYzA2N2IyNTdlZGEwYmNiZDljOGQ4MTgwNzdhMDlhOTU2OGMwZDRjYTA2MDM4ZGVkOGZhZGRmODEzZmQ2In0.rQqiANogDOMafgg_B6p362PuhInAro9lMm2j_vruBA0"; + String signatureKey = TEST_SIGNATURE_KEY; + String receivedAt = "2021-07-05T12:00:00+02:00"; + String requestParams = ""; + String requestPayload = "Hello, World!"; + + RequestValidationException e = assertThrows(RequestValidationException.class, + () -> runTestValidateSignature(signature, signatureKey, receivedAt, requestParams, requestPayload)); + assertEquals("The Claim 'payload_hash' value doesn't match the required one.", e.getMessage()); + } + + @Test + public void testInvalidSignatureKey() { + String signature = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIyNDNjMjdhZS0yZjAyLTQ2YTAtODg1Mi1jNjZmMzdlYTlmNDYiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._Uwf4HMtfAT6jvbBbh85Q9TunX0QlsXoaLGKX0I4VDg"; + String signatureKey = TEST_SIGNATURE_KEY; + String receivedAt = "2021-07-05T12:00:00+02:00"; + String requestParams = ""; + String requestPayload = "Hello, World!"; + + RequestValidationException e = assertThrows(RequestValidationException.class, + () -> runTestValidateSignature(signature, signatureKey, receivedAt, requestParams, requestPayload)); + + assertEquals("Signature is invalid.", e.getMessage()); + } + + @Test + public void testInvalidMissingPayload() { + String signature = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiIzMjRjYzA2N2IyNTdlZGEwYmNiZDljOGQ4MTgwNzdhMDlhOTU2OGMwZDRjYTA2MDM4ZGVkOGZhZGRmODEzZmQ2In0.rQqiANogDOMafgg_B6p362PuhInAro9lMm2j_vruBA0"; + String signatureKey = TEST_SIGNATURE_KEY; + String receivedAt = "2021-07-05T12:00:00+02:00"; + String requestParams = ""; + String requestPayload = ""; + + RequestValidationException e = assertThrows(RequestValidationException.class, + () -> runTestValidateSignature(signature, signatureKey, receivedAt, requestParams, requestPayload)); + assertEquals("The Claim 'payload_hash' was set but no payload value.", e.getMessage()); + } + + @Test + public void testInvalidUnexpectedPayload() { + String signature = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE"; + String signatureKey = TEST_SIGNATURE_KEY; + String receivedAt = "2021-07-05T12:00:00+02:00"; + String requestParams = ""; + String requestPayload = "Hello, World!"; + + RequestValidationException e = assertThrows(RequestValidationException.class, + () -> runTestValidateSignature(signature, signatureKey, receivedAt, requestParams, requestPayload)); + assertEquals("The Claim 'payload_hash' value doesn't match the required one.", e.getMessage()); + } + + private void runTestValidateSignature(String signature, String signatureKey, String receivedAt, + String requestParams, String requestPayload) { + String reqUrl = TEST_BASE_URL + requestParams; + if (requestParams == "") { + reqUrl += "/"; + } + + RequestValidator validator = new RequestValidator(signatureKey); + + Clock clock = mock(Clock.class); + Date clockDate = spy(Date.from(OffsetDateTime.parse(receivedAt).toInstant())); + when(clock.getToday()).thenReturn(clockDate); + + validator.validateSignature(clock, signature, reqUrl, requestPayload.getBytes(Charset.forName("UTF-8"))); + } +} From 4595214371d47cacc6b900e86021bc42863c814a Mon Sep 17 00:00:00 2001 From: "khanh.nguyen" Date: Thu, 22 Jul 2021 17:32:39 +0200 Subject: [PATCH 302/516] Add test data for request validator unittest. --- .../com/messagebird/RequestValidator.java | 22 +- .../com/messagebird/RequestValidatorTest.java | 200 +++--- api/src/test/resources/webhook_test_data.json | 567 ++++++++++++++++++ 3 files changed, 657 insertions(+), 132 deletions(-) create mode 100644 api/src/test/resources/webhook_test_data.json diff --git a/api/src/main/java/com/messagebird/RequestValidator.java b/api/src/main/java/com/messagebird/RequestValidator.java index f585cf55..bf7a9451 100644 --- a/api/src/main/java/com/messagebird/RequestValidator.java +++ b/api/src/main/java/com/messagebird/RequestValidator.java @@ -23,23 +23,33 @@ public class RequestValidator { public static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - private String signatureKey; + private final Algorithm algorithm; public RequestValidator(String signatureKey) { - this.signatureKey = signatureKey; + this.algorithm = Algorithm.HMAC256(signatureKey); + } + + public RequestValidator(byte[] signatureKey) { + this.algorithm = Algorithm.HMAC256(signatureKey); } DecodedJWT validateSignature(Clock clock, String signature, String url, byte[] requestBody) throws RequestValidationException { - Algorithm algorithmHS = Algorithm.HMAC256(this.signatureKey); DecodedJWT jwt = JWT.decode(signature); - BaseVerification builder = (BaseVerification) JWT.require(algorithmHS).withIssuer("MessageBird").acceptLeeway(1) + BaseVerification builder = (BaseVerification) JWT.require(this.algorithm) + .withIssuer("MessageBird") + .acceptLeeway(1) .withClaim("url_hash", calculateSha256(url.getBytes())); + boolean payloadHashClaimExist = !jwt.getClaim("payload_hash").isNull(); + if (requestBody != null && requestBody.length > 0) { + if (!payloadHashClaimExist) { + throw new RequestValidationException("The Claim 'payload_hash' is not set but payload is present."); + } builder.withClaim("payload_hash", calculateSha256(requestBody)); - } else if (!jwt.getClaim("payload_hash").isNull()) { - throw new RequestValidationException("The Claim 'payload_hash' was set but no payload value."); + } else if (payloadHashClaimExist) { + throw new RequestValidationException("The Claim 'payload_hash' is set but actual payload is missing."); } JWTVerifier verifier; diff --git a/api/src/test/java/com/messagebird/RequestValidatorTest.java b/api/src/test/java/com/messagebird/RequestValidatorTest.java index 6c19fde4..2101b1c1 100644 --- a/api/src/test/java/com/messagebird/RequestValidatorTest.java +++ b/api/src/test/java/com/messagebird/RequestValidatorTest.java @@ -1,165 +1,113 @@ package com.messagebird; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; +import java.io.IOException; import java.nio.charset.Charset; import java.time.OffsetDateTime; +import java.util.Collection; import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import javax.annotation.Resources; import com.auth0.jwt.interfaces.Clock; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.messagebird.exceptions.RequestValidationException; import org.junit.Test; +import org.junit.function.ThrowingRunnable; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; +@RunWith(Parameterized.class) public class RequestValidatorTest { - private static final String TEST_SIGNATURE_KEY = "hunter2"; - - private static final String TEST_BASE_URL = "https://example.com"; - - @Test - public void testValidWithNoParamsBody() { - String signature = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE"; - String signatureKey = TEST_SIGNATURE_KEY; - String receivedAt = "2021-07-05T12:00:00+02:00"; - String requestParams = ""; - String requestPayload = ""; - - runTestValidateSignature(signature, signatureKey, receivedAt, requestParams, requestPayload); + /** + * WebhookSignatureTestCase + */ + public static class WebhookSignatureTestCase { + public String name; + public String method; + public String secret; + public String url; + public String payload; + public String timestamp; + public String token; + public String outcome; } - @Test - public void testValidWithParamsAndWithoutBody() { - String signature = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJjOTQ2YWY3Ny1lMTgyLTRlYWEtYjJmZi0xYTU0NWI1ZTk5MWEiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAifQ.wUeGukU50HcPIr8d-zcCpttlGnPE-W57ujVb36AbAYw"; - String signatureKey = TEST_SIGNATURE_KEY; - String receivedAt = "2021-07-05T12:00:00+02:00"; - String requestParams = "/path?bar=1&foo=2"; - String requestPayload = ""; - - runTestValidateSignature(signature, signatureKey, receivedAt, requestParams, requestPayload); - } + /** + * Error Map that maps test data expected outcome to actual error message. + */ + private static final Map ERROR_MAP = new HashMap() { + { + put("invalid jwt: claim iat is in the future", "The Token can't be used before"); + put("invalid jwt: claim exp is in the past", "The Token has expired on"); + put("invalid jwt: claim url_hash is invalid", "The Claim 'url_hash' value doesn't match the required one."); + put("invalid jwt: claim payload_hash is invalid", + "The Claim 'payload_hash' value doesn't match the required one."); + put("invalid jwt: signature is invalid", "Signature is invalid."); + put("invalid jwt: claim payload_hash is set but actual payload is missing", + "The Claim 'payload_hash' is set but actual payload is missing."); + put("invalid jwt: claim payload_hash is not set but payload is present", + "The Claim 'payload_hash' is not set but payload is present."); - @Test - public void testValidWithParamsAndBody() { - String signature = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI5M2U1NTAwNi1hMGU4LTQ1MjYtYTE5MC1mYTVmZjAwZWExMTYiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAiLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.K6HyLDRdYgQBKN2tBcu0dOSxsfb_lOLaWby3un4rxIc"; - String signatureKey = TEST_SIGNATURE_KEY; - String receivedAt = "2021-07-05T12:00:00+02:00"; - String requestParams = "/path?bar=1&foo=2"; - String requestPayload = "Hello, World!"; - - runTestValidateSignature(signature, signatureKey, receivedAt, requestParams, requestPayload); - } + } + }; - @Test - public void testInvalidTokenReceivedBeforeIssued() { - String signature = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ4MjgwMCwiZXhwIjoxNjI1NDgyODYwLCJqdGkiOiJmOWY4YzM4Mi0yNDQ5LTQzMTEtYjcyYi0xZGY3MTY4NzkzMWUiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._59NNTg0j5YVXCRHgyeJAj8n6rTg1gwTh_I_coe7RDQ"; - String signatureKey = TEST_SIGNATURE_KEY; - String receivedAt = "2021-07-05T12:00:00+02:00"; - String requestParams = ""; - String requestPayload = ""; - - RequestValidationException e = assertThrows(RequestValidationException.class, - () -> runTestValidateSignature(signature, signatureKey, receivedAt, requestParams, requestPayload)); - assertTrue(e.getMessage().contains("The Token can't be used before")); - } + private final WebhookSignatureTestCase testCase; - @Test - public void testInvalidTokenReceivedAfterExpired() { - String signature = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3NTYwMCwiZXhwIjoxNjI1NDc1NjYwLCJqdGkiOiI1ZjAyZjUyMi02MDMwLTQ2YzgtYjVhMy0wMTI0NjQ3OGQ4YmMiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.iGUCLsYVQG4iYWe2MkRoLQBBMzq7p_bLy4u0mhC3Jfc"; - String signatureKey = TEST_SIGNATURE_KEY; - String receivedAt = "2021-07-05T12:00:00+02:00"; - String requestParams = ""; - String requestPayload = ""; - - RequestValidationException e = assertThrows(RequestValidationException.class, - () -> runTestValidateSignature(signature, signatureKey, receivedAt, requestParams, requestPayload)); - assertTrue(e.getMessage().contains("The Token has expired")); + public RequestValidatorTest(String testName, WebhookSignatureTestCase testCase) { + this.testCase = testCase; } - @Test - public void testInvalidTokenReceivedOnDifferentURL() { - String signature = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJhNzVjOTA5Ni1lODIzLTQ0MmItODVmMi03ZDNjOWQ5YjcyNmIiLCJ1cmxfaGFzaCI6IjlmZGExZmNkYzc0YjEwMzUzNjhlNWY2NjhmNTdjOTFlOTk0MTJmZjU5Y2YwM2E0NmNlYjk1YWVhNWU2YjU4ZmQifQ.G4lpxrDOxZs75G1vIJ6J1jVbYS19tx2yq-lkIE-oETY"; - String signatureKey = TEST_SIGNATURE_KEY; - String receivedAt = "2021-07-05T12:00:00+02:00"; - String requestParams = ""; - String requestPayload = ""; - - RequestValidationException e = assertThrows(RequestValidationException.class, - () -> runTestValidateSignature(signature, signatureKey, receivedAt, requestParams, requestPayload)); - assertEquals("The Claim 'url_hash' value doesn't match the required one.", e.getMessage()); - } + @Parameters(name = "{0}") + public static Collection data() throws JsonParseException, JsonMappingException, IOException { + List testCases = new ObjectMapper().readValue( + Resources.class.getResourceAsStream("/webhook_test_data.json"), + new TypeReference>() { + }); - @Test - public void testInvalidPayloadNotMatch() { - String signature = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiIzMjRjYzA2N2IyNTdlZGEwYmNiZDljOGQ4MTgwNzdhMDlhOTU2OGMwZDRjYTA2MDM4ZGVkOGZhZGRmODEzZmQ2In0.rQqiANogDOMafgg_B6p362PuhInAro9lMm2j_vruBA0"; - String signatureKey = TEST_SIGNATURE_KEY; - String receivedAt = "2021-07-05T12:00:00+02:00"; - String requestParams = ""; - String requestPayload = "Hello, World!"; - - RequestValidationException e = assertThrows(RequestValidationException.class, - () -> runTestValidateSignature(signature, signatureKey, receivedAt, requestParams, requestPayload)); - assertEquals("The Claim 'payload_hash' value doesn't match the required one.", e.getMessage()); + return testCases.stream() + .map(tc -> new Object[]{ tc.name, tc }) + .collect(Collectors.toList()); } @Test - public void testInvalidSignatureKey() { - String signature = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIyNDNjMjdhZS0yZjAyLTQ2YTAtODg1Mi1jNjZmMzdlYTlmNDYiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._Uwf4HMtfAT6jvbBbh85Q9TunX0QlsXoaLGKX0I4VDg"; - String signatureKey = TEST_SIGNATURE_KEY; - String receivedAt = "2021-07-05T12:00:00+02:00"; - String requestParams = ""; - String requestPayload = "Hello, World!"; + public void testWebhookSignature() throws Throwable { + RequestValidator validator = new RequestValidator(testCase.secret); - RequestValidationException e = assertThrows(RequestValidationException.class, - () -> runTestValidateSignature(signature, signatureKey, receivedAt, requestParams, requestPayload)); - - assertEquals("Signature is invalid.", e.getMessage()); - } - - @Test - public void testInvalidMissingPayload() { - String signature = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiIzMjRjYzA2N2IyNTdlZGEwYmNiZDljOGQ4MTgwNzdhMDlhOTU2OGMwZDRjYTA2MDM4ZGVkOGZhZGRmODEzZmQ2In0.rQqiANogDOMafgg_B6p362PuhInAro9lMm2j_vruBA0"; - String signatureKey = TEST_SIGNATURE_KEY; - String receivedAt = "2021-07-05T12:00:00+02:00"; - String requestParams = ""; - String requestPayload = ""; - - RequestValidationException e = assertThrows(RequestValidationException.class, - () -> runTestValidateSignature(signature, signatureKey, receivedAt, requestParams, requestPayload)); - assertEquals("The Claim 'payload_hash' was set but no payload value.", e.getMessage()); - } + Clock clock = mock(Clock.class); + Date clockDate = spy(Date.from(OffsetDateTime.parse(testCase.timestamp).toInstant())); + when(clock.getToday()).thenReturn(clockDate); - @Test - public void testInvalidUnexpectedPayload() { - String signature = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE"; - String signatureKey = TEST_SIGNATURE_KEY; - String receivedAt = "2021-07-05T12:00:00+02:00"; - String requestParams = ""; - String requestPayload = "Hello, World!"; - - RequestValidationException e = assertThrows(RequestValidationException.class, - () -> runTestValidateSignature(signature, signatureKey, receivedAt, requestParams, requestPayload)); - assertEquals("The Claim 'payload_hash' value doesn't match the required one.", e.getMessage()); - } + ThrowingRunnable runnable = () -> validator.validateSignature(clock, testCase.token, testCase.url, + (testCase.payload == null) ? null : testCase.payload.getBytes(Charset.forName("UTF-8"))); - private void runTestValidateSignature(String signature, String signatureKey, String receivedAt, - String requestParams, String requestPayload) { - String reqUrl = TEST_BASE_URL + requestParams; - if (requestParams == "") { - reqUrl += "/"; + if (testCase.outcome.equals("valid")) { + runnable.run(); + return; } - RequestValidator validator = new RequestValidator(signatureKey); + assertTrue(String.format("Expected error message mapping for '%s' but it was not found.", testCase.outcome), + ERROR_MAP.containsKey(testCase.outcome)); - Clock clock = mock(Clock.class); - Date clockDate = spy(Date.from(OffsetDateTime.parse(receivedAt).toInstant())); - when(clock.getToday()).thenReturn(clockDate); + String expectedError = ERROR_MAP.get(testCase.outcome); - validator.validateSignature(clock, signature, reqUrl, requestPayload.getBytes(Charset.forName("UTF-8"))); + RequestValidationException err = assertThrows(RequestValidationException.class, runnable); + assertTrue(String.format("Expected error message containing: %s (originally %s) but was: %s", expectedError, + testCase.outcome, err.getMessage()), err.getMessage().contains(expectedError)); } } diff --git a/api/src/test/resources/webhook_test_data.json b/api/src/test/resources/webhook_test_data.json new file mode 100644 index 00000000..0f112a12 --- /dev/null +++ b/api/src/test/resources/webhook_test_data.json @@ -0,0 +1,567 @@ +[ + { + "name": "Valid JWT with no URL parameters or payload - DELETE", + "method": "DELETE", + "secret": "hunter2", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE", + "outcome": "valid" + }, + { + "name": "Valid JWT with no URL parameters or payload - GET", + "method": "GET", + "secret": "hunter2", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE", + "outcome": "valid" + }, + { + "name": "Valid JWT with no URL parameters or payload - PATCH", + "method": "PATCH", + "secret": "hunter2", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE", + "outcome": "valid" + }, + { + "name": "Valid JWT with no URL parameters or payload - POST", + "method": "POST", + "secret": "hunter2", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE", + "outcome": "valid" + }, + { + "name": "Valid JWT with no URL parameters or payload - PUT", + "method": "PUT", + "secret": "hunter2", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE", + "outcome": "valid" + }, + { + "name": "Valid JWT with URL parameters and no payload - DELETE", + "method": "DELETE", + "secret": "hunter2", + "url": "https://example.com/path?bar=1\u0026foo=2", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJjOTQ2YWY3Ny1lMTgyLTRlYWEtYjJmZi0xYTU0NWI1ZTk5MWEiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAifQ.wUeGukU50HcPIr8d-zcCpttlGnPE-W57ujVb36AbAYw", + "outcome": "valid" + }, + { + "name": "Valid JWT with URL parameters and no payload - GET", + "method": "GET", + "secret": "hunter2", + "url": "https://example.com/path?bar=1\u0026foo=2", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJjOTQ2YWY3Ny1lMTgyLTRlYWEtYjJmZi0xYTU0NWI1ZTk5MWEiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAifQ.wUeGukU50HcPIr8d-zcCpttlGnPE-W57ujVb36AbAYw", + "outcome": "valid" + }, + { + "name": "Valid JWT with URL parameters and no payload - PATCH", + "method": "PATCH", + "secret": "hunter2", + "url": "https://example.com/path?bar=1\u0026foo=2", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJjOTQ2YWY3Ny1lMTgyLTRlYWEtYjJmZi0xYTU0NWI1ZTk5MWEiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAifQ.wUeGukU50HcPIr8d-zcCpttlGnPE-W57ujVb36AbAYw", + "outcome": "valid" + }, + { + "name": "Valid JWT with URL parameters and no payload - POST", + "method": "POST", + "secret": "hunter2", + "url": "https://example.com/path?bar=1\u0026foo=2", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJjOTQ2YWY3Ny1lMTgyLTRlYWEtYjJmZi0xYTU0NWI1ZTk5MWEiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAifQ.wUeGukU50HcPIr8d-zcCpttlGnPE-W57ujVb36AbAYw", + "outcome": "valid" + }, + { + "name": "Valid JWT with URL parameters and no payload - PUT", + "method": "PUT", + "secret": "hunter2", + "url": "https://example.com/path?bar=1\u0026foo=2", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJjOTQ2YWY3Ny1lMTgyLTRlYWEtYjJmZi0xYTU0NWI1ZTk5MWEiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAifQ.wUeGukU50HcPIr8d-zcCpttlGnPE-W57ujVb36AbAYw", + "outcome": "valid" + }, + { + "name": "Valid JWT with URL parameters and payload - DELETE", + "method": "DELETE", + "secret": "hunter2", + "url": "https://example.com/path?bar=1\u0026foo=2", + "payload": "Hello, World!", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI5M2U1NTAwNi1hMGU4LTQ1MjYtYTE5MC1mYTVmZjAwZWExMTYiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAiLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.K6HyLDRdYgQBKN2tBcu0dOSxsfb_lOLaWby3un4rxIc", + "outcome": "valid" + }, + { + "name": "Valid JWT with URL parameters and payload - GET", + "method": "GET", + "secret": "hunter2", + "url": "https://example.com/path?bar=1\u0026foo=2", + "payload": "Hello, World!", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI5M2U1NTAwNi1hMGU4LTQ1MjYtYTE5MC1mYTVmZjAwZWExMTYiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAiLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.K6HyLDRdYgQBKN2tBcu0dOSxsfb_lOLaWby3un4rxIc", + "outcome": "valid" + }, + { + "name": "Valid JWT with URL parameters and payload - PATCH", + "method": "PATCH", + "secret": "hunter2", + "url": "https://example.com/path?bar=1\u0026foo=2", + "payload": "Hello, World!", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI5M2U1NTAwNi1hMGU4LTQ1MjYtYTE5MC1mYTVmZjAwZWExMTYiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAiLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.K6HyLDRdYgQBKN2tBcu0dOSxsfb_lOLaWby3un4rxIc", + "outcome": "valid" + }, + { + "name": "Valid JWT with URL parameters and payload - POST", + "method": "POST", + "secret": "hunter2", + "url": "https://example.com/path?bar=1\u0026foo=2", + "payload": "Hello, World!", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI5M2U1NTAwNi1hMGU4LTQ1MjYtYTE5MC1mYTVmZjAwZWExMTYiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAiLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.K6HyLDRdYgQBKN2tBcu0dOSxsfb_lOLaWby3un4rxIc", + "outcome": "valid" + }, + { + "name": "Valid JWT with URL parameters and payload - PUT", + "method": "PUT", + "secret": "hunter2", + "url": "https://example.com/path?bar=1\u0026foo=2", + "payload": "Hello, World!", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI5M2U1NTAwNi1hMGU4LTQ1MjYtYTE5MC1mYTVmZjAwZWExMTYiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAiLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.K6HyLDRdYgQBKN2tBcu0dOSxsfb_lOLaWby3un4rxIc", + "outcome": "valid" + }, + { + "name": "Token received before it was issued - DELETE", + "method": "DELETE", + "secret": "hunter2", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ4MjgwMCwiZXhwIjoxNjI1NDgyODYwLCJqdGkiOiJmOWY4YzM4Mi0yNDQ5LTQzMTEtYjcyYi0xZGY3MTY4NzkzMWUiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._59NNTg0j5YVXCRHgyeJAj8n6rTg1gwTh_I_coe7RDQ", + "outcome": "invalid jwt: claim iat is in the future" + }, + { + "name": "Token received before it was issued - GET", + "method": "GET", + "secret": "hunter2", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ4MjgwMCwiZXhwIjoxNjI1NDgyODYwLCJqdGkiOiJmOWY4YzM4Mi0yNDQ5LTQzMTEtYjcyYi0xZGY3MTY4NzkzMWUiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._59NNTg0j5YVXCRHgyeJAj8n6rTg1gwTh_I_coe7RDQ", + "outcome": "invalid jwt: claim iat is in the future" + }, + { + "name": "Token received before it was issued - PATCH", + "method": "PATCH", + "secret": "hunter2", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ4MjgwMCwiZXhwIjoxNjI1NDgyODYwLCJqdGkiOiJmOWY4YzM4Mi0yNDQ5LTQzMTEtYjcyYi0xZGY3MTY4NzkzMWUiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._59NNTg0j5YVXCRHgyeJAj8n6rTg1gwTh_I_coe7RDQ", + "outcome": "invalid jwt: claim iat is in the future" + }, + { + "name": "Token received before it was issued - POST", + "method": "POST", + "secret": "hunter2", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ4MjgwMCwiZXhwIjoxNjI1NDgyODYwLCJqdGkiOiJmOWY4YzM4Mi0yNDQ5LTQzMTEtYjcyYi0xZGY3MTY4NzkzMWUiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._59NNTg0j5YVXCRHgyeJAj8n6rTg1gwTh_I_coe7RDQ", + "outcome": "invalid jwt: claim iat is in the future" + }, + { + "name": "Token received before it was issued - PUT", + "method": "PUT", + "secret": "hunter2", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ4MjgwMCwiZXhwIjoxNjI1NDgyODYwLCJqdGkiOiJmOWY4YzM4Mi0yNDQ5LTQzMTEtYjcyYi0xZGY3MTY4NzkzMWUiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._59NNTg0j5YVXCRHgyeJAj8n6rTg1gwTh_I_coe7RDQ", + "outcome": "invalid jwt: claim iat is in the future" + }, + { + "name": "Token received after it was expired - DELETE", + "method": "DELETE", + "secret": "hunter2", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3NTYwMCwiZXhwIjoxNjI1NDc1NjYwLCJqdGkiOiI1ZjAyZjUyMi02MDMwLTQ2YzgtYjVhMy0wMTI0NjQ3OGQ4YmMiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.iGUCLsYVQG4iYWe2MkRoLQBBMzq7p_bLy4u0mhC3Jfc", + "outcome": "invalid jwt: claim exp is in the past" + }, + { + "name": "Token received after it was expired - GET", + "method": "GET", + "secret": "hunter2", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3NTYwMCwiZXhwIjoxNjI1NDc1NjYwLCJqdGkiOiI1ZjAyZjUyMi02MDMwLTQ2YzgtYjVhMy0wMTI0NjQ3OGQ4YmMiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.iGUCLsYVQG4iYWe2MkRoLQBBMzq7p_bLy4u0mhC3Jfc", + "outcome": "invalid jwt: claim exp is in the past" + }, + { + "name": "Token received after it was expired - PATCH", + "method": "PATCH", + "secret": "hunter2", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3NTYwMCwiZXhwIjoxNjI1NDc1NjYwLCJqdGkiOiI1ZjAyZjUyMi02MDMwLTQ2YzgtYjVhMy0wMTI0NjQ3OGQ4YmMiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.iGUCLsYVQG4iYWe2MkRoLQBBMzq7p_bLy4u0mhC3Jfc", + "outcome": "invalid jwt: claim exp is in the past" + }, + { + "name": "Token received after it was expired - POST", + "method": "POST", + "secret": "hunter2", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3NTYwMCwiZXhwIjoxNjI1NDc1NjYwLCJqdGkiOiI1ZjAyZjUyMi02MDMwLTQ2YzgtYjVhMy0wMTI0NjQ3OGQ4YmMiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.iGUCLsYVQG4iYWe2MkRoLQBBMzq7p_bLy4u0mhC3Jfc", + "outcome": "invalid jwt: claim exp is in the past" + }, + { + "name": "Token received after it was expired - PUT", + "method": "PUT", + "secret": "hunter2", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3NTYwMCwiZXhwIjoxNjI1NDc1NjYwLCJqdGkiOiI1ZjAyZjUyMi02MDMwLTQ2YzgtYjVhMy0wMTI0NjQ3OGQ4YmMiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.iGUCLsYVQG4iYWe2MkRoLQBBMzq7p_bLy4u0mhC3Jfc", + "outcome": "invalid jwt: claim exp is in the past" + }, + { + "name": "Token received on different URL (parameters were sorted out of order) - DELETE", + "method": "DELETE", + "secret": "hunter2", + "url": "https://example.com/path?foo=1\u0026bar=2", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJhNzVjOTA5Ni1lODIzLTQ0MmItODVmMi03ZDNjOWQ5YjcyNmIiLCJ1cmxfaGFzaCI6IjZhMDIyZDgzNGMxODMzMGJhYWQ4YTJiZDYxMzUxNzNlZDIxNjEwYTQ1NDUxNmJlMGRmM2YxY2MwMTUxNjEwZWEifQ.LtoTBRRo4Zcw9VlEhS5WCwX4cI_f-mYznekIzXkxqds", + "outcome": "invalid jwt: claim url_hash is invalid" + }, + { + "name": "Token received on different URL (parameters were sorted out of order) - GET", + "method": "GET", + "secret": "hunter2", + "url": "https://example.com/path?foo=1\u0026bar=2", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJhNzVjOTA5Ni1lODIzLTQ0MmItODVmMi03ZDNjOWQ5YjcyNmIiLCJ1cmxfaGFzaCI6IjZhMDIyZDgzNGMxODMzMGJhYWQ4YTJiZDYxMzUxNzNlZDIxNjEwYTQ1NDUxNmJlMGRmM2YxY2MwMTUxNjEwZWEifQ.LtoTBRRo4Zcw9VlEhS5WCwX4cI_f-mYznekIzXkxqds", + "outcome": "invalid jwt: claim url_hash is invalid" + }, + { + "name": "Token received on different URL (parameters were sorted out of order) - PATCH", + "method": "PATCH", + "secret": "hunter2", + "url": "https://example.com/path?foo=1\u0026bar=2", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJhNzVjOTA5Ni1lODIzLTQ0MmItODVmMi03ZDNjOWQ5YjcyNmIiLCJ1cmxfaGFzaCI6IjZhMDIyZDgzNGMxODMzMGJhYWQ4YTJiZDYxMzUxNzNlZDIxNjEwYTQ1NDUxNmJlMGRmM2YxY2MwMTUxNjEwZWEifQ.LtoTBRRo4Zcw9VlEhS5WCwX4cI_f-mYznekIzXkxqds", + "outcome": "invalid jwt: claim url_hash is invalid" + }, + { + "name": "Token received on different URL (parameters were sorted out of order) - POST", + "method": "POST", + "secret": "hunter2", + "url": "https://example.com/path?foo=1\u0026bar=2", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJhNzVjOTA5Ni1lODIzLTQ0MmItODVmMi03ZDNjOWQ5YjcyNmIiLCJ1cmxfaGFzaCI6IjZhMDIyZDgzNGMxODMzMGJhYWQ4YTJiZDYxMzUxNzNlZDIxNjEwYTQ1NDUxNmJlMGRmM2YxY2MwMTUxNjEwZWEifQ.LtoTBRRo4Zcw9VlEhS5WCwX4cI_f-mYznekIzXkxqds", + "outcome": "invalid jwt: claim url_hash is invalid" + }, + { + "name": "Token received on different URL (parameters were sorted out of order) - PUT", + "method": "PUT", + "secret": "hunter2", + "url": "https://example.com/path?foo=1\u0026bar=2", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJhNzVjOTA5Ni1lODIzLTQ0MmItODVmMi03ZDNjOWQ5YjcyNmIiLCJ1cmxfaGFzaCI6IjZhMDIyZDgzNGMxODMzMGJhYWQ4YTJiZDYxMzUxNzNlZDIxNjEwYTQ1NDUxNmJlMGRmM2YxY2MwMTUxNjEwZWEifQ.LtoTBRRo4Zcw9VlEhS5WCwX4cI_f-mYznekIzXkxqds", + "outcome": "invalid jwt: claim url_hash is invalid" + }, + { + "name": "Payload does not match - DELETE", + "method": "DELETE", + "secret": "hunter2", + "url": "https://example.com/", + "payload": "Hello, World!", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJmYjYyZjAyYWNkYTdkNzQxNzdhNzAxYTFjZTAwNmU2YmFjZDkwYzdkNGQ3YWI0ODE2OTJjMWRhNDdjODEwNzZiIn0.wt_2rlnGfmMQsZ8tYtN_D5V5oIMt4wXp1s2b0uVwcvk", + "outcome": "invalid jwt: claim payload_hash is invalid" + }, + { + "name": "Payload does not match - GET", + "method": "GET", + "secret": "hunter2", + "url": "https://example.com/", + "payload": "Hello, World!", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJmYjYyZjAyYWNkYTdkNzQxNzdhNzAxYTFjZTAwNmU2YmFjZDkwYzdkNGQ3YWI0ODE2OTJjMWRhNDdjODEwNzZiIn0.wt_2rlnGfmMQsZ8tYtN_D5V5oIMt4wXp1s2b0uVwcvk", + "outcome": "invalid jwt: claim payload_hash is invalid" + }, + { + "name": "Payload does not match - PATCH", + "method": "PATCH", + "secret": "hunter2", + "url": "https://example.com/", + "payload": "Hello, World!", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJmYjYyZjAyYWNkYTdkNzQxNzdhNzAxYTFjZTAwNmU2YmFjZDkwYzdkNGQ3YWI0ODE2OTJjMWRhNDdjODEwNzZiIn0.wt_2rlnGfmMQsZ8tYtN_D5V5oIMt4wXp1s2b0uVwcvk", + "outcome": "invalid jwt: claim payload_hash is invalid" + }, + { + "name": "Payload does not match - POST", + "method": "POST", + "secret": "hunter2", + "url": "https://example.com/", + "payload": "Hello, World!", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJmYjYyZjAyYWNkYTdkNzQxNzdhNzAxYTFjZTAwNmU2YmFjZDkwYzdkNGQ3YWI0ODE2OTJjMWRhNDdjODEwNzZiIn0.wt_2rlnGfmMQsZ8tYtN_D5V5oIMt4wXp1s2b0uVwcvk", + "outcome": "invalid jwt: claim payload_hash is invalid" + }, + { + "name": "Payload does not match - PUT", + "method": "PUT", + "secret": "hunter2", + "url": "https://example.com/", + "payload": "Hello, World!", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJmYjYyZjAyYWNkYTdkNzQxNzdhNzAxYTFjZTAwNmU2YmFjZDkwYzdkNGQ3YWI0ODE2OTJjMWRhNDdjODEwNzZiIn0.wt_2rlnGfmMQsZ8tYtN_D5V5oIMt4wXp1s2b0uVwcvk", + "outcome": "invalid jwt: claim payload_hash is invalid" + }, + { + "name": "Different secret - DELETE", + "method": "DELETE", + "secret": "hunter2", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIyNDNjMjdhZS0yZjAyLTQ2YTAtODg1Mi1jNjZmMzdlYTlmNDYiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._Uwf4HMtfAT6jvbBbh85Q9TunX0QlsXoaLGKX0I4VDg", + "outcome": "invalid jwt: signature is invalid" + }, + { + "name": "Different secret - GET", + "method": "GET", + "secret": "hunter2", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIyNDNjMjdhZS0yZjAyLTQ2YTAtODg1Mi1jNjZmMzdlYTlmNDYiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._Uwf4HMtfAT6jvbBbh85Q9TunX0QlsXoaLGKX0I4VDg", + "outcome": "invalid jwt: signature is invalid" + }, + { + "name": "Different secret - PATCH", + "method": "PATCH", + "secret": "hunter2", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIyNDNjMjdhZS0yZjAyLTQ2YTAtODg1Mi1jNjZmMzdlYTlmNDYiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._Uwf4HMtfAT6jvbBbh85Q9TunX0QlsXoaLGKX0I4VDg", + "outcome": "invalid jwt: signature is invalid" + }, + { + "name": "Different secret - POST", + "method": "POST", + "secret": "hunter2", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIyNDNjMjdhZS0yZjAyLTQ2YTAtODg1Mi1jNjZmMzdlYTlmNDYiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._Uwf4HMtfAT6jvbBbh85Q9TunX0QlsXoaLGKX0I4VDg", + "outcome": "invalid jwt: signature is invalid" + }, + { + "name": "Different secret - PUT", + "method": "PUT", + "secret": "hunter2", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIyNDNjMjdhZS0yZjAyLTQ2YTAtODg1Mi1jNjZmMzdlYTlmNDYiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._Uwf4HMtfAT6jvbBbh85Q9TunX0QlsXoaLGKX0I4VDg", + "outcome": "invalid jwt: signature is invalid" + }, + { + "name": "payload was removed in transit - DELETE", + "method": "DELETE", + "secret": "hunter2", + "url": "https://example.com/", + "payload": "", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.K2VPo6K75lV2rXAvXfm9kBhSEQNYyBaIqwC73h-BPKI", + "outcome": "invalid jwt: claim payload_hash is set but actual payload is missing" + }, + { + "name": "payload was removed in transit - GET", + "method": "GET", + "secret": "hunter2", + "url": "https://example.com/", + "payload": "", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.K2VPo6K75lV2rXAvXfm9kBhSEQNYyBaIqwC73h-BPKI", + "outcome": "invalid jwt: claim payload_hash is set but actual payload is missing" + }, + { + "name": "payload was removed in transit - PATCH", + "method": "PATCH", + "secret": "hunter2", + "url": "https://example.com/", + "payload": "", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.K2VPo6K75lV2rXAvXfm9kBhSEQNYyBaIqwC73h-BPKI", + "outcome": "invalid jwt: claim payload_hash is set but actual payload is missing" + }, + { + "name": "payload was removed in transit - POST", + "method": "POST", + "secret": "hunter2", + "url": "https://example.com/", + "payload": "", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.K2VPo6K75lV2rXAvXfm9kBhSEQNYyBaIqwC73h-BPKI", + "outcome": "invalid jwt: claim payload_hash is set but actual payload is missing" + }, + { + "name": "payload was removed in transit - PUT", + "method": "PUT", + "secret": "hunter2", + "url": "https://example.com/", + "payload": "", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.K2VPo6K75lV2rXAvXfm9kBhSEQNYyBaIqwC73h-BPKI", + "outcome": "invalid jwt: claim payload_hash is set but actual payload is missing" + }, + { + "name": "payload was added in transit - DELETE", + "method": "DELETE", + "secret": "hunter2", + "url": "https://example.com/", + "payload": "Hello, World!", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE", + "outcome": "invalid jwt: claim payload_hash is not set but payload is present" + }, + { + "name": "payload was added in transit - GET", + "method": "GET", + "secret": "hunter2", + "url": "https://example.com/", + "payload": "Hello, World!", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE", + "outcome": "invalid jwt: claim payload_hash is not set but payload is present" + }, + { + "name": "payload was added in transit - PATCH", + "method": "PATCH", + "secret": "hunter2", + "url": "https://example.com/", + "payload": "Hello, World!", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE", + "outcome": "invalid jwt: claim payload_hash is not set but payload is present" + }, + { + "name": "payload was added in transit - POST", + "method": "POST", + "secret": "hunter2", + "url": "https://example.com/", + "payload": "Hello, World!", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE", + "outcome": "invalid jwt: claim payload_hash is not set but payload is present" + }, + { + "name": "payload was added in transit - PUT", + "method": "PUT", + "secret": "hunter2", + "url": "https://example.com/", + "payload": "Hello, World!", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE", + "outcome": "invalid jwt: claim payload_hash is not set but payload is present" + }, + { + "name": "Special characters in URL - DELETE", + "method": "DELETE", + "secret": "hunter2", + "url": "https://example.com/?obj%5Bfield1%5D=val1\u0026obj%5Bfield2%5D=val2\u0026param=value+with+spaces", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjhhZmYzNzQ4ZDc4OWM0MzMzNTczZTFjMzFmZTViMDA0OTQwY2I1ZmM0NzQ2MGVkM2QwZTY1NGY3ZmM0ZTVmYWUifQ.uKyViTrquY1DAtEaeBrz6RvLNsLdSg0n4YVDuO2juj4", + "outcome": "valid" + }, + { + "name": "Special characters in URL - GET", + "method": "GET", + "secret": "hunter2", + "url": "https://example.com/?obj%5Bfield1%5D=val1\u0026obj%5Bfield2%5D=val2\u0026param=value+with+spaces", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjhhZmYzNzQ4ZDc4OWM0MzMzNTczZTFjMzFmZTViMDA0OTQwY2I1ZmM0NzQ2MGVkM2QwZTY1NGY3ZmM0ZTVmYWUifQ.uKyViTrquY1DAtEaeBrz6RvLNsLdSg0n4YVDuO2juj4", + "outcome": "valid" + }, + { + "name": "Special characters in URL - PATCH", + "method": "PATCH", + "secret": "hunter2", + "url": "https://example.com/?obj%5Bfield1%5D=val1\u0026obj%5Bfield2%5D=val2\u0026param=value+with+spaces", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjhhZmYzNzQ4ZDc4OWM0MzMzNTczZTFjMzFmZTViMDA0OTQwY2I1ZmM0NzQ2MGVkM2QwZTY1NGY3ZmM0ZTVmYWUifQ.uKyViTrquY1DAtEaeBrz6RvLNsLdSg0n4YVDuO2juj4", + "outcome": "valid" + }, + { + "name": "Special characters in URL - POST", + "method": "POST", + "secret": "hunter2", + "url": "https://example.com/?obj%5Bfield1%5D=val1\u0026obj%5Bfield2%5D=val2\u0026param=value+with+spaces", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjhhZmYzNzQ4ZDc4OWM0MzMzNTczZTFjMzFmZTViMDA0OTQwY2I1ZmM0NzQ2MGVkM2QwZTY1NGY3ZmM0ZTVmYWUifQ.uKyViTrquY1DAtEaeBrz6RvLNsLdSg0n4YVDuO2juj4", + "outcome": "valid" + }, + { + "name": "Special characters in URL - PUT", + "method": "PUT", + "secret": "hunter2", + "url": "https://example.com/?obj%5Bfield1%5D=val1\u0026obj%5Bfield2%5D=val2\u0026param=value+with+spaces", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjhhZmYzNzQ4ZDc4OWM0MzMzNTczZTFjMzFmZTViMDA0OTQwY2I1ZmM0NzQ2MGVkM2QwZTY1NGY3ZmM0ZTVmYWUifQ.uKyViTrquY1DAtEaeBrz6RvLNsLdSg0n4YVDuO2juj4", + "outcome": "valid" + }, + { + "name": "Special characters in the payload - DELETE", + "method": "DELETE", + "secret": "hunter2", + "url": "https://example.com/", + "payload": "Some text containg \u0026 \u003c \u003e, \u0026 and \\u0026", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiIyNDMxYmQ5Y2NiNDhlZDAxNmZhZDU2N2IwNzcxMjAzOGI1Y2RkOTQ5YWM5ZDQxZmU0NjkzZDVhMzg0NWNmN2U4In0.oQZwEMcMsT3SQhMozbnAo2445PYDKwoD77e2-dJQpdc", + "outcome": "valid" + }, + { + "name": "Special characters in the payload - GET", + "method": "GET", + "secret": "hunter2", + "url": "https://example.com/", + "payload": "Some text containg \u0026 \u003c \u003e, \u0026 and \\u0026", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiIyNDMxYmQ5Y2NiNDhlZDAxNmZhZDU2N2IwNzcxMjAzOGI1Y2RkOTQ5YWM5ZDQxZmU0NjkzZDVhMzg0NWNmN2U4In0.oQZwEMcMsT3SQhMozbnAo2445PYDKwoD77e2-dJQpdc", + "outcome": "valid" + }, + { + "name": "Special characters in the payload - PATCH", + "method": "PATCH", + "secret": "hunter2", + "url": "https://example.com/", + "payload": "Some text containg \u0026 \u003c \u003e, \u0026 and \\u0026", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiIyNDMxYmQ5Y2NiNDhlZDAxNmZhZDU2N2IwNzcxMjAzOGI1Y2RkOTQ5YWM5ZDQxZmU0NjkzZDVhMzg0NWNmN2U4In0.oQZwEMcMsT3SQhMozbnAo2445PYDKwoD77e2-dJQpdc", + "outcome": "valid" + }, + { + "name": "Special characters in the payload - POST", + "method": "POST", + "secret": "hunter2", + "url": "https://example.com/", + "payload": "Some text containg \u0026 \u003c \u003e, \u0026 and \\u0026", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiIyNDMxYmQ5Y2NiNDhlZDAxNmZhZDU2N2IwNzcxMjAzOGI1Y2RkOTQ5YWM5ZDQxZmU0NjkzZDVhMzg0NWNmN2U4In0.oQZwEMcMsT3SQhMozbnAo2445PYDKwoD77e2-dJQpdc", + "outcome": "valid" + }, + { + "name": "Special characters in the payload - PUT", + "method": "PUT", + "secret": "hunter2", + "url": "https://example.com/", + "payload": "Some text containg \u0026 \u003c \u003e, \u0026 and \\u0026", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiIyNDMxYmQ5Y2NiNDhlZDAxNmZhZDU2N2IwNzcxMjAzOGI1Y2RkOTQ5YWM5ZDQxZmU0NjkzZDVhMzg0NWNmN2U4In0.oQZwEMcMsT3SQhMozbnAo2445PYDKwoD77e2-dJQpdc", + "outcome": "valid" + } +] From f6e07e848e4949a407d4f6703b62fceb4f45179b Mon Sep 17 00:00:00 2001 From: "khanh.nguyen" Date: Tue, 3 Aug 2021 12:11:44 +0200 Subject: [PATCH 303/516] Updated request validator implementation and test cases --- .../com/messagebird/RequestValidator.java | 48 +- .../com/messagebird/RequestValidatorTest.java | 16 +- api/src/test/resources/webhook_test_data.json | 466 +++++++----------- 3 files changed, 209 insertions(+), 321 deletions(-) diff --git a/api/src/main/java/com/messagebird/RequestValidator.java b/api/src/main/java/com/messagebird/RequestValidator.java index bf7a9451..9206e234 100644 --- a/api/src/main/java/com/messagebird/RequestValidator.java +++ b/api/src/main/java/com/messagebird/RequestValidator.java @@ -14,38 +14,58 @@ import com.messagebird.exceptions.RequestValidationException; /** - * RequestValidator + * RequestValidator validates webhook signature signed by MessageBird services. */ public class RequestValidator { public static final String SIGNATURE_HEADER = "MessageBird-Signature-JWT"; + private static final String ALGORITHM_SHA256 = "SHA-256"; - public static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', - 'f' }; - private final Algorithm algorithm; + private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', + 'e', 'f' }; - public RequestValidator(String signatureKey) { - this.algorithm = Algorithm.HMAC256(signatureKey); - } + private final String signatureKey; - public RequestValidator(byte[] signatureKey) { - this.algorithm = Algorithm.HMAC256(signatureKey); + /** + * RequestValidator validates webhook signature with a customer signature key. + * + * @param signatureKey customer signature key + */ + public RequestValidator(String signatureKey) { + this.signatureKey = signatureKey; } - DecodedJWT validateSignature(Clock clock, String signature, String url, byte[] requestBody) + public DecodedJWT validateSignature(Clock clock, String signature, String url, byte[] requestBody) throws RequestValidationException { DecodedJWT jwt = JWT.decode(signature); - BaseVerification builder = (BaseVerification) JWT.require(this.algorithm) + + Algorithm algorithm; + switch (jwt.getAlgorithm()) { + case "HS256": + algorithm = Algorithm.HMAC256(this.signatureKey); + break; + case "HS384": + algorithm = Algorithm.HMAC384(this.signatureKey); + break; + case "HS512": + algorithm = Algorithm.HMAC512(this.signatureKey); + break; + default: + throw new RequestValidationException("The signing method is invalid."); + } + + BaseVerification builder = (BaseVerification) JWT.require(algorithm) .withIssuer("MessageBird") + .ignoreIssuedAt() .acceptLeeway(1) .withClaim("url_hash", calculateSha256(url.getBytes())); boolean payloadHashClaimExist = !jwt.getClaim("payload_hash").isNull(); - + if (requestBody != null && requestBody.length > 0) { if (!payloadHashClaimExist) { - throw new RequestValidationException("The Claim 'payload_hash' is not set but payload is present."); + throw new RequestValidationException("The Claim 'payload_hash' is not set but payload is present."); } builder.withClaim("payload_hash", calculateSha256(requestBody)); } else if (payloadHashClaimExist) { @@ -64,7 +84,7 @@ DecodedJWT validateSignature(Clock clock, String signature, String url, byte[] r } catch (SignatureVerificationException e) { throw new RequestValidationException("Signature is invalid.", e); } catch (JWTVerificationException e) { - throw new RequestValidationException(e.getMessage()); + throw new RequestValidationException(e.getMessage(), e.getCause()); } } diff --git a/api/src/test/java/com/messagebird/RequestValidatorTest.java b/api/src/test/java/com/messagebird/RequestValidatorTest.java index 2101b1c1..fd50a92a 100644 --- a/api/src/test/java/com/messagebird/RequestValidatorTest.java +++ b/api/src/test/java/com/messagebird/RequestValidatorTest.java @@ -45,7 +45,8 @@ public static class WebhookSignatureTestCase { public String payload; public String timestamp; public String token; - public String outcome; + public Boolean valid; + public String reason; } /** @@ -53,7 +54,7 @@ public static class WebhookSignatureTestCase { */ private static final Map ERROR_MAP = new HashMap() { { - put("invalid jwt: claim iat is in the future", "The Token can't be used before"); + put("invalid jwt: claim nbf is in the future", "The Token can't be used before"); put("invalid jwt: claim exp is in the past", "The Token has expired on"); put("invalid jwt: claim url_hash is invalid", "The Claim 'url_hash' value doesn't match the required one."); put("invalid jwt: claim payload_hash is invalid", @@ -63,6 +64,7 @@ public static class WebhookSignatureTestCase { "The Claim 'payload_hash' is set but actual payload is missing."); put("invalid jwt: claim payload_hash is not set but payload is present", "The Claim 'payload_hash' is not set but payload is present."); + put("invalid jwt: signing method none is invalid", "The signing method is invalid."); } }; @@ -96,18 +98,18 @@ public void testWebhookSignature() throws Throwable { ThrowingRunnable runnable = () -> validator.validateSignature(clock, testCase.token, testCase.url, (testCase.payload == null) ? null : testCase.payload.getBytes(Charset.forName("UTF-8"))); - if (testCase.outcome.equals("valid")) { + if (testCase.valid) { runnable.run(); return; } - assertTrue(String.format("Expected error message mapping for '%s' but it was not found.", testCase.outcome), - ERROR_MAP.containsKey(testCase.outcome)); + assertTrue(String.format("Expected error message mapping for '%s' but it was not found.", testCase.reason), + ERROR_MAP.containsKey(testCase.reason)); - String expectedError = ERROR_MAP.get(testCase.outcome); + String expectedError = ERROR_MAP.get(testCase.reason); RequestValidationException err = assertThrows(RequestValidationException.class, runnable); assertTrue(String.format("Expected error message containing: %s (originally %s) but was: %s", expectedError, - testCase.outcome, err.getMessage()), err.getMessage().contains(expectedError)); + testCase.reason, err.getMessage()), err.getMessage().contains(expectedError)); } } diff --git a/api/src/test/resources/webhook_test_data.json b/api/src/test/resources/webhook_test_data.json index 0f112a12..da8cb6c2 100644 --- a/api/src/test/resources/webhook_test_data.json +++ b/api/src/test/resources/webhook_test_data.json @@ -2,566 +2,432 @@ { "name": "Valid JWT with no URL parameters or payload - DELETE", "method": "DELETE", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE", - "outcome": "valid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.6Fp0rVOsRr1fj9S2GidXAfkmPVofKr8_RTffC6G6r2E", + "valid": true }, { "name": "Valid JWT with no URL parameters or payload - GET", "method": "GET", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE", - "outcome": "valid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.6Fp0rVOsRr1fj9S2GidXAfkmPVofKr8_RTffC6G6r2E", + "valid": true }, { "name": "Valid JWT with no URL parameters or payload - PATCH", "method": "PATCH", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE", - "outcome": "valid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.6Fp0rVOsRr1fj9S2GidXAfkmPVofKr8_RTffC6G6r2E", + "valid": true }, { "name": "Valid JWT with no URL parameters or payload - POST", "method": "POST", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE", - "outcome": "valid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.6Fp0rVOsRr1fj9S2GidXAfkmPVofKr8_RTffC6G6r2E", + "valid": true }, { "name": "Valid JWT with no URL parameters or payload - PUT", "method": "PUT", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE", - "outcome": "valid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.6Fp0rVOsRr1fj9S2GidXAfkmPVofKr8_RTffC6G6r2E", + "valid": true }, { "name": "Valid JWT with URL parameters and no payload - DELETE", "method": "DELETE", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/path?bar=1\u0026foo=2", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJjOTQ2YWY3Ny1lMTgyLTRlYWEtYjJmZi0xYTU0NWI1ZTk5MWEiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAifQ.wUeGukU50HcPIr8d-zcCpttlGnPE-W57ujVb36AbAYw", - "outcome": "valid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJjOTQ2YWY3Ny1lMTgyLTRlYWEtYjJmZi0xYTU0NWI1ZTk5MWEiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAifQ.huo2ou6JDoDc7sV25d75UMWeYhBeavQlLsqIibSZuac", + "valid": true }, { "name": "Valid JWT with URL parameters and no payload - GET", "method": "GET", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/path?bar=1\u0026foo=2", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJjOTQ2YWY3Ny1lMTgyLTRlYWEtYjJmZi0xYTU0NWI1ZTk5MWEiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAifQ.wUeGukU50HcPIr8d-zcCpttlGnPE-W57ujVb36AbAYw", - "outcome": "valid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJjOTQ2YWY3Ny1lMTgyLTRlYWEtYjJmZi0xYTU0NWI1ZTk5MWEiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAifQ.huo2ou6JDoDc7sV25d75UMWeYhBeavQlLsqIibSZuac", + "valid": true }, { "name": "Valid JWT with URL parameters and no payload - PATCH", "method": "PATCH", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/path?bar=1\u0026foo=2", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJjOTQ2YWY3Ny1lMTgyLTRlYWEtYjJmZi0xYTU0NWI1ZTk5MWEiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAifQ.wUeGukU50HcPIr8d-zcCpttlGnPE-W57ujVb36AbAYw", - "outcome": "valid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJjOTQ2YWY3Ny1lMTgyLTRlYWEtYjJmZi0xYTU0NWI1ZTk5MWEiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAifQ.huo2ou6JDoDc7sV25d75UMWeYhBeavQlLsqIibSZuac", + "valid": true }, { "name": "Valid JWT with URL parameters and no payload - POST", "method": "POST", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/path?bar=1\u0026foo=2", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJjOTQ2YWY3Ny1lMTgyLTRlYWEtYjJmZi0xYTU0NWI1ZTk5MWEiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAifQ.wUeGukU50HcPIr8d-zcCpttlGnPE-W57ujVb36AbAYw", - "outcome": "valid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJjOTQ2YWY3Ny1lMTgyLTRlYWEtYjJmZi0xYTU0NWI1ZTk5MWEiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAifQ.huo2ou6JDoDc7sV25d75UMWeYhBeavQlLsqIibSZuac", + "valid": true }, { "name": "Valid JWT with URL parameters and no payload - PUT", "method": "PUT", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/path?bar=1\u0026foo=2", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJjOTQ2YWY3Ny1lMTgyLTRlYWEtYjJmZi0xYTU0NWI1ZTk5MWEiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAifQ.wUeGukU50HcPIr8d-zcCpttlGnPE-W57ujVb36AbAYw", - "outcome": "valid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJjOTQ2YWY3Ny1lMTgyLTRlYWEtYjJmZi0xYTU0NWI1ZTk5MWEiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAifQ.huo2ou6JDoDc7sV25d75UMWeYhBeavQlLsqIibSZuac", + "valid": true }, { "name": "Valid JWT with URL parameters and payload - DELETE", "method": "DELETE", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/path?bar=1\u0026foo=2", "payload": "Hello, World!", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI5M2U1NTAwNi1hMGU4LTQ1MjYtYTE5MC1mYTVmZjAwZWExMTYiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAiLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.K6HyLDRdYgQBKN2tBcu0dOSxsfb_lOLaWby3un4rxIc", - "outcome": "valid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI5M2U1NTAwNi1hMGU4LTQ1MjYtYTE5MC1mYTVmZjAwZWExMTYiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAiLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0._H--TOuYFLpeEH39-rg5E3IHVkjHozBcaKVWPRC5m9I", + "valid": true }, { "name": "Valid JWT with URL parameters and payload - GET", "method": "GET", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/path?bar=1\u0026foo=2", "payload": "Hello, World!", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI5M2U1NTAwNi1hMGU4LTQ1MjYtYTE5MC1mYTVmZjAwZWExMTYiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAiLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.K6HyLDRdYgQBKN2tBcu0dOSxsfb_lOLaWby3un4rxIc", - "outcome": "valid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI5M2U1NTAwNi1hMGU4LTQ1MjYtYTE5MC1mYTVmZjAwZWExMTYiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAiLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0._H--TOuYFLpeEH39-rg5E3IHVkjHozBcaKVWPRC5m9I", + "valid": true }, { "name": "Valid JWT with URL parameters and payload - PATCH", "method": "PATCH", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/path?bar=1\u0026foo=2", "payload": "Hello, World!", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI5M2U1NTAwNi1hMGU4LTQ1MjYtYTE5MC1mYTVmZjAwZWExMTYiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAiLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.K6HyLDRdYgQBKN2tBcu0dOSxsfb_lOLaWby3un4rxIc", - "outcome": "valid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI5M2U1NTAwNi1hMGU4LTQ1MjYtYTE5MC1mYTVmZjAwZWExMTYiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAiLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0._H--TOuYFLpeEH39-rg5E3IHVkjHozBcaKVWPRC5m9I", + "valid": true }, { "name": "Valid JWT with URL parameters and payload - POST", "method": "POST", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/path?bar=1\u0026foo=2", "payload": "Hello, World!", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI5M2U1NTAwNi1hMGU4LTQ1MjYtYTE5MC1mYTVmZjAwZWExMTYiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAiLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.K6HyLDRdYgQBKN2tBcu0dOSxsfb_lOLaWby3un4rxIc", - "outcome": "valid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI5M2U1NTAwNi1hMGU4LTQ1MjYtYTE5MC1mYTVmZjAwZWExMTYiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAiLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0._H--TOuYFLpeEH39-rg5E3IHVkjHozBcaKVWPRC5m9I", + "valid": true }, { "name": "Valid JWT with URL parameters and payload - PUT", "method": "PUT", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/path?bar=1\u0026foo=2", "payload": "Hello, World!", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI5M2U1NTAwNi1hMGU4LTQ1MjYtYTE5MC1mYTVmZjAwZWExMTYiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAiLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.K6HyLDRdYgQBKN2tBcu0dOSxsfb_lOLaWby3un4rxIc", - "outcome": "valid" - }, - { - "name": "Token received before it was issued - DELETE", - "method": "DELETE", - "secret": "hunter2", - "url": "https://example.com/", - "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ4MjgwMCwiZXhwIjoxNjI1NDgyODYwLCJqdGkiOiJmOWY4YzM4Mi0yNDQ5LTQzMTEtYjcyYi0xZGY3MTY4NzkzMWUiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._59NNTg0j5YVXCRHgyeJAj8n6rTg1gwTh_I_coe7RDQ", - "outcome": "invalid jwt: claim iat is in the future" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI5M2U1NTAwNi1hMGU4LTQ1MjYtYTE5MC1mYTVmZjAwZWExMTYiLCJ1cmxfaGFzaCI6IjQxZjA1ZjBkZGQwYTIyYWIyMDlhYzQ2ZjQ3YzQ1NzJkOWNlZmEyNTdlZDc0YjI0MDA0YmFlNzUzZWNlNmMyNjAiLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0._H--TOuYFLpeEH39-rg5E3IHVkjHozBcaKVWPRC5m9I", + "valid": true }, { "name": "Token received before it was issued - GET", "method": "GET", - "secret": "hunter2", - "url": "https://example.com/", - "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ4MjgwMCwiZXhwIjoxNjI1NDgyODYwLCJqdGkiOiJmOWY4YzM4Mi0yNDQ5LTQzMTEtYjcyYi0xZGY3MTY4NzkzMWUiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._59NNTg0j5YVXCRHgyeJAj8n6rTg1gwTh_I_coe7RDQ", - "outcome": "invalid jwt: claim iat is in the future" - }, - { - "name": "Token received before it was issued - PATCH", - "method": "PATCH", - "secret": "hunter2", - "url": "https://example.com/", - "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ4MjgwMCwiZXhwIjoxNjI1NDgyODYwLCJqdGkiOiJmOWY4YzM4Mi0yNDQ5LTQzMTEtYjcyYi0xZGY3MTY4NzkzMWUiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._59NNTg0j5YVXCRHgyeJAj8n6rTg1gwTh_I_coe7RDQ", - "outcome": "invalid jwt: claim iat is in the future" - }, - { - "name": "Token received before it was issued - POST", - "method": "POST", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ4MjgwMCwiZXhwIjoxNjI1NDgyODYwLCJqdGkiOiJmOWY4YzM4Mi0yNDQ5LTQzMTEtYjcyYi0xZGY3MTY4NzkzMWUiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._59NNTg0j5YVXCRHgyeJAj8n6rTg1gwTh_I_coe7RDQ", - "outcome": "invalid jwt: claim iat is in the future" - }, - { - "name": "Token received before it was issued - PUT", - "method": "PUT", - "secret": "hunter2", - "url": "https://example.com/", - "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ4MjgwMCwiZXhwIjoxNjI1NDgyODYwLCJqdGkiOiJmOWY4YzM4Mi0yNDQ5LTQzMTEtYjcyYi0xZGY3MTY4NzkzMWUiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._59NNTg0j5YVXCRHgyeJAj8n6rTg1gwTh_I_coe7RDQ", - "outcome": "invalid jwt: claim iat is in the future" - }, - { - "name": "Token received after it was expired - DELETE", - "method": "DELETE", - "secret": "hunter2", - "url": "https://example.com/", - "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3NTYwMCwiZXhwIjoxNjI1NDc1NjYwLCJqdGkiOiI1ZjAyZjUyMi02MDMwLTQ2YzgtYjVhMy0wMTI0NjQ3OGQ4YmMiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.iGUCLsYVQG4iYWe2MkRoLQBBMzq7p_bLy4u0mhC3Jfc", - "outcome": "invalid jwt: claim exp is in the past" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ4MjgwMCwiZXhwIjoxNjI1NDgyODYwLCJqdGkiOiJmOWY4YzM4Mi0yNDQ5LTQzMTEtYjcyYi0xZGY3MTY4NzkzMWUiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.ZELgDFNGhjZH9CffQKcq3sytBe2I0KciLxpBhcfstHQ", + "valid": false, + "reason": "invalid jwt: claim nbf is in the future" }, { "name": "Token received after it was expired - GET", "method": "GET", - "secret": "hunter2", - "url": "https://example.com/", - "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3NTYwMCwiZXhwIjoxNjI1NDc1NjYwLCJqdGkiOiI1ZjAyZjUyMi02MDMwLTQ2YzgtYjVhMy0wMTI0NjQ3OGQ4YmMiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.iGUCLsYVQG4iYWe2MkRoLQBBMzq7p_bLy4u0mhC3Jfc", - "outcome": "invalid jwt: claim exp is in the past" - }, - { - "name": "Token received after it was expired - PATCH", - "method": "PATCH", - "secret": "hunter2", - "url": "https://example.com/", - "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3NTYwMCwiZXhwIjoxNjI1NDc1NjYwLCJqdGkiOiI1ZjAyZjUyMi02MDMwLTQ2YzgtYjVhMy0wMTI0NjQ3OGQ4YmMiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.iGUCLsYVQG4iYWe2MkRoLQBBMzq7p_bLy4u0mhC3Jfc", - "outcome": "invalid jwt: claim exp is in the past" - }, - { - "name": "Token received after it was expired - POST", - "method": "POST", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3NTYwMCwiZXhwIjoxNjI1NDc1NjYwLCJqdGkiOiI1ZjAyZjUyMi02MDMwLTQ2YzgtYjVhMy0wMTI0NjQ3OGQ4YmMiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.iGUCLsYVQG4iYWe2MkRoLQBBMzq7p_bLy4u0mhC3Jfc", - "outcome": "invalid jwt: claim exp is in the past" - }, - { - "name": "Token received after it was expired - PUT", - "method": "PUT", - "secret": "hunter2", - "url": "https://example.com/", - "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3NTYwMCwiZXhwIjoxNjI1NDc1NjYwLCJqdGkiOiI1ZjAyZjUyMi02MDMwLTQ2YzgtYjVhMy0wMTI0NjQ3OGQ4YmMiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.iGUCLsYVQG4iYWe2MkRoLQBBMzq7p_bLy4u0mhC3Jfc", - "outcome": "invalid jwt: claim exp is in the past" - }, - { - "name": "Token received on different URL (parameters were sorted out of order) - DELETE", - "method": "DELETE", - "secret": "hunter2", - "url": "https://example.com/path?foo=1\u0026bar=2", - "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJhNzVjOTA5Ni1lODIzLTQ0MmItODVmMi03ZDNjOWQ5YjcyNmIiLCJ1cmxfaGFzaCI6IjZhMDIyZDgzNGMxODMzMGJhYWQ4YTJiZDYxMzUxNzNlZDIxNjEwYTQ1NDUxNmJlMGRmM2YxY2MwMTUxNjEwZWEifQ.LtoTBRRo4Zcw9VlEhS5WCwX4cI_f-mYznekIzXkxqds", - "outcome": "invalid jwt: claim url_hash is invalid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3NTYwMCwiZXhwIjoxNjI1NDc1NjYwLCJqdGkiOiI1ZjAyZjUyMi02MDMwLTQ2YzgtYjVhMy0wMTI0NjQ3OGQ4YmMiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.45MSST3B_2PsjNUeiuW54_vUQgVw4rBXrdWrOUEz3lM", + "valid": false, + "reason": "invalid jwt: claim exp is in the past" }, { "name": "Token received on different URL (parameters were sorted out of order) - GET", "method": "GET", - "secret": "hunter2", - "url": "https://example.com/path?foo=1\u0026bar=2", - "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJhNzVjOTA5Ni1lODIzLTQ0MmItODVmMi03ZDNjOWQ5YjcyNmIiLCJ1cmxfaGFzaCI6IjZhMDIyZDgzNGMxODMzMGJhYWQ4YTJiZDYxMzUxNzNlZDIxNjEwYTQ1NDUxNmJlMGRmM2YxY2MwMTUxNjEwZWEifQ.LtoTBRRo4Zcw9VlEhS5WCwX4cI_f-mYznekIzXkxqds", - "outcome": "invalid jwt: claim url_hash is invalid" - }, - { - "name": "Token received on different URL (parameters were sorted out of order) - PATCH", - "method": "PATCH", - "secret": "hunter2", - "url": "https://example.com/path?foo=1\u0026bar=2", - "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJhNzVjOTA5Ni1lODIzLTQ0MmItODVmMi03ZDNjOWQ5YjcyNmIiLCJ1cmxfaGFzaCI6IjZhMDIyZDgzNGMxODMzMGJhYWQ4YTJiZDYxMzUxNzNlZDIxNjEwYTQ1NDUxNmJlMGRmM2YxY2MwMTUxNjEwZWEifQ.LtoTBRRo4Zcw9VlEhS5WCwX4cI_f-mYznekIzXkxqds", - "outcome": "invalid jwt: claim url_hash is invalid" - }, - { - "name": "Token received on different URL (parameters were sorted out of order) - POST", - "method": "POST", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/path?foo=1\u0026bar=2", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJhNzVjOTA5Ni1lODIzLTQ0MmItODVmMi03ZDNjOWQ5YjcyNmIiLCJ1cmxfaGFzaCI6IjZhMDIyZDgzNGMxODMzMGJhYWQ4YTJiZDYxMzUxNzNlZDIxNjEwYTQ1NDUxNmJlMGRmM2YxY2MwMTUxNjEwZWEifQ.LtoTBRRo4Zcw9VlEhS5WCwX4cI_f-mYznekIzXkxqds", - "outcome": "invalid jwt: claim url_hash is invalid" - }, - { - "name": "Token received on different URL (parameters were sorted out of order) - PUT", - "method": "PUT", - "secret": "hunter2", - "url": "https://example.com/path?foo=1\u0026bar=2", - "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJhNzVjOTA5Ni1lODIzLTQ0MmItODVmMi03ZDNjOWQ5YjcyNmIiLCJ1cmxfaGFzaCI6IjZhMDIyZDgzNGMxODMzMGJhYWQ4YTJiZDYxMzUxNzNlZDIxNjEwYTQ1NDUxNmJlMGRmM2YxY2MwMTUxNjEwZWEifQ.LtoTBRRo4Zcw9VlEhS5WCwX4cI_f-mYznekIzXkxqds", - "outcome": "invalid jwt: claim url_hash is invalid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiJhNzVjOTA5Ni1lODIzLTQ0MmItODVmMi03ZDNjOWQ5YjcyNmIiLCJ1cmxfaGFzaCI6IjZhMDIyZDgzNGMxODMzMGJhYWQ4YTJiZDYxMzUxNzNlZDIxNjEwYTQ1NDUxNmJlMGRmM2YxY2MwMTUxNjEwZWEifQ.z6Sw1XQIM0wuEQGBhXBdawDIIrtMg2XnmA_bpDq53pE", + "valid": false, + "reason": "invalid jwt: claim url_hash is invalid" }, { "name": "Payload does not match - DELETE", "method": "DELETE", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "payload": "Hello, World!", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJmYjYyZjAyYWNkYTdkNzQxNzdhNzAxYTFjZTAwNmU2YmFjZDkwYzdkNGQ3YWI0ODE2OTJjMWRhNDdjODEwNzZiIn0.wt_2rlnGfmMQsZ8tYtN_D5V5oIMt4wXp1s2b0uVwcvk", - "outcome": "invalid jwt: claim payload_hash is invalid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJmYjYyZjAyYWNkYTdkNzQxNzdhNzAxYTFjZTAwNmU2YmFjZDkwYzdkNGQ3YWI0ODE2OTJjMWRhNDdjODEwNzZiIn0.m79RCwO6dGa9pvzsQypkVuXQ6eM0CkRl6_U7MfWg6TM", + "valid": false, + "reason": "invalid jwt: claim payload_hash is invalid" }, { "name": "Payload does not match - GET", "method": "GET", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "payload": "Hello, World!", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJmYjYyZjAyYWNkYTdkNzQxNzdhNzAxYTFjZTAwNmU2YmFjZDkwYzdkNGQ3YWI0ODE2OTJjMWRhNDdjODEwNzZiIn0.wt_2rlnGfmMQsZ8tYtN_D5V5oIMt4wXp1s2b0uVwcvk", - "outcome": "invalid jwt: claim payload_hash is invalid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJmYjYyZjAyYWNkYTdkNzQxNzdhNzAxYTFjZTAwNmU2YmFjZDkwYzdkNGQ3YWI0ODE2OTJjMWRhNDdjODEwNzZiIn0.m79RCwO6dGa9pvzsQypkVuXQ6eM0CkRl6_U7MfWg6TM", + "valid": false, + "reason": "invalid jwt: claim payload_hash is invalid" }, { "name": "Payload does not match - PATCH", "method": "PATCH", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "payload": "Hello, World!", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJmYjYyZjAyYWNkYTdkNzQxNzdhNzAxYTFjZTAwNmU2YmFjZDkwYzdkNGQ3YWI0ODE2OTJjMWRhNDdjODEwNzZiIn0.wt_2rlnGfmMQsZ8tYtN_D5V5oIMt4wXp1s2b0uVwcvk", - "outcome": "invalid jwt: claim payload_hash is invalid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJmYjYyZjAyYWNkYTdkNzQxNzdhNzAxYTFjZTAwNmU2YmFjZDkwYzdkNGQ3YWI0ODE2OTJjMWRhNDdjODEwNzZiIn0.m79RCwO6dGa9pvzsQypkVuXQ6eM0CkRl6_U7MfWg6TM", + "valid": false, + "reason": "invalid jwt: claim payload_hash is invalid" }, { "name": "Payload does not match - POST", "method": "POST", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "payload": "Hello, World!", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJmYjYyZjAyYWNkYTdkNzQxNzdhNzAxYTFjZTAwNmU2YmFjZDkwYzdkNGQ3YWI0ODE2OTJjMWRhNDdjODEwNzZiIn0.wt_2rlnGfmMQsZ8tYtN_D5V5oIMt4wXp1s2b0uVwcvk", - "outcome": "invalid jwt: claim payload_hash is invalid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJmYjYyZjAyYWNkYTdkNzQxNzdhNzAxYTFjZTAwNmU2YmFjZDkwYzdkNGQ3YWI0ODE2OTJjMWRhNDdjODEwNzZiIn0.m79RCwO6dGa9pvzsQypkVuXQ6eM0CkRl6_U7MfWg6TM", + "valid": false, + "reason": "invalid jwt: claim payload_hash is invalid" }, { "name": "Payload does not match - PUT", "method": "PUT", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "payload": "Hello, World!", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJmYjYyZjAyYWNkYTdkNzQxNzdhNzAxYTFjZTAwNmU2YmFjZDkwYzdkNGQ3YWI0ODE2OTJjMWRhNDdjODEwNzZiIn0.wt_2rlnGfmMQsZ8tYtN_D5V5oIMt4wXp1s2b0uVwcvk", - "outcome": "invalid jwt: claim payload_hash is invalid" - }, - { - "name": "Different secret - DELETE", - "method": "DELETE", - "secret": "hunter2", - "url": "https://example.com/", - "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIyNDNjMjdhZS0yZjAyLTQ2YTAtODg1Mi1jNjZmMzdlYTlmNDYiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._Uwf4HMtfAT6jvbBbh85Q9TunX0QlsXoaLGKX0I4VDg", - "outcome": "invalid jwt: signature is invalid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJmYjYyZjAyYWNkYTdkNzQxNzdhNzAxYTFjZTAwNmU2YmFjZDkwYzdkNGQ3YWI0ODE2OTJjMWRhNDdjODEwNzZiIn0.m79RCwO6dGa9pvzsQypkVuXQ6eM0CkRl6_U7MfWg6TM", + "valid": false, + "reason": "invalid jwt: claim payload_hash is invalid" }, { "name": "Different secret - GET", "method": "GET", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIyNDNjMjdhZS0yZjAyLTQ2YTAtODg1Mi1jNjZmMzdlYTlmNDYiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._Uwf4HMtfAT6jvbBbh85Q9TunX0QlsXoaLGKX0I4VDg", - "outcome": "invalid jwt: signature is invalid" - }, - { - "name": "Different secret - PATCH", - "method": "PATCH", - "secret": "hunter2", - "url": "https://example.com/", - "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIyNDNjMjdhZS0yZjAyLTQ2YTAtODg1Mi1jNjZmMzdlYTlmNDYiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._Uwf4HMtfAT6jvbBbh85Q9TunX0QlsXoaLGKX0I4VDg", - "outcome": "invalid jwt: signature is invalid" - }, - { - "name": "Different secret - POST", - "method": "POST", - "secret": "hunter2", - "url": "https://example.com/", - "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIyNDNjMjdhZS0yZjAyLTQ2YTAtODg1Mi1jNjZmMzdlYTlmNDYiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._Uwf4HMtfAT6jvbBbh85Q9TunX0QlsXoaLGKX0I4VDg", - "outcome": "invalid jwt: signature is invalid" - }, - { - "name": "Different secret - PUT", - "method": "PUT", - "secret": "hunter2", - "url": "https://example.com/", - "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIyNDNjMjdhZS0yZjAyLTQ2YTAtODg1Mi1jNjZmMzdlYTlmNDYiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ._Uwf4HMtfAT6jvbBbh85Q9TunX0QlsXoaLGKX0I4VDg", - "outcome": "invalid jwt: signature is invalid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIyNDNjMjdhZS0yZjAyLTQ2YTAtODg1Mi1jNjZmMzdlYTlmNDYiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.JgSeYyOtlEKAXk8bz30iJI4tXgf4lxknoiezawuVhb4", + "valid": false, + "reason": "invalid jwt: signature is invalid" }, { "name": "payload was removed in transit - DELETE", "method": "DELETE", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "payload": "", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.K2VPo6K75lV2rXAvXfm9kBhSEQNYyBaIqwC73h-BPKI", - "outcome": "invalid jwt: claim payload_hash is set but actual payload is missing" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.bHfsjj3tljfzTufoG3EU3p_yFrQh9CufyzRSaRMd4ss", + "valid": false, + "reason": "invalid jwt: claim payload_hash is set but actual payload is missing" }, { "name": "payload was removed in transit - GET", "method": "GET", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "payload": "", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.K2VPo6K75lV2rXAvXfm9kBhSEQNYyBaIqwC73h-BPKI", - "outcome": "invalid jwt: claim payload_hash is set but actual payload is missing" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.bHfsjj3tljfzTufoG3EU3p_yFrQh9CufyzRSaRMd4ss", + "valid": false, + "reason": "invalid jwt: claim payload_hash is set but actual payload is missing" }, { "name": "payload was removed in transit - PATCH", "method": "PATCH", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "payload": "", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.K2VPo6K75lV2rXAvXfm9kBhSEQNYyBaIqwC73h-BPKI", - "outcome": "invalid jwt: claim payload_hash is set but actual payload is missing" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.bHfsjj3tljfzTufoG3EU3p_yFrQh9CufyzRSaRMd4ss", + "valid": false, + "reason": "invalid jwt: claim payload_hash is set but actual payload is missing" }, { "name": "payload was removed in transit - POST", "method": "POST", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "payload": "", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.K2VPo6K75lV2rXAvXfm9kBhSEQNYyBaIqwC73h-BPKI", - "outcome": "invalid jwt: claim payload_hash is set but actual payload is missing" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.bHfsjj3tljfzTufoG3EU3p_yFrQh9CufyzRSaRMd4ss", + "valid": false, + "reason": "invalid jwt: claim payload_hash is set but actual payload is missing" }, { "name": "payload was removed in transit - PUT", "method": "PUT", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "payload": "", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.K2VPo6K75lV2rXAvXfm9kBhSEQNYyBaIqwC73h-BPKI", - "outcome": "invalid jwt: claim payload_hash is set but actual payload is missing" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiIxNDUwMTUzMi05NmYyLTQ2ODQtOTgzMi02OGYwOTUxYWUzNDIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiJkZmZkNjAyMWJiMmJkNWIwYWY2NzYyOTA4MDllYzNhNTMxOTFkZDgxYzdmNzBhNGIyODY4OGEzNjIxODI5ODZmIn0.bHfsjj3tljfzTufoG3EU3p_yFrQh9CufyzRSaRMd4ss", + "valid": false, + "reason": "invalid jwt: claim payload_hash is set but actual payload is missing" }, { "name": "payload was added in transit - DELETE", "method": "DELETE", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "payload": "Hello, World!", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE", - "outcome": "invalid jwt: claim payload_hash is not set but payload is present" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.6Fp0rVOsRr1fj9S2GidXAfkmPVofKr8_RTffC6G6r2E", + "valid": false, + "reason": "invalid jwt: claim payload_hash is not set but payload is present" }, { "name": "payload was added in transit - GET", "method": "GET", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "payload": "Hello, World!", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE", - "outcome": "invalid jwt: claim payload_hash is not set but payload is present" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.6Fp0rVOsRr1fj9S2GidXAfkmPVofKr8_RTffC6G6r2E", + "valid": false, + "reason": "invalid jwt: claim payload_hash is not set but payload is present" }, { "name": "payload was added in transit - PATCH", "method": "PATCH", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "payload": "Hello, World!", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE", - "outcome": "invalid jwt: claim payload_hash is not set but payload is present" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.6Fp0rVOsRr1fj9S2GidXAfkmPVofKr8_RTffC6G6r2E", + "valid": false, + "reason": "invalid jwt: claim payload_hash is not set but payload is present" }, { "name": "payload was added in transit - POST", "method": "POST", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "payload": "Hello, World!", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE", - "outcome": "invalid jwt: claim payload_hash is not set but payload is present" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.6Fp0rVOsRr1fj9S2GidXAfkmPVofKr8_RTffC6G6r2E", + "valid": false, + "reason": "invalid jwt: claim payload_hash is not set but payload is present" }, { "name": "payload was added in transit - PUT", "method": "PUT", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "payload": "Hello, World!", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.SrhlKJ-ES4Dg8BBXKtop3u92Z_k4L4VjHKsyHWpweGE", - "outcome": "invalid jwt: claim payload_hash is not set but payload is present" - }, - { - "name": "Special characters in URL - DELETE", - "method": "DELETE", - "secret": "hunter2", - "url": "https://example.com/?obj%5Bfield1%5D=val1\u0026obj%5Bfield2%5D=val2\u0026param=value+with+spaces", - "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjhhZmYzNzQ4ZDc4OWM0MzMzNTczZTFjMzFmZTViMDA0OTQwY2I1ZmM0NzQ2MGVkM2QwZTY1NGY3ZmM0ZTVmYWUifQ.uKyViTrquY1DAtEaeBrz6RvLNsLdSg0n4YVDuO2juj4", - "outcome": "valid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.6Fp0rVOsRr1fj9S2GidXAfkmPVofKr8_RTffC6G6r2E", + "valid": false, + "reason": "invalid jwt: claim payload_hash is not set but payload is present" }, { "name": "Special characters in URL - GET", "method": "GET", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/?obj%5Bfield1%5D=val1\u0026obj%5Bfield2%5D=val2\u0026param=value+with+spaces", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjhhZmYzNzQ4ZDc4OWM0MzMzNTczZTFjMzFmZTViMDA0OTQwY2I1ZmM0NzQ2MGVkM2QwZTY1NGY3ZmM0ZTVmYWUifQ.uKyViTrquY1DAtEaeBrz6RvLNsLdSg0n4YVDuO2juj4", - "outcome": "valid" - }, - { - "name": "Special characters in URL - PATCH", - "method": "PATCH", - "secret": "hunter2", - "url": "https://example.com/?obj%5Bfield1%5D=val1\u0026obj%5Bfield2%5D=val2\u0026param=value+with+spaces", - "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjhhZmYzNzQ4ZDc4OWM0MzMzNTczZTFjMzFmZTViMDA0OTQwY2I1ZmM0NzQ2MGVkM2QwZTY1NGY3ZmM0ZTVmYWUifQ.uKyViTrquY1DAtEaeBrz6RvLNsLdSg0n4YVDuO2juj4", - "outcome": "valid" - }, - { - "name": "Special characters in URL - POST", - "method": "POST", - "secret": "hunter2", - "url": "https://example.com/?obj%5Bfield1%5D=val1\u0026obj%5Bfield2%5D=val2\u0026param=value+with+spaces", - "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjhhZmYzNzQ4ZDc4OWM0MzMzNTczZTFjMzFmZTViMDA0OTQwY2I1ZmM0NzQ2MGVkM2QwZTY1NGY3ZmM0ZTVmYWUifQ.uKyViTrquY1DAtEaeBrz6RvLNsLdSg0n4YVDuO2juj4", - "outcome": "valid" - }, - { - "name": "Special characters in URL - PUT", - "method": "PUT", - "secret": "hunter2", - "url": "https://example.com/?obj%5Bfield1%5D=val1\u0026obj%5Bfield2%5D=val2\u0026param=value+with+spaces", - "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjhhZmYzNzQ4ZDc4OWM0MzMzNTczZTFjMzFmZTViMDA0OTQwY2I1ZmM0NzQ2MGVkM2QwZTY1NGY3ZmM0ZTVmYWUifQ.uKyViTrquY1DAtEaeBrz6RvLNsLdSg0n4YVDuO2juj4", - "outcome": "valid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjhhZmYzNzQ4ZDc4OWM0MzMzNTczZTFjMzFmZTViMDA0OTQwY2I1ZmM0NzQ2MGVkM2QwZTY1NGY3ZmM0ZTVmYWUifQ.mJBCMfEjKmN3IMuzqPXPHktWETrcu0iNdF3agE8PDyI", + "valid": true }, { "name": "Special characters in the payload - DELETE", "method": "DELETE", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "payload": "Some text containg \u0026 \u003c \u003e, \u0026 and \\u0026", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiIyNDMxYmQ5Y2NiNDhlZDAxNmZhZDU2N2IwNzcxMjAzOGI1Y2RkOTQ5YWM5ZDQxZmU0NjkzZDVhMzg0NWNmN2U4In0.oQZwEMcMsT3SQhMozbnAo2445PYDKwoD77e2-dJQpdc", - "outcome": "valid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiIyNDMxYmQ5Y2NiNDhlZDAxNmZhZDU2N2IwNzcxMjAzOGI1Y2RkOTQ5YWM5ZDQxZmU0NjkzZDVhMzg0NWNmN2U4In0.IQiKzeEPaO3A48lhKmBDSmxZyCESPCGxdSKFdi0dEJs", + "valid": true }, { "name": "Special characters in the payload - GET", "method": "GET", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "payload": "Some text containg \u0026 \u003c \u003e, \u0026 and \\u0026", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiIyNDMxYmQ5Y2NiNDhlZDAxNmZhZDU2N2IwNzcxMjAzOGI1Y2RkOTQ5YWM5ZDQxZmU0NjkzZDVhMzg0NWNmN2U4In0.oQZwEMcMsT3SQhMozbnAo2445PYDKwoD77e2-dJQpdc", - "outcome": "valid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiIyNDMxYmQ5Y2NiNDhlZDAxNmZhZDU2N2IwNzcxMjAzOGI1Y2RkOTQ5YWM5ZDQxZmU0NjkzZDVhMzg0NWNmN2U4In0.IQiKzeEPaO3A48lhKmBDSmxZyCESPCGxdSKFdi0dEJs", + "valid": true }, { "name": "Special characters in the payload - PATCH", "method": "PATCH", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "payload": "Some text containg \u0026 \u003c \u003e, \u0026 and \\u0026", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiIyNDMxYmQ5Y2NiNDhlZDAxNmZhZDU2N2IwNzcxMjAzOGI1Y2RkOTQ5YWM5ZDQxZmU0NjkzZDVhMzg0NWNmN2U4In0.oQZwEMcMsT3SQhMozbnAo2445PYDKwoD77e2-dJQpdc", - "outcome": "valid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiIyNDMxYmQ5Y2NiNDhlZDAxNmZhZDU2N2IwNzcxMjAzOGI1Y2RkOTQ5YWM5ZDQxZmU0NjkzZDVhMzg0NWNmN2U4In0.IQiKzeEPaO3A48lhKmBDSmxZyCESPCGxdSKFdi0dEJs", + "valid": true }, { "name": "Special characters in the payload - POST", "method": "POST", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "payload": "Some text containg \u0026 \u003c \u003e, \u0026 and \\u0026", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiIyNDMxYmQ5Y2NiNDhlZDAxNmZhZDU2N2IwNzcxMjAzOGI1Y2RkOTQ5YWM5ZDQxZmU0NjkzZDVhMzg0NWNmN2U4In0.oQZwEMcMsT3SQhMozbnAo2445PYDKwoD77e2-dJQpdc", - "outcome": "valid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiIyNDMxYmQ5Y2NiNDhlZDAxNmZhZDU2N2IwNzcxMjAzOGI1Y2RkOTQ5YWM5ZDQxZmU0NjkzZDVhMzg0NWNmN2U4In0.IQiKzeEPaO3A48lhKmBDSmxZyCESPCGxdSKFdi0dEJs", + "valid": true }, { "name": "Special characters in the payload - PUT", "method": "PUT", - "secret": "hunter2", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", "url": "https://example.com/", "payload": "Some text containg \u0026 \u003c \u003e, \u0026 and \\u0026", "timestamp": "2021-07-05T12:00:00+02:00", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiIyNDMxYmQ5Y2NiNDhlZDAxNmZhZDU2N2IwNzcxMjAzOGI1Y2RkOTQ5YWM5ZDQxZmU0NjkzZDVhMzg0NWNmN2U4In0.oQZwEMcMsT3SQhMozbnAo2445PYDKwoD77e2-dJQpdc", - "outcome": "valid" + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDciLCJwYXlsb2FkX2hhc2giOiIyNDMxYmQ5Y2NiNDhlZDAxNmZhZDU2N2IwNzcxMjAzOGI1Y2RkOTQ5YWM5ZDQxZmU0NjkzZDVhMzg0NWNmN2U4In0.IQiKzeEPaO3A48lhKmBDSmxZyCESPCGxdSKFdi0dEJs", + "valid": true + }, + { + "name": "HS384 alg - GET", + "method": "GET", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.KNMW-29X77lZeuPmThmHWc_RUAvTkaDkpxIZK6mqE08v8mWKiU9Edh4QXwAJO2nv", + "valid": true + }, + { + "name": "HS512 alg - GET", + "method": "GET", + "secret": "36efdd1aace2e26cd490f0d951138253bef2f7c6d34d18981da781555cc4cebb", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJNZXNzYWdlQmlyZCIsIm5iZiI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.rd6r0iMyNGnVPCwurETphE3Y8rpAyvvnUK0S8WvGUkt2E1QSRAZ7NZJZBHw1Y_Wb5W-sK9HJr_PRL2vz4jRT3Q", + "valid": true + }, + { + "name": "none alg - GET", + "method": "GET", + "url": "https://example.com/", + "timestamp": "2021-07-05T12:00:00+02:00", + "token": "eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJpc3MiOiJNZXNzYWdlQmlyZCIsImlhdCI6MTYyNTQ3OTIwMCwiZXhwIjoxNjI1NDc5MjYwLCJqdGkiOiI1OWEyNDRkYy1lOWFkLTRlMjMtOTc3OC0zNzFmYWEyMzhmNzIiLCJ1cmxfaGFzaCI6IjBmMTE1ZGIwNjJiN2MwZGQwMzBiMTY4NzhjOTlkZWE1YzM1NGI0OWRjMzdiMzhlYjg4NDYxNzljNzc4M2U5ZDcifQ.", + "valid": false, + "reason": "invalid jwt: signing method none is invalid" } ] From 4ce603c4821e89aaaccbc855ba7ed1ba9d5778b8 Mon Sep 17 00:00:00 2001 From: "khanh.nguyen" Date: Mon, 30 Aug 2021 12:10:30 +0200 Subject: [PATCH 304/516] Updated webhook signature jwt implementation and tests --- .../com/messagebird/RequestValidator.java | 79 +++++++++++++++---- .../com/messagebird/RequestValidatorTest.java | 76 ++++++++---------- 2 files changed, 96 insertions(+), 59 deletions(-) diff --git a/api/src/main/java/com/messagebird/RequestValidator.java b/api/src/main/java/com/messagebird/RequestValidator.java index 9206e234..122a32b3 100644 --- a/api/src/main/java/com/messagebird/RequestValidator.java +++ b/api/src/main/java/com/messagebird/RequestValidator.java @@ -1,8 +1,5 @@ package com.messagebird; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - import com.auth0.jwt.JWT; import com.auth0.jwt.JWTVerifier.BaseVerification; import com.auth0.jwt.algorithms.Algorithm; @@ -13,29 +10,60 @@ import com.auth0.jwt.interfaces.JWTVerifier; import com.messagebird.exceptions.RequestValidationException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + /** * RequestValidator validates webhook signature signed by MessageBird services. + * + * @see Verify HTTP Requests */ public class RequestValidator { + /** + * Signature of signed request is set with header name 'MessageBird-Signature-JWT' + */ public static final String SIGNATURE_HEADER = "MessageBird-Signature-JWT"; - private static final String ALGORITHM_SHA256 = "SHA-256"; + private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', + 'e', 'f'}; - private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', - 'e', 'f' }; - - private final String signatureKey; + private final Algorithm HMAC256, HMAC384, HMAC512; /** * RequestValidator validates webhook signature with a customer signature key. - * - * @param signatureKey customer signature key + * + * @param signatureKey customer signature key. Can be retrieved through Developer Settings. This is NOT your API key. + * @see Verify HTTP Requests */ public RequestValidator(String signatureKey) { - this.signatureKey = signatureKey; + this.HMAC256 = Algorithm.HMAC256(signatureKey); + this.HMAC384 = Algorithm.HMAC384(signatureKey); + this.HMAC512 = Algorithm.HMAC512(signatureKey); } + /** + * Returns raw signature payload after validating a signature successfully, + * otherwise throws {@code RequestValidationException}. + *

+ * This JWT is signed with a MessageBird account unique secret key, ensuring the request is from MessageBird and a specific account. + * The JWT contains the following claims:

+ *
    + *
  • "url_hash" - the raw URL hashed with SHA256 ensuring the URL wasn't altered (validated by default)
  • + *
  • "payload_hash" - the raw payload hashed with SHA256 ensuring the payload wasn't altered (validated by default)
  • + *
  • "jti" - a unique token ID to implement an optional non-replay check (NOT validated by default)
  • + *
  • "nbf" - the not before timestamp (validated by default)
  • + *
  • "exp" - the expiration timestamp is ensuring that a request isn't captured and used at a later time. (validated by default)
  • + *
  • "iss" - the issuer name, always MessageBird (validated by default)
  • + *
+ * + * @param clock custom {@link Clock} instance to validate timestamp claims. + * @param signature the actual signature. + * @param url the raw url including the protocol, hostname and query string, https://example.com/?example=42. + * @param requestBody the raw request body. + * @return raw signature payload as {@link DecodedJWT} object. + * @throws RequestValidationException when the signature is invalid. + */ public DecodedJWT validateSignature(Clock clock, String signature, String url, byte[] requestBody) throws RequestValidationException { DecodedJWT jwt = JWT.decode(signature); @@ -43,16 +71,16 @@ public DecodedJWT validateSignature(Clock clock, String signature, String url, b Algorithm algorithm; switch (jwt.getAlgorithm()) { case "HS256": - algorithm = Algorithm.HMAC256(this.signatureKey); + algorithm = HMAC256; break; case "HS384": - algorithm = Algorithm.HMAC384(this.signatureKey); + algorithm = HMAC384; break; case "HS512": - algorithm = Algorithm.HMAC512(this.signatureKey); + algorithm = HMAC512; break; default: - throw new RequestValidationException("The signing method is invalid."); + throw new RequestValidationException(String.format("The signing method '%s' is invalid.", jwt.getAlgorithm())); } BaseVerification builder = (BaseVerification) JWT.require(algorithm) @@ -88,6 +116,27 @@ public DecodedJWT validateSignature(Clock clock, String signature, String url, b } } + /** + * Returns raw signature payload after validating a signature successfully, + * otherwise throws {@code RequestValidationException}. + *

+ * This JWT is signed with a MessageBird account unique secret key, ensuring the request is from MessageBird and a specific account. + * The JWT contains the following claims:

+ *
    + *
  • "url_hash" - the raw URL hashed with SHA256 ensuring the URL wasn't altered (validated by default)
  • + *
  • "payload_hash" - the raw payload hashed with SHA256 ensuring the payload wasn't altered (validated by default)
  • + *
  • "jti" - a unique token ID to implement an optional non-replay check (NOT validated by default)
  • + *
  • "nbf" - the not before timestamp (validated by default)
  • + *
  • "exp" - the expiration timestamp is ensuring that a request isn't captured and used at a later time. (validated by default)
  • + *
  • "iss" - the issuer name, always MessageBird (validated by default)
  • + *
+ * + * @param signature the actual signature. + * @param url the raw url including the protocol, hostname and query string, https://example.com/?example=42. + * @param requestBody the raw request body. + * @return raw signature payload as {@link DecodedJWT} object. + * @throws RequestValidationException when the signature is invalid. + */ public DecodedJWT validateSignature(String signature, String url, byte[] requestBody) throws RequestValidationException { return validateSignature(null, signature, url, requestBody); diff --git a/api/src/test/java/com/messagebird/RequestValidatorTest.java b/api/src/test/java/com/messagebird/RequestValidatorTest.java index fd50a92a..a8d38132 100644 --- a/api/src/test/java/com/messagebird/RequestValidatorTest.java +++ b/api/src/test/java/com/messagebird/RequestValidatorTest.java @@ -1,54 +1,28 @@ package com.messagebird; -import static org.junit.Assert.assertThrows; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -import java.io.IOException; -import java.nio.charset.Charset; -import java.time.OffsetDateTime; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import javax.annotation.Resources; - import com.auth0.jwt.interfaces.Clock; -import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.messagebird.exceptions.RequestValidationException; - +import com.messagebird.util.Resources; import org.junit.Test; import org.junit.function.ThrowingRunnable; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; -@RunWith(Parameterized.class) -public class RequestValidatorTest { +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.time.OffsetDateTime; +import java.util.*; +import java.util.stream.Collectors; - /** - * WebhookSignatureTestCase - */ - public static class WebhookSignatureTestCase { - public String name; - public String method; - public String secret; - public String url; - public String payload; - public String timestamp; - public String token; - public Boolean valid; - public String reason; - } +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.*; +@RunWith(Parameterized.class) +public class RequestValidatorTest { /** * Error Map that maps test data expected outcome to actual error message. */ @@ -64,11 +38,10 @@ public static class WebhookSignatureTestCase { "The Claim 'payload_hash' is set but actual payload is missing."); put("invalid jwt: claim payload_hash is not set but payload is present", "The Claim 'payload_hash' is not set but payload is present."); - put("invalid jwt: signing method none is invalid", "The signing method is invalid."); + put("invalid jwt: signing method none is invalid", "The signing method 'none' is invalid."); } }; - private final WebhookSignatureTestCase testCase; public RequestValidatorTest(String testName, WebhookSignatureTestCase testCase) { @@ -76,27 +49,27 @@ public RequestValidatorTest(String testName, WebhookSignatureTestCase testCase) } @Parameters(name = "{0}") - public static Collection data() throws JsonParseException, JsonMappingException, IOException { + public static Collection data() throws IOException { List testCases = new ObjectMapper().readValue( - Resources.class.getResourceAsStream("/webhook_test_data.json"), + Resources.readResourceText("/webhook_test_data.json"), new TypeReference>() { }); return testCases.stream() - .map(tc -> new Object[]{ tc.name, tc }) + .map(tc -> new Object[]{tc.name, tc}) .collect(Collectors.toList()); } @Test public void testWebhookSignature() throws Throwable { - RequestValidator validator = new RequestValidator(testCase.secret); + RequestValidator validator = new RequestValidator(testCase.secret != null ? testCase.secret : ""); Clock clock = mock(Clock.class); Date clockDate = spy(Date.from(OffsetDateTime.parse(testCase.timestamp).toInstant())); when(clock.getToday()).thenReturn(clockDate); ThrowingRunnable runnable = () -> validator.validateSignature(clock, testCase.token, testCase.url, - (testCase.payload == null) ? null : testCase.payload.getBytes(Charset.forName("UTF-8"))); + (testCase.payload == null) ? null : testCase.payload.getBytes(StandardCharsets.UTF_8)); if (testCase.valid) { runnable.run(); @@ -112,4 +85,19 @@ public void testWebhookSignature() throws Throwable { assertTrue(String.format("Expected error message containing: %s (originally %s) but was: %s", expectedError, testCase.reason, err.getMessage()), err.getMessage().contains(expectedError)); } + + /** + * WebhookSignatureTestCase + */ + public static class WebhookSignatureTestCase { + public String name; + public String method; + public String secret; + public String url; + public String payload; + public String timestamp; + public String token; + public Boolean valid; + public String reason; + } } From 028dbac8748518142885264e51f9aca432333275 Mon Sep 17 00:00:00 2001 From: "khanh.nguyen" Date: Mon, 30 Aug 2021 13:24:35 +0200 Subject: [PATCH 305/516] Re-adding deprecated RequestSigner to not break the API --- api/src/main/java/com/messagebird/Base64.java | 512 ++++++++++++++++++ .../main/java/com/messagebird/Request.java | 60 ++ .../java/com/messagebird/RequestSigner.java | 128 +++++ .../com/messagebird/RequestValidator.java | 2 +- .../exceptions/RequestSigningException.java | 21 + .../com/messagebird/RequestSignerTest.java | 114 ++++ 6 files changed, 836 insertions(+), 1 deletion(-) create mode 100644 api/src/main/java/com/messagebird/Base64.java create mode 100644 api/src/main/java/com/messagebird/Request.java create mode 100644 api/src/main/java/com/messagebird/RequestSigner.java create mode 100644 api/src/main/java/com/messagebird/exceptions/RequestSigningException.java create mode 100644 api/src/test/java/com/messagebird/RequestSignerTest.java diff --git a/api/src/main/java/com/messagebird/Base64.java b/api/src/main/java/com/messagebird/Base64.java new file mode 100644 index 00000000..f96ef9fa --- /dev/null +++ b/api/src/main/java/com/messagebird/Base64.java @@ -0,0 +1,512 @@ +package com.messagebird; + +/** + * Cutted version of iharder's base64 implementation + * + * @author Robert Harder + * @author rob@iharder.net + * @version 2.3.7 + * @todo replace with actual library on next major bump + * + *

Encodes and decodes to and from Base64 notation.

+ *

Homepage: http://iharder.net/base64.

+ * + *

+ * I am placing this code in the Public Domain. Do with it as you will. + * This software comes with no guarantees or warranties but with + * plenty of well-wishing instead! + * Please visit http://iharder.net/base64 + * periodically to check for updates or to contribute improvements. + *

+ * @deprecated This class is being deprecated together with {@link RequestSigner} + */ +@Deprecated +class Base64 { + + /* ******** P U B L I C F I E L D S ******** */ + + + /** + * No options specified. Value is zero. + */ + public final static int NO_OPTIONS = 0; + + /** + * Specify that gzipped data should not be automatically gunzipped. + */ + public final static int DONT_GUNZIP = 4; + + /** + * Encode using Base64-like encoding that is URL- and Filename-safe as described + * in Section 4 of RFC3548: + * http://www.faqs.org/rfcs/rfc3548.html. + * It is important to note that data encoded this way is not officially valid Base64, + * or at the very least should not be called Base64 without also specifying that is + * was encoded using the URL- and Filename-safe dialect. + */ + public final static int URL_SAFE = 16; + + + /** + * Encode using the special "ordered" dialect of Base64 described here: + * http://www.faqs.org/qa/rfcc-1940.html. + */ + public final static int ORDERED = 32; + + + /* ******** P R I V A T E F I E L D S ******** */ + + + /** + * The equals sign (=) as a byte. + */ + private final static byte EQUALS_SIGN = (byte) '='; + + + /** + * Preferred encoding. + */ + private final static String PREFERRED_ENCODING = "US-ASCII"; + + + private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding + private final static byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding + + + /* ******** S T A N D A R D B A S E 6 4 A L P H A B E T ******** */ + + /** + * Translates a Base64 value to either its 6-bit reconstruction value + * or a negative number indicating some other meaning. + **/ + private final static byte[] _STANDARD_DECODABET = { + -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8 + -5, -5, // Whitespace: Tab and Linefeed + -9, -9, // Decimal 11 - 12 + -5, // Whitespace: Carriage Return + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26 + -9, -9, -9, -9, -9, // Decimal 27 - 31 + -5, // Whitespace: Space + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42 + 62, // Plus sign at decimal 43 + -9, -9, -9, // Decimal 44 - 46 + 63, // Slash at decimal 47 + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine + -9, -9, -9, // Decimal 58 - 60 + -1, // Equals sign at decimal 61 + -9, -9, -9, // Decimal 62 - 64 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N' + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z' + -9, -9, -9, -9, -9, -9, // Decimal 91 - 96 + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm' + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z' + -9, -9, -9, -9, -9 // Decimal 123 - 127 + , -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 128 - 139 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 140 - 152 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 153 - 165 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 166 - 178 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 179 - 191 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 192 - 204 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 205 - 217 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 218 - 230 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 231 - 243 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 // Decimal 244 - 255 + }; + + + /* ******** U R L S A F E B A S E 6 4 A L P H A B E T ******** */ + + /** + * Used in decoding URL- and Filename-safe dialects of Base64. + */ + private final static byte[] _URL_SAFE_DECODABET = { + -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8 + -5, -5, // Whitespace: Tab and Linefeed + -9, -9, // Decimal 11 - 12 + -5, // Whitespace: Carriage Return + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26 + -9, -9, -9, -9, -9, // Decimal 27 - 31 + -5, // Whitespace: Space + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42 + -9, // Plus sign at decimal 43 + -9, // Decimal 44 + 62, // Minus sign at decimal 45 + -9, // Decimal 46 + -9, // Slash at decimal 47 + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine + -9, -9, -9, // Decimal 58 - 60 + -1, // Equals sign at decimal 61 + -9, -9, -9, // Decimal 62 - 64 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N' + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z' + -9, -9, -9, -9, // Decimal 91 - 94 + 63, // Underscore at decimal 95 + -9, // Decimal 96 + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm' + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z' + -9, -9, -9, -9, -9 // Decimal 123 - 127 + , -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 128 - 139 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 140 - 152 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 153 - 165 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 166 - 178 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 179 - 191 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 192 - 204 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 205 - 217 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 218 - 230 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 231 - 243 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 // Decimal 244 - 255 + }; + + + + /* ******** O R D E R E D B A S E 6 4 A L P H A B E T ******** */ + + /** + * Used in decoding the "ordered" dialect of Base64. + */ + private final static byte[] _ORDERED_DECODABET = { + -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8 + -5, -5, // Whitespace: Tab and Linefeed + -9, -9, // Decimal 11 - 12 + -5, // Whitespace: Carriage Return + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26 + -9, -9, -9, -9, -9, // Decimal 27 - 31 + -5, // Whitespace: Space + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42 + -9, // Plus sign at decimal 43 + -9, // Decimal 44 + 0, // Minus sign at decimal 45 + -9, // Decimal 46 + -9, // Slash at decimal 47 + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // Numbers zero through nine + -9, -9, -9, // Decimal 58 - 60 + -1, // Equals sign at decimal 61 + -9, -9, -9, // Decimal 62 - 64 + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, // Letters 'A' through 'M' + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, // Letters 'N' through 'Z' + -9, -9, -9, -9, // Decimal 91 - 94 + 37, // Underscore at decimal 95 + -9, // Decimal 96 + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, // Letters 'a' through 'm' + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // Letters 'n' through 'z' + -9, -9, -9, -9, -9 // Decimal 123 - 127 + , -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 128 - 139 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 140 - 152 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 153 - 165 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 166 - 178 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 179 - 191 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 192 - 204 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 205 - 217 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 218 - 230 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 231 - 243 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 // Decimal 244 - 255 + }; + + + /* ******** D E T E R M I N E W H I C H A L H A B E T ******** */ + + /** + * Returns one of the _SOMETHING_DECODABET byte arrays depending on + * the options specified. + * It's possible, though silly, to specify ORDERED and URL_SAFE + * in which case one of them will be picked, though there is + * no guarantee as to which one will be picked. + */ + private final static byte[] getDecodabet(int options) { + if ((options & URL_SAFE) == URL_SAFE) { + return _URL_SAFE_DECODABET; + } else if ((options & ORDERED) == ORDERED) { + return _ORDERED_DECODABET; + } else { + return _STANDARD_DECODABET; + } + } // end getAlphabet + + + /** + * Defeats instantiation. + */ + private Base64() { + } + + + + /* ******** D E C O D I N G M E T H O D S ******** */ + + + /** + * Decodes four bytes from array source + * and writes the resulting bytes (up to three of them) + * to destination. + * The source and destination arrays can be manipulated + * anywhere along their length by specifying + * srcOffset and destOffset. + * This method does not check to make sure your arrays + * are large enough to accomodate srcOffset + 4 for + * the source array or destOffset + 3 for + * the destination array. + * This method returns the actual number of bytes that + * were converted from the Base64 encoding. + *

This is the lowest level of the decoding methods with + * all possible parameters.

+ * + * @param source the array to convert + * @param srcOffset the index where conversion begins + * @param destination the array to hold the conversion + * @param destOffset the index where output will be put + * @param options alphabet type is pulled from this (standard, url-safe, ordered) + * @return the number of decoded bytes converted + * @throws NullPointerException if source or destination arrays are null + * @throws IllegalArgumentException if srcOffset or destOffset are invalid + * or there is not enough room in the array. + * @since 1.3 + */ + private static int decode4to3( + byte[] source, int srcOffset, + byte[] destination, int destOffset, int options) { + + // Lots of error checking and exception throwing + if (source == null) { + throw new NullPointerException("Source array was null."); + } // end if + if (destination == null) { + throw new NullPointerException("Destination array was null."); + } // end if + if (srcOffset < 0 || srcOffset + 3 >= source.length) { + throw new IllegalArgumentException(String.format( + "Source array with length %d cannot have offset of %d and still process four bytes.", source.length, srcOffset)); + } // end if + if (destOffset < 0 || destOffset + 2 >= destination.length) { + throw new IllegalArgumentException(String.format( + "Destination array with length %d cannot have offset of %d and still store three bytes.", destination.length, destOffset)); + } // end if + + + byte[] DECODABET = getDecodabet(options); + + // Example: Dk== + if (source[srcOffset + 2] == EQUALS_SIGN) { + // Two ways to do the same thing. Don't know which way I like best. + //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) + // | ( ( DECODABET[ source[ srcOffset + 1] ] << 24 ) >>> 12 ); + int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18) + | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12); + + destination[destOffset] = (byte) (outBuff >>> 16); + return 1; + } + + // Example: DkL= + else if (source[srcOffset + 3] == EQUALS_SIGN) { + // Two ways to do the same thing. Don't know which way I like best. + //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) + // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) + // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ); + int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18) + | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12) + | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6); + + destination[destOffset] = (byte) (outBuff >>> 16); + destination[destOffset + 1] = (byte) (outBuff >>> 8); + return 2; + } + + // Example: DkLE + else { + // Two ways to do the same thing. Don't know which way I like best. + //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) + // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) + // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ) + // | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 ); + int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18) + | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12) + | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6) + | ((DECODABET[source[srcOffset + 3]] & 0xFF)); + + + destination[destOffset] = (byte) (outBuff >> 16); + destination[destOffset + 1] = (byte) (outBuff >> 8); + destination[destOffset + 2] = (byte) (outBuff); + + return 3; + } + } // end decodeToBytes + + + /** + * Low-level access to decoding ASCII characters in + * the form of a byte array. Ignores GUNZIP option, if + * it's set. This is not generally a recommended method, + * although it is used internally as part of the decoding process. + * Special case: if len = 0, an empty array is returned. Still, + * if you need more speed and reduced memory footprint (and aren't + * gzipping), consider this method. + * + * @param source The Base64 encoded data + * @param off The offset of where to begin decoding + * @param len The length of characters to decode + * @param options Can specify options such as alphabet type to use + * @return decoded data + * @throws java.io.IOException If bogus characters exist in source data + * @since 1.3 + */ + public static byte[] decode(byte[] source, int off, int len, int options) + throws java.io.IOException { + + // Lots of error checking and exception throwing + if (source == null) { + throw new NullPointerException("Cannot decode null source array."); + } // end if + if (off < 0 || off + len > source.length) { + throw new IllegalArgumentException(String.format( + "Source array with length %d cannot have offset of %d and process %d bytes.", source.length, off, len)); + } // end if + + if (len == 0) { + return new byte[0]; + } else if (len < 4) { + throw new IllegalArgumentException( + "Base64-encoded string must have at least four characters, but length specified was " + len); + } // end if + + byte[] DECODABET = getDecodabet(options); + + int len34 = len * 3 / 4; // Estimate on array size + byte[] outBuff = new byte[len34]; // Upper limit on size of output + int outBuffPosn = 0; // Keep track of where we're writing + + byte[] b4 = new byte[4]; // Four byte buffer from source, eliminating white space + int b4Posn = 0; // Keep track of four byte input buffer + int i = 0; // Source array counter + byte sbiDecode = 0; // Special value from DECODABET + + for (i = off; i < off + len; i++) { // Loop through source + + sbiDecode = DECODABET[source[i] & 0xFF]; + + // White space, Equals sign, or legit Base64 character + // Note the values such as -5 and -9 in the + // DECODABETs at the top of the file. + if (sbiDecode >= WHITE_SPACE_ENC) { + if (sbiDecode >= EQUALS_SIGN_ENC) { + b4[b4Posn++] = source[i]; // Save non-whitespace + if (b4Posn > 3) { // Time to decode? + outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, options); + b4Posn = 0; + + // If that was the equals sign, break out of 'for' loop + if (source[i] == EQUALS_SIGN) { + break; + } // end if: equals sign + } // end if: quartet built + } // end if: equals sign or better + } // end if: white space, equals sign or better + else { + // There's a bad input character in the Base64 stream. + throw new java.io.IOException(String.format( + "Bad Base64 input character decimal %d in array position %d", ((int) source[i]) & 0xFF, i)); + } // end else: + } // each input character + + byte[] out = new byte[outBuffPosn]; + System.arraycopy(outBuff, 0, out, 0, outBuffPosn); + return out; + } // end decode + + + /** + * Decodes data from Base64 notation, automatically + * detecting gzip-compressed data and decompressing it. + * + * @param s the string to decode + * @return the decoded data + * @throws java.io.IOException If there is a problem + * @since 1.4 + */ + public static byte[] decode(String s) throws java.io.IOException { + return decode(s, NO_OPTIONS); + } + + + /** + * Decodes data from Base64 notation, automatically + * detecting gzip-compressed data and decompressing it. + * + * @param s the string to decode + * @param options encode options such as URL_SAFE + * @return the decoded data + * @throws java.io.IOException if there is an error + * @throws NullPointerException if s is null + * @since 1.4 + */ + public static byte[] decode(String s, int options) throws java.io.IOException { + + if (s == null) { + throw new NullPointerException("Input string was null."); + } // end if + + byte[] bytes; + try { + bytes = s.getBytes(PREFERRED_ENCODING); + } // end try + catch (java.io.UnsupportedEncodingException uee) { + bytes = s.getBytes(); + } // end catch + // + + // Decode + bytes = decode(bytes, 0, bytes.length, options); + + // Check to see if it's gzip-compressed + // GZIP Magic Two-Byte Number: 0x8b1f (35615) + boolean dontGunzip = (options & DONT_GUNZIP) != 0; + if ((bytes != null) && (bytes.length >= 4) && (!dontGunzip)) { + + int head = ((int) bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00); + if (java.util.zip.GZIPInputStream.GZIP_MAGIC == head) { + java.io.ByteArrayInputStream bais = null; + java.util.zip.GZIPInputStream gzis = null; + java.io.ByteArrayOutputStream baos = null; + byte[] buffer = new byte[2048]; + int length = 0; + + try { + baos = new java.io.ByteArrayOutputStream(); + bais = new java.io.ByteArrayInputStream(bytes); + gzis = new java.util.zip.GZIPInputStream(bais); + + while ((length = gzis.read(buffer)) >= 0) { + baos.write(buffer, 0, length); + } // end while: reading input + + // No error? Get new bytes. + bytes = baos.toByteArray(); + + } // end try + catch (java.io.IOException e) { + e.printStackTrace(); + // Just return originally-decoded bytes + } // end catch + finally { + try { + baos.close(); + } catch (Exception e) { + } + try { + gzis.close(); + } catch (Exception e) { + } + try { + bais.close(); + } catch (Exception e) { + } + } // end finally + + } // end if: gzipped + } // end if: bytes.length >= 2 + + return bytes; + } // end decode + + +} // end class Base64 diff --git a/api/src/main/java/com/messagebird/Request.java b/api/src/main/java/com/messagebird/Request.java new file mode 100644 index 00000000..46048b0e --- /dev/null +++ b/api/src/main/java/com/messagebird/Request.java @@ -0,0 +1,60 @@ +package com.messagebird; + +import java.util.Arrays; + +/** + * Holds request data needed to calculate a signature hash for incoming + * webhooks. + * + * @deprecated This class is being deprecated together with {@link RequestSigner} + */ +@Deprecated +public class Request { + + private final String timestamp; + private final String queryParameters; + private final byte[] data; + + private final static String QUERY_PARAMETERS_DELIMITER = "&"; + + /** + * Constructs a new request instance. + * + * @param timestamp Timestamp provided in the MessageBird-Request-Timestamp + * header. + * @param queryParameters Query parameters in abc=foo&def=ghi format. + * @param data Raw body of this request. + * @deprecated + */ + @Deprecated + public Request(String timestamp, String queryParameters, byte[] data) { + if (timestamp == null || timestamp.isEmpty()) { + throw new IllegalArgumentException("Timestamp can not be null or empty"); + } + + this.timestamp = timestamp; + this.queryParameters = queryParameters; + this.data = data; + } + + String getTimestamp() { + return timestamp; + } + + String getSortedQueryParameters() { + String[] params = queryParameters.split(QUERY_PARAMETERS_DELIMITER); + Arrays.sort(params); + StringBuilder sortedParamsAccumulator = new StringBuilder(); + for (int i = 0, paramsLength = params.length; i < paramsLength; i++) { + sortedParamsAccumulator.append(params[i]); + if (i < paramsLength - 1) { + sortedParamsAccumulator.append(QUERY_PARAMETERS_DELIMITER); + } + } + return sortedParamsAccumulator.toString(); + } + + byte[] getData() { + return data; + } +} diff --git a/api/src/main/java/com/messagebird/RequestSigner.java b/api/src/main/java/com/messagebird/RequestSigner.java new file mode 100644 index 00000000..32c257a2 --- /dev/null +++ b/api/src/main/java/com/messagebird/RequestSigner.java @@ -0,0 +1,128 @@ +package com.messagebird; + +import com.messagebird.exceptions.RequestSigningException; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; + +/** + * RequestSigner is used to verify HTTP requests and is an implementation of: + * https://developers.messagebird.com/docs/verify-http-requests. Retrieve your + * signing key at https://dashboard.messagebird.com/developers/settings. + * + * @deprecated This class is being deprecated. + *

Use {@link RequestValidator} instead.

+ */ +@Deprecated +public class RequestSigner { + + private static final String ALGORITHM_SHA256 = "SHA-256"; + private static final String ALGORITHM_HMAC_SHA256 = "HmacSHA256"; + private static final Charset CHARSET_UTF8 = StandardCharsets.UTF_8; + + private SecretKeySpec secret; + + /** + * Constructs a new RequestSigner instance. + * + * @param key Signing key. Can be retrieved through + * https://dashboard.messagebird.com/developers/settings. This + * is NOT your API key. + * @deprecated Use {@link RequestValidator#RequestValidator(String)} )} instead. + */ + @Deprecated + public RequestSigner(byte[] key) { + this.secret = new SecretKeySpec(key, ALGORITHM_HMAC_SHA256); + } + + /** + * Computes the signature for the provided request and determines whether + * it matches the expected signature (from the raw MessageBird-Signature header). + * + * @param expectedSignature Signature from the MessageBird-Signature + * header in its original base64 encoded state. + * @param request Request containing the values from the incoming webhook. + * @return True if the computed signature matches the expected signature. + * @deprecated Use {@link RequestValidator#validateSignature(String, String, byte[])} instead. + */ + @Deprecated + public boolean isMatch(String expectedSignature, Request request) { + try { + return isMatch(Base64.decode(expectedSignature), request); + } catch (IOException e) { + throw new RequestSigningException(e); + } + } + + /** + * Computes the signature for the provided request and determines whether + * it matches the expected signature + * + * @param expectedSignature Decoded (with base64) signature + * from the MessageBird-Signature header + * @param request Request containing the values from the incoming webhook. + * @return True if the computed signature matches the expected signature. + * @deprecated Use {@link RequestValidator#validateSignature(String, String, byte[])} instead. + */ + @Deprecated + public boolean isMatch(byte[] expectedSignature, Request request) { + return Arrays.equals(computeSignature(request), expectedSignature); + } + + /** + * Computes the signature for a request instance. + * + * @param request Request to compute signature for. + * @return HMAC-SHA2556 signature for the provided request. + */ + private byte[] computeSignature(Request request) { + String timestampAndQuery = request.getTimestamp() + '\n' + + request.getSortedQueryParameters() + '\n'; + + byte[] timestampAndQueryBytes = timestampAndQuery.getBytes(CHARSET_UTF8); + byte[] bodyHashBytes = getSha256Hash(request.getData()); + + return getHmacSha256Signature(appendArrays(timestampAndQueryBytes, bodyHashBytes)); + } + + private byte[] getSha256Hash(byte[] bytes) { + try { + return MessageDigest.getInstance(ALGORITHM_SHA256).digest(bytes); + } catch (NoSuchAlgorithmException e) { + throw new RequestSigningException(e); + } + } + + /** + * Stitches the two arrays together and returns a new one. + * + * @param first Start of the new array. + * @param second End of the new array. + * @return New array based on first and second. + */ + private byte[] appendArrays(byte[] first, byte[] second) { + byte[] result = new byte[first.length + second.length]; + System.arraycopy(first, 0, result, 0, first.length); + System.arraycopy(second, 0, result, first.length, second.length); + + return result; + } + + private byte[] getHmacSha256Signature(byte[] bytes) { + try { + Mac mac = Mac.getInstance(ALGORITHM_HMAC_SHA256); + mac.init(secret); + + return mac.doFinal(bytes); + } catch (InvalidKeyException | NoSuchAlgorithmException e) { + throw new RequestSigningException(e); + } + } +} diff --git a/api/src/main/java/com/messagebird/RequestValidator.java b/api/src/main/java/com/messagebird/RequestValidator.java index 122a32b3..36c0bec9 100644 --- a/api/src/main/java/com/messagebird/RequestValidator.java +++ b/api/src/main/java/com/messagebird/RequestValidator.java @@ -159,4 +159,4 @@ private static String encodeHex(final byte[] data) { } return new String(out); } -} \ No newline at end of file +} diff --git a/api/src/main/java/com/messagebird/exceptions/RequestSigningException.java b/api/src/main/java/com/messagebird/exceptions/RequestSigningException.java new file mode 100644 index 00000000..d69a1922 --- /dev/null +++ b/api/src/main/java/com/messagebird/exceptions/RequestSigningException.java @@ -0,0 +1,21 @@ +package com.messagebird.exceptions; + +/** + * Thrown if an error occurs during request signing. + * + * @deprecated This class is being deprecated together with {@link com.messagebird.RequestSigner} + */ +@Deprecated +public class RequestSigningException extends RuntimeException { + + public RequestSigningException() { + } + + public RequestSigningException(String message) { + super(message); + } + + public RequestSigningException(Throwable cause) { + super(cause); + } +} diff --git a/api/src/test/java/com/messagebird/RequestSignerTest.java b/api/src/test/java/com/messagebird/RequestSignerTest.java new file mode 100644 index 00000000..17adc0dc --- /dev/null +++ b/api/src/test/java/com/messagebird/RequestSignerTest.java @@ -0,0 +1,114 @@ +package com.messagebird; + +import org.junit.Test; + +import java.nio.charset.StandardCharsets; + +import static org.junit.Assert.*; + +/** + * @deprecated This class is being deprecated together with {@link RequestSigner} + */ +@Deprecated +public class RequestSignerTest { + + /** + * Helper to get the bytes the provided UTF-8 encoded string represents. + */ + private static byte[] getBytes(String s) { + return s.getBytes(StandardCharsets.UTF_8); + } + + @Test + public void testIsMatchEmptyQueryParamsAndEmptyData() { + RequestSigner requestSigner = new RequestSigner(getBytes("secret")); + String expectedSignature = "LISw4Je7n0/MkYDgVSzTJm8dW6BkytKTXMZZk1IElMs="; + Request request = new Request("1544544948", "", getBytes("")); + + assertTrue(requestSigner.isMatch(expectedSignature, request)); + } + + @Test + public void testIsMatchWithData() { + RequestSigner requestSigner = new RequestSigner(getBytes("secret")); + String expectedSignature = "p2e20OtAg39DEmz1ORHpjQ556U4o1ZaH4NWbM9Q8Qjk="; + Request request = new Request("1544544948", "", getBytes("{\"a key\":\"some value\"}")); + + assertTrue(requestSigner.isMatch(expectedSignature, request)); + } + + @Test + public void testIsMatchWithQueryParams() { + RequestSigner requestSigner = new RequestSigner(getBytes("secret")); + String expectedSignature = "Tfn+nRUBsn6lQgf6IpxBMS1j9lm7XsGjt5xh47M3jCk="; + Request request = new Request("1544544948", "abc=foo&def=bar", getBytes("")); + + assertTrue(requestSigner.isMatch(expectedSignature, request)); + } + + @Test + public void testIsMatchWithShuffledQueryParams() { + RequestSigner requestSigner = new RequestSigner(getBytes("secret")); + String expectedSignature = "Tfn+nRUBsn6lQgf6IpxBMS1j9lm7XsGjt5xh47M3jCk="; + Request request = new Request("1544544948", "def=bar&abc=foo", getBytes("")); + + assertTrue(requestSigner.isMatch(expectedSignature, request)); + } + + @Test + public void testIsMatchWithDataAndQueryParams() { + RequestSigner requestSigner = new RequestSigner(getBytes("other-secret")); + String expectedSignature = "orb0adPhRCYND1WCAvPBr+qjm4STGtyvNDIDNBZ4Ir4="; + Request request = new Request("1544544948", "abc=foo&def=bar", getBytes("{\"a key\":\"some value\"}")); + + assertTrue(requestSigner.isMatch(expectedSignature, request)); + } + + @Test + public void testIsNotMatch() { + RequestSigner requestSigner = new RequestSigner(getBytes("secret")); + String expectedSignature = ""; + Request request = new Request("1544544948", "abc=foo&def=bar", getBytes("{\"a key\":\"some value\"}")); + + assertFalse(requestSigner.isMatch(expectedSignature, request)); + } + + @Test + public void testWithRealSignature() { + /* + * Here we use real signature from MessageBird webhook call + */ + + RequestSigner requestSigner = new RequestSigner(getBytes("Wb3N9gKeFf8ZoCzlOb5lJSic7bHLUcSu")); + String requestSignature = "5Jha9Yyhwgc1nTsgJ9WyzeHilsuUumydICdf4LuIZE8="; + String requestTimestamp = "1547036603"; + String requestParams = "id=57db52e04e2f4001b555f79813a0f503&mccmnc=20409&ported=0&recipient=31667788880&reference=curl&status=delivered&statusDatetime=2019-01-09T12%3A23%3A23%2B00%3A00"; + byte[] requestBody = new byte[0]; + + String spoiledSignature = "5Jha9Yyhwgc1nTsgJ9WyzeHilsuUumydICdf4LUIZE8="; + String spoiledTimestamp = "1547036605"; + String spoiledParams = "id=57db52e04e2f4001b555f79813a0f503&mccmnc=20409&ported=0&recipient=31667788880&reference=curvy&status=delivered&statusDatetime=2019-01-09T12%3A23%3A23%2B00%3A00"; + byte[] spoiledBody = getBytes("get shit spoiled"); + + assertTrue( + "Definitely valid signature is threaten as invalid", + requestSigner.isMatch(requestSignature, new Request(requestTimestamp, requestParams, requestBody)) + ); + assertFalse( + "Invalid signature is threaten as invalid", + requestSigner.isMatch(spoiledSignature, new Request(requestTimestamp, requestParams, requestBody)) + ); + assertFalse( + "Signature is still valid with replaced timestamp", + requestSigner.isMatch(requestSignature, new Request(spoiledTimestamp, requestParams, requestBody)) + ); + assertFalse( + "Signature is still valid with replaced params", + requestSigner.isMatch(requestSignature, new Request(requestTimestamp, spoiledParams, requestBody)) + ); + assertFalse( + "Signature is still valid with replaced body", + requestSigner.isMatch(requestSignature, new Request(requestTimestamp, requestParams, spoiledBody)) + ); + } +} From ea108540d9bf80ccfac2d201c8c1758df33fc3ec Mon Sep 17 00:00:00 2001 From: "khanh.nguyen" Date: Mon, 30 Aug 2021 13:48:26 +0200 Subject: [PATCH 306/516] Update ExampleRequestSignatureValidation.java --- .../ExampleRequestSignatureValidation.java | 54 +++++++++---------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/examples/src/main/java/ExampleRequestSignatureValidation.java b/examples/src/main/java/ExampleRequestSignatureValidation.java index 37ee8af6..4c4dbe00 100644 --- a/examples/src/main/java/ExampleRequestSignatureValidation.java +++ b/examples/src/main/java/ExampleRequestSignatureValidation.java @@ -1,28 +1,25 @@ import com.messagebird.MessageBirdClient; import com.messagebird.MessageBirdService; import com.messagebird.MessageBirdServiceImpl; -import com.messagebird.RequestSigner; +import com.messagebird.RequestValidator; import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.RequestValidationException; import com.messagebird.exceptions.UnauthorizedException; import com.messagebird.objects.Message; -import com.messagebird.Request; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; import util.HttpHandlerHelpers; -import java.io.*; +import java.io.IOException; import java.net.InetSocketAddress; import java.net.URL; import java.nio.charset.StandardCharsets; -import java.util.*; +import java.util.Map; /** * Created by hasselbach * - * Complete example of MessageBird webhook signature verification - * @see com.messagebird.RequestSignerTest for simplified examples - * * For exposing your application for external calls (webhooks from MessageBird) * you can use serveo.net: `ssh -R 80:localhost:3000 serveo.net` * @@ -85,14 +82,14 @@ public static void main(String[] args) { String apiSecret = args[2]; URL reportURL = new URL(args[3]); - RequestSigner reqSigner = new RequestSigner(apiSecret.getBytes()); + RequestValidator reqValidator = new RequestValidator(apiSecret); // Creating MessageBird client final MessageBirdService wsr = new MessageBirdServiceImpl(apiKey); final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); HttpServer httpServer = HttpServer.create(new InetSocketAddress(serverPort), 0); - httpServer.createContext("/webhook", new MessageBirdWebhookHandler(reqSigner)); + httpServer.createContext("/webhook", new MessageBirdWebhookHandler(reqValidator)); httpServer.createContext("/send", new MessageBirdSender(messageBirdClient, reportURL)); @@ -110,10 +107,10 @@ public static void main(String[] args) { */ static class MessageBirdWebhookHandler extends HttpHandlerHelpers implements HttpHandler { - private final RequestSigner reqSigner; + private final RequestValidator reqValidator; - MessageBirdWebhookHandler(RequestSigner reqSigner) { - this.reqSigner = reqSigner; + MessageBirdWebhookHandler(RequestValidator reqSigner) { + this.reqValidator = reqSigner; } @Override @@ -121,33 +118,29 @@ public void handle(HttpExchange he) throws IOException { System.out.println("New request:"); try { - String requestSignature = he.getRequestHeaders().getFirst("MessageBird-Signature"); - String requestTimestamp = he.getRequestHeaders().getFirst("MessageBird-Request-Timestamp"); - String requestParams = he.getRequestURI().getRawQuery(); + String requestSignature = he.getRequestHeaders().getFirst(RequestValidator.SIGNATURE_HEADER); + String requestURL = he.getRequestURI().toString(); byte[] requestBody = readAllBytes(he.getRequestBody()); - Request request = new Request(requestTimestamp, requestParams, requestBody); - printRequest( he.getRequestMethod(), he.getRequestURI().toString(), new String(requestBody, StandardCharsets.UTF_8) ); - if (reqSigner.isMatch(requestSignature, request)) { - // then only if signature is valid we can look at what is sent - // for SMS status parameters can be found on https://developers.messagebird.com/docs/sms-messaging#handle-a-status-report - reportStatus(parseQuery(he.getRequestURI().getQuery())); + reqValidator.validateSignature(requestSignature, requestURL, requestBody); - // MessageBird expects for `200 OK` status - // otherwise, MessageBird will retry this request limited times - sendResponse(he, 200, "Ok"); - System.out.println("Request has valid signature"); + // then only if signature is valid we can look at what is sent + // for SMS status parameters can be found on https://developers.messagebird.com/docs/sms-messaging#handle-a-status-report + reportStatus(parseQuery(he.getRequestURI().getQuery())); - } else { - sendResponse(he, 401, "Signature is invalid"); - System.out.println("Request has invalid signature"); - } + // MessageBird expects for `200 OK` status + // otherwise, MessageBird will retry this request limited times + sendResponse(he, 200, "Ok"); + System.out.println("Request has valid signature"); + } catch (RequestValidationException e) { + sendResponse(he, 401, "Signature is invalid"); + System.out.println("Request has invalid signature: " + e.getMessage()); } catch (Exception e) { sendResponse(he, 500, e.getMessage()); } @@ -163,6 +156,7 @@ private void reportStatus(Map queryParams) { /** * Simple endpoint for sending SMS-messages via MessageBird + * * @see ExampleSendMessage simplified example for message sending */ static class MessageBirdSender extends HttpHandlerHelpers implements HttpHandler { @@ -192,7 +186,7 @@ public void handle(HttpExchange he) throws IOException { try { messageBirdClient.sendMessage(message); - sendResponse(he,201, "Message sent"); + sendResponse(he, 201, "Message sent"); } catch (GeneralException | UnauthorizedException e) { sendResponse(he, 500, e.getMessage()); throw new IOException(e); From aeaa9c843d79283b23455e64bcc4a8b3a6ffc6c1 Mon Sep 17 00:00:00 2001 From: "khanh.nguyen" Date: Mon, 30 Aug 2021 14:49:01 +0200 Subject: [PATCH 307/516] Make webhook signature url check optional --- .../com/messagebird/RequestValidator.java | 106 ++++++++++++------ .../ExampleRequestSignatureValidation.java | 14 ++- 2 files changed, 82 insertions(+), 38 deletions(-) diff --git a/api/src/main/java/com/messagebird/RequestValidator.java b/api/src/main/java/com/messagebird/RequestValidator.java index 36c0bec9..f2a4613b 100644 --- a/api/src/main/java/com/messagebird/RequestValidator.java +++ b/api/src/main/java/com/messagebird/RequestValidator.java @@ -14,7 +14,7 @@ import java.security.NoSuchAlgorithmException; /** - * RequestValidator validates webhook signature signed by MessageBird services. + * RequestValidator validates request signature signed by MessageBird services. * * @see Verify HTTP Requests */ @@ -31,41 +31,78 @@ public class RequestValidator { private final Algorithm HMAC256, HMAC384, HMAC512; /** - * RequestValidator validates webhook signature with a customer signature key. + * This field instructs Validator to not validate url_hash claim. + * It is recommended to not skip URL validation to ensure high security. + * but the ability to skip URL validation is necessary in some cases, e.g. + * your service is behind proxy or when you want to validate it yourself. + * Note that when true, no query parameters should be trusted. + * Defaults to false. + */ + private final boolean skipURLValidation; + + /** + * RequestValidator validates request signature with a customer signature key. * - * @param signatureKey customer signature key. Can be retrieved through Developer Settings. This is NOT your API key. + * @param signatureKey customer signature key. Can be retrieved through + * Developer Settings. + * This is NOT your API key. * @see Verify HTTP Requests */ public RequestValidator(String signatureKey) { + this(signatureKey, false); + } + + /** + * RequestValidator validates webhook signature with a customer signature key. + * + * @param signatureKey customer signature key. Can be retrieved through + * Developer Settings. + * This is NOT your API key. + * @param skipURLValidation whether url_hash claim validation should be skipped. + * Note that when true, no query parameters should be trusted. + * @see Verify HTTP Requests + */ + public RequestValidator(String signatureKey, boolean skipURLValidation) { this.HMAC256 = Algorithm.HMAC256(signatureKey); this.HMAC384 = Algorithm.HMAC384(signatureKey); this.HMAC512 = Algorithm.HMAC512(signatureKey); + this.skipURLValidation = skipURLValidation; } /** * Returns raw signature payload after validating a signature successfully, * otherwise throws {@code RequestValidationException}. *

- * This JWT is signed with a MessageBird account unique secret key, ensuring the request is from MessageBird and a specific account. - * The JWT contains the following claims:

+ * This JWT is signed with a MessageBird account unique secret key, ensuring the request is from MessageBird and + * a specific account. + * The JWT contains the following claims: + *

*
    - *
  • "url_hash" - the raw URL hashed with SHA256 ensuring the URL wasn't altered (validated by default)
  • - *
  • "payload_hash" - the raw payload hashed with SHA256 ensuring the payload wasn't altered (validated by default)
  • - *
  • "jti" - a unique token ID to implement an optional non-replay check (NOT validated by default)
  • - *
  • "nbf" - the not before timestamp (validated by default)
  • - *
  • "exp" - the expiration timestamp is ensuring that a request isn't captured and used at a later time. (validated by default)
  • - *
  • "iss" - the issuer name, always MessageBird (validated by default)
  • + *
  • "url_hash" - the raw URL hashed with SHA256 ensuring the URL wasn't altered.
  • + *
  • "payload_hash" - the raw payload hashed with SHA256 ensuring the payload wasn't altered.
  • + *
  • "jti" - a unique token ID to implement an optional non-replay check (NOT validated by default).
  • + *
  • "nbf" - the not before timestamp.
  • + *
  • "exp" - the expiration timestamp is ensuring that a request isn't captured and used at a later time.
  • + *
  • "iss" - the issuer name, always MessageBird.
  • *
* * @param clock custom {@link Clock} instance to validate timestamp claims. * @param signature the actual signature. - * @param url the raw url including the protocol, hostname and query string, https://example.com/?example=42. + * @param url the raw url including the protocol, hostname and query string, + * {@code https://example.com/?example=42}. * @param requestBody the raw request body. * @return raw signature payload as {@link DecodedJWT} object. * @throws RequestValidationException when the signature is invalid. + * @see Verify HTTP Requests */ public DecodedJWT validateSignature(Clock clock, String signature, String url, byte[] requestBody) throws RequestValidationException { + if (signature == null || signature.length() == 0) + throw new RequestValidationException("The signature can not be empty."); + + if (!skipURLValidation && (url == null || url.length() == 0)) + throw new RequestValidationException("The url can not be empty."); + DecodedJWT jwt = JWT.decode(signature); Algorithm algorithm; @@ -86,11 +123,12 @@ public DecodedJWT validateSignature(Clock clock, String signature, String url, b BaseVerification builder = (BaseVerification) JWT.require(algorithm) .withIssuer("MessageBird") .ignoreIssuedAt() - .acceptLeeway(1) - .withClaim("url_hash", calculateSha256(url.getBytes())); + .acceptLeeway(1); - boolean payloadHashClaimExist = !jwt.getClaim("payload_hash").isNull(); + if (!skipURLValidation) + builder.withClaim("url_hash", calculateSha256(url.getBytes())); + boolean payloadHashClaimExist = !jwt.getClaim("payload_hash").isNull(); if (requestBody != null && requestBody.length > 0) { if (!payloadHashClaimExist) { throw new RequestValidationException("The Claim 'payload_hash' is not set but payload is present."); @@ -100,12 +138,7 @@ public DecodedJWT validateSignature(Clock clock, String signature, String url, b throw new RequestValidationException("The Claim 'payload_hash' is set but actual payload is missing."); } - JWTVerifier verifier; - if (clock == null) { - verifier = builder.build(); - } else { - verifier = builder.build(clock); - } + JWTVerifier verifier = clock == null ? builder.build() : builder.build(clock); try { return verifier.verify(jwt); @@ -119,29 +152,36 @@ public DecodedJWT validateSignature(Clock clock, String signature, String url, b /** * Returns raw signature payload after validating a signature successfully, * otherwise throws {@code RequestValidationException}. - *

- * This JWT is signed with a MessageBird account unique secret key, ensuring the request is from MessageBird and a specific account. - * The JWT contains the following claims:

- *
    - *
  • "url_hash" - the raw URL hashed with SHA256 ensuring the URL wasn't altered (validated by default)
  • - *
  • "payload_hash" - the raw payload hashed with SHA256 ensuring the payload wasn't altered (validated by default)
  • - *
  • "jti" - a unique token ID to implement an optional non-replay check (NOT validated by default)
  • - *
  • "nbf" - the not before timestamp (validated by default)
  • - *
  • "exp" - the expiration timestamp is ensuring that a request isn't captured and used at a later time. (validated by default)
  • - *
  • "iss" - the issuer name, always MessageBird (validated by default)
  • - *
* * @param signature the actual signature. - * @param url the raw url including the protocol, hostname and query string, https://example.com/?example=42. + * @param url the raw url including the protocol, hostname and query string, + * {@code https://example.com/?example=42}. * @param requestBody the raw request body. * @return raw signature payload as {@link DecodedJWT} object. * @throws RequestValidationException when the signature is invalid. + * @see RequestValidator#validateSignature(Clock, String, String, byte[]) */ public DecodedJWT validateSignature(String signature, String url, byte[] requestBody) throws RequestValidationException { return validateSignature(null, signature, url, requestBody); } + /** + * Validates request signature with URL validation disabled. + * Note that no query parameters should be trusted and this only works if {@code RequestValidator} is constructed + * with {@code skipURLValidation} set to true. + * + * @param signature the actual signature. + * @param requestBody the raw request body. + * @return raw signature payload as {@link DecodedJWT} object. + * @throws RequestValidationException when the signature is invalid. + * @see RequestValidator#validateSignature(String, String, byte[]) + */ + public DecodedJWT validateSignature(String signature, byte[] requestBody) + throws RequestValidationException { + return validateSignature(null, signature, null, requestBody); + } + private static String calculateSha256(byte[] bytes) { try { return encodeHex(MessageDigest.getInstance(ALGORITHM_SHA256).digest(bytes)); diff --git a/examples/src/main/java/ExampleRequestSignatureValidation.java b/examples/src/main/java/ExampleRequestSignatureValidation.java index 4c4dbe00..4f54297c 100644 --- a/examples/src/main/java/ExampleRequestSignatureValidation.java +++ b/examples/src/main/java/ExampleRequestSignatureValidation.java @@ -13,6 +13,7 @@ import java.io.IOException; import java.net.InetSocketAddress; +import java.net.URI; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Map; @@ -47,7 +48,7 @@ * *NOTE* you should use `Live` key for receiving webhooks * * Run this example as: - * java -jar $MBEXAMPLEPORT test_accesskey test_secret $FORWARDING_URL/webhook + * java -jar $MBEXAMPLEPORT test_accesskey test_secret $FORWARDING_URL * * Now you able to play: * send an SMS: @@ -80,7 +81,8 @@ public static void main(String[] args) { int serverPort = Integer.parseInt(args[0]); String apiKey = args[1]; String apiSecret = args[2]; - URL reportURL = new URL(args[3]); + String forwardURL = args[3]; + URL reportURL = new URL(forwardURL + "/webhook"); RequestValidator reqValidator = new RequestValidator(apiSecret); @@ -89,7 +91,7 @@ public static void main(String[] args) { final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); HttpServer httpServer = HttpServer.create(new InetSocketAddress(serverPort), 0); - httpServer.createContext("/webhook", new MessageBirdWebhookHandler(reqValidator)); + httpServer.createContext("/webhook", new MessageBirdWebhookHandler(reqValidator, forwardURL)); httpServer.createContext("/send", new MessageBirdSender(messageBirdClient, reportURL)); @@ -108,9 +110,11 @@ public static void main(String[] args) { static class MessageBirdWebhookHandler extends HttpHandlerHelpers implements HttpHandler { private final RequestValidator reqValidator; + private final String baseURL; - MessageBirdWebhookHandler(RequestValidator reqSigner) { + MessageBirdWebhookHandler(RequestValidator reqSigner, String baseURL) { this.reqValidator = reqSigner; + this.baseURL = baseURL; } @Override @@ -119,7 +123,7 @@ public void handle(HttpExchange he) throws IOException { try { String requestSignature = he.getRequestHeaders().getFirst(RequestValidator.SIGNATURE_HEADER); - String requestURL = he.getRequestURI().toString(); + String requestURL = URI.create(baseURL).resolve(he.getRequestURI()).toString(); byte[] requestBody = readAllBytes(he.getRequestBody()); printRequest( From 44bf5ae6cc7ea163cfb74ff2f2ac17b21707315b Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Mon, 13 Sep 2021 16:23:51 +0200 Subject: [PATCH 308/516] added new classes for media template support --- .../conversations/ConversationContentHsm.java | 14 +++- .../objects/conversations/HSMCurrency.java | 31 +++++++ .../objects/conversations/Media.java | 31 +++++++ .../conversations/MessageComponent.java | 53 ++++++++++++ .../objects/conversations/MessageParam.java | 81 +++++++++++++++++++ .../conversations/TemplateMediaType.java | 46 +++++++++++ 6 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 api/src/main/java/com/messagebird/objects/conversations/HSMCurrency.java create mode 100644 api/src/main/java/com/messagebird/objects/conversations/Media.java create mode 100644 api/src/main/java/com/messagebird/objects/conversations/MessageComponent.java create mode 100644 api/src/main/java/com/messagebird/objects/conversations/MessageParam.java create mode 100644 api/src/main/java/com/messagebird/objects/conversations/TemplateMediaType.java diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationContentHsm.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationContentHsm.java index 3da74c2c..824f7fc8 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationContentHsm.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationContentHsm.java @@ -18,17 +18,20 @@ public class ConversationContentHsm { private String templateName; private ConversationHsmLanguage language; private List params; + private List components; public ConversationContentHsm( final String namespace, final String templateName, final ConversationHsmLanguage language, - final List params + final List params, + final List components ) { this.namespace = namespace; this.templateName = templateName; this.language = language; this.params = params; + this.components = components; } public ConversationContentHsm( @@ -85,6 +88,14 @@ public void setParams(final List params) { this.params = params; } + public List getComponents() { + return components; + } + + public void setComponents(List components) { + this.components = components; + } + @Override public String toString() { return "ConversationContentHsm{" + @@ -92,6 +103,7 @@ public String toString() { ", templateName='" + templateName + '\'' + ", language=" + language + ", params=" + params + + ", components=" + components + '}'; } } diff --git a/api/src/main/java/com/messagebird/objects/conversations/HSMCurrency.java b/api/src/main/java/com/messagebird/objects/conversations/HSMCurrency.java new file mode 100644 index 00000000..24ea4be6 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/HSMCurrency.java @@ -0,0 +1,31 @@ +package com.messagebird.objects.conversations; + +public class HSMCurrency { + + private String currencyCode; + private int amount; + + public String getCurrencyCode() { + return currencyCode; + } + + public void setCurrencyCode(String currencyCode) { + this.currencyCode = currencyCode; + } + + public int getAmount() { + return amount; + } + + public void setAmount(int amount) { + this.amount = amount; + } + + @Override + public String toString() { + return "HSMCurrency{" + + "currencyCode='" + currencyCode + '\'' + + ", amount=" + amount + + '}'; + } +} diff --git a/api/src/main/java/com/messagebird/objects/conversations/Media.java b/api/src/main/java/com/messagebird/objects/conversations/Media.java new file mode 100644 index 00000000..4a9bf4ea --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/Media.java @@ -0,0 +1,31 @@ +package com.messagebird.objects.conversations; + +public class Media { + + private String url; + private String caption; + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getCaption() { + return caption; + } + + public void setCaption(String caption) { + this.caption = caption; + } + + @Override + public String toString() { + return "Media{" + + "url='" + url + '\'' + + ", caption='" + caption + '\'' + + '}'; + } +} diff --git a/api/src/main/java/com/messagebird/objects/conversations/MessageComponent.java b/api/src/main/java/com/messagebird/objects/conversations/MessageComponent.java new file mode 100644 index 00000000..22081acb --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/MessageComponent.java @@ -0,0 +1,53 @@ +package com.messagebird.objects.conversations; + +import java.util.List; + +public class MessageComponent { + + private String type; + private String sub_type; + private int index; + private List parameters; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getSub_type() { + return sub_type; + } + + public void setSub_type(String sub_type) { + this.sub_type = sub_type; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + public List getParameters() { + return parameters; + } + + public void setParameters(List parameters) { + this.parameters = parameters; + } + + @Override + public String toString() { + return "MessageComponent{" + + "type='" + type + '\'' + + ", sub_type='" + sub_type + '\'' + + ", index=" + index + + ", parameters=" + parameters + + '}'; + } +} diff --git a/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java b/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java new file mode 100644 index 00000000..8de37ab7 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java @@ -0,0 +1,81 @@ +package com.messagebird.objects.conversations; + +public class MessageParam { + + private TemplateMediaType type; + private String text; + private String payload; + private HSMCurrency currency; + private String dateTime; + private Media document; + private Media image; + + public TemplateMediaType getType() { + return type; + } + + public void setType(TemplateMediaType type) { + this.type = type; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } + + public HSMCurrency getCurrency() { + return currency; + } + + public void setCurrency(HSMCurrency currency) { + this.currency = currency; + } + + public String getDateTime() { + return dateTime; + } + + public void setDateTime(String dateTime) { + this.dateTime = dateTime; + } + + public Media getDocument() { + return document; + } + + public void setDocument(Media document) { + this.document = document; + } + + public Media getImage() { + return image; + } + + public void setImage(Media image) { + this.image = image; + } + + @Override + public String toString() { + return "MessageParam{" + + "type=" + type + + ", text='" + text + '\'' + + ", payload='" + payload + '\'' + + ", currency=" + currency + + ", dateTime='" + dateTime + '\'' + + ", document=" + document + + ", image=" + image + + '}'; + } +} diff --git a/api/src/main/java/com/messagebird/objects/conversations/TemplateMediaType.java b/api/src/main/java/com/messagebird/objects/conversations/TemplateMediaType.java new file mode 100644 index 00000000..51afa594 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/TemplateMediaType.java @@ -0,0 +1,46 @@ +package com.messagebird.objects.conversations; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public enum TemplateMediaType { + + IMAGE("image"), + DOCUMENT("document"), + TEXT("text"), + CURRENCY("currency"), + DATETIME("date_time"), + PAYLOAD("payload"); + + private final String type; + + TemplateMediaType(final String type) { + this.type = type; + } + + @JsonCreator + public static TemplateMediaType forValue(String value) { + for (TemplateMediaType templateMediaType: TemplateMediaType.values()) { + if (templateMediaType.getType().equals(value)) { + return templateMediaType; + } + } + + return null; + } + + @JsonValue + public String toJson() { + return getType(); + } + + public String getType() { + return type; + } + + @Override + public String toString() { + return getType(); + } + +} \ No newline at end of file From e308ca022156766540587d72897f81859854d618 Mon Sep 17 00:00:00 2001 From: cemturker Date: Tue, 14 Sep 2021 13:47:37 +0300 Subject: [PATCH 309/516] Add example for HSM media template --- .../conversations/MessageComponent.java | 10 +- .../conversations/MessageComponentType.java | 44 ++++++++ ...ampleConversationSendHSMMediaTemplate.java | 103 ++++++++++++++++++ 3 files changed, 152 insertions(+), 5 deletions(-) create mode 100644 api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java create mode 100644 examples/src/main/java/ExampleConversationSendHSMMediaTemplate.java diff --git a/api/src/main/java/com/messagebird/objects/conversations/MessageComponent.java b/api/src/main/java/com/messagebird/objects/conversations/MessageComponent.java index 22081acb..9dd25b3a 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/MessageComponent.java +++ b/api/src/main/java/com/messagebird/objects/conversations/MessageComponent.java @@ -4,17 +4,17 @@ public class MessageComponent { - private String type; + private MessageComponentType type; private String sub_type; private int index; private List parameters; - public String getType() { - return type; + public void setType(MessageComponentType type) { + this.type = type; } - public void setType(String type) { - this.type = type; + public MessageComponentType getType() { + return type; } public String getSub_type() { diff --git a/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java b/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java new file mode 100644 index 00000000..073b5735 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java @@ -0,0 +1,44 @@ +package com.messagebird.objects.conversations; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public enum MessageComponentType { + + HEADER("header"), + BODY("body"), + FOOTER("footer"), + BUTTONS("buttons"); + + + private final String type; + + MessageComponentType(final String type) { + this.type = type; + } + + @JsonCreator + public static MessageComponentType forValue(String value) { + for (MessageComponentType componentType: MessageComponentType.values()) { + if (componentType.getType().equals(value)) { + return componentType; + } + } + + return null; + } + + @JsonValue + public String toJson() { + return getType(); + } + + public String getType() { + return type; + } + + @Override + public String toString() { + return getType(); + } +} diff --git a/examples/src/main/java/ExampleConversationSendHSMMediaTemplate.java b/examples/src/main/java/ExampleConversationSendHSMMediaTemplate.java new file mode 100644 index 00000000..3f495aee --- /dev/null +++ b/examples/src/main/java/ExampleConversationSendHSMMediaTemplate.java @@ -0,0 +1,103 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.conversations.ConversationContent; +import com.messagebird.objects.conversations.ConversationContentHsm; +import com.messagebird.objects.conversations.ConversationContentType; +import com.messagebird.objects.conversations.ConversationHsmLanguage; +import com.messagebird.objects.conversations.ConversationSendRequest; +import com.messagebird.objects.conversations.ConversationSendResponse; +import com.messagebird.objects.conversations.Media; +import com.messagebird.objects.conversations.MessageComponent; +import com.messagebird.objects.conversations.MessageComponentType; +import com.messagebird.objects.conversations.MessageParam; +import com.messagebird.objects.conversations.TemplateMediaType; +import java.util.ArrayList; +import java.util.List; + +public class ExampleConversationSendHSMMediaTemplate { + + // Reference Example: https://developers.messagebird.com/quickstarts/whatsapp/send-media-template-message/ + public static void main(String[] args) { + + if (args.length < 4) { + System.out.println("Please at least specify your access key, the channel id and destination address.\n" + + "Usage : java -jar test_accesskey(Required) channel_id(Required) from(Required) to(Required)"); + return; + } + + //First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + //Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + + ConversationContent conversationContent = new ConversationContent(); + ConversationContentHsm conversationContentHsm = new ConversationContentHsm(); + conversationContentHsm.setNamespace("20332cd4_f095_b080_d255_35677159aaff"); + conversationContentHsm.setTemplateName("33172012024_ship_img_but_1"); + ConversationHsmLanguage language = new ConversationHsmLanguage(); + language.setCode("en"); + conversationContentHsm.setLanguage(language); + List messageComponents = new ArrayList<>(); + //Define header component with image + MessageComponent messageHeaderComponent = new MessageComponent(); + messageHeaderComponent.setType(MessageComponentType.HEADER); + MessageParam imageParam = new MessageParam(); + Media media = new Media(); + media.setUrl("https://i.ytimg.com/vi/3fDoOw4lIeU/maxresdefault.jpg"); + imageParam.setImage(media); + imageParam.setType(TemplateMediaType.IMAGE); + List messageHeaderParams = new ArrayList<>(); + messageHeaderParams.add(imageParam); + messageHeaderComponent.setParameters(messageHeaderParams); + //Define body component with texts + MessageComponent messageBodyComponent = new MessageComponent(); + messageBodyComponent.setType(MessageComponentType.BODY); + List messageBodyParams = new ArrayList<>(); + messageBodyComponent.setParameters(messageBodyParams); + MessageParam firstText = new MessageParam(); + firstText.setType(TemplateMediaType.TEXT); + firstText.setText("John"); + messageBodyParams.add(firstText); + + MessageParam secondText = new MessageParam(); + secondText.setType(TemplateMediaType.TEXT); + secondText.setText("MB93824"); + messageBodyParams.add(secondText); + + MessageParam thirdText = new MessageParam(); + thirdText.setType(TemplateMediaType.TEXT); + thirdText.setText("2 days"); + messageBodyParams.add(thirdText); + + MessageParam fourthText = new MessageParam(); + fourthText.setType(TemplateMediaType.TEXT); + fourthText.setText("MessageBird"); + messageBodyParams.add(fourthText); + + messageComponents.add(messageHeaderComponent); + messageComponents.add(messageBodyComponent); + conversationContentHsm.setComponents(messageComponents); + conversationContent.setHsm(conversationContentHsm); + ConversationSendRequest request = new ConversationSendRequest( + args[2], + ConversationContentType.HSM, + conversationContent, + args[1], + "", + null, + null, + null); + + try { + ConversationSendResponse sendResponse = messageBirdClient.sendMessage(request); + System.out.println(sendResponse.toString()); + + } catch (GeneralException | UnauthorizedException exception) { + exception.printStackTrace(); + } + } +} From efa9070ac167cff4e51124a2245d50d1d753acc3 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Tue, 14 Sep 2021 15:45:38 +0200 Subject: [PATCH 310/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 0f0ef660..89378e1b 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.1 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index e31187b4..23850cf9 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -61,7 +61,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.1.1"; + private final String clientVersion = "3.1.2"; private final String userAgentString; private Proxy proxy = null; From 1fa7a2139d5107f1ab38ab1abbfd197959a3b85d Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Tue, 14 Sep 2021 15:46:18 +0200 Subject: [PATCH 311/516] [maven-release-plugin] prepare release v3.1.2 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 89378e1b..ee0104f7 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.2-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.1.2 From ddf327b93ac0d4e88c76bfae9df9d45ed2933adc Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Tue, 14 Sep 2021 15:46:23 +0200 Subject: [PATCH 312/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index ee0104f7..eba7bc41 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.2 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.1.2 + HEAD From ce8e0fde7f510b4705c36808eaa4e62136964c20 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Wed, 15 Sep 2021 08:18:56 +0200 Subject: [PATCH 313/516] updated for the new release --- api/pom.xml | 2 +- examples/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index eba7bc41..47e53822 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.3-SNAPSHOT diff --git a/examples/pom.xml b/examples/pom.xml index 6839c044..438522e7 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.1.1 + 3.1.2 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.1.1 + 3.1.2 compile From cbac7847010174d7b0dcaab987649fd45ca50587 Mon Sep 17 00:00:00 2001 From: ssk910 Date: Wed, 29 Sep 2021 17:22:42 +0900 Subject: [PATCH 314/516] feat: Add features for integrations API Added missing features and examples as below: - Create template - List templates - List templates by name - Fetch template by name and language - Delete templates by name - Delete template by name and language Reference: https://developers.messagebird.com/api/integrations/ Committed because java-rest-api SDK does not include integrations API. Please feel free to refactor my codes. Need to write unit test. --- .../com/messagebird/MessageBirdClient.java | 180 +++++++++++++++++- .../com/messagebird/MessageBirdService.java | 30 ++- .../messagebird/MessageBirdServiceImpl.java | 51 +++-- .../objects/integrations/HSMCategory.java | 55 ++++++ .../objects/integrations/HSMComponent.java | 144 ++++++++++++++ .../integrations/HSMComponentButton.java | 89 +++++++++ .../integrations/HSMComponentButtonType.java | 48 +++++ .../integrations/HSMComponentFormat.java | 49 +++++ .../integrations/HSMComponentType.java | 47 +++++ .../objects/integrations/HSMExample.java | 54 ++++++ .../integrations/HSMRejectedReason.java | 51 +++++ .../objects/integrations/HSMStatus.java | 51 +++++ .../integrations/WhatsAppTemplate.java | 86 +++++++++ .../integrations/WhatsAppTemplateList.java | 12 ++ .../WhatsAppTemplateResponse.java | 105 ++++++++++ .../src/main/java/ExampleCreateTemplate.java | 97 ++++++++++ ...xampleDeleteTemplateByNameAndLanguage.java | 40 ++++ .../java/ExampleDeleteTemplatesByName.java | 39 ++++ ...ExampleFetchTemplateByNameAndLanguage.java | 41 ++++ .../src/main/java/ExampleListTemplates.java | 36 ++++ .../main/java/ExampleListTemplatesByName.java | 41 ++++ 21 files changed, 1326 insertions(+), 20 deletions(-) create mode 100644 api/src/main/java/com/messagebird/objects/integrations/HSMCategory.java create mode 100644 api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java create mode 100644 api/src/main/java/com/messagebird/objects/integrations/HSMComponentButton.java create mode 100644 api/src/main/java/com/messagebird/objects/integrations/HSMComponentButtonType.java create mode 100644 api/src/main/java/com/messagebird/objects/integrations/HSMComponentFormat.java create mode 100644 api/src/main/java/com/messagebird/objects/integrations/HSMComponentType.java create mode 100644 api/src/main/java/com/messagebird/objects/integrations/HSMExample.java create mode 100644 api/src/main/java/com/messagebird/objects/integrations/HSMRejectedReason.java create mode 100644 api/src/main/java/com/messagebird/objects/integrations/HSMStatus.java create mode 100644 api/src/main/java/com/messagebird/objects/integrations/WhatsAppTemplate.java create mode 100644 api/src/main/java/com/messagebird/objects/integrations/WhatsAppTemplateList.java create mode 100644 api/src/main/java/com/messagebird/objects/integrations/WhatsAppTemplateResponse.java create mode 100644 examples/src/main/java/ExampleCreateTemplate.java create mode 100644 examples/src/main/java/ExampleDeleteTemplateByNameAndLanguage.java create mode 100644 examples/src/main/java/ExampleDeleteTemplatesByName.java create mode 100644 examples/src/main/java/ExampleFetchTemplateByNameAndLanguage.java create mode 100644 examples/src/main/java/ExampleListTemplates.java create mode 100644 examples/src/main/java/ExampleListTemplatesByName.java diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 0bff2580..317b02d4 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -24,8 +24,8 @@ import com.messagebird.objects.PhoneNumbersResponse; import com.messagebird.objects.PurchasedNumber; import com.messagebird.objects.PurchasedNumberCreatedResponse; -import com.messagebird.objects.PurchasedNumbersResponse; import com.messagebird.objects.PurchasedNumbersFilter; +import com.messagebird.objects.PurchasedNumbersResponse; import com.messagebird.objects.Verify; import com.messagebird.objects.VerifyMessage; import com.messagebird.objects.VerifyRequest; @@ -46,6 +46,9 @@ import com.messagebird.objects.conversations.ConversationWebhookCreateRequest; import com.messagebird.objects.conversations.ConversationWebhookList; import com.messagebird.objects.conversations.ConversationWebhookUpdateRequest; +import com.messagebird.objects.integrations.WhatsAppTemplate; +import com.messagebird.objects.integrations.WhatsAppTemplateList; +import com.messagebird.objects.integrations.WhatsAppTemplateResponse; import com.messagebird.objects.voicecalls.RecordingResponse; import com.messagebird.objects.voicecalls.TranscriptionResponse; import com.messagebird.objects.voicecalls.VoiceCall; @@ -59,20 +62,19 @@ import com.messagebird.objects.voicecalls.Webhook; import com.messagebird.objects.voicecalls.WebhookList; import com.messagebird.objects.voicecalls.WebhookResponseData; - import java.io.UnsupportedEncodingException; import java.math.BigInteger; -import java.nio.charset.StandardCharsets; import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; -import java.util.HashSet; /** * Message bird general client @@ -102,6 +104,8 @@ public class MessageBirdClient { static final String VOICE_CALLS_BASE_URL = "https://voice.messagebird.com"; static final String NUMBERS_CALLS_BASE_URL = "https://numbers.messagebird.com/v1"; static final String MESSAGING_BASE_URL = "https://messaging.messagebird.com/v1"; + static final String INTEGRATIONS_BASE_URL_V2 = "https://integrations.messagebird.com/v2"; + static final String INTEGRATIONS_BASE_URL_V3 = "https://integrations.messagebird.com/v3"; private static String[] supportedLanguages = {"de-DE", "en-AU", "en-UK", "en-US", "es-ES", "es-LA", "fr-FR", "it-IT", "nl-NL", "pt-BR"}; private static final String BALANCEPATH = "/balance"; @@ -118,6 +122,7 @@ public class MessageBirdClient { private static final String CONVERSATION_SEND_PATH = "/send"; private static final String CONVERSATION_MESSAGE_PATH = "/messages"; private static final String CONVERSATION_WEBHOOK_PATH = "/webhooks"; + private static final String INTEGRATIONS_WHATSAPP_PATH = "/platforms/whatsapp"; static final String VOICECALLSPATH = "/calls"; static final String LEGSPATH = "/legs"; static final String RECORDINGPATH = "/recordings"; @@ -126,6 +131,7 @@ public class MessageBirdClient { static final String VOICECALLFLOWPATH = "/call-flows"; private static final String VOICELEGS_SUFFIX_PATH = "/legs"; static final String FILES_PATH = "/files"; + static final String TEMPLATES_PATH = "/templates"; static final String RECORDING_DOWNLOAD_FORMAT = ".wav"; @@ -1848,4 +1854,168 @@ public String downloadFile(String id, String filename, String basePath) throws G final String url = String.format("%s%s/%s", MESSAGING_BASE_URL, FILES_PATH, id); return messageBirdService.getBinaryData(url, basePath, filename); } -} + + /****************************************************************************************************/ + /** WhatsApp Templates **/ + /****************************************************************************************************/ + + /** + * Create a WhatsApp message template through messagebird. + * + * @param template {@link WhatsAppTemplate} object to be created + * @return {@link WhatsAppTemplateResponse} response object + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception or invalid template format + */ + public WhatsAppTemplateResponse createWhatsAppTemplate(final WhatsAppTemplate template) + throws UnauthorizedException, GeneralException { + template.validate(); + + String url = String.format( + "%s%s%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH + ); + return messageBirdService.sendPayLoad(url, template, WhatsAppTemplateResponse.class); + } + + /** + * Gets a WhatsAppTemplate listing with specified pagination options. + * + * @param offset Number of objects to skip. + * @param limit Number of objects to take. + * @return List of templates. + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + */ + public WhatsAppTemplateList listWhatsAppTemplates(final int offset, final int limit) + throws UnauthorizedException, GeneralException { + String url = String.format( + "%s%s%s", + INTEGRATIONS_BASE_URL_V3, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH + ); + return messageBirdService.requestList(url, offset, limit, WhatsAppTemplateList.class); + } + + /** + * Gets a template listing with default pagination options. + * + * @return List of whatsapp templates. + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + */ + public WhatsAppTemplateList listWhatsAppTemplates() throws UnauthorizedException, GeneralException { + final int offset = 0; + final int limit = 10; + + return listWhatsAppTemplates(offset, limit); + } + + /** + * Retrieves the template of an existing template name. + * + * @param templateName A name as returned by getWhatsAppTemplateBy in the name variable + * @return {@code List} template list + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + * @throws NotFoundException if template name is not found + */ + public List getWhatsAppTemplatesBy(final String templateName) + throws GeneralException, UnauthorizedException, NotFoundException { + if (templateName == null) { + throw new IllegalArgumentException("Template name must be specified."); + } + + String url = String.format( + "%s%s%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH + ); + + final WhatsAppTemplateResponse[] templateResponses = messageBirdService.requestByID(url, templateName, WhatsAppTemplateResponse[].class); + return Arrays.asList(templateResponses); + } + + /** + * Retrieves the template of an existing template name and language. + * + * @param templateName A name as returned by getWhatsAppTemplateBy in the name variable + * @param language A language code as returned by getWhatsAppTemplateBy in the language variable + * + * @return {@code WhatsAppTemplateResponse} template list + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + * @throws NotFoundException if template name and language are not found + */ + public WhatsAppTemplateResponse fetchWhatsAppTemplateBy(final String templateName, final String language) + throws GeneralException, UnauthorizedException, NotFoundException { + if (templateName == null || language == null) { + throw new IllegalArgumentException("Template name and language must be specified."); + } + + String url = String.format( + "%s%s%s/%s/%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH, + templateName, + language + ); + return messageBirdService.request(url, WhatsAppTemplateResponse.class); + } + + + /** + * Delete templates of an existing template name. + * + * @param templateName A template name which is created on the MessageBird platform + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + * @throws NotFoundException if template name is not found + */ + public void deleteTemplatesBy(final String templateName) + throws UnauthorizedException, GeneralException, NotFoundException { + if (templateName == null) { + throw new IllegalArgumentException("Template name must be specified."); + } + + String url = String.format( + "%s%s%s/%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH, + templateName + ); + messageBirdService.delete(url, null); + } + + /** + * Delete template of an existing template name and language. + * + * @param templateName A template name which is created on the MessageBird platform + * @param language A language which is created on the MessageBird platform + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + * @throws NotFoundException if template name or language are not found + */ + public void deleteTemplatesBy(final String templateName, final String language) + throws UnauthorizedException, GeneralException, NotFoundException { + if (templateName == null || language == null) { + throw new IllegalArgumentException("Template name and language must be specified."); + } + + String url = String.format( + "%s%s%s/%s/%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH, + templateName, + language + ); + messageBirdService.delete(url, null); + } +} \ No newline at end of file diff --git a/api/src/main/java/com/messagebird/MessageBirdService.java b/api/src/main/java/com/messagebird/MessageBirdService.java index fdbf6f43..7f0a8641 100644 --- a/api/src/main/java/com/messagebird/MessageBirdService.java +++ b/api/src/main/java/com/messagebird/MessageBirdService.java @@ -1,16 +1,29 @@ package com.messagebird; -import java.util.Map; - import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; import com.messagebird.objects.PagedPaging; +import java.util.Map; /** * Created by rvt on 1/7/15. */ public interface MessageBirdService { + + /** + * Send GET request . It will retrieve a json object R back. + * + * @author ssk910 + * @param request path to the request, for example "/messages/id/language" + * @param clazz Class type to return + * @return new class with returned dataset + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + * @throws NotFoundException if id not found + */ + R request(String request, Class clazz) throws UnauthorizedException, GeneralException, NotFoundException; + /** * Execute a object by ID request. It will add the id to the request parameter and retreive a json object R back. * @@ -36,6 +49,19 @@ public interface MessageBirdService { */ void deleteByID(String request, String id) throws UnauthorizedException, GeneralException, NotFoundException; + /** + * Send DELETE request. It will retrieve a json object R back. + * + * @author ssk910 + * @param request path to the request, for example "/messages/id/language" + * @param clazz Class type to return + * @return class with returned dataset + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + * @throws NotFoundException if id not found + */ + R delete(String request, Class clazz) throws UnauthorizedException, GeneralException, NotFoundException; + /** * Request a List 'of' object. * Allow to request a listMessage or listViewMessages objects. diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 23850cf9..93507d08 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -1,17 +1,5 @@ package com.messagebird; -import java.io.*; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.net.HttpURLConnection; -import java.net.Proxy; -import java.net.URL; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.*; - import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonNode; @@ -22,6 +10,29 @@ import com.messagebird.exceptions.UnauthorizedException; import com.messagebird.objects.ErrorReport; import com.messagebird.objects.PagedPaging; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.net.HttpURLConnection; +import java.net.Proxy; +import java.net.URL; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Scanner; /** * Implementation of MessageBirdService @@ -98,6 +109,12 @@ public MessageBirdServiceImpl(final String accessKey) { this(accessKey, "https://rest.messagebird.com"); } + @Override + public R request(String request, Class clazz) + throws UnauthorizedException, GeneralException, NotFoundException { + return getJsonData(request, null, "GET", clazz); + } + @Override public R requestByID(String request, String id, Class clazz) throws UnauthorizedException, GeneralException, NotFoundException { String path = ""; @@ -126,6 +143,11 @@ public void deleteByID(String request, String id) throws UnauthorizedException, getJsonData(request + "/" + id, null, "DELETE", null); } + @Override + public R delete(String request, Class clazz) throws UnauthorizedException, GeneralException, NotFoundException { + return getJsonData(request, null, "DELETE", clazz); + } + @Override public R requestList(String request, Integer offset, Integer limit, Class clazz) throws UnauthorizedException, GeneralException { Map map = new LinkedHashMap<>(); @@ -235,7 +257,10 @@ public T getJsonData(final String request, final P payload, final String mapper.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES); mapper.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS); - return mapper.readValue(body, clazz); + // Prevents mismatched exception when clazz is null + return clazz == null + ? null + : mapper.readValue(body, clazz); } catch (IOException ioe) { throw new GeneralException(ioe); } diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMCategory.java b/api/src/main/java/com/messagebird/objects/integrations/HSMCategory.java new file mode 100644 index 00000000..15f4d31d --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMCategory.java @@ -0,0 +1,55 @@ +package com.messagebird.objects.integrations; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * An enum for HSMComponentFormat + * + * @see HSMComponentFormat + * @author ssk910 + */ +public enum HSMCategory { + + ACCOUNT_UPDATE("ACCOUNT_UPDATE"), + PAYMENT_UPDATE("PAYMENT_UPDATE"), + PERSONAL_FINANCE_UPDATE("PERSONAL_FINANCE_UPDATE"), + SHIPPING_UPDATE("SHIPPING_UPDATE"), + RESERVATION_UPDATE("RESERVATION_UPDATE"), + ISSUE_RESOLUTION("ISSUE_RESOLUTION"), + APPOINTMENT_UPDATE("APPOINTMENT_UPDATE"), + TRANSPORTATION_UPDATE("TRANSPORTATION_UPDATE"), + TICKET_UPDATE("TICKET_UPDATE"), + ALERT_UPDATE("ALERT_UPDATE"); + + private final String category; + + HSMCategory(String category) { + this.category = category; + } + + @JsonCreator + public static HSMCategory forValue(String value) { + for (HSMCategory hsmCategory : HSMCategory.values()) { + if (hsmCategory.getCategory().equals(value)) { + return hsmCategory; + } + } + + return null; + } + + @JsonValue + public String toJson() { + return getCategory(); + } + + public String getCategory() { + return category; + } + + @Override + public String toString() { + return getCategory(); + } +} diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java b/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java new file mode 100644 index 00000000..eb6b5694 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java @@ -0,0 +1,144 @@ +package com.messagebird.objects.integrations; + +import com.messagebird.exceptions.GeneralException; +import java.util.List; + +/** + * A class for HSMComponent object + * + * @see HSMComponent + * @author ssk910 + */ +public class HSMComponent { + + private HSMComponentType type; + private HSMComponentFormat format; + private String text; + private List buttons; + private HSMExample example; + + public HSMComponentType getType() { + return type; + } + + public void setType(HSMComponentType type) { + this.type = type; + } + + public HSMComponentFormat getFormat() { + return format; + } + + public void setFormat(HSMComponentFormat format) { + this.format = format; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public List getButtons() { + return buttons; + } + + public void setButtons(List buttons) { + this.buttons = buttons; + } + + public HSMExample getExample() { + return example; + } + + public void setExample(HSMExample example) { + this.example = example; + } + + @Override + public String toString() { + return "HSMComponent{" + + "type='" + type + '\'' + + ", format='" + format + '\'' + + ", text='" + text + '\'' + + ", buttons=" + buttons + + ", example=" + example + + '}'; + } + + /** + * Check if this component is valid. + * + * @throws GeneralException Occurs when validation is not passed. + */ + public void validateComponent() throws GeneralException { + this.validateButtons(); + this.validateComponentExample(); + } + + /** + * Check if button list is valid. + * + * @throws GeneralException Occurs when validation is not passed. + */ + private void validateButtons() throws GeneralException { + if (this.buttons == null) { + return; + } + + for (final HSMComponentButton button : this.buttons) { + button.validateButtonExample(); + } + } + + /** + * Check for header_text and header_url. + * + * @throws GeneralException Occurs when {@code header_text} or {@code header_url} is not able to use. + */ + private void validateComponentExample() throws GeneralException { + final boolean isExampleNotNull = this.example != null; + final boolean isHeaderTextNotEmpty = + isExampleNotNull && !(this.example.getHeader_text() == null || this.example.getHeader_text() + .isEmpty()); + final boolean isHeaderUrlNotEmpty = + isExampleNotNull && !(this.example.getHeader_url() == null || this.example.getHeader_url() + .isEmpty()); + + if (isHeaderTextNotEmpty) { + this.checkHeaderText(); + } + + if (isHeaderUrlNotEmpty) { + this.checkHeaderUrl(); + } + } + + /** + * Check if header_text is able to use. + * + * @throws GeneralException Occurs when type is not {@code HEADER} and format is not {@code TEXT}. + */ + private void checkHeaderText() throws GeneralException { + if (!(type.equals(HSMComponentType.HEADER) + && format.equals(HSMComponentFormat.TEXT)) + ) { + throw new GeneralException("\"header_text\" is available for only HEADER type and TEXT format."); + } + } + + /** + * Check if header_url is able to use. + * + * @throws GeneralException Occurs when type is not {@code HEADER} and format is not {@code IMAGE}. + */ + private void checkHeaderUrl() throws GeneralException { + if (!(type.equals(HSMComponentType.HEADER) + && format.equals(HSMComponentFormat.IMAGE)) + ) { + throw new GeneralException("\"header_url\" is available for only HEADER type and IMAGE format."); + } + } +} diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButton.java b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButton.java new file mode 100644 index 00000000..02dd241c --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButton.java @@ -0,0 +1,89 @@ +package com.messagebird.objects.integrations; + +import com.messagebird.exceptions.GeneralException; +import java.util.List; + +/** + * HSMComponentButton + * + * @see HSMComponentButton + * @author ssk910 + */ +public class HSMComponentButton { + + private HSMComponentButtonType type; + private String text; + private String url; + private String phone_number; + private List example; + + public HSMComponentButtonType getType() { + return type; + } + + public void setType(HSMComponentButtonType type) { + this.type = type; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getPhone_number() { + return phone_number; + } + + public void setPhone_number(String phone_number) { + this.phone_number = phone_number; + } + + public List getExample() { + return example; + } + + public void setExample(List example) { + this.example = example; + } + + @Override + public String toString() { + return "HSMComponentButton{" + + "type=" + type + + ", text='" + text + '\'' + + ", url='" + url + '\'' + + ", phone_number='" + phone_number + '\'' + + ", example=" + example + + '}'; + } + + /** + * Check if example field is able to use. + * + * @throws GeneralException Occurs if button type is not {@code URL} or {@code QUICK_REPLY}. + */ + public void validateButtonExample() throws GeneralException { + final boolean isExampleEmpty = this.example == null || this.example.isEmpty(); + final boolean isNotProperType = !(this.type.equals(HSMComponentButtonType.URL) + || this.type.equals(HSMComponentButtonType.QUICK_REPLY)); + + if (isExampleEmpty) { + return; + } + + if (isNotProperType) { + throw new GeneralException("An example field in HSMComponentButton is available for only URL or QUICK_REPLY button types."); + } + } +} diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButtonType.java b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButtonType.java new file mode 100644 index 00000000..937f6baf --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButtonType.java @@ -0,0 +1,48 @@ +package com.messagebird.objects.integrations; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * HSMComponentButtonType + * + * @see HSMComponentButtonType + * @author ssk910 + */ +public enum HSMComponentButtonType { + + PHONE_NUMBER("PHONE_NUMBER"), + URL("URL"), + QUICK_REPLY("QUICK_REPLY"); + + private final String type; + + HSMComponentButtonType(String type) { + this.type = type; + } + + @JsonCreator + public static HSMComponentButtonType forValue(String value) { + for (HSMComponentButtonType hsmComponentButtonType : HSMComponentButtonType.values()) { + if (hsmComponentButtonType.getType().equals(value)) { + return hsmComponentButtonType; + } + } + + return null; + } + + @JsonValue + public String toJson() { + return getType(); + } + + public String getType() { + return type; + } + + @Override + public String toString() { + return getType(); + } +} diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMComponentFormat.java b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentFormat.java new file mode 100644 index 00000000..ac7d199d --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentFormat.java @@ -0,0 +1,49 @@ +package com.messagebird.objects.integrations; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * An enum for HSMComponentFormat + * + * @see HSMComponentFormat + * @author ssk910 + */ +public enum HSMComponentFormat { + + TEXT("TEXT"), + IMAGE("IMAGE"), + DOCUMENT("DOCUMENT"), + VIDEO("VIDEO"); + + private final String format; + + HSMComponentFormat(String format) { + this.format = format; + } + + @JsonCreator + public static HSMComponentFormat forValue(String value) { + for (HSMComponentFormat hsmComponentFormat : HSMComponentFormat.values()) { + if (hsmComponentFormat.getFormat().equals(value)) { + return hsmComponentFormat; + } + } + + return null; + } + + @JsonValue + public String toJson() { + return getFormat(); + } + + public String getFormat() { + return format; + } + + @Override + public String toString() { + return getFormat(); + } +} diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMComponentType.java b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentType.java new file mode 100644 index 00000000..0acda414 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentType.java @@ -0,0 +1,47 @@ +package com.messagebird.objects.integrations; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * An enum for HSMComponentType + * + * @see HSMComponentType + */ +public enum HSMComponentType { + BODY("BODY"), + HEADER("HEADER"), + FOOTER("FOOTER"), + BUTTONS("BUTTONS"); + + private final String type; + + HSMComponentType(String type) { + this.type = type; + } + + @JsonCreator + public static HSMComponentType forValue(String value) { + for (HSMComponentType hsmComponentType : HSMComponentType.values()) { + if (hsmComponentType.getType().equals(value)) { + return hsmComponentType; + } + } + + return null; + } + + @JsonValue + public String toJson() { + return getType(); + } + + public String getType() { + return type; + } + + @Override + public String toString() { + return getType(); + } +} diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMExample.java b/api/src/main/java/com/messagebird/objects/integrations/HSMExample.java new file mode 100644 index 00000000..a28fcc38 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMExample.java @@ -0,0 +1,54 @@ +package com.messagebird.objects.integrations; + +import java.util.List; + +/** + * HSMExample object + * + * @see HSMExample object + * @author ssk910 + */ +public class HSMExample { + + /* Example values for HEADER type components, TEXT format */ + private List header_text; + + /* Example set of values for the body text variables */ + private List> body_text; + + /* Example values for HEADER type components, IMAGE format */ + private List header_url; + + public List getHeader_text() { + return header_text; + } + + public void setHeader_text(List header_text) { + this.header_text = header_text; + } + + public List> getBody_text() { + return body_text; + } + + public void setBody_text(List> body_text) { + this.body_text = body_text; + } + + public List getHeader_url() { + return header_url; + } + + public void setHeader_url(List header_url) { + this.header_url = header_url; + } + + @Override + public String toString() { + return "HSMExample{" + + "header_text=" + header_text + + ", body_text=" + body_text + + ", header_url=" + header_url + + '}'; + } +} diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMRejectedReason.java b/api/src/main/java/com/messagebird/objects/integrations/HSMRejectedReason.java new file mode 100644 index 00000000..55937ef4 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMRejectedReason.java @@ -0,0 +1,51 @@ +package com.messagebird.objects.integrations; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * An enum class for HSMRejectedReason + * + * @see HSMRejectedReason object + * @author ssk910 + */ +public enum HSMRejectedReason { + + ABUSIVE_CONTENT("ABUSIVE_CONTENT"), + INVALID_FORMAT("INVALID_FORMAT"), + NONE("NONE"), + PROMOTIONAL("PROMOTIONAL"), + TAG_CONTENT_MISMATCH("TAG_CONTENT_MISMATCH"), + NON_TRANSIENT_ERROR("NON_TRANSIENT_ERROR"); + + private final String rejectedReason; + + HSMRejectedReason(String rejectedReason) { + this.rejectedReason = rejectedReason; + } + + @JsonCreator + public static HSMRejectedReason forValue(String value) { + for (HSMRejectedReason hsmRejectedReason : HSMRejectedReason.values()) { + if (hsmRejectedReason.getRejectedReason().equals(value)) { + return hsmRejectedReason; + } + } + + return null; + } + + @JsonValue + public String toJson() { + return getRejectedReason(); + } + + public String getRejectedReason() { + return rejectedReason; + } + + @Override + public String toString() { + return getRejectedReason(); + } +} diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMStatus.java b/api/src/main/java/com/messagebird/objects/integrations/HSMStatus.java new file mode 100644 index 00000000..fa179b0f --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMStatus.java @@ -0,0 +1,51 @@ +package com.messagebird.objects.integrations; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * An enum for HSMStatus object + * + * @see HSMStatus object + * @author ssk910 + */ +public enum HSMStatus { + + NEW("NEW"), + APPROVED("APPROVED"), + PENDING("PENDING"), + REJECTED("REJECTED"), + PENDING_DELETION("PENDING_DELETION"), + DELETED("DELETED"); + + private final String status; + + HSMStatus(String status) { + this.status = status; + } + + @JsonCreator + public static HSMStatus forValue(String value) { + for (HSMStatus hsmStatus : HSMStatus.values()) { + if (hsmStatus.getStatus().equals(value)) { + return hsmStatus; + } + } + + return null; + } + + @JsonValue + public String toJson() { + return getStatus(); + } + + public String getStatus() { + return status; + } + + @Override + public String toString() { + return getStatus(); + } +} diff --git a/api/src/main/java/com/messagebird/objects/integrations/WhatsAppTemplate.java b/api/src/main/java/com/messagebird/objects/integrations/WhatsAppTemplate.java new file mode 100644 index 00000000..3d3ba755 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/integrations/WhatsAppTemplate.java @@ -0,0 +1,86 @@ +package com.messagebird.objects.integrations; + +import com.messagebird.exceptions.GeneralException; +import java.util.List; + +/** + * WhatsApp Template Object as integrations API request. + * + * @see Integrations API + * @author ssk910 + */ +public class WhatsAppTemplate { + + private String name; + private String language; + private List components; + private HSMCategory category; + + public WhatsAppTemplate() { + } + + public WhatsAppTemplate(String name, String language, + List components, HSMCategory category) { + this.name = name; + this.language = language; + this.components = components; + this.category = category; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public List getComponents() { + return components; + } + + public void setComponents(List components) { + this.components = components; + } + + public HSMCategory getCategory() { + return category; + } + + public void setCategory(HSMCategory category) { + this.category = category; + } + + /** + * Check if components field is valid. + * + * @throws GeneralException Occurs when it is invalid. + */ + public void validate() throws GeneralException { + if (this.components == null) { + return; + } + + for (final HSMComponent component : this.components) { + component.validateComponent(); + } + } + + @Override + public String toString() { + return "WhatsAppTemplate{" + + "name='" + name + '\'' + + ", language='" + language + '\'' + + ", components=" + components + + ", category='" + category + '\'' + + '}'; + } +} diff --git a/api/src/main/java/com/messagebird/objects/integrations/WhatsAppTemplateList.java b/api/src/main/java/com/messagebird/objects/integrations/WhatsAppTemplateList.java new file mode 100644 index 00000000..9e6e4894 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/integrations/WhatsAppTemplateList.java @@ -0,0 +1,12 @@ +package com.messagebird.objects.integrations; + +import com.messagebird.objects.ListBase; + +/** + * Response object representing the Template list type. + * + * @author ssk910 + */ +public class WhatsAppTemplateList extends ListBase { + +} diff --git a/api/src/main/java/com/messagebird/objects/integrations/WhatsAppTemplateResponse.java b/api/src/main/java/com/messagebird/objects/integrations/WhatsAppTemplateResponse.java new file mode 100644 index 00000000..687401b8 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/integrations/WhatsAppTemplateResponse.java @@ -0,0 +1,105 @@ +package com.messagebird.objects.integrations; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + * WhatsApp Template response using integrations API. + * + * @author ssk910 + */ +public class WhatsAppTemplateResponse implements Serializable { + + private static final long serialVersionUID = 7154209824478715861L; + private String name; + private String language; + private HSMCategory category; + private List components; + private HSMStatus status; + private HSMRejectedReason rejectedReason; + private Date createdAt; + private Date updatedAt; + + public static long getSerialVersionUID() { + return serialVersionUID; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public HSMCategory getCategory() { + return category; + } + + public void setCategory(HSMCategory category) { + this.category = category; + } + + public List getComponents() { + return components; + } + + public void setComponents(List components) { + this.components = components; + } + + public HSMStatus getStatus() { + return status; + } + + public void setStatus(HSMStatus status) { + this.status = status; + } + + public HSMRejectedReason getRejectedReason() { + return rejectedReason; + } + + public void setRejectedReason(HSMRejectedReason rejectedReason) { + this.rejectedReason = rejectedReason; + } + + public Date getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + public Date getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Date updatedAt) { + this.updatedAt = updatedAt; + } + + @Override + public String toString() { + return "WhatsAppTemplateResponse{" + + "name='" + name + '\'' + + ", language='" + language + '\'' + + ", category='" + category + '\'' + + ", components=" + components + + ", status='" + status + '\'' + + ", rejectedReason='" + rejectedReason + '\'' + + ", createdAt=" + createdAt + + ", updatedAt=" + updatedAt + + '}'; + } +} diff --git a/examples/src/main/java/ExampleCreateTemplate.java b/examples/src/main/java/ExampleCreateTemplate.java new file mode 100644 index 00000000..275c5bab --- /dev/null +++ b/examples/src/main/java/ExampleCreateTemplate.java @@ -0,0 +1,97 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.integrations.HSMCategory; +import com.messagebird.objects.integrations.HSMComponent; +import com.messagebird.objects.integrations.HSMComponentButton; +import com.messagebird.objects.integrations.HSMComponentButtonType; +import com.messagebird.objects.integrations.HSMComponentFormat; +import com.messagebird.objects.integrations.HSMComponentType; +import com.messagebird.objects.integrations.HSMExample; +import com.messagebird.objects.integrations.WhatsAppTemplate; +import com.messagebird.objects.integrations.WhatsAppTemplateResponse; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Create template. + * + * @see Doc - Create template + * @author ssk910 + */ +public class ExampleCreateTemplate { + + public static void main(String[] args) { + if (args.length < 2) { + System.out.println("Please specify your access key and a template name example : java -jar test_accesskey \"My template name\""); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + /* header */ + final HSMComponent headerComponent = new HSMComponent(); + final HSMExample headerExample = new HSMExample(); + headerExample.setHeader_url(Arrays.asList("https://images.freeimages.com/images/small-previews/c5a/colourful-paper-rip-1-1195879.jpg")); + + headerComponent.setType(HSMComponentType.HEADER); + headerComponent.setFormat(HSMComponentFormat.IMAGE); + headerComponent.setExample(headerExample); + + /* body */ + final HSMComponent bodyComponent = new HSMComponent(); + final HSMExample bodyExample = new HSMExample(); + final List> bodyText = new ArrayList<>(); + bodyText.add(Arrays.asList("John")); + bodyText.add(Arrays.asList("Anna")); + bodyExample.setBody_text(bodyText); + + bodyComponent.setType(HSMComponentType.BODY); + bodyComponent.setText("Hey {{1}}! This is a sample template from Java."); + bodyComponent.setExample(bodyExample); + + /* footer */ + final HSMComponent footerComponent = new HSMComponent(); + footerComponent.setType(HSMComponentType.FOOTER); + footerComponent.setText("This is a sample footer"); + + /* button */ + final HSMComponent buttonComponent = new HSMComponent(); + final List buttons = new ArrayList<>(); + final HSMComponentButton button = new HSMComponentButton(); + button.setType(HSMComponentButtonType.URL); + button.setText("Touch it"); + button.setUrl("https://www.messagebird.com"); + button.setExample(Arrays.asList("https://developers.messagebird.com")); + buttons.add(button); + buttonComponent.setType(HSMComponentType.BUTTONS); + buttonComponent.setButtons(buttons); + + /* set components */ + final WhatsAppTemplate template = new WhatsAppTemplate(); + final List components = new ArrayList<>(); + components.add(headerComponent); + components.add(bodyComponent); + components.add(footerComponent); + components.add(buttonComponent); + + template.setName(args[1]); + template.setLanguage("en_US"); + template.setComponents(components); + template.setCategory(HSMCategory.ACCOUNT_UPDATE); + + try { + WhatsAppTemplateResponse response = messageBirdClient.createWhatsAppTemplate(template); + System.out.println(response.toString()); + } catch (GeneralException | UnauthorizedException exception) { + exception.printStackTrace(); + } + } +} diff --git a/examples/src/main/java/ExampleDeleteTemplateByNameAndLanguage.java b/examples/src/main/java/ExampleDeleteTemplateByNameAndLanguage.java new file mode 100644 index 00000000..1b215f10 --- /dev/null +++ b/examples/src/main/java/ExampleDeleteTemplateByNameAndLanguage.java @@ -0,0 +1,40 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; + +/** + * Delete template by name and language + * + * @see Delete template by name and language + * @author ssk910 + */ +public class ExampleDeleteTemplateByNameAndLanguage { + + public static void main(String[] args) { + if (args.length < 3) { + System.out.println("Please specify your access key and a template name example : java -jar test_accesskey \"My template name\" \"Template language\""); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + // template name and langugae from input + final String templateName = args[1]; + final String language = args[2]; + + try { + System.out.println("Deleting WhatsApp Template list by {name: " + templateName + ", language: " + language + "}"); + messageBirdClient.deleteTemplatesBy(templateName, language); + System.out.println("Deleted {name: " + templateName + ", language: " + language + "}"); + } catch (GeneralException | UnauthorizedException | NotFoundException exception) { + exception.printStackTrace(); + } + } +} diff --git a/examples/src/main/java/ExampleDeleteTemplatesByName.java b/examples/src/main/java/ExampleDeleteTemplatesByName.java new file mode 100644 index 00000000..c8d529f3 --- /dev/null +++ b/examples/src/main/java/ExampleDeleteTemplatesByName.java @@ -0,0 +1,39 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; + +/** + * List templates by name + * + * @see List templates by name + * @author ssk910 + */ +public class ExampleDeleteTemplatesByName { + + public static void main(String[] args) { + if (args.length < 2) { + System.out.println("Please specify your access key and a template name example : java -jar test_accesskey \"My template name\""); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + // template name from input + final String templateName = args[1]; + + try { + System.out.println("Deleting WhatsApp Templates by name : " + templateName); + messageBirdClient.deleteTemplatesBy(templateName); + System.out.println("Template [" + templateName + "] deleted."); + } catch (GeneralException | UnauthorizedException | NotFoundException exception) { + exception.printStackTrace(); + } + } +} diff --git a/examples/src/main/java/ExampleFetchTemplateByNameAndLanguage.java b/examples/src/main/java/ExampleFetchTemplateByNameAndLanguage.java new file mode 100644 index 00000000..e1ad9bb6 --- /dev/null +++ b/examples/src/main/java/ExampleFetchTemplateByNameAndLanguage.java @@ -0,0 +1,41 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.integrations.WhatsAppTemplateResponse; + +/** + * Fetch template by name and language + * + * @see Fetch template by name and language + * @author ssk910 + */ +public class ExampleFetchTemplateByNameAndLanguage { + + public static void main(String[] args) { + if (args.length < 3) { + System.out.println("Please specify your access key and a template name example : java -jar test_accesskey \"My template name\" \"Template language\""); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + // template name and langugae from input + final String templateName = args[1]; + final String language = args[2]; + + try { + System.out.println("Fetching WhatsApp Template list by {name: " + templateName + ", language: " + language + "}"); + final WhatsAppTemplateResponse template = messageBirdClient.fetchWhatsAppTemplateBy(templateName, language); + System.out.println(template.toString()); + } catch (GeneralException | UnauthorizedException | NotFoundException exception) { + exception.printStackTrace(); + } + } +} diff --git a/examples/src/main/java/ExampleListTemplates.java b/examples/src/main/java/ExampleListTemplates.java new file mode 100644 index 00000000..db9fc21b --- /dev/null +++ b/examples/src/main/java/ExampleListTemplates.java @@ -0,0 +1,36 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.integrations.WhatsAppTemplateList; + +/** + * List templates + * + * @see List templates + * @author ssk910 + */ +public class ExampleListTemplates { + + public static void main(String[] args) { + if (args.length == 0) { + System.out.println("Please specify your access key example : java -jar test_accesskey"); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + System.out.println("Retrieving WhatsApp Template list"); + final WhatsAppTemplateList templateList = messageBirdClient.listWhatsAppTemplates(); + System.out.println(templateList.toString()); + } catch (GeneralException | UnauthorizedException exception) { + exception.printStackTrace(); + } + } +} diff --git a/examples/src/main/java/ExampleListTemplatesByName.java b/examples/src/main/java/ExampleListTemplatesByName.java new file mode 100644 index 00000000..e68a6446 --- /dev/null +++ b/examples/src/main/java/ExampleListTemplatesByName.java @@ -0,0 +1,41 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.integrations.WhatsAppTemplateResponse; +import java.util.List; + +/** + * List templates by name + * + * @see List templates by name + * @author ssk910 + */ +public class ExampleListTemplatesByName { + + public static void main(String[] args) { + if (args.length < 2) { + System.out.println("Please specify your access key and a template name example : java -jar test_accesskey \"My template name\""); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + // template name from input + final String templateName = args[1]; + + try { + System.out.println("Retrieving WhatsApp Template list by name : " + templateName); + final List templateList = messageBirdClient.getWhatsAppTemplatesBy(templateName); + System.out.println(templateList.toString()); + } catch (GeneralException | UnauthorizedException | NotFoundException exception) { + exception.printStackTrace(); + } + } +} From 994aa7c6a9070e285a8089e8ca15f4320abb5e81 Mon Sep 17 00:00:00 2001 From: ssk910 Date: Thu, 30 Sep 2021 22:33:11 +0900 Subject: [PATCH 315/516] feat: Add features for retrieve list of specified objects MessageBirdServiceImpl.getJsonDataAsList() method needs to refactor. It has some duplicated code as mentioned at todo comment. --- .../com/messagebird/MessageBirdService.java | 15 +++++ .../messagebird/MessageBirdServiceImpl.java | 67 ++++++++++++++++++- 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdService.java b/api/src/main/java/com/messagebird/MessageBirdService.java index 7f0a8641..43201fb7 100644 --- a/api/src/main/java/com/messagebird/MessageBirdService.java +++ b/api/src/main/java/com/messagebird/MessageBirdService.java @@ -4,6 +4,7 @@ import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; import com.messagebird.objects.PagedPaging; +import java.util.List; import java.util.Map; /** @@ -38,6 +39,20 @@ public interface MessageBirdService { R requestByID(String request, String id, Map params, Class clazz) throws UnauthorizedException, GeneralException, NotFoundException; + /** + * Execute a object by ID request. It will add the id to the request parameter and retrieve a list of an object E back. + * + * @author ssk910 + * @param request path to the request, for example "/messages" + * @param id id of the object to request. id can be null in case request's that don't need a id, for example /balance + * @param elementClass Class type of List to return + * @return new list of elementClass + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + * @throws NotFoundException + */ + List requestByIdAsList(String request, String id, Class elementClass) throws UnauthorizedException, GeneralException, NotFoundException; + /** * Delete a object by ID. * diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 93507d08..2497d524 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -1,6 +1,7 @@ package com.messagebird; import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.MapperFeature; @@ -27,6 +28,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; @@ -138,6 +140,17 @@ public R requestByID(String request, String id, Map params, return getJsonData(request + path + queryParams, null, "GET", clazz); } + @Override + public List requestByIdAsList(String request, String id, Class elementClass) + throws UnauthorizedException, GeneralException, NotFoundException { + String path = ""; + if (id != null) { + path = "/" + id; + } + + return getJsonDataAsList(request + path, null, "GET", elementClass); + } + @Override public void deleteByID(String request, String id) throws UnauthorizedException, GeneralException, NotFoundException { getJsonData(request + "/" + id, null, "DELETE", null); @@ -234,6 +247,10 @@ public T getJsonData(final String request, final P payload, final String return getJsonData(request, payload, requestType, new HashMap<>(), clazz); } + public List getJsonDataAsList(final String request, final P payload, final String requestType, final Class elementClass) throws UnauthorizedException, GeneralException, NotFoundException { + return getJsonDataAsList(request, payload, requestType, new HashMap<>(), elementClass); + } + public T getJsonData(final String request, final P payload, final String requestType, final Map headers, final Class clazz) throws UnauthorizedException, GeneralException, NotFoundException { if (request == null) { throw new IllegalArgumentException(REQUEST_VALUE_MUST_BE_SPECIFIED); @@ -260,7 +277,7 @@ public T getJsonData(final String request, final P payload, final String // Prevents mismatched exception when clazz is null return clazz == null ? null - : mapper.readValue(body, clazz); + : this.readValue(mapper, body, clazz); } catch (IOException ioe) { throw new GeneralException(ioe); } @@ -271,6 +288,54 @@ public T getJsonData(final String request, final P payload, final String return null; } + // todo: need to refactor for duplicated code. + public List getJsonDataAsList(final String request, + final P payload, final String requestType, final Map headers, final Class elementClass) + throws UnauthorizedException, GeneralException, NotFoundException { + if (request == null) { + throw new IllegalArgumentException(REQUEST_VALUE_MUST_BE_SPECIFIED); + } + + String url = request; + if (!isURLAbsolute(url)) { + url = serviceUrl + url; + } + final APIResponse apiResponse = doRequest(requestType, url, headers, payload); + + final String body = apiResponse.getBody(); + final int status = apiResponse.getStatus(); + + if (status == HttpURLConnection.HTTP_OK || status == HttpURLConnection.HTTP_CREATED || status == HttpURLConnection.HTTP_ACCEPTED) { + try { + final ObjectMapper mapper = new ObjectMapper(); + // If we as new properties, we don't want the system to fail, we rather want to ignore them + mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + // Enable case insensitivity to avoid parsing errors if parameters' case in api response doesn't match sdk's + mapper.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES); + mapper.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS); + + // Prevents mismatched exception when clazz is null + return this.readValueAsList(mapper, body, elementClass); + } catch (IOException ioe) { + throw new GeneralException(ioe); + } + } else if (status == HttpURLConnection.HTTP_NO_CONTENT) { + return Collections.emptyList(); // no content doesn't mean an error + } + handleHttpFailStatuses(status, body); + return Collections.emptyList(); + } + + private T readValue(ObjectMapper mapper, String content, Class clazz) + throws JsonProcessingException { + return mapper.readValue(content, clazz); + } + + private List readValueAsList(ObjectMapper mapper, String content, final Class elementClass) + throws JsonProcessingException { + return mapper.readValue(content, mapper.getTypeFactory().constructCollectionType(List.class, elementClass)); + } + private void handleHttpFailStatuses(final int status, String body) throws UnauthorizedException, NotFoundException, GeneralException { if (status == HttpURLConnection.HTTP_UNAUTHORIZED) { final List errorReport = getErrorReportOrNull(body); From b9a59fb7a59e9743b624d5a3f37b941cdb17d03d Mon Sep 17 00:00:00 2001 From: ssk910 Date: Thu, 30 Sep 2021 22:35:26 +0900 Subject: [PATCH 316/516] test: Add unit tests for Integrations API Added just a few unit tests. --- .../com/messagebird/MessageBirdClient.java | 5 +- .../messagebird/MessageBirdClientTest.java | 189 ++++++++++++++++++ .../test/java/com/messagebird/TestUtil.java | 109 ++++++++++ 3 files changed, 300 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 317b02d4..fc075fa0 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -122,7 +122,7 @@ public class MessageBirdClient { private static final String CONVERSATION_SEND_PATH = "/send"; private static final String CONVERSATION_MESSAGE_PATH = "/messages"; private static final String CONVERSATION_WEBHOOK_PATH = "/webhooks"; - private static final String INTEGRATIONS_WHATSAPP_PATH = "/platforms/whatsapp"; + static final String INTEGRATIONS_WHATSAPP_PATH = "/platforms/whatsapp"; static final String VOICECALLSPATH = "/calls"; static final String LEGSPATH = "/legs"; static final String RECORDINGPATH = "/recordings"; @@ -1936,8 +1936,7 @@ public List getWhatsAppTemplatesBy(final String templa TEMPLATES_PATH ); - final WhatsAppTemplateResponse[] templateResponses = messageBirdService.requestByID(url, templateName, WhatsAppTemplateResponse[].class); - return Arrays.asList(templateResponses); + return messageBirdService.requestByIdAsList(url, templateName, WhatsAppTemplateResponse.class); } /** diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 956b177b..73731f96 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -4,10 +4,19 @@ import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; import com.messagebird.objects.*; +import com.messagebird.objects.integrations.WhatsAppTemplate; +import com.messagebird.objects.integrations.WhatsAppTemplateList; +import com.messagebird.objects.integrations.WhatsAppTemplateResponse; import com.messagebird.objects.voicecalls.*; +import java.util.ArrayList; +import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.Mockito; import java.io.*; @@ -17,6 +26,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import org.mockito.stubbing.OngoingStubbing; import static com.messagebird.MessageBirdClient.*; import static org.junit.Assert.*; @@ -33,6 +43,13 @@ public class MessageBirdClientTest { MessageBirdServiceImpl messageBirdService; MessageBirdClient messageBirdClient; + @Captor + ArgumentCaptor argument = ArgumentCaptor.forClass(WhatsAppTemplateResponse.class); + + @Captor + ArgumentCaptor valueCaptor; + + @BeforeClass public static void setUpClass() { messageBirdAccessKey = System.getProperty("messageBirdAccessKey"); @@ -1042,4 +1059,176 @@ public void testDownloadFileWithNullBasePath() throws GeneralException, Unauthor String url = MESSAGING_BASE_URL + FILES_PATH + "/" + id; verify(messageBirdServiceMock, times(1)).getBinaryData(url, null, filename); } + + /****************************************************************************************************/ + /** Testing WhatsApp Templates **/ + /****************************************************************************************************/ + + @Test + public void testCreateWhatsAppTemplate() throws UnauthorizedException, GeneralException { + final WhatsAppTemplateResponse templateResponse = TestUtil.createWhatsAppTemplateResponse("sample_template_name", "ko"); + final WhatsAppTemplate template = TestUtil.createWhatsAppTemplate("sample_template_name", "ko"); + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + + String url = String.format( + "%s%s%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH + ); + + when(messageBirdServiceMock.sendPayLoad(url, template, WhatsAppTemplateResponse.class)) + .thenReturn(templateResponse); + + final WhatsAppTemplateResponse response = messageBirdClientInjectMock.createWhatsAppTemplate(template); + + verify(messageBirdServiceMock, times(1)).sendPayLoad(url, template, WhatsAppTemplateResponse.class); + assertNotNull(response); + assertEquals(response.getName(), templateResponse.getName()); + assertEquals(response.getLanguage(), templateResponse.getLanguage()); + assertEquals(response.getCategory(), templateResponse.getCategory()); + assertEquals(response.getStatus(), templateResponse.getStatus()); + assertEquals(response.getCreatedAt(), templateResponse.getCreatedAt()); + assertEquals(response.getUpdatedAt(), templateResponse.getUpdatedAt()); + + /* verify components */ + for (int i = 0; i < response.getComponents().size(); i++) { + assertEquals(response.getComponents().get(i).getType(), templateResponse.getComponents().get(i).getType()); + assertEquals(response.getComponents().get(i).getFormat(), templateResponse.getComponents().get(i).getFormat()); + assertEquals(response.getComponents().get(i).getText(), templateResponse.getComponents().get(i).getText()); + } + } + + @Test + public void testListWhatsAppTemplates() throws UnauthorizedException, GeneralException { + final WhatsAppTemplateList templateList = TestUtil.createWhatsAppTemplateList("sample_template_name"); + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + + String url = String.format( + "%s%s%s", + INTEGRATIONS_BASE_URL_V3, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH + ); + + when(messageBirdServiceMock.requestList(url, 0, 0, WhatsAppTemplateList.class)) + .thenReturn(templateList); + + final WhatsAppTemplateList response = messageBirdClientInjectMock.listWhatsAppTemplates(0, 0); + verify(messageBirdServiceMock, times(1)).requestList(url, 0, 0, WhatsAppTemplateList.class); + assertNotNull(response); + for(int i = 0; i < response.getItems().size() ; i++) { + assertReflectionEquals(response.getItems().get(i), templateList.getItems().get(i)); + } + } + + @Test + public void testGetWhatsAppTemplatesBy() + throws GeneralException, UnauthorizedException, NotFoundException, ClassNotFoundException { + final String templateName = "sample_template_name"; + final WhatsAppTemplateResponse templateResponse1 = TestUtil.createWhatsAppTemplateResponse(templateName, "en_US"); + final WhatsAppTemplateResponse templateResponse2 = TestUtil.createWhatsAppTemplateResponse("another_template", "en_US"); + final List templateList = new ArrayList<>(); + templateList.add(templateResponse1); + templateList.add(templateResponse2); + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + + String url = String.format( + "%s%s%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH + ); + + when(messageBirdServiceMock.requestByIdAsList(url, templateName, WhatsAppTemplateResponse.class)) + .thenReturn(templateList); + + final List response = messageBirdClientInjectMock.getWhatsAppTemplatesBy(templateName); + verify(messageBirdServiceMock, times(1)).requestByIdAsList(url, templateName, WhatsAppTemplateResponse.class); + assertNotNull(response); + assertEquals(response.size(), templateList.size()); + for(int i = 0; i < response.size() ; i++) { + assertReflectionEquals(response.get(i), templateList.get(i)); + } + } + + @Test + public void testFetchWhatsAppTemplateBy() + throws UnauthorizedException, GeneralException, NotFoundException { + final String templateName = "sample_template_name"; + final String language = "ko"; + final WhatsAppTemplateResponse template = TestUtil.createWhatsAppTemplateResponse(templateName, language); + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + + String url = String.format( + "%s%s%s/%s/%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH, + templateName, + language + ); + + when(messageBirdServiceMock.request(url, WhatsAppTemplateResponse.class)) + .thenReturn(template); + + final WhatsAppTemplateResponse response = messageBirdClientInjectMock.fetchWhatsAppTemplateBy(templateName, language); + verify(messageBirdServiceMock, times(1)).request(url, WhatsAppTemplateResponse.class); + assertNotNull(response); + assertEquals(response.getName(), template.getName()); + assertEquals(response.getLanguage(), template.getLanguage()); + assertEquals(response.getStatus(), template.getStatus()); + assertReflectionEquals(response.getComponents(), template.getComponents()); + } + + @Test + public void testDeleteTemplatesByName() + throws UnauthorizedException, GeneralException, NotFoundException { + final String templateName = "sample_template_name"; + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + + String url = String.format( + "%s%s%s/%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH, + templateName + ); + + when(messageBirdServiceMock.delete(url, null)).thenReturn(null); + messageBirdClientInjectMock.deleteTemplatesBy(templateName); + verify(messageBirdServiceMock).delete(url, null); + } + + @Test + public void testDeleteTemplatesByNameAndLanguage() + throws UnauthorizedException, GeneralException, NotFoundException { + final String templateName = "sample_template_name"; + final String language = "en_US"; + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + + String url = String.format( + "%s%s%s/%s/%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH, + templateName, + language + ); + + when(messageBirdServiceMock.delete(url, null)).thenReturn(null); + messageBirdClientInjectMock.deleteTemplatesBy(templateName, language); + verify(messageBirdServiceMock).delete(url, null); + } } diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index 5a854b45..07072aff 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -2,6 +2,17 @@ import com.messagebird.objects.*; import com.messagebird.objects.conversations.*; +import com.messagebird.objects.integrations.HSMCategory; +import com.messagebird.objects.integrations.HSMComponent; +import com.messagebird.objects.integrations.HSMComponentButton; +import com.messagebird.objects.integrations.HSMComponentButtonType; +import com.messagebird.objects.integrations.HSMComponentFormat; +import com.messagebird.objects.integrations.HSMComponentType; +import com.messagebird.objects.integrations.HSMExample; +import com.messagebird.objects.integrations.HSMStatus; +import com.messagebird.objects.integrations.WhatsAppTemplate; +import com.messagebird.objects.integrations.WhatsAppTemplateList; +import com.messagebird.objects.integrations.WhatsAppTemplateResponse; import com.messagebird.objects.voicecalls.*; import java.util.*; @@ -240,4 +251,102 @@ static ConversationWebhookCreateRequest createConversationWebhookRequest() { ) ); } + + private static HSMComponent createHSMComponentHeader() { + final HSMComponent headerComponent = new HSMComponent(); + final HSMExample headerExample = new HSMExample(); + headerExample.setHeader_url(Arrays.asList("https://www.mysample.com/sample.img")); + + headerComponent.setType(HSMComponentType.HEADER); + headerComponent.setFormat(HSMComponentFormat.IMAGE); + headerComponent.setExample(headerExample); + + return headerComponent; + } + + private static HSMComponent createHSMComponentBody() { + final HSMComponent bodyComponent = new HSMComponent(); + final HSMExample bodyExample = new HSMExample(); + final List> bodyText = new ArrayList<>(); + bodyText.add(Arrays.asList("John")); + bodyText.add(Arrays.asList("Anna")); + bodyExample.setBody_text(bodyText); + + bodyComponent.setType(HSMComponentType.BODY); + bodyComponent.setText("Hey {{1}}! This is a sample template from Java."); + bodyComponent.setExample(bodyExample); + + return bodyComponent; + } + + private static HSMComponent createHSMComponentFooter() { + final HSMComponent footerComponent = new HSMComponent(); + footerComponent.setType(HSMComponentType.FOOTER); + footerComponent.setText("This is a sample footer"); + + return footerComponent; + } + + private static HSMComponent createHSMComponentButton() { + final HSMComponent buttonComponent = new HSMComponent(); + final List buttons = new ArrayList<>(); + final HSMComponentButton button = new HSMComponentButton(); + button.setType(HSMComponentButtonType.URL); + button.setText("Touch it"); + button.setUrl("https://www.messagebird.com"); + button.setExample(Arrays.asList("https://developers.messagebird.com")); + buttons.add(button); + buttonComponent.setType(HSMComponentType.BUTTONS); + buttonComponent.setButtons(buttons); + + return buttonComponent; + } + + public static WhatsAppTemplateResponse createWhatsAppTemplateResponse(final String templateName, final String language) { + final WhatsAppTemplateResponse templateResponse = new WhatsAppTemplateResponse(); + templateResponse.setName(templateName); + templateResponse.setLanguage(language); + templateResponse.setCategory(HSMCategory.ACCOUNT_UPDATE); + templateResponse.setStatus(HSMStatus.NEW); + templateResponse.setCreatedAt(new Date()); + templateResponse.setUpdatedAt(new Date()); + + final List components = new ArrayList<>(); + components.add(createHSMComponentHeader()); + components.add(createHSMComponentBody()); + components.add(createHSMComponentFooter()); + components.add(createHSMComponentButton()); + templateResponse.setComponents(components); + + return templateResponse; + } + + public static WhatsAppTemplate createWhatsAppTemplate(final String templateName, final String language) { + final WhatsAppTemplate template = new WhatsAppTemplate(); + template.setName(templateName); + template.setLanguage(language); + template.setCategory(HSMCategory.ACCOUNT_UPDATE); + + final List components = new ArrayList<>(); + components.add(createHSMComponentHeader()); + components.add(createHSMComponentBody()); + components.add(createHSMComponentFooter()); + components.add(createHSMComponentButton()); + template.setComponents(components); + + return template; + } + + public static WhatsAppTemplateList createWhatsAppTemplateList(final String templateName) { + final WhatsAppTemplateResponse template1 = TestUtil.createWhatsAppTemplateResponse(templateName, "en_US"); + final WhatsAppTemplateResponse template2 = TestUtil.createWhatsAppTemplateResponse(templateName, "ko"); + final WhatsAppTemplateList templateList = new WhatsAppTemplateList(); + + List templateResponseList = new ArrayList<>(); + templateResponseList.add(template1); + templateResponseList.add(template2); + + templateList.setItems(templateResponseList); + return templateList; + } } From 2d4593e15389051ce3a3d2f53540366027d6d779 Mon Sep 17 00:00:00 2001 From: ssk910 Date: Tue, 5 Oct 2021 13:15:50 +0900 Subject: [PATCH 317/516] refactor: Rename classes and interfaces Applied @olimpias 's suggestion in #160 --- .../com/messagebird/MessageBirdClient.java | 28 ++++----- .../{WhatsAppTemplate.java => Template.java} | 8 +-- ...AppTemplateList.java => TemplateList.java} | 2 +- ...ateResponse.java => TemplateResponse.java} | 4 +- .../messagebird/MessageBirdClientTest.java | 57 +++++++------------ .../test/java/com/messagebird/TestUtil.java | 24 ++++---- .../src/main/java/ExampleCreateTemplate.java | 8 +-- ...ExampleFetchTemplateByNameAndLanguage.java | 4 +- .../src/main/java/ExampleListTemplates.java | 4 +- .../main/java/ExampleListTemplatesByName.java | 4 +- 10 files changed, 65 insertions(+), 78 deletions(-) rename api/src/main/java/com/messagebird/objects/integrations/{WhatsAppTemplate.java => Template.java} (90%) rename api/src/main/java/com/messagebird/objects/integrations/{WhatsAppTemplateList.java => TemplateList.java} (69%) rename api/src/main/java/com/messagebird/objects/integrations/{WhatsAppTemplateResponse.java => TemplateResponse.java} (94%) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index fc075fa0..d463488a 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -46,9 +46,9 @@ import com.messagebird.objects.conversations.ConversationWebhookCreateRequest; import com.messagebird.objects.conversations.ConversationWebhookList; import com.messagebird.objects.conversations.ConversationWebhookUpdateRequest; -import com.messagebird.objects.integrations.WhatsAppTemplate; -import com.messagebird.objects.integrations.WhatsAppTemplateList; -import com.messagebird.objects.integrations.WhatsAppTemplateResponse; +import com.messagebird.objects.integrations.Template; +import com.messagebird.objects.integrations.TemplateList; +import com.messagebird.objects.integrations.TemplateResponse; import com.messagebird.objects.voicecalls.RecordingResponse; import com.messagebird.objects.voicecalls.TranscriptionResponse; import com.messagebird.objects.voicecalls.VoiceCall; @@ -1862,12 +1862,12 @@ public String downloadFile(String id, String filename, String basePath) throws G /** * Create a WhatsApp message template through messagebird. * - * @param template {@link WhatsAppTemplate} object to be created - * @return {@link WhatsAppTemplateResponse} response object + * @param template {@link Template} object to be created + * @return {@link TemplateResponse} response object * @throws UnauthorizedException if client is unauthorized * @throws GeneralException general exception or invalid template format */ - public WhatsAppTemplateResponse createWhatsAppTemplate(final WhatsAppTemplate template) + public TemplateResponse createWhatsAppTemplate(final Template template) throws UnauthorizedException, GeneralException { template.validate(); @@ -1877,7 +1877,7 @@ public WhatsAppTemplateResponse createWhatsAppTemplate(final WhatsAppTemplate te INTEGRATIONS_WHATSAPP_PATH, TEMPLATES_PATH ); - return messageBirdService.sendPayLoad(url, template, WhatsAppTemplateResponse.class); + return messageBirdService.sendPayLoad(url, template, TemplateResponse.class); } /** @@ -1889,7 +1889,7 @@ public WhatsAppTemplateResponse createWhatsAppTemplate(final WhatsAppTemplate te * @throws UnauthorizedException if client is unauthorized * @throws GeneralException general exception */ - public WhatsAppTemplateList listWhatsAppTemplates(final int offset, final int limit) + public TemplateList listWhatsAppTemplates(final int offset, final int limit) throws UnauthorizedException, GeneralException { String url = String.format( "%s%s%s", @@ -1897,7 +1897,7 @@ public WhatsAppTemplateList listWhatsAppTemplates(final int offset, final int li INTEGRATIONS_WHATSAPP_PATH, TEMPLATES_PATH ); - return messageBirdService.requestList(url, offset, limit, WhatsAppTemplateList.class); + return messageBirdService.requestList(url, offset, limit, TemplateList.class); } /** @@ -1907,7 +1907,7 @@ public WhatsAppTemplateList listWhatsAppTemplates(final int offset, final int li * @throws UnauthorizedException if client is unauthorized * @throws GeneralException general exception */ - public WhatsAppTemplateList listWhatsAppTemplates() throws UnauthorizedException, GeneralException { + public TemplateList listWhatsAppTemplates() throws UnauthorizedException, GeneralException { final int offset = 0; final int limit = 10; @@ -1923,7 +1923,7 @@ public WhatsAppTemplateList listWhatsAppTemplates() throws UnauthorizedException * @throws GeneralException general exception * @throws NotFoundException if template name is not found */ - public List getWhatsAppTemplatesBy(final String templateName) + public List getWhatsAppTemplatesBy(final String templateName) throws GeneralException, UnauthorizedException, NotFoundException { if (templateName == null) { throw new IllegalArgumentException("Template name must be specified."); @@ -1936,7 +1936,7 @@ public List getWhatsAppTemplatesBy(final String templa TEMPLATES_PATH ); - return messageBirdService.requestByIdAsList(url, templateName, WhatsAppTemplateResponse.class); + return messageBirdService.requestByIdAsList(url, templateName, TemplateResponse.class); } /** @@ -1950,7 +1950,7 @@ public List getWhatsAppTemplatesBy(final String templa * @throws GeneralException general exception * @throws NotFoundException if template name and language are not found */ - public WhatsAppTemplateResponse fetchWhatsAppTemplateBy(final String templateName, final String language) + public TemplateResponse fetchWhatsAppTemplateBy(final String templateName, final String language) throws GeneralException, UnauthorizedException, NotFoundException { if (templateName == null || language == null) { throw new IllegalArgumentException("Template name and language must be specified."); @@ -1964,7 +1964,7 @@ public WhatsAppTemplateResponse fetchWhatsAppTemplateBy(final String templateNam templateName, language ); - return messageBirdService.request(url, WhatsAppTemplateResponse.class); + return messageBirdService.request(url, TemplateResponse.class); } diff --git a/api/src/main/java/com/messagebird/objects/integrations/WhatsAppTemplate.java b/api/src/main/java/com/messagebird/objects/integrations/Template.java similarity index 90% rename from api/src/main/java/com/messagebird/objects/integrations/WhatsAppTemplate.java rename to api/src/main/java/com/messagebird/objects/integrations/Template.java index 3d3ba755..6bcf145d 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/WhatsAppTemplate.java +++ b/api/src/main/java/com/messagebird/objects/integrations/Template.java @@ -4,22 +4,22 @@ import java.util.List; /** - * WhatsApp Template Object as integrations API request. + * Template Object as integrations API request. * * @see Integrations API * @author ssk910 */ -public class WhatsAppTemplate { +public class Template { private String name; private String language; private List components; private HSMCategory category; - public WhatsAppTemplate() { + public Template() { } - public WhatsAppTemplate(String name, String language, + public Template(String name, String language, List components, HSMCategory category) { this.name = name; this.language = language; diff --git a/api/src/main/java/com/messagebird/objects/integrations/WhatsAppTemplateList.java b/api/src/main/java/com/messagebird/objects/integrations/TemplateList.java similarity index 69% rename from api/src/main/java/com/messagebird/objects/integrations/WhatsAppTemplateList.java rename to api/src/main/java/com/messagebird/objects/integrations/TemplateList.java index 9e6e4894..5cea4023 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/WhatsAppTemplateList.java +++ b/api/src/main/java/com/messagebird/objects/integrations/TemplateList.java @@ -7,6 +7,6 @@ * * @author ssk910 */ -public class WhatsAppTemplateList extends ListBase { +public class TemplateList extends ListBase { } diff --git a/api/src/main/java/com/messagebird/objects/integrations/WhatsAppTemplateResponse.java b/api/src/main/java/com/messagebird/objects/integrations/TemplateResponse.java similarity index 94% rename from api/src/main/java/com/messagebird/objects/integrations/WhatsAppTemplateResponse.java rename to api/src/main/java/com/messagebird/objects/integrations/TemplateResponse.java index 687401b8..ac34efd0 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/WhatsAppTemplateResponse.java +++ b/api/src/main/java/com/messagebird/objects/integrations/TemplateResponse.java @@ -5,11 +5,11 @@ import java.util.List; /** - * WhatsApp Template response using integrations API. + * Template response using integrations API. * * @author ssk910 */ -public class WhatsAppTemplateResponse implements Serializable { +public class TemplateResponse implements Serializable { private static final long serialVersionUID = 7154209824478715861L; private String name; diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 73731f96..ea7ed524 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -4,19 +4,14 @@ import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; import com.messagebird.objects.*; -import com.messagebird.objects.integrations.WhatsAppTemplate; -import com.messagebird.objects.integrations.WhatsAppTemplateList; -import com.messagebird.objects.integrations.WhatsAppTemplateResponse; +import com.messagebird.objects.integrations.Template; +import com.messagebird.objects.integrations.TemplateList; +import com.messagebird.objects.integrations.TemplateResponse; import com.messagebird.objects.voicecalls.*; import java.util.ArrayList; -import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; import org.mockito.Mockito; import java.io.*; @@ -26,7 +21,6 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import org.mockito.stubbing.OngoingStubbing; import static com.messagebird.MessageBirdClient.*; import static org.junit.Assert.*; @@ -43,13 +37,6 @@ public class MessageBirdClientTest { MessageBirdServiceImpl messageBirdService; MessageBirdClient messageBirdClient; - @Captor - ArgumentCaptor argument = ArgumentCaptor.forClass(WhatsAppTemplateResponse.class); - - @Captor - ArgumentCaptor valueCaptor; - - @BeforeClass public static void setUpClass() { messageBirdAccessKey = System.getProperty("messageBirdAccessKey"); @@ -1066,8 +1053,8 @@ public void testDownloadFileWithNullBasePath() throws GeneralException, Unauthor @Test public void testCreateWhatsAppTemplate() throws UnauthorizedException, GeneralException { - final WhatsAppTemplateResponse templateResponse = TestUtil.createWhatsAppTemplateResponse("sample_template_name", "ko"); - final WhatsAppTemplate template = TestUtil.createWhatsAppTemplate("sample_template_name", "ko"); + final TemplateResponse templateResponse = TestUtil.createWhatsAppTemplateResponse("sample_template_name", "ko"); + final Template template = TestUtil.createWhatsAppTemplate("sample_template_name", "ko"); MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); @@ -1079,12 +1066,12 @@ public void testCreateWhatsAppTemplate() throws UnauthorizedException, GeneralEx TEMPLATES_PATH ); - when(messageBirdServiceMock.sendPayLoad(url, template, WhatsAppTemplateResponse.class)) + when(messageBirdServiceMock.sendPayLoad(url, template, TemplateResponse.class)) .thenReturn(templateResponse); - final WhatsAppTemplateResponse response = messageBirdClientInjectMock.createWhatsAppTemplate(template); + final TemplateResponse response = messageBirdClientInjectMock.createWhatsAppTemplate(template); - verify(messageBirdServiceMock, times(1)).sendPayLoad(url, template, WhatsAppTemplateResponse.class); + verify(messageBirdServiceMock, times(1)).sendPayLoad(url, template, TemplateResponse.class); assertNotNull(response); assertEquals(response.getName(), templateResponse.getName()); assertEquals(response.getLanguage(), templateResponse.getLanguage()); @@ -1103,7 +1090,7 @@ public void testCreateWhatsAppTemplate() throws UnauthorizedException, GeneralEx @Test public void testListWhatsAppTemplates() throws UnauthorizedException, GeneralException { - final WhatsAppTemplateList templateList = TestUtil.createWhatsAppTemplateList("sample_template_name"); + final TemplateList templateList = TestUtil.createWhatsAppTemplateList("sample_template_name"); MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); @@ -1114,11 +1101,11 @@ public void testListWhatsAppTemplates() throws UnauthorizedException, GeneralExc TEMPLATES_PATH ); - when(messageBirdServiceMock.requestList(url, 0, 0, WhatsAppTemplateList.class)) + when(messageBirdServiceMock.requestList(url, 0, 0, TemplateList.class)) .thenReturn(templateList); - final WhatsAppTemplateList response = messageBirdClientInjectMock.listWhatsAppTemplates(0, 0); - verify(messageBirdServiceMock, times(1)).requestList(url, 0, 0, WhatsAppTemplateList.class); + final TemplateList response = messageBirdClientInjectMock.listWhatsAppTemplates(0, 0); + verify(messageBirdServiceMock, times(1)).requestList(url, 0, 0, TemplateList.class); assertNotNull(response); for(int i = 0; i < response.getItems().size() ; i++) { assertReflectionEquals(response.getItems().get(i), templateList.getItems().get(i)); @@ -1129,9 +1116,9 @@ public void testListWhatsAppTemplates() throws UnauthorizedException, GeneralExc public void testGetWhatsAppTemplatesBy() throws GeneralException, UnauthorizedException, NotFoundException, ClassNotFoundException { final String templateName = "sample_template_name"; - final WhatsAppTemplateResponse templateResponse1 = TestUtil.createWhatsAppTemplateResponse(templateName, "en_US"); - final WhatsAppTemplateResponse templateResponse2 = TestUtil.createWhatsAppTemplateResponse("another_template", "en_US"); - final List templateList = new ArrayList<>(); + final TemplateResponse templateResponse1 = TestUtil.createWhatsAppTemplateResponse(templateName, "en_US"); + final TemplateResponse templateResponse2 = TestUtil.createWhatsAppTemplateResponse("another_template", "en_US"); + final List templateList = new ArrayList<>(); templateList.add(templateResponse1); templateList.add(templateResponse2); @@ -1145,11 +1132,11 @@ public void testGetWhatsAppTemplatesBy() TEMPLATES_PATH ); - when(messageBirdServiceMock.requestByIdAsList(url, templateName, WhatsAppTemplateResponse.class)) + when(messageBirdServiceMock.requestByIdAsList(url, templateName, TemplateResponse.class)) .thenReturn(templateList); - final List response = messageBirdClientInjectMock.getWhatsAppTemplatesBy(templateName); - verify(messageBirdServiceMock, times(1)).requestByIdAsList(url, templateName, WhatsAppTemplateResponse.class); + final List response = messageBirdClientInjectMock.getWhatsAppTemplatesBy(templateName); + verify(messageBirdServiceMock, times(1)).requestByIdAsList(url, templateName, TemplateResponse.class); assertNotNull(response); assertEquals(response.size(), templateList.size()); for(int i = 0; i < response.size() ; i++) { @@ -1162,7 +1149,7 @@ public void testFetchWhatsAppTemplateBy() throws UnauthorizedException, GeneralException, NotFoundException { final String templateName = "sample_template_name"; final String language = "ko"; - final WhatsAppTemplateResponse template = TestUtil.createWhatsAppTemplateResponse(templateName, language); + final TemplateResponse template = TestUtil.createWhatsAppTemplateResponse(templateName, language); MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); @@ -1176,11 +1163,11 @@ public void testFetchWhatsAppTemplateBy() language ); - when(messageBirdServiceMock.request(url, WhatsAppTemplateResponse.class)) + when(messageBirdServiceMock.request(url, TemplateResponse.class)) .thenReturn(template); - final WhatsAppTemplateResponse response = messageBirdClientInjectMock.fetchWhatsAppTemplateBy(templateName, language); - verify(messageBirdServiceMock, times(1)).request(url, WhatsAppTemplateResponse.class); + final TemplateResponse response = messageBirdClientInjectMock.fetchWhatsAppTemplateBy(templateName, language); + verify(messageBirdServiceMock, times(1)).request(url, TemplateResponse.class); assertNotNull(response); assertEquals(response.getName(), template.getName()); assertEquals(response.getLanguage(), template.getLanguage()); diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index 07072aff..9cf0b2b9 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -10,9 +10,9 @@ import com.messagebird.objects.integrations.HSMComponentType; import com.messagebird.objects.integrations.HSMExample; import com.messagebird.objects.integrations.HSMStatus; -import com.messagebird.objects.integrations.WhatsAppTemplate; -import com.messagebird.objects.integrations.WhatsAppTemplateList; -import com.messagebird.objects.integrations.WhatsAppTemplateResponse; +import com.messagebird.objects.integrations.Template; +import com.messagebird.objects.integrations.TemplateList; +import com.messagebird.objects.integrations.TemplateResponse; import com.messagebird.objects.voicecalls.*; import java.util.*; @@ -302,8 +302,8 @@ private static HSMComponent createHSMComponentButton() { return buttonComponent; } - public static WhatsAppTemplateResponse createWhatsAppTemplateResponse(final String templateName, final String language) { - final WhatsAppTemplateResponse templateResponse = new WhatsAppTemplateResponse(); + public static TemplateResponse createWhatsAppTemplateResponse(final String templateName, final String language) { + final TemplateResponse templateResponse = new TemplateResponse(); templateResponse.setName(templateName); templateResponse.setLanguage(language); templateResponse.setCategory(HSMCategory.ACCOUNT_UPDATE); @@ -321,8 +321,8 @@ public static WhatsAppTemplateResponse createWhatsAppTemplateResponse(final Stri return templateResponse; } - public static WhatsAppTemplate createWhatsAppTemplate(final String templateName, final String language) { - final WhatsAppTemplate template = new WhatsAppTemplate(); + public static Template createWhatsAppTemplate(final String templateName, final String language) { + final Template template = new Template(); template.setName(templateName); template.setLanguage(language); template.setCategory(HSMCategory.ACCOUNT_UPDATE); @@ -337,12 +337,12 @@ public static WhatsAppTemplate createWhatsAppTemplate(final String templateName, return template; } - public static WhatsAppTemplateList createWhatsAppTemplateList(final String templateName) { - final WhatsAppTemplateResponse template1 = TestUtil.createWhatsAppTemplateResponse(templateName, "en_US"); - final WhatsAppTemplateResponse template2 = TestUtil.createWhatsAppTemplateResponse(templateName, "ko"); - final WhatsAppTemplateList templateList = new WhatsAppTemplateList(); + public static TemplateList createWhatsAppTemplateList(final String templateName) { + final TemplateResponse template1 = TestUtil.createWhatsAppTemplateResponse(templateName, "en_US"); + final TemplateResponse template2 = TestUtil.createWhatsAppTemplateResponse(templateName, "ko"); + final TemplateList templateList = new TemplateList(); - List templateResponseList = new ArrayList<>(); + List templateResponseList = new ArrayList<>(); templateResponseList.add(template1); templateResponseList.add(template2); diff --git a/examples/src/main/java/ExampleCreateTemplate.java b/examples/src/main/java/ExampleCreateTemplate.java index 275c5bab..8e2d9887 100644 --- a/examples/src/main/java/ExampleCreateTemplate.java +++ b/examples/src/main/java/ExampleCreateTemplate.java @@ -10,8 +10,8 @@ import com.messagebird.objects.integrations.HSMComponentFormat; import com.messagebird.objects.integrations.HSMComponentType; import com.messagebird.objects.integrations.HSMExample; -import com.messagebird.objects.integrations.WhatsAppTemplate; -import com.messagebird.objects.integrations.WhatsAppTemplateResponse; +import com.messagebird.objects.integrations.Template; +import com.messagebird.objects.integrations.TemplateResponse; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -75,7 +75,7 @@ public static void main(String[] args) { buttonComponent.setButtons(buttons); /* set components */ - final WhatsAppTemplate template = new WhatsAppTemplate(); + final Template template = new Template(); final List components = new ArrayList<>(); components.add(headerComponent); components.add(bodyComponent); @@ -88,7 +88,7 @@ public static void main(String[] args) { template.setCategory(HSMCategory.ACCOUNT_UPDATE); try { - WhatsAppTemplateResponse response = messageBirdClient.createWhatsAppTemplate(template); + TemplateResponse response = messageBirdClient.createWhatsAppTemplate(template); System.out.println(response.toString()); } catch (GeneralException | UnauthorizedException exception) { exception.printStackTrace(); diff --git a/examples/src/main/java/ExampleFetchTemplateByNameAndLanguage.java b/examples/src/main/java/ExampleFetchTemplateByNameAndLanguage.java index e1ad9bb6..02377ed0 100644 --- a/examples/src/main/java/ExampleFetchTemplateByNameAndLanguage.java +++ b/examples/src/main/java/ExampleFetchTemplateByNameAndLanguage.java @@ -4,7 +4,7 @@ import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; -import com.messagebird.objects.integrations.WhatsAppTemplateResponse; +import com.messagebird.objects.integrations.TemplateResponse; /** * Fetch template by name and language @@ -32,7 +32,7 @@ public static void main(String[] args) { try { System.out.println("Fetching WhatsApp Template list by {name: " + templateName + ", language: " + language + "}"); - final WhatsAppTemplateResponse template = messageBirdClient.fetchWhatsAppTemplateBy(templateName, language); + final TemplateResponse template = messageBirdClient.fetchWhatsAppTemplateBy(templateName, language); System.out.println(template.toString()); } catch (GeneralException | UnauthorizedException | NotFoundException exception) { exception.printStackTrace(); diff --git a/examples/src/main/java/ExampleListTemplates.java b/examples/src/main/java/ExampleListTemplates.java index db9fc21b..b91b2ec2 100644 --- a/examples/src/main/java/ExampleListTemplates.java +++ b/examples/src/main/java/ExampleListTemplates.java @@ -3,7 +3,7 @@ import com.messagebird.MessageBirdServiceImpl; import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.UnauthorizedException; -import com.messagebird.objects.integrations.WhatsAppTemplateList; +import com.messagebird.objects.integrations.TemplateList; /** * List templates @@ -27,7 +27,7 @@ public static void main(String[] args) { try { System.out.println("Retrieving WhatsApp Template list"); - final WhatsAppTemplateList templateList = messageBirdClient.listWhatsAppTemplates(); + final TemplateList templateList = messageBirdClient.listWhatsAppTemplates(); System.out.println(templateList.toString()); } catch (GeneralException | UnauthorizedException exception) { exception.printStackTrace(); diff --git a/examples/src/main/java/ExampleListTemplatesByName.java b/examples/src/main/java/ExampleListTemplatesByName.java index e68a6446..36159796 100644 --- a/examples/src/main/java/ExampleListTemplatesByName.java +++ b/examples/src/main/java/ExampleListTemplatesByName.java @@ -4,7 +4,7 @@ import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; -import com.messagebird.objects.integrations.WhatsAppTemplateResponse; +import com.messagebird.objects.integrations.TemplateResponse; import java.util.List; /** @@ -32,7 +32,7 @@ public static void main(String[] args) { try { System.out.println("Retrieving WhatsApp Template list by name : " + templateName); - final List templateList = messageBirdClient.getWhatsAppTemplatesBy(templateName); + final List templateList = messageBirdClient.getWhatsAppTemplatesBy(templateName); System.out.println(templateList.toString()); } catch (GeneralException | UnauthorizedException | NotFoundException exception) { exception.printStackTrace(); From ef2bd682e43fda6a5c00c255509d64ca7f5141a6 Mon Sep 17 00:00:00 2001 From: ssk910 Date: Thu, 7 Oct 2021 21:14:56 +0900 Subject: [PATCH 318/516] feat: Add more validations for required fields in Template #160 --- .../com/messagebird/MessageBirdClient.java | 7 +- .../objects/integrations/HSMComponent.java | 25 +++--- .../integrations/HSMComponentButton.java | 7 +- .../objects/integrations/Template.java | 80 +++++++++++++++---- 4 files changed, 84 insertions(+), 35 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index d463488a..920f8a86 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1864,11 +1864,12 @@ public String downloadFile(String id, String filename, String basePath) throws G * * @param template {@link Template} object to be created * @return {@link TemplateResponse} response object - * @throws UnauthorizedException if client is unauthorized - * @throws GeneralException general exception or invalid template format + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + * @throws IllegalArgumentException invalid template format */ public TemplateResponse createWhatsAppTemplate(final Template template) - throws UnauthorizedException, GeneralException { + throws UnauthorizedException, GeneralException, IllegalArgumentException { template.validate(); String url = String.format( diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java b/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java index eb6b5694..51b7efba 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java @@ -1,6 +1,5 @@ package com.messagebird.objects.integrations; -import com.messagebird.exceptions.GeneralException; import java.util.List; /** @@ -71,9 +70,9 @@ public String toString() { /** * Check if this component is valid. * - * @throws GeneralException Occurs when validation is not passed. + * @throws IllegalArgumentException Occurs when validation is not passed. */ - public void validateComponent() throws GeneralException { + public void validateComponent() throws IllegalArgumentException { this.validateButtons(); this.validateComponentExample(); } @@ -81,9 +80,9 @@ public void validateComponent() throws GeneralException { /** * Check if button list is valid. * - * @throws GeneralException Occurs when validation is not passed. + * @throws IllegalArgumentException Occurs when validation is not passed. */ - private void validateButtons() throws GeneralException { + private void validateButtons() throws IllegalArgumentException { if (this.buttons == null) { return; } @@ -96,9 +95,9 @@ private void validateButtons() throws GeneralException { /** * Check for header_text and header_url. * - * @throws GeneralException Occurs when {@code header_text} or {@code header_url} is not able to use. + * @throws IllegalArgumentException Occurs when {@code header_text} or {@code header_url} is not able to use. */ - private void validateComponentExample() throws GeneralException { + private void validateComponentExample() throws IllegalArgumentException { final boolean isExampleNotNull = this.example != null; final boolean isHeaderTextNotEmpty = isExampleNotNull && !(this.example.getHeader_text() == null || this.example.getHeader_text() @@ -119,26 +118,26 @@ private void validateComponentExample() throws GeneralException { /** * Check if header_text is able to use. * - * @throws GeneralException Occurs when type is not {@code HEADER} and format is not {@code TEXT}. + * @throws IllegalArgumentException Occurs when type is not {@code HEADER} and format is not {@code TEXT}. */ - private void checkHeaderText() throws GeneralException { + private void checkHeaderText() throws IllegalArgumentException { if (!(type.equals(HSMComponentType.HEADER) && format.equals(HSMComponentFormat.TEXT)) ) { - throw new GeneralException("\"header_text\" is available for only HEADER type and TEXT format."); + throw new IllegalArgumentException("\"header_text\" is available for only HEADER type and TEXT format."); } } /** * Check if header_url is able to use. * - * @throws GeneralException Occurs when type is not {@code HEADER} and format is not {@code IMAGE}. + * @throws IllegalArgumentException Occurs when type is not {@code HEADER} and format is not {@code IMAGE}. */ - private void checkHeaderUrl() throws GeneralException { + private void checkHeaderUrl() throws IllegalArgumentException { if (!(type.equals(HSMComponentType.HEADER) && format.equals(HSMComponentFormat.IMAGE)) ) { - throw new GeneralException("\"header_url\" is available for only HEADER type and IMAGE format."); + throw new IllegalArgumentException("\"header_url\" is available for only HEADER type and IMAGE format."); } } } diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButton.java b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButton.java index 02dd241c..6438f79e 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButton.java +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButton.java @@ -1,6 +1,5 @@ package com.messagebird.objects.integrations; -import com.messagebird.exceptions.GeneralException; import java.util.List; /** @@ -71,9 +70,9 @@ public String toString() { /** * Check if example field is able to use. * - * @throws GeneralException Occurs if button type is not {@code URL} or {@code QUICK_REPLY}. + * @throws IllegalArgumentException Occurs if button type is not {@code URL} or {@code QUICK_REPLY}. */ - public void validateButtonExample() throws GeneralException { + public void validateButtonExample() throws IllegalArgumentException { final boolean isExampleEmpty = this.example == null || this.example.isEmpty(); final boolean isNotProperType = !(this.type.equals(HSMComponentButtonType.URL) || this.type.equals(HSMComponentButtonType.QUICK_REPLY)); @@ -83,7 +82,7 @@ public void validateButtonExample() throws GeneralException { } if (isNotProperType) { - throw new GeneralException("An example field in HSMComponentButton is available for only URL or QUICK_REPLY button types."); + throw new IllegalArgumentException("An example field in HSMComponentButton is available for only URL or QUICK_REPLY button types."); } } } diff --git a/api/src/main/java/com/messagebird/objects/integrations/Template.java b/api/src/main/java/com/messagebird/objects/integrations/Template.java index 6bcf145d..715aeb48 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/Template.java +++ b/api/src/main/java/com/messagebird/objects/integrations/Template.java @@ -1,6 +1,5 @@ package com.messagebird.objects.integrations; -import com.messagebird.exceptions.GeneralException; import java.util.List; /** @@ -59,28 +58,79 @@ public void setCategory(HSMCategory category) { this.category = category; } + @Override + public String toString() { + return "WhatsAppTemplate{" + + "name='" + name + '\'' + + ", language='" + language + '\'' + + ", components=" + components + + ", category='" + category + '\'' + + '}'; + } + + /** + * Validate required fields: components, name, language, category + * + * @throws IllegalArgumentException if required fields are invalid. + */ + public void validate() throws IllegalArgumentException { + this.validateComponents(); + this.validateName(); + this.validateLanguage(); + this.validateCategory(); + } + /** * Check if components field is valid. * - * @throws GeneralException Occurs when it is invalid. + * @throws IllegalArgumentException If components field is null or empty list. */ - public void validate() throws GeneralException { - if (this.components == null) { - return; + private void validateComponents() throws IllegalArgumentException { + final boolean componentsNotEmpty = !(this.components == null || this.components.isEmpty()); + + if (componentsNotEmpty) { + for (final HSMComponent component : this.components) { + component.validateComponent(); + } + } else { + throw new IllegalArgumentException("A \"components\" field is required and should not be empty list."); } + } - for (final HSMComponent component : this.components) { - component.validateComponent(); + /** + * Check if name field is valid. + * + * @throws IllegalArgumentException If name field is null or empty string. + */ + private void validateName() { + if (this.name == null) { + throw new IllegalArgumentException("A \"name\" field is required."); + } else if (this.name.length() == 0) { + throw new IllegalArgumentException("A \"name\" field can not be an empty string."); } } - @Override - public String toString() { - return "WhatsAppTemplate{" + - "name='" + name + '\'' + - ", language='" + language + '\'' + - ", components=" + components + - ", category='" + category + '\'' + - '}'; + /** + * Check if language field is valid. + * + * @throws IllegalArgumentException If language field is null or empty string. + */ + private void validateLanguage() { + if (this.language == null) { + throw new IllegalArgumentException("A \"language\" field is required."); + } else if (this.language.length() == 0) { + throw new IllegalArgumentException("A \"language\" field can not be an empty string."); + } + } + + /** + * Check if category field is valid. + * + * @throws IllegalArgumentException If category field is null. + */ + private void validateCategory() { + if (this.category == null) { + throw new IllegalArgumentException("A \"category\" field is required."); + } } } From e528447951c8f19cc690e5ded657ff5595e777a6 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Fri, 8 Oct 2021 10:27:53 +0200 Subject: [PATCH 319/516] partners api implemented --- .../com/messagebird/MessageBirdClient.java | 117 +++++++++++++----- .../com/messagebird/objects/AccessKey.java | 31 +++++ .../objects/ChildAccountCreateResponse.java | 51 ++++++++ .../objects/ChildAccountDetailedResponse.java | 13 ++ .../objects/ChildAccountResponse.java | 22 ++++ .../objects/PartnerAccountsResponse.java | 15 +++ .../messagebird/MessageBirdClientTest.java | 82 ++++++++++++ .../test/java/com/messagebird/TestUtil.java | 39 ++++++ .../main/java/ExampleCreateChildAccount.java | 26 ++++ .../main/java/ExampleDeleteChildAccount.java | 27 ++++ .../main/java/ExampleGetChildAccountById.java | 26 ++++ .../main/java/ExampleGetChildAccounts.java | 24 ++++ .../main/java/ExampleUpdateChildAccount.java | 25 ++++ 13 files changed, 468 insertions(+), 30 deletions(-) create mode 100644 api/src/main/java/com/messagebird/objects/AccessKey.java create mode 100644 api/src/main/java/com/messagebird/objects/ChildAccountCreateResponse.java create mode 100644 api/src/main/java/com/messagebird/objects/ChildAccountDetailedResponse.java create mode 100644 api/src/main/java/com/messagebird/objects/ChildAccountResponse.java create mode 100644 api/src/main/java/com/messagebird/objects/PartnerAccountsResponse.java create mode 100644 examples/src/main/java/ExampleCreateChildAccount.java create mode 100644 examples/src/main/java/ExampleDeleteChildAccount.java create mode 100644 examples/src/main/java/ExampleGetChildAccountById.java create mode 100644 examples/src/main/java/ExampleGetChildAccounts.java create mode 100644 examples/src/main/java/ExampleUpdateChildAccount.java diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 0bff2580..378cf334 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -3,35 +3,7 @@ import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; -import com.messagebird.objects.Balance; -import com.messagebird.objects.Contact; -import com.messagebird.objects.ContactList; -import com.messagebird.objects.ContactRequest; -import com.messagebird.objects.ErrorReport; -import com.messagebird.objects.FileUploadResponse; -import com.messagebird.objects.Group; -import com.messagebird.objects.GroupList; -import com.messagebird.objects.GroupRequest; -import com.messagebird.objects.Hlr; -import com.messagebird.objects.Lookup; -import com.messagebird.objects.LookupHlr; -import com.messagebird.objects.Message; -import com.messagebird.objects.MessageList; -import com.messagebird.objects.MessageResponse; -import com.messagebird.objects.MsgType; -import com.messagebird.objects.PagedPaging; -import com.messagebird.objects.PhoneNumbersLookup; -import com.messagebird.objects.PhoneNumbersResponse; -import com.messagebird.objects.PurchasedNumber; -import com.messagebird.objects.PurchasedNumberCreatedResponse; -import com.messagebird.objects.PurchasedNumbersResponse; -import com.messagebird.objects.PurchasedNumbersFilter; -import com.messagebird.objects.Verify; -import com.messagebird.objects.VerifyMessage; -import com.messagebird.objects.VerifyRequest; -import com.messagebird.objects.VoiceMessage; -import com.messagebird.objects.VoiceMessageList; -import com.messagebird.objects.VoiceMessageResponse; +import com.messagebird.objects.*; import com.messagebird.objects.conversations.Conversation; import com.messagebird.objects.conversations.ConversationList; import com.messagebird.objects.conversations.ConversationMessage; @@ -103,6 +75,7 @@ public class MessageBirdClient { static final String NUMBERS_CALLS_BASE_URL = "https://numbers.messagebird.com/v1"; static final String MESSAGING_BASE_URL = "https://messaging.messagebird.com/v1"; private static String[] supportedLanguages = {"de-DE", "en-AU", "en-UK", "en-US", "es-ES", "es-LA", "fr-FR", "it-IT", "nl-NL", "pt-BR"}; + static final String PARTNER_ACCOUNTS_BASE_URL = "https://partner-accounts.messagebird.com"; private static final String BALANCEPATH = "/balance"; private static final String CONTACTPATH = "/contacts"; @@ -496,7 +469,7 @@ Verify getVerifyObject(String id) throws NotFoundException, GeneralException, Un } /** - * @param id id is for the email message part of a verify object + * @param messageId is for the email message part of a verify object * @return Verify object * @throws NotFoundException if id is not found * @throws UnauthorizedException if client is unauthorized @@ -1848,4 +1821,88 @@ public String downloadFile(String id, String filename, String basePath) throws G final String url = String.format("%s%s/%s", MESSAGING_BASE_URL, FILES_PATH, id); return messageBirdService.getBinaryData(url, basePath, filename); } + + /** + * Function to create a child account + * + * @param name of child account to create + * @return ChildAccountResponse created + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + */ + public ChildAccountCreateResponse createChildAccount(String name) throws UnauthorizedException, GeneralException { + if (name == null) { + throw new IllegalArgumentException("Name must be specified."); + } + + String url = String.format("%s%s", PARTNER_ACCOUNTS_BASE_URL, "/child-accounts"); + return messageBirdService.sendPayLoad(url, name, ChildAccountCreateResponse.class); + } + + /** + * Function to update a child account + * + * @param id of child account to update + * @return ChildAccountResponse created + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + */ + public ChildAccountResponse updateChildAccount(String name, String id) throws UnauthorizedException, GeneralException { + if (name == null) { + throw new IllegalArgumentException("Name must be specified."); + } + + if (id == null) { + throw new IllegalArgumentException("Child account id must be specified."); + } + + final String url = String.format("%s/child-accounts/%s", PARTNER_ACCOUNTS_BASE_URL, id); + return messageBirdService.sendPayLoad("PATCH", url, name, ChildAccountResponse.class); + } + + /** + * Function to get a child account + * + * @param id of child account to update + * @return ChildAccountResponse created + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + * @throws NotFoundException if id is not found + */ + public ChildAccountDetailedResponse getChildAccountById(String id) throws UnauthorizedException, GeneralException, NotFoundException { + if (id == null) { + throw new IllegalArgumentException("Child account id must be specified."); + } + + return messageBirdService.requestByID(PARTNER_ACCOUNTS_BASE_URL, id, ChildAccountDetailedResponse.class); + } + + /** + * Function to get a child account + * + * @return ChildAccountResponse created + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + */ + public PartnerAccountsResponse getChildAccounts(final Integer offset, final Integer limit) throws UnauthorizedException, GeneralException { + verifyOffsetAndLimit(offset, limit); + return messageBirdService.requestList(PARTNER_ACCOUNTS_BASE_URL, offset, limit, PartnerAccountsResponse.class); + } + + /** + * Function to delete a child account + * + * @param id of child account to delete + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + * @throws NotFoundException if id is not found + */ + public void deleteChildAccount(String id) throws UnauthorizedException, GeneralException, NotFoundException { + if (id == null) { + throw new IllegalArgumentException("Child account id must be specified."); + } + + String url = String.format("%s/child-accounts/%s", PARTNER_ACCOUNTS_BASE_URL, id); + messageBirdService.deleteByID(url, id); + } } diff --git a/api/src/main/java/com/messagebird/objects/AccessKey.java b/api/src/main/java/com/messagebird/objects/AccessKey.java new file mode 100644 index 00000000..14505dc7 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/AccessKey.java @@ -0,0 +1,31 @@ +package com.messagebird.objects; + +public class AccessKey { + private String id; + private String key; + private String mod; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getMod() { + return mod; + } + + public void setMod(String mod) { + this.mod = mod; + } +} diff --git a/api/src/main/java/com/messagebird/objects/ChildAccountCreateResponse.java b/api/src/main/java/com/messagebird/objects/ChildAccountCreateResponse.java new file mode 100644 index 00000000..768fd71f --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/ChildAccountCreateResponse.java @@ -0,0 +1,51 @@ +package com.messagebird.objects; + +import java.util.List; + +public class ChildAccountCreateResponse { + private String id; + private String name; + private List accessKeys; + private String signingKey; + private String invoiceAggregation; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getAccessKeys() { + return accessKeys; + } + + public void setAccessKeys(List accessKeys) { + this.accessKeys = accessKeys; + } + + public String getSigningKey() { + return signingKey; + } + + public void setSigningKey(String signingKey) { + this.signingKey = signingKey; + } + + public String getInvoiceAggregation() { + return invoiceAggregation; + } + + public void setInvoiceAggregation(String invoiceAggregation) { + this.invoiceAggregation = invoiceAggregation; + } +} diff --git a/api/src/main/java/com/messagebird/objects/ChildAccountDetailedResponse.java b/api/src/main/java/com/messagebird/objects/ChildAccountDetailedResponse.java new file mode 100644 index 00000000..d3aac825 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/ChildAccountDetailedResponse.java @@ -0,0 +1,13 @@ +package com.messagebird.objects; + +public class ChildAccountDetailedResponse extends ChildAccountResponse{ + private String invoiceAggregation; + + public String getInvoiceAggregation() { + return invoiceAggregation; + } + + public void setInvoiceAggregation(String invoiceAggregation) { + this.invoiceAggregation = invoiceAggregation; + } +} diff --git a/api/src/main/java/com/messagebird/objects/ChildAccountResponse.java b/api/src/main/java/com/messagebird/objects/ChildAccountResponse.java new file mode 100644 index 00000000..2e4853aa --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/ChildAccountResponse.java @@ -0,0 +1,22 @@ +package com.messagebird.objects; + +public class ChildAccountResponse { + private String id; + private String name; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/api/src/main/java/com/messagebird/objects/PartnerAccountsResponse.java b/api/src/main/java/com/messagebird/objects/PartnerAccountsResponse.java new file mode 100644 index 00000000..410cd360 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/PartnerAccountsResponse.java @@ -0,0 +1,15 @@ +package com.messagebird.objects; + +import java.util.List; + +public class PartnerAccountsResponse { + private List childAccountResponses; + + public List getChildAccountResponses() { + return childAccountResponses; + } + + public void setChildAccountResponses(List childAccountResponses) { + this.childAccountResponses = childAccountResponses; + } +} diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 956b177b..457cd94e 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -19,6 +19,7 @@ import java.util.Map; import static com.messagebird.MessageBirdClient.*; +import static com.messagebird.TestUtil.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; import static org.unitils.reflectionassert.ReflectionAssert.assertReflectionEquals; @@ -1042,4 +1043,85 @@ public void testDownloadFileWithNullBasePath() throws GeneralException, Unauthor String url = MESSAGING_BASE_URL + FILES_PATH + "/" + id; verify(messageBirdServiceMock, times(1)).getBinaryData(url, null, filename); } + + @Test + public void testCreateChildAccounts() throws GeneralException, UnauthorizedException { + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + ChildAccountCreateResponse childAccountCreateResponse = createChildAccountCreateResponse(); + when(messageBirdServiceMock.sendPayLoad(PARTNER_ACCOUNTS_BASE_URL + "/child-accounts" , "name", ChildAccountCreateResponse.class)) + .thenReturn(childAccountCreateResponse); + final ChildAccountCreateResponse response = messageBirdClientInjectMock.createChildAccount("name"); + + verify(messageBirdServiceMock, times(1)) + .sendPayLoad(PARTNER_ACCOUNTS_BASE_URL + "/child-accounts" , "name", ChildAccountCreateResponse.class); + assertNotNull(response); + assertEquals(response.getId(), childAccountCreateResponse.getId()); + assertEquals(response.getName(), childAccountCreateResponse.getName()); + assertEquals(response.getInvoiceAggregation(), childAccountCreateResponse.getInvoiceAggregation()); + assertEquals(response.getSigningKey(), childAccountCreateResponse.getSigningKey()); + assertEquals(response.getAccessKeys().get(0).getId(), childAccountCreateResponse.getAccessKeys().get(0).getId()); + assertEquals(response.getAccessKeys().get(0).getKey(), childAccountCreateResponse.getAccessKeys().get(0).getKey()); + assertEquals(response.getAccessKeys().get(0).getMod(), childAccountCreateResponse.getAccessKeys().get(0).getMod()); + } + + @Test + public void testGetChildAccount() throws GeneralException, UnauthorizedException, NotFoundException { + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + ChildAccountDetailedResponse childAccountDetailedResponse = createChildAccountDetailedResponse(); + when(messageBirdServiceMock.requestByID(PARTNER_ACCOUNTS_BASE_URL, "ANY_ID", ChildAccountDetailedResponse.class)) + .thenReturn(childAccountDetailedResponse); + ChildAccountDetailedResponse response = messageBirdClientInjectMock.getChildAccountById("ANY_ID"); + + verify(messageBirdServiceMock, times(1)) + .requestByID(PARTNER_ACCOUNTS_BASE_URL, "ANY_ID", ChildAccountDetailedResponse.class); + assertNotNull(response); + assertEquals(response.getId(), childAccountDetailedResponse.getId()); + assertEquals(response.getName(), childAccountDetailedResponse.getName()); + assertEquals(response.getInvoiceAggregation(), childAccountDetailedResponse.getInvoiceAggregation()); + } + + @Test + public void testGetChildAccounts() throws GeneralException, UnauthorizedException { + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + PartnerAccountsResponse partnerAccountsResponse = createPartnerAccountsResponse(); + when(messageBirdServiceMock.requestList(PARTNER_ACCOUNTS_BASE_URL, 1, 10, PartnerAccountsResponse.class)) + .thenReturn(partnerAccountsResponse); + + PartnerAccountsResponse response = messageBirdClientInjectMock.getChildAccounts(1, 10); + + verify(messageBirdServiceMock, times(1)) + .requestList(PARTNER_ACCOUNTS_BASE_URL, 1, 10, PartnerAccountsResponse.class); + assertNotNull(response); + assertEquals(response.getChildAccountResponses().get(0).getId(), partnerAccountsResponse.getChildAccountResponses().get(0).getId()); + assertEquals(response.getChildAccountResponses().get(0).getName(), partnerAccountsResponse.getChildAccountResponses().get(0).getName()); + } + + @Test + public void testUpdateChildAccount() throws GeneralException, UnauthorizedException { + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + ChildAccountResponse childAccountResponse = createChildAccountResponse(); + final String url = String.format("%s/child-accounts/%s", PARTNER_ACCOUNTS_BASE_URL, "ANY_ID"); + when(messageBirdServiceMock.sendPayLoad("PATCH", url, "ANY_NAME", ChildAccountResponse.class)) + .thenReturn(childAccountResponse); + ChildAccountResponse response = messageBirdClientInjectMock.updateChildAccount("ANY_NAME", "ANY_ID"); + + verify(messageBirdServiceMock, times(1)) + .sendPayLoad("PATCH", url, "ANY_NAME", ChildAccountResponse.class); + assertNotNull(response); + assertEquals(response.getId(), childAccountResponse.getId()); + assertEquals(response.getName(), childAccountResponse.getName()); + } + + @Test + public void testDeleteChildAccount() throws GeneralException, UnauthorizedException, NotFoundException { + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + String url = String.format("%s/child-accounts/%s", PARTNER_ACCOUNTS_BASE_URL, "ANY_ID"); + doNothing().when(messageBirdServiceMock).deleteByID(url, "ANY_ID"); + messageBirdClientInjectMock.deleteChildAccount("id"); + } } diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index 5a854b45..fef25193 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -240,4 +240,43 @@ static ConversationWebhookCreateRequest createConversationWebhookRequest() { ) ); } + + public static ChildAccountCreateResponse createChildAccountCreateResponse() { + final AccessKey accessKey = new AccessKey(); + accessKey.setId("ANY_ID"); + accessKey.setKey("ANY_KEY"); + accessKey.setMod("ANY_MOD"); + + final ChildAccountCreateResponse childAccountCreateResponse = new ChildAccountCreateResponse(); + childAccountCreateResponse.setId("ANY_ID"); + childAccountCreateResponse.setName("ANY_NAME"); + childAccountCreateResponse.setAccessKeys(Collections.singletonList(accessKey)); + childAccountCreateResponse.setInvoiceAggregation("ANY_INVOICE_AGGREGATION"); + childAccountCreateResponse.setSigningKey("ANY_SIGNING_KEY"); + + return childAccountCreateResponse; + } + + public static ChildAccountDetailedResponse createChildAccountDetailedResponse(){ + final ChildAccountDetailedResponse childAccountDetailedResponse = new ChildAccountDetailedResponse(); + childAccountDetailedResponse.setId("ANY_ID"); + childAccountDetailedResponse.setName("ANY_NAME"); + childAccountDetailedResponse.setInvoiceAggregation("ANY_INVOICE_AGGREGATION"); + return childAccountDetailedResponse; + } + + public static ChildAccountResponse createChildAccountResponse(){ + final ChildAccountResponse childAccountResponse = new ChildAccountResponse(); + childAccountResponse.setId("ANY_ID"); + childAccountResponse.setName("ANY_NAME"); + return childAccountResponse; + } + + public static PartnerAccountsResponse createPartnerAccountsResponse(){ + final ChildAccountResponse childAccountResponse = createChildAccountResponse(); + final PartnerAccountsResponse partnerAccountsResponse = new PartnerAccountsResponse(); + partnerAccountsResponse.setChildAccountResponses(Collections.singletonList(childAccountResponse)); + return partnerAccountsResponse; + } + } diff --git a/examples/src/main/java/ExampleCreateChildAccount.java b/examples/src/main/java/ExampleCreateChildAccount.java new file mode 100644 index 00000000..e4ec5df7 --- /dev/null +++ b/examples/src/main/java/ExampleCreateChildAccount.java @@ -0,0 +1,26 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; + +public class ExampleCreateChildAccount { + public static void main(String[] args) { + if (args.length < 2) { + System.out.println("Please specify your access key and name of child account arguments"); + return; + } + + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + System.out.println("Creating a child account of partner accounts"); + messageBirdClient.createChildAccount(args[1]); + System.out.println("Child account is created"); + + } catch (GeneralException | UnauthorizedException exception) { + exception.printStackTrace(); + } + } +} diff --git a/examples/src/main/java/ExampleDeleteChildAccount.java b/examples/src/main/java/ExampleDeleteChildAccount.java new file mode 100644 index 00000000..2724a59a --- /dev/null +++ b/examples/src/main/java/ExampleDeleteChildAccount.java @@ -0,0 +1,27 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; + +public class ExampleDeleteChildAccount { + public static void main(String[] args) { + if (args.length < 2) { + System.out.println("Please specify your access key and id of child account arguments"); + return; + } + + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + System.out.println("Deleting a child account of partner accounts"); + messageBirdClient.deleteChildAccount(args[1]); + System.out.println("Child account is deleted"); + + } catch (GeneralException | UnauthorizedException | NotFoundException exception) { + exception.printStackTrace(); + } + } +} diff --git a/examples/src/main/java/ExampleGetChildAccountById.java b/examples/src/main/java/ExampleGetChildAccountById.java new file mode 100644 index 00000000..ae1acbc9 --- /dev/null +++ b/examples/src/main/java/ExampleGetChildAccountById.java @@ -0,0 +1,26 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; + +public class ExampleGetChildAccountById { + public static void main(String[] args) { + if (args.length < 2) { + System.out.println("Please specify your access key and id of child account arguments"); + return; + } + + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + System.out.println("Get a child account by id"); + messageBirdClient.getChildAccountById(args[1]); + + } catch (GeneralException | UnauthorizedException | NotFoundException exception) { + exception.printStackTrace(); + } + } +} diff --git a/examples/src/main/java/ExampleGetChildAccounts.java b/examples/src/main/java/ExampleGetChildAccounts.java new file mode 100644 index 00000000..5d7be592 --- /dev/null +++ b/examples/src/main/java/ExampleGetChildAccounts.java @@ -0,0 +1,24 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; + +public class ExampleGetChildAccounts { + public static void main(String[] args) { + if (args.length < 2) { + System.out.println("Please specify your access key, offset, limit arguments"); + return; + } + + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + System.out.println("Get a child accounts of partner account"); + messageBirdClient.getChildAccounts(Integer.valueOf(args[1]), Integer.valueOf(args[2])); + } catch (GeneralException | UnauthorizedException exception) { + exception.printStackTrace(); + } + } +} diff --git a/examples/src/main/java/ExampleUpdateChildAccount.java b/examples/src/main/java/ExampleUpdateChildAccount.java new file mode 100644 index 00000000..e90b9b51 --- /dev/null +++ b/examples/src/main/java/ExampleUpdateChildAccount.java @@ -0,0 +1,25 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; + +public class ExampleUpdateChildAccount { + public static void main(String[] args) { + if (args.length < 2) { + System.out.println("Please specify your access key, name of child account, id of child account parameters"); + return; + } + + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + System.out.println("Updating a child account"); + messageBirdClient.updateChildAccount(args[1], args[2]); + System.out.println("Child account is updated"); + } catch (GeneralException | UnauthorizedException exception) { + exception.printStackTrace(); + } + } +} From 7dfcb052dd3366dddbc170b3425347dbb41d4a65 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Fri, 8 Oct 2021 11:05:20 +0200 Subject: [PATCH 320/516] updated after review --- .../objects/ChildAccountCreateResponse.java | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/ChildAccountCreateResponse.java b/api/src/main/java/com/messagebird/objects/ChildAccountCreateResponse.java index 768fd71f..57aff09e 100644 --- a/api/src/main/java/com/messagebird/objects/ChildAccountCreateResponse.java +++ b/api/src/main/java/com/messagebird/objects/ChildAccountCreateResponse.java @@ -2,29 +2,11 @@ import java.util.List; -public class ChildAccountCreateResponse { - private String id; - private String name; +public class ChildAccountCreateResponse extends ChildAccountResponse{ private List accessKeys; private String signingKey; private String invoiceAggregation; - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - public List getAccessKeys() { return accessKeys; } From 3895bc1cb85d281f02d67ed6458eaf235ecb072f Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Fri, 8 Oct 2021 14:11:57 +0200 Subject: [PATCH 321/516] minor things are updated --- .../java/com/messagebird/MessageBirdClient.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 7a817c3a..7cdfbc68 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -678,8 +678,8 @@ public VoiceCallFlowResponse sendVoiceCallFlow(final VoiceCallFlowRequest voiceC * @param id String * @param voiceCallFlowRequest VoiceCallFlowRequest * @return VoiceCallFlowResponse - * @throws UnauthorizedException - * @throws GeneralException + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception */ public VoiceCallFlowResponse updateVoiceCallFlow(String id, VoiceCallFlowRequest voiceCallFlowRequest) throws UnauthorizedException, GeneralException { @@ -1893,7 +1893,7 @@ public TemplateList listWhatsAppTemplates() throws UnauthorizedException, Genera * Retrieves the template of an existing template name. * * @param templateName A name as returned by getWhatsAppTemplateBy in the name variable - * @return {@code List} template list + * @return {@code List} template list * @throws UnauthorizedException if client is unauthorized * @throws GeneralException general exception * @throws NotFoundException if template name is not found @@ -1920,7 +1920,7 @@ public List getWhatsAppTemplatesBy(final String templateName) * @param templateName A name as returned by getWhatsAppTemplateBy in the name variable * @param language A language code as returned by getWhatsAppTemplateBy in the language variable * - * @return {@code WhatsAppTemplateResponse} template list + * @return {@code TemplateResponse} template list * @throws UnauthorizedException if client is unauthorized * @throws GeneralException general exception * @throws NotFoundException if template name and language are not found @@ -2000,7 +2000,7 @@ public void deleteTemplatesBy(final String templateName, final String language) * @throws UnauthorizedException if client is unauthorized * @throws GeneralException general exception */ - public ChildAccountCreateResponse createChildAccount(String name) throws UnauthorizedException, GeneralException { + public ChildAccountCreateResponse createChildAccount(final String name) throws UnauthorizedException, GeneralException { if (name == null) { throw new IllegalArgumentException("Name must be specified."); } @@ -2017,7 +2017,7 @@ public ChildAccountCreateResponse createChildAccount(String name) throws Unautho * @throws UnauthorizedException if client is unauthorized * @throws GeneralException general exception */ - public ChildAccountResponse updateChildAccount(String name, String id) throws UnauthorizedException, GeneralException { + public ChildAccountResponse updateChildAccount(final String name, final String id) throws UnauthorizedException, GeneralException { if (name == null) { throw new IllegalArgumentException("Name must be specified."); } @@ -2039,7 +2039,7 @@ public ChildAccountResponse updateChildAccount(String name, String id) throws Un * @throws GeneralException general exception * @throws NotFoundException if id is not found */ - public ChildAccountDetailedResponse getChildAccountById(String id) throws UnauthorizedException, GeneralException, NotFoundException { + public ChildAccountDetailedResponse getChildAccountById(final String id) throws UnauthorizedException, GeneralException, NotFoundException { if (id == null) { throw new IllegalArgumentException("Child account id must be specified."); } @@ -2067,7 +2067,7 @@ public PartnerAccountsResponse getChildAccounts(final Integer offset, final Inte * @throws GeneralException general exception * @throws NotFoundException if id is not found */ - public void deleteChildAccount(String id) throws UnauthorizedException, GeneralException, NotFoundException { + public void deleteChildAccount(final String id) throws UnauthorizedException, GeneralException, NotFoundException { if (id == null) { throw new IllegalArgumentException("Child account id must be specified."); } From 45952f878658869158fd0302b8ff8cb5c45f2815 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Fri, 8 Oct 2021 14:38:59 +0200 Subject: [PATCH 322/516] added toString methods --- .../main/java/com/messagebird/objects/AccessKey.java | 9 +++++++++ .../objects/ChildAccountCreateResponse.java | 11 +++++++++++ .../objects/ChildAccountDetailedResponse.java | 9 +++++++++ .../com/messagebird/objects/ChildAccountResponse.java | 8 ++++++++ examples/src/main/java/ExampleCreateChildAccount.java | 5 +++-- 5 files changed, 40 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/AccessKey.java b/api/src/main/java/com/messagebird/objects/AccessKey.java index 14505dc7..65ee9fd7 100644 --- a/api/src/main/java/com/messagebird/objects/AccessKey.java +++ b/api/src/main/java/com/messagebird/objects/AccessKey.java @@ -28,4 +28,13 @@ public String getMod() { public void setMod(String mod) { this.mod = mod; } + + @Override + public String toString() { + return "AccessKey{" + + "id='" + id + '\'' + + ", key='" + key + '\'' + + ", mod='" + mod + '\'' + + '}'; + } } diff --git a/api/src/main/java/com/messagebird/objects/ChildAccountCreateResponse.java b/api/src/main/java/com/messagebird/objects/ChildAccountCreateResponse.java index 57aff09e..dcf201b6 100644 --- a/api/src/main/java/com/messagebird/objects/ChildAccountCreateResponse.java +++ b/api/src/main/java/com/messagebird/objects/ChildAccountCreateResponse.java @@ -30,4 +30,15 @@ public String getInvoiceAggregation() { public void setInvoiceAggregation(String invoiceAggregation) { this.invoiceAggregation = invoiceAggregation; } + + @Override + public String toString() { + return "ChildAccountCreateResponse{" + + "id='" + getId() + '\'' + + ", name='" + getName() + '\'' + + ", accessKeys=" + accessKeys + '\'' + + ", signingKey='" + signingKey + '\'' + + ", invoiceAggregation='" + invoiceAggregation + '\'' + + '}'; + } } diff --git a/api/src/main/java/com/messagebird/objects/ChildAccountDetailedResponse.java b/api/src/main/java/com/messagebird/objects/ChildAccountDetailedResponse.java index d3aac825..cdf23d4a 100644 --- a/api/src/main/java/com/messagebird/objects/ChildAccountDetailedResponse.java +++ b/api/src/main/java/com/messagebird/objects/ChildAccountDetailedResponse.java @@ -10,4 +10,13 @@ public String getInvoiceAggregation() { public void setInvoiceAggregation(String invoiceAggregation) { this.invoiceAggregation = invoiceAggregation; } + + @Override + public String toString() { + return "ChildAccountDetailedResponse{" + + "id='" + getId() + '\'' + + ", name='" + getName() + '\'' + + "invoiceAggregation='" + invoiceAggregation + '\'' + + '}'; + } } diff --git a/api/src/main/java/com/messagebird/objects/ChildAccountResponse.java b/api/src/main/java/com/messagebird/objects/ChildAccountResponse.java index 2e4853aa..637a258f 100644 --- a/api/src/main/java/com/messagebird/objects/ChildAccountResponse.java +++ b/api/src/main/java/com/messagebird/objects/ChildAccountResponse.java @@ -19,4 +19,12 @@ public String getName() { public void setName(String name) { this.name = name; } + + @Override + public String toString() { + return "ChildAccountResponse{" + + "id='" + id + '\'' + + ", name='" + name + '\'' + + '}'; + } } diff --git a/examples/src/main/java/ExampleCreateChildAccount.java b/examples/src/main/java/ExampleCreateChildAccount.java index e4ec5df7..037f90dd 100644 --- a/examples/src/main/java/ExampleCreateChildAccount.java +++ b/examples/src/main/java/ExampleCreateChildAccount.java @@ -3,6 +3,7 @@ import com.messagebird.MessageBirdServiceImpl; import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.ChildAccountCreateResponse; public class ExampleCreateChildAccount { public static void main(String[] args) { @@ -16,8 +17,8 @@ public static void main(String[] args) { try { System.out.println("Creating a child account of partner accounts"); - messageBirdClient.createChildAccount(args[1]); - System.out.println("Child account is created"); + ChildAccountCreateResponse childAccount = messageBirdClient.createChildAccount(args[1]); + System.out.println("Child account is created: " + childAccount.toString()); } catch (GeneralException | UnauthorizedException exception) { exception.printStackTrace(); From 6cc657f88cb81e62a63967710057e24e61242ea2 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Fri, 8 Oct 2021 16:56:59 +0200 Subject: [PATCH 323/516] updated examples --- .../com/messagebird/MessageBirdClient.java | 22 +++---- .../objects/ChildAccountDetailedResponse.java | 2 +- .../objects/ChildAccountRequest.java | 13 +++++ .../objects/ChildAccountResponse.java | 6 +- .../objects/PartnerAccountsResponse.java | 12 +--- .../messagebird/MessageBirdClientTest.java | 57 ++++++++++--------- .../test/java/com/messagebird/TestUtil.java | 2 +- .../main/java/ExampleCreateChildAccount.java | 5 +- .../main/java/ExampleGetChildAccountById.java | 5 +- .../main/java/ExampleGetChildAccounts.java | 4 +- .../main/java/ExampleUpdateChildAccount.java | 5 +- 11 files changed, 74 insertions(+), 59 deletions(-) create mode 100644 api/src/main/java/com/messagebird/objects/ChildAccountRequest.java diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 7cdfbc68..5f8d489f 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -47,7 +47,6 @@ import java.util.Locale; import java.util.Map; import java.util.Set; -import java.util.HashSet; /** * Message bird general client @@ -1995,18 +1994,18 @@ public void deleteTemplatesBy(final String templateName, final String language) /** * Function to create a child account * - * @param name of child account to create + * @param childAccountRequest of child account to create * @return ChildAccountResponse created * @throws UnauthorizedException if client is unauthorized * @throws GeneralException general exception */ - public ChildAccountCreateResponse createChildAccount(final String name) throws UnauthorizedException, GeneralException { - if (name == null) { + public ChildAccountCreateResponse createChildAccount(final ChildAccountRequest childAccountRequest) throws UnauthorizedException, GeneralException { + if (childAccountRequest.getName() == null || childAccountRequest.getName().isEmpty()) { throw new IllegalArgumentException("Name must be specified."); } String url = String.format("%s%s", PARTNER_ACCOUNTS_BASE_URL, "/child-accounts"); - return messageBirdService.sendPayLoad(url, name, ChildAccountCreateResponse.class); + return messageBirdService.sendPayLoad(url, childAccountRequest, ChildAccountCreateResponse.class); } /** @@ -2025,9 +2024,10 @@ public ChildAccountResponse updateChildAccount(final String name, final String i if (id == null) { throw new IllegalArgumentException("Child account id must be specified."); } - + final ChildAccountRequest childAccountRequest = new ChildAccountRequest(); + childAccountRequest.setName(name); final String url = String.format("%s/child-accounts/%s", PARTNER_ACCOUNTS_BASE_URL, id); - return messageBirdService.sendPayLoad("PATCH", url, name, ChildAccountResponse.class); + return messageBirdService.sendPayLoad("PATCH", url, childAccountRequest, ChildAccountResponse.class); } /** @@ -2043,8 +2043,7 @@ public ChildAccountDetailedResponse getChildAccountById(final String id) throws if (id == null) { throw new IllegalArgumentException("Child account id must be specified."); } - - return messageBirdService.requestByID(PARTNER_ACCOUNTS_BASE_URL, id, ChildAccountDetailedResponse.class); + return messageBirdService.requestByID(PARTNER_ACCOUNTS_BASE_URL + "/child-accounts", id, ChildAccountDetailedResponse.class); } /** @@ -2056,7 +2055,7 @@ public ChildAccountDetailedResponse getChildAccountById(final String id) throws */ public PartnerAccountsResponse getChildAccounts(final Integer offset, final Integer limit) throws UnauthorizedException, GeneralException { verifyOffsetAndLimit(offset, limit); - return messageBirdService.requestList(PARTNER_ACCOUNTS_BASE_URL, offset, limit, PartnerAccountsResponse.class); + return messageBirdService.requestList(PARTNER_ACCOUNTS_BASE_URL + "/child-accounts", offset, limit, PartnerAccountsResponse.class); } /** @@ -2072,7 +2071,8 @@ public void deleteChildAccount(final String id) throws UnauthorizedException, Ge throw new IllegalArgumentException("Child account id must be specified."); } - String url = String.format("%s/child-accounts/%s", PARTNER_ACCOUNTS_BASE_URL, id); + String url = String.format("%s/child-accounts", PARTNER_ACCOUNTS_BASE_URL); + System.out.println("url: " + url); messageBirdService.deleteByID(url, id); } } diff --git a/api/src/main/java/com/messagebird/objects/ChildAccountDetailedResponse.java b/api/src/main/java/com/messagebird/objects/ChildAccountDetailedResponse.java index cdf23d4a..e39d5969 100644 --- a/api/src/main/java/com/messagebird/objects/ChildAccountDetailedResponse.java +++ b/api/src/main/java/com/messagebird/objects/ChildAccountDetailedResponse.java @@ -16,7 +16,7 @@ public String toString() { return "ChildAccountDetailedResponse{" + "id='" + getId() + '\'' + ", name='" + getName() + '\'' + - "invoiceAggregation='" + invoiceAggregation + '\'' + + ", invoiceAggregation='" + invoiceAggregation + '\'' + '}'; } } diff --git a/api/src/main/java/com/messagebird/objects/ChildAccountRequest.java b/api/src/main/java/com/messagebird/objects/ChildAccountRequest.java new file mode 100644 index 00000000..aa0e9e5f --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/ChildAccountRequest.java @@ -0,0 +1,13 @@ +package com.messagebird.objects; + +public class ChildAccountRequest { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/api/src/main/java/com/messagebird/objects/ChildAccountResponse.java b/api/src/main/java/com/messagebird/objects/ChildAccountResponse.java index 637a258f..de232f05 100644 --- a/api/src/main/java/com/messagebird/objects/ChildAccountResponse.java +++ b/api/src/main/java/com/messagebird/objects/ChildAccountResponse.java @@ -1,6 +1,10 @@ package com.messagebird.objects; -public class ChildAccountResponse { +import java.io.Serializable; + +public class ChildAccountResponse implements Serializable { + private static final long serialVersionUID = -8605510461438669942L; + private String id; private String name; diff --git a/api/src/main/java/com/messagebird/objects/PartnerAccountsResponse.java b/api/src/main/java/com/messagebird/objects/PartnerAccountsResponse.java index 410cd360..deb82067 100644 --- a/api/src/main/java/com/messagebird/objects/PartnerAccountsResponse.java +++ b/api/src/main/java/com/messagebird/objects/PartnerAccountsResponse.java @@ -1,15 +1,5 @@ package com.messagebird.objects; -import java.util.List; +public class PartnerAccountsResponse extends ListBase{ -public class PartnerAccountsResponse { - private List childAccountResponses; - - public List getChildAccountResponses() { - return childAccountResponses; - } - - public void setChildAccountResponses(List childAccountResponses) { - this.childAccountResponses = childAccountResponses; - } } diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index b523a2a4..c948154e 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -134,7 +134,7 @@ public void testListScheduledMessages() throws Exception { public void testListScheduledMessagesWrongFilter() throws Exception { Map filters = new LinkedHashMap<>(); filters.put("does not exist", null); - + messageBirdClient.listMessagesFiltered(null, null, filters); } @@ -816,7 +816,7 @@ public void testListNumbersForPurchase() throws IllegalArgumentException, Genera final PhoneNumbersResponse response = messageBirdClientMock.listNumbersForPurchase("NL"); verify(messageBirdServiceMock, times(1)).requestByID(url, "NL", PhoneNumbersResponse.class); - + assertNotNull(response); assertEquals(response, mockedResponse); } @@ -835,7 +835,7 @@ public void testListNumbersForPurchaseWithParams() throws IllegalArgumentExcepti options.setLimit(1); options.setNumber(562); options.setSearchPattern(PhoneNumberSearchPattern.START); - + when(messageBirdServiceMock.requestByID(url, "US", options.toHashMap(), PhoneNumbersResponse.class)) .thenReturn(mockedResponse); @@ -853,12 +853,12 @@ public void testPurchaseNumber() throws UnauthorizedException, GeneralException MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); - + final Map payload = new LinkedHashMap(); payload.put("number", "15625267429"); payload.put("countryCode", "US"); payload.put("billingIntervalMonths", 1); - + when(messageBirdServiceMock.sendPayLoad(url, payload, PurchasedNumberCreatedResponse.class)) .thenReturn(purchasedNumberMockData); final PurchasedNumberCreatedResponse response = messageBirdClientMock.purchaseNumber("15625267429", "US", 1); @@ -866,13 +866,13 @@ public void testPurchaseNumber() throws UnauthorizedException, GeneralException assertNotNull(response); assertEquals(response, purchasedNumberMockData); } - + @Test public void testListPurchasedNumbers() throws UnauthorizedException, GeneralException, NotFoundException { final String url = String.format("%s/phone-numbers", NUMBERS_CALLS_BASE_URL); - + PurchasedNumbersResponse purchasedNumbersMockData = new PurchasedNumbersResponse(); - + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); @@ -895,9 +895,9 @@ public void testListPurchasedNumbers() throws UnauthorizedException, GeneralExce @Test public void testViewPurchasedNumber() throws UnauthorizedException, GeneralException, NotFoundException { final String url = String.format("%s/phone-numbers", NUMBERS_CALLS_BASE_URL); - + PurchasedNumber purchasedNumberMockData = new PurchasedNumber(); - + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); when(messageBirdServiceMock.requestByID(url, "15625267429", PurchasedNumber.class)) @@ -913,15 +913,15 @@ public void testViewPurchasedNumber() throws UnauthorizedException, GeneralExce public void updatePurchasedNumber() throws UnauthorizedException, GeneralException { final String phoneNumber = "15625267429"; final String url = String.format("%s/phone-numbers/%s", NUMBERS_CALLS_BASE_URL, phoneNumber); - + PurchasedNumber updatedNumberMock = new PurchasedNumber(); - + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); - + final Map> payload = new HashMap>(); payload.put("tags", Collections.singletonList("tag")); - + when(messageBirdServiceMock.sendPayLoad("PATCH", url, payload, PurchasedNumber.class)) .thenReturn(updatedNumberMock); final PurchasedNumber response = messageBirdClientMock.updateNumber(phoneNumber, "tag"); @@ -934,10 +934,10 @@ public void updatePurchasedNumber() throws UnauthorizedException, GeneralExcept public void deletePurchasedNumber() throws UnauthorizedException, GeneralException, NotFoundException { final String phoneNumber = "15625267429"; final String url = String.format("%s/phone-numbers", NUMBERS_CALLS_BASE_URL); - + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); - + messageBirdClientMock.cancelNumber(phoneNumber); verify(messageBirdServiceMock, times(1)).deleteByID(url, phoneNumber); } @@ -1225,12 +1225,14 @@ public void testCreateChildAccounts() throws GeneralException, UnauthorizedExcep MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); ChildAccountCreateResponse childAccountCreateResponse = createChildAccountCreateResponse(); - when(messageBirdServiceMock.sendPayLoad(PARTNER_ACCOUNTS_BASE_URL + "/child-accounts" , "name", ChildAccountCreateResponse.class)) + ChildAccountRequest childAccountRequest = new ChildAccountRequest(); + childAccountRequest.setName("name"); + when(messageBirdServiceMock.sendPayLoad(PARTNER_ACCOUNTS_BASE_URL + "/child-accounts" , childAccountRequest, ChildAccountCreateResponse.class)) .thenReturn(childAccountCreateResponse); - final ChildAccountCreateResponse response = messageBirdClientInjectMock.createChildAccount("name"); + final ChildAccountCreateResponse response = messageBirdClientInjectMock.createChildAccount(childAccountRequest); verify(messageBirdServiceMock, times(1)) - .sendPayLoad(PARTNER_ACCOUNTS_BASE_URL + "/child-accounts" , "name", ChildAccountCreateResponse.class); + .sendPayLoad(PARTNER_ACCOUNTS_BASE_URL + "/child-accounts" , childAccountRequest, ChildAccountCreateResponse.class); assertNotNull(response); assertEquals(response.getId(), childAccountCreateResponse.getId()); assertEquals(response.getName(), childAccountCreateResponse.getName()); @@ -1246,12 +1248,12 @@ public void testGetChildAccount() throws GeneralException, UnauthorizedException MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); ChildAccountDetailedResponse childAccountDetailedResponse = createChildAccountDetailedResponse(); - when(messageBirdServiceMock.requestByID(PARTNER_ACCOUNTS_BASE_URL, "ANY_ID", ChildAccountDetailedResponse.class)) + when(messageBirdServiceMock.requestByID(PARTNER_ACCOUNTS_BASE_URL + "/child-accounts", "ANY_ID", ChildAccountDetailedResponse.class)) .thenReturn(childAccountDetailedResponse); ChildAccountDetailedResponse response = messageBirdClientInjectMock.getChildAccountById("ANY_ID"); verify(messageBirdServiceMock, times(1)) - .requestByID(PARTNER_ACCOUNTS_BASE_URL, "ANY_ID", ChildAccountDetailedResponse.class); + .requestByID(PARTNER_ACCOUNTS_BASE_URL + "/child-accounts", "ANY_ID", ChildAccountDetailedResponse.class); assertNotNull(response); assertEquals(response.getId(), childAccountDetailedResponse.getId()); assertEquals(response.getName(), childAccountDetailedResponse.getName()); @@ -1263,16 +1265,16 @@ public void testGetChildAccounts() throws GeneralException, UnauthorizedExceptio MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); PartnerAccountsResponse partnerAccountsResponse = createPartnerAccountsResponse(); - when(messageBirdServiceMock.requestList(PARTNER_ACCOUNTS_BASE_URL, 1, 10, PartnerAccountsResponse.class)) + when(messageBirdServiceMock.requestList(PARTNER_ACCOUNTS_BASE_URL + "/child-accounts", 1, 10, PartnerAccountsResponse.class)) .thenReturn(partnerAccountsResponse); PartnerAccountsResponse response = messageBirdClientInjectMock.getChildAccounts(1, 10); verify(messageBirdServiceMock, times(1)) - .requestList(PARTNER_ACCOUNTS_BASE_URL, 1, 10, PartnerAccountsResponse.class); + .requestList(PARTNER_ACCOUNTS_BASE_URL + "/child-accounts", 1, 10, PartnerAccountsResponse.class); assertNotNull(response); - assertEquals(response.getChildAccountResponses().get(0).getId(), partnerAccountsResponse.getChildAccountResponses().get(0).getId()); - assertEquals(response.getChildAccountResponses().get(0).getName(), partnerAccountsResponse.getChildAccountResponses().get(0).getName()); + assertEquals(response.getItems().get(0).getId(), partnerAccountsResponse.getItems().get(0).getId()); + assertEquals(response.getItems().get(0).getName(), partnerAccountsResponse.getItems().get(0).getName()); } @Test @@ -1280,13 +1282,12 @@ public void testUpdateChildAccount() throws GeneralException, UnauthorizedExcept MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); ChildAccountResponse childAccountResponse = createChildAccountResponse(); - final String url = String.format("%s/child-accounts/%s", PARTNER_ACCOUNTS_BASE_URL, "ANY_ID"); - when(messageBirdServiceMock.sendPayLoad("PATCH", url, "ANY_NAME", ChildAccountResponse.class)) + when(messageBirdServiceMock.sendPayLoad(any(), any(), any(), any())) .thenReturn(childAccountResponse); ChildAccountResponse response = messageBirdClientInjectMock.updateChildAccount("ANY_NAME", "ANY_ID"); verify(messageBirdServiceMock, times(1)) - .sendPayLoad("PATCH", url, "ANY_NAME", ChildAccountResponse.class); + .sendPayLoad(any(), any(), any(), any()); assertNotNull(response); assertEquals(response.getId(), childAccountResponse.getId()); assertEquals(response.getName(), childAccountResponse.getName()); diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index 0e293855..a66c0aad 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -384,7 +384,7 @@ public static ChildAccountResponse createChildAccountResponse(){ public static PartnerAccountsResponse createPartnerAccountsResponse(){ final ChildAccountResponse childAccountResponse = createChildAccountResponse(); final PartnerAccountsResponse partnerAccountsResponse = new PartnerAccountsResponse(); - partnerAccountsResponse.setChildAccountResponses(Collections.singletonList(childAccountResponse)); + partnerAccountsResponse.setItems(Collections.singletonList(childAccountResponse)); return partnerAccountsResponse; } } diff --git a/examples/src/main/java/ExampleCreateChildAccount.java b/examples/src/main/java/ExampleCreateChildAccount.java index 037f90dd..2c71ae51 100644 --- a/examples/src/main/java/ExampleCreateChildAccount.java +++ b/examples/src/main/java/ExampleCreateChildAccount.java @@ -3,6 +3,7 @@ import com.messagebird.MessageBirdServiceImpl; import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.ChildAccountRequest; import com.messagebird.objects.ChildAccountCreateResponse; public class ExampleCreateChildAccount { @@ -17,7 +18,9 @@ public static void main(String[] args) { try { System.out.println("Creating a child account of partner accounts"); - ChildAccountCreateResponse childAccount = messageBirdClient.createChildAccount(args[1]); + final ChildAccountRequest childAccountRequest = new ChildAccountRequest(); + childAccountRequest.setName(args[1]); + ChildAccountCreateResponse childAccount = messageBirdClient.createChildAccount(childAccountRequest); System.out.println("Child account is created: " + childAccount.toString()); } catch (GeneralException | UnauthorizedException exception) { diff --git a/examples/src/main/java/ExampleGetChildAccountById.java b/examples/src/main/java/ExampleGetChildAccountById.java index ae1acbc9..2e42fd6e 100644 --- a/examples/src/main/java/ExampleGetChildAccountById.java +++ b/examples/src/main/java/ExampleGetChildAccountById.java @@ -4,6 +4,7 @@ import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.ChildAccountDetailedResponse; public class ExampleGetChildAccountById { public static void main(String[] args) { @@ -17,8 +18,8 @@ public static void main(String[] args) { try { System.out.println("Get a child account by id"); - messageBirdClient.getChildAccountById(args[1]); - + ChildAccountDetailedResponse response = messageBirdClient.getChildAccountById(args[1]); + System.out.println("Response: " + response.toString()); } catch (GeneralException | UnauthorizedException | NotFoundException exception) { exception.printStackTrace(); } diff --git a/examples/src/main/java/ExampleGetChildAccounts.java b/examples/src/main/java/ExampleGetChildAccounts.java index 5d7be592..01a29dbb 100644 --- a/examples/src/main/java/ExampleGetChildAccounts.java +++ b/examples/src/main/java/ExampleGetChildAccounts.java @@ -3,6 +3,7 @@ import com.messagebird.MessageBirdServiceImpl; import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.PartnerAccountsResponse; public class ExampleGetChildAccounts { public static void main(String[] args) { @@ -16,7 +17,8 @@ public static void main(String[] args) { try { System.out.println("Get a child accounts of partner account"); - messageBirdClient.getChildAccounts(Integer.valueOf(args[1]), Integer.valueOf(args[2])); + PartnerAccountsResponse response = messageBirdClient.getChildAccounts(Integer.valueOf(args[1]), Integer.valueOf(args[2])); + System.out.println("response: " + response); } catch (GeneralException | UnauthorizedException exception) { exception.printStackTrace(); } diff --git a/examples/src/main/java/ExampleUpdateChildAccount.java b/examples/src/main/java/ExampleUpdateChildAccount.java index e90b9b51..1976f6ab 100644 --- a/examples/src/main/java/ExampleUpdateChildAccount.java +++ b/examples/src/main/java/ExampleUpdateChildAccount.java @@ -3,6 +3,7 @@ import com.messagebird.MessageBirdServiceImpl; import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.ChildAccountResponse; public class ExampleUpdateChildAccount { public static void main(String[] args) { @@ -16,8 +17,8 @@ public static void main(String[] args) { try { System.out.println("Updating a child account"); - messageBirdClient.updateChildAccount(args[1], args[2]); - System.out.println("Child account is updated"); + ChildAccountResponse response = messageBirdClient.updateChildAccount(args[1], args[2]); + System.out.println("Child account is updated: " + response.toString()); } catch (GeneralException | UnauthorizedException exception) { exception.printStackTrace(); } From 89715d8b384b10ba864cfb29a8dacd2d3c2e628a Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Fri, 8 Oct 2021 17:33:47 +0200 Subject: [PATCH 324/516] getAccounts is fixed --- .../java/com/messagebird/MessageBirdClient.java | 4 ++-- .../objects/PartnerAccountsResponse.java | 5 ----- .../com/messagebird/MessageBirdClientTest.java | 15 ++++++++------- api/src/test/java/com/messagebird/TestUtil.java | 7 ------- .../src/main/java/ExampleGetChildAccounts.java | 6 ++++-- 5 files changed, 14 insertions(+), 23 deletions(-) delete mode 100644 api/src/main/java/com/messagebird/objects/PartnerAccountsResponse.java diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 5f8d489f..cd8ca60a 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -2053,9 +2053,9 @@ public ChildAccountDetailedResponse getChildAccountById(final String id) throws * @throws UnauthorizedException if client is unauthorized * @throws GeneralException general exception */ - public PartnerAccountsResponse getChildAccounts(final Integer offset, final Integer limit) throws UnauthorizedException, GeneralException { + public List getChildAccounts(final Integer offset, final Integer limit) throws UnauthorizedException, GeneralException { verifyOffsetAndLimit(offset, limit); - return messageBirdService.requestList(PARTNER_ACCOUNTS_BASE_URL + "/child-accounts", offset, limit, PartnerAccountsResponse.class); + return messageBirdService.requestList(PARTNER_ACCOUNTS_BASE_URL + "/child-accounts", offset, limit, List.class); } /** diff --git a/api/src/main/java/com/messagebird/objects/PartnerAccountsResponse.java b/api/src/main/java/com/messagebird/objects/PartnerAccountsResponse.java deleted file mode 100644 index deb82067..00000000 --- a/api/src/main/java/com/messagebird/objects/PartnerAccountsResponse.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.messagebird.objects; - -public class PartnerAccountsResponse extends ListBase{ - -} diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index c948154e..139ede8a 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -24,6 +24,7 @@ import static com.messagebird.MessageBirdClient.*; import static com.messagebird.TestUtil.*; +import static com.messagebird.TestUtil.createChildAccountDetailedResponse; import static org.junit.Assert.*; import static org.mockito.Mockito.*; import static org.unitils.reflectionassert.ReflectionAssert.assertReflectionEquals; @@ -1264,17 +1265,17 @@ public void testGetChildAccount() throws GeneralException, UnauthorizedException public void testGetChildAccounts() throws GeneralException, UnauthorizedException { MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); - PartnerAccountsResponse partnerAccountsResponse = createPartnerAccountsResponse(); - when(messageBirdServiceMock.requestList(PARTNER_ACCOUNTS_BASE_URL + "/child-accounts", 1, 10, PartnerAccountsResponse.class)) - .thenReturn(partnerAccountsResponse); + List childAccountResponses = Collections.singletonList(createChildAccountResponse()); + when(messageBirdServiceMock.requestList(PARTNER_ACCOUNTS_BASE_URL + "/child-accounts", 1, 10, List.class)) + .thenReturn(childAccountResponses); - PartnerAccountsResponse response = messageBirdClientInjectMock.getChildAccounts(1, 10); + List response = messageBirdClientInjectMock.getChildAccounts(1, 10); verify(messageBirdServiceMock, times(1)) - .requestList(PARTNER_ACCOUNTS_BASE_URL + "/child-accounts", 1, 10, PartnerAccountsResponse.class); + .requestList(PARTNER_ACCOUNTS_BASE_URL + "/child-accounts", 1, 10, List.class); assertNotNull(response); - assertEquals(response.getItems().get(0).getId(), partnerAccountsResponse.getItems().get(0).getId()); - assertEquals(response.getItems().get(0).getName(), partnerAccountsResponse.getItems().get(0).getName()); + assertEquals(response.get(0).getId(), childAccountResponses.get(0).getId()); + assertEquals(response.get(0).getName(), childAccountResponses.get(0).getName()); } @Test diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index a66c0aad..7518776b 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -380,11 +380,4 @@ public static ChildAccountResponse createChildAccountResponse(){ childAccountResponse.setName("ANY_NAME"); return childAccountResponse; } - - public static PartnerAccountsResponse createPartnerAccountsResponse(){ - final ChildAccountResponse childAccountResponse = createChildAccountResponse(); - final PartnerAccountsResponse partnerAccountsResponse = new PartnerAccountsResponse(); - partnerAccountsResponse.setItems(Collections.singletonList(childAccountResponse)); - return partnerAccountsResponse; - } } diff --git a/examples/src/main/java/ExampleGetChildAccounts.java b/examples/src/main/java/ExampleGetChildAccounts.java index 01a29dbb..79dd17cb 100644 --- a/examples/src/main/java/ExampleGetChildAccounts.java +++ b/examples/src/main/java/ExampleGetChildAccounts.java @@ -3,7 +3,9 @@ import com.messagebird.MessageBirdServiceImpl; import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.UnauthorizedException; -import com.messagebird.objects.PartnerAccountsResponse; +import com.messagebird.objects.ChildAccountResponse; + +import java.util.List; public class ExampleGetChildAccounts { public static void main(String[] args) { @@ -17,7 +19,7 @@ public static void main(String[] args) { try { System.out.println("Get a child accounts of partner account"); - PartnerAccountsResponse response = messageBirdClient.getChildAccounts(Integer.valueOf(args[1]), Integer.valueOf(args[2])); + List response = messageBirdClient.getChildAccounts(Integer.valueOf(args[1]), Integer.valueOf(args[2])); System.out.println("response: " + response); } catch (GeneralException | UnauthorizedException exception) { exception.printStackTrace(); From 74e2370069cd4350893fe0e101a1343573384f34 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Mon, 11 Oct 2021 10:23:26 +0200 Subject: [PATCH 325/516] new release changes --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 47e53822..073b9f80 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.2 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 2497d524..b941ea0f 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -74,7 +74,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.1.2"; + private final String clientVersion = "3.1.4"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 438522e7..c551756a 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.1.2 + 3.1.4 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.1.2 + 3.1.4 compile From 6e07c1dde7e7b54524d97d9f0475c4388b10fcaa Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Mon, 11 Oct 2021 10:24:25 +0200 Subject: [PATCH 326/516] [maven-release-plugin] prepare release v3.1.4 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 073b9f80..6e21c631 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.4-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.1.4 From 3c34b3b186db79779b64d8a907e0181fade0ab25 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Mon, 11 Oct 2021 10:24:28 +0200 Subject: [PATCH 327/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 6e21c631..2da56990 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.4 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.1.4 + HEAD From 4fd0996c25ca93b2579609adc4ead7a4bbb4f44f Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Mon, 11 Oct 2021 14:38:11 +0200 Subject: [PATCH 328/516] new release changes --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 2da56990..d56811e3 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.5-SNAPSHOT From e540a5e9c22323dc51c9de62ccb49fdd5d6a206a Mon Sep 17 00:00:00 2001 From: "khanh.nguyen" Date: Tue, 19 Oct 2021 12:16:24 +0200 Subject: [PATCH 329/516] Update request signature validation example --- .../java/ExampleRequestSignatureValidation.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/examples/src/main/java/ExampleRequestSignatureValidation.java b/examples/src/main/java/ExampleRequestSignatureValidation.java index 4f54297c..e7b92566 100644 --- a/examples/src/main/java/ExampleRequestSignatureValidation.java +++ b/examples/src/main/java/ExampleRequestSignatureValidation.java @@ -22,25 +22,26 @@ * Created by hasselbach * * For exposing your application for external calls (webhooks from MessageBird) - * you can use serveo.net: `ssh -R 80:localhost:3000 serveo.net` + * you can use localtunnel (requires NodeJS). * - * Here is example of usage + * Here is example of usage: + * + * Install localtunnel globally: + * npm install -g localtunnel * * Select a free port: 3000, for example * export MBEXAMPLEPORT=3000 * * Run: - * ssh -R 80:localhost:$MBEXAMPLEPORT serveo.net + * lt --port $MBEXAMPLEPORT * * It will show you something like this: - * Hi there - * Forwarding HTTP traffic from https://blabla.serveo.net - * Press g to start a GUI session and ctrl-c to quit. + * your url is: https://loud-yak-31.loca.lt * * * NOTE * you should not terminate this process, so next operations should be done in the other terminal session * * Remember the address from output: - * export FORWARDING_URL=https://blabla.serveo.net + * export FORWARDING_URL=https://loud-yak-31.loca.lt * * Take your access and secret key from Dashboard: * secret key from https://dashboard.messagebird.com/en/developers/settings @@ -57,8 +58,8 @@ * and then you will see in example app output: * New request: * GET /webhook?id=ee2d02749a6fb78a572bd7ce9118dff&mccmnc=20409&ported=0&recipient=XXXXXX&reference=example-server&status=delivered&statusDatetime=2019-01-10T09%3A23%3A03%2B00%3A00 - * Request has valid signature * Message for XXXXXX is delivered + * Request has valid signature * * Description of webhook parameters can be found on * https://developers.messagebird.com/docs/sms-messaging#handle-a-status-report From a376f3115246476dd85316bb7a41b7e650f2908c Mon Sep 17 00:00:00 2001 From: cemturker Date: Fri, 5 Nov 2021 11:13:34 +0100 Subject: [PATCH 330/516] Add messaging listings with query param for Conversations API --- .../com/messagebird/MessageBirdClient.java | 20 +++++++++ ...istConversationMessagesWithQueryParam.java | 43 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 examples/src/main/java/ExampleListConversationMessagesWithQueryParam.java diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index cd8ca60a..a5337d91 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -117,6 +117,9 @@ public class MessageBirdClient { private static final String[] MESSAGE_LIST_FILTERS_VALS = {"originator", "recipient", "direction", "searchterm", "type", "contact_id", "status", "from", "until"}; private static final Set MESSAGE_LIST_FILTERS = new HashSet<>(Arrays.asList(MESSAGE_LIST_FILTERS_VALS)); + private static final String[] CONVERSATION_MESSAGE_LIST_FILTERS_VALS = {"ids", "from"}; + private static final Set CONVERSATION_MESSAGE_LIST_FILTERS = new HashSet<>(Arrays.asList(CONVERSATION_MESSAGE_LIST_FILTERS_VALS)); + private final String DOWNLOADS = "Downloads"; private MessageBirdService messageBirdService; @@ -1006,6 +1009,23 @@ public ConversationMessage viewConversationMessage(final String messageId) return messageBirdService.requestByID(url, messageId, ConversationMessage.class); } + /** + * Gets messages based on query param. + * + * @param queryParams + * @return The retrieved messages. + */ + public ConversationMessageList listConversationMessagesWithQueryParam(Map queryParams) + throws NotFoundException, GeneralException, UnauthorizedException { + for (String queryParam : queryParams.keySet()) { + if (!CONVERSATION_MESSAGE_LIST_FILTERS.contains(queryParam)) { + throw new IllegalArgumentException("Invalid filter name: " + queryParam); + } + } + String url = CONVERSATIONS_BASE_URL + CONVERSATION_MESSAGE_PATH; + return messageBirdService.requestByID(url, null, queryParams, ConversationMessageList.class); + } + /** * Sends a message to an existing Conversation. * diff --git a/examples/src/main/java/ExampleListConversationMessagesWithQueryParam.java b/examples/src/main/java/ExampleListConversationMessagesWithQueryParam.java new file mode 100644 index 00000000..fe7ec7e7 --- /dev/null +++ b/examples/src/main/java/ExampleListConversationMessagesWithQueryParam.java @@ -0,0 +1,43 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.conversations.ConversationMessageList; +import java.util.HashMap; + +public class ExampleListConversationMessagesWithQueryParam { + public static void main(String[] args) { + + if (args.length == 0) { + System.out.println("Please specify your access key example : java -jar test_accesskey"); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + // Get list of conversation messages with query param + System.out.println("Retrieving message list"); + final ConversationMessageList conversationMessageList = messageBirdClient.listConversationMessagesWithQueryParam( + new HashMap() { + { + put("ids", "9f0b413e79e24d76b01b895381b12a6d,d46054ee0f7245bcbc7ba586878d0ab4"); + } + }); + + // Display balance + System.out.println(conversationMessageList.toString()); + } catch (UnauthorizedException | GeneralException | NotFoundException exception) { + if (exception.getErrors() != null) { + System.out.println(exception.getErrors().toString()); + } + exception.printStackTrace(); + } + } +} From d27b0300f23e5a92dc2835ad26d4f2eb907de5bd Mon Sep 17 00:00:00 2001 From: cemturker Date: Fri, 5 Nov 2021 11:14:31 +0100 Subject: [PATCH 331/516] fix the comment --- .../java/ExampleListConversationMessagesWithQueryParam.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/src/main/java/ExampleListConversationMessagesWithQueryParam.java b/examples/src/main/java/ExampleListConversationMessagesWithQueryParam.java index fe7ec7e7..5ab13cf5 100644 --- a/examples/src/main/java/ExampleListConversationMessagesWithQueryParam.java +++ b/examples/src/main/java/ExampleListConversationMessagesWithQueryParam.java @@ -31,7 +31,7 @@ public static void main(String[] args) { } }); - // Display balance + // Display conversation Message list System.out.println(conversationMessageList.toString()); } catch (UnauthorizedException | GeneralException | NotFoundException exception) { if (exception.getErrors() != null) { From 99ff4016903044738aa6462ddbbebb07ee9d2703 Mon Sep 17 00:00:00 2001 From: cemturker Date: Fri, 5 Nov 2021 11:15:19 +0100 Subject: [PATCH 332/516] Add comments --- api/src/main/java/com/messagebird/MessageBirdClient.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index a5337d91..0e4f9ce2 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1010,9 +1010,9 @@ public ConversationMessage viewConversationMessage(final String messageId) } /** - * Gets messages based on query param. + * Gets conversation messages based on query param. * - * @param queryParams + * @param queryParams only `ids` and `from` is available as an option * @return The retrieved messages. */ public ConversationMessageList listConversationMessagesWithQueryParam(Map queryParams) From d5fe3f95aff24541d617920573cda22ad49b0cbe Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Sat, 6 Nov 2021 23:54:40 +0100 Subject: [PATCH 333/516] create child account response fields are updated --- .../com/messagebird/objects/AccessKey.java | 64 +++++++++++++++++-- .../objects/ChildAccountCreateResponse.java | 13 +++- .../messagebird/MessageBirdClientTest.java | 2 +- .../test/java/com/messagebird/TestUtil.java | 2 +- 4 files changed, 71 insertions(+), 10 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/AccessKey.java b/api/src/main/java/com/messagebird/objects/AccessKey.java index 65ee9fd7..78d168c0 100644 --- a/api/src/main/java/com/messagebird/objects/AccessKey.java +++ b/api/src/main/java/com/messagebird/objects/AccessKey.java @@ -1,9 +1,16 @@ package com.messagebird.objects; +import java.util.List; + public class AccessKey { private String id; - private String key; + private String access_key; private String mod; + private String description; + private int core_user_id; + private int user_id; + private int external_id; + private List roles; public String getId() { return id; @@ -13,12 +20,12 @@ public void setId(String id) { this.id = id; } - public String getKey() { - return key; + public String getAccess_key() { + return access_key; } - public void setKey(String key) { - this.key = key; + public void setAccess_key(String access_key) { + this.access_key = access_key; } public String getMod() { @@ -29,12 +36,57 @@ public void setMod(String mod) { this.mod = mod; } + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public int getCore_user_id() { + return core_user_id; + } + + public void setCore_user_id(int core_user_id) { + this.core_user_id = core_user_id; + } + + public int getUser_id() { + return user_id; + } + + public void setUser_id(int user_id) { + this.user_id = user_id; + } + + public int getExternal_id() { + return external_id; + } + + public void setExternal_id(int external_id) { + this.external_id = external_id; + } + + public List getRoles() { + return roles; + } + + public void setRoles(List roles) { + this.roles = roles; + } + @Override public String toString() { return "AccessKey{" + "id='" + id + '\'' + - ", key='" + key + '\'' + + ", access_key='" + access_key + '\'' + ", mod='" + mod + '\'' + + ", description='" + description + '\'' + + ", core_user_id=" + core_user_id + + ", user_id=" + user_id + + ", external_id=" + external_id + + ", roles=" + roles + '}'; } } diff --git a/api/src/main/java/com/messagebird/objects/ChildAccountCreateResponse.java b/api/src/main/java/com/messagebird/objects/ChildAccountCreateResponse.java index dcf201b6..40ec38a4 100644 --- a/api/src/main/java/com/messagebird/objects/ChildAccountCreateResponse.java +++ b/api/src/main/java/com/messagebird/objects/ChildAccountCreateResponse.java @@ -6,6 +6,7 @@ public class ChildAccountCreateResponse extends ChildAccountResponse{ private List accessKeys; private String signingKey; private String invoiceAggregation; + private String paymentMoment; public List getAccessKeys() { return accessKeys; @@ -31,14 +32,22 @@ public void setInvoiceAggregation(String invoiceAggregation) { this.invoiceAggregation = invoiceAggregation; } + public String getPaymentMoment() { + return paymentMoment; + } + + public void setPaymentMoment(String paymentMoment) { + this.paymentMoment = paymentMoment; + } + @Override public String toString() { return "ChildAccountCreateResponse{" + "id='" + getId() + '\'' + ", name='" + getName() + '\'' + ", accessKeys=" + accessKeys + '\'' + - ", signingKey='" + signingKey + '\'' + ", invoiceAggregation='" + invoiceAggregation + '\'' + + ", paymentMoment='" + paymentMoment + '\'' + '}'; - } + } } diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 139ede8a..e342c165 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -1240,7 +1240,7 @@ public void testCreateChildAccounts() throws GeneralException, UnauthorizedExcep assertEquals(response.getInvoiceAggregation(), childAccountCreateResponse.getInvoiceAggregation()); assertEquals(response.getSigningKey(), childAccountCreateResponse.getSigningKey()); assertEquals(response.getAccessKeys().get(0).getId(), childAccountCreateResponse.getAccessKeys().get(0).getId()); - assertEquals(response.getAccessKeys().get(0).getKey(), childAccountCreateResponse.getAccessKeys().get(0).getKey()); + assertEquals(response.getAccessKeys().get(0).getAccess_key(), childAccountCreateResponse.getAccessKeys().get(0).getAccess_key()); assertEquals(response.getAccessKeys().get(0).getMod(), childAccountCreateResponse.getAccessKeys().get(0).getMod()); } diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index 7518776b..269f8e40 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -353,7 +353,7 @@ public static TemplateList createWhatsAppTemplateList(final String templateName) public static ChildAccountCreateResponse createChildAccountCreateResponse() { final AccessKey accessKey = new AccessKey(); accessKey.setId("ANY_ID"); - accessKey.setKey("ANY_KEY"); + accessKey.setAccess_key("ANY_KEY"); accessKey.setMod("ANY_MOD"); final ChildAccountCreateResponse childAccountCreateResponse = new ChildAccountCreateResponse(); From 6a6a13552846e2392dc35b8cc6181302f8098036 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Mon, 8 Nov 2021 18:55:56 +0100 Subject: [PATCH 334/516] updated after review --- .../java/com/messagebird/objects/AccessKey.java | 15 +++++++++------ .../com/messagebird/MessageBirdClientTest.java | 2 +- api/src/test/java/com/messagebird/TestUtil.java | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/AccessKey.java b/api/src/main/java/com/messagebird/objects/AccessKey.java index 78d168c0..d03a23d3 100644 --- a/api/src/main/java/com/messagebird/objects/AccessKey.java +++ b/api/src/main/java/com/messagebird/objects/AccessKey.java @@ -1,10 +1,13 @@ package com.messagebird.objects; +import com.fasterxml.jackson.annotation.JsonProperty; + import java.util.List; public class AccessKey { private String id; - private String access_key; + @JsonProperty("access_key") + private String accessKey; private String mod; private String description; private int core_user_id; @@ -20,12 +23,12 @@ public void setId(String id) { this.id = id; } - public String getAccess_key() { - return access_key; + public String getAccessKey() { + return accessKey; } - public void setAccess_key(String access_key) { - this.access_key = access_key; + public void setAccessKey(String accessKey) { + this.accessKey = accessKey; } public String getMod() { @@ -80,7 +83,7 @@ public void setRoles(List roles) { public String toString() { return "AccessKey{" + "id='" + id + '\'' + - ", access_key='" + access_key + '\'' + + ", access_key='" + accessKey + '\'' + ", mod='" + mod + '\'' + ", description='" + description + '\'' + ", core_user_id=" + core_user_id + diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index e342c165..af9c170f 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -1240,7 +1240,7 @@ public void testCreateChildAccounts() throws GeneralException, UnauthorizedExcep assertEquals(response.getInvoiceAggregation(), childAccountCreateResponse.getInvoiceAggregation()); assertEquals(response.getSigningKey(), childAccountCreateResponse.getSigningKey()); assertEquals(response.getAccessKeys().get(0).getId(), childAccountCreateResponse.getAccessKeys().get(0).getId()); - assertEquals(response.getAccessKeys().get(0).getAccess_key(), childAccountCreateResponse.getAccessKeys().get(0).getAccess_key()); + assertEquals(response.getAccessKeys().get(0).getAccessKey(), childAccountCreateResponse.getAccessKeys().get(0).getAccessKey()); assertEquals(response.getAccessKeys().get(0).getMod(), childAccountCreateResponse.getAccessKeys().get(0).getMod()); } diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index 269f8e40..19c30c46 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -353,7 +353,7 @@ public static TemplateList createWhatsAppTemplateList(final String templateName) public static ChildAccountCreateResponse createChildAccountCreateResponse() { final AccessKey accessKey = new AccessKey(); accessKey.setId("ANY_ID"); - accessKey.setAccess_key("ANY_KEY"); + accessKey.setAccessKey("ANY_KEY"); accessKey.setMod("ANY_MOD"); final ChildAccountCreateResponse childAccountCreateResponse = new ChildAccountCreateResponse(); From fac98a4c9f9ae1cabbe8c215451adf6c2a139714 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Mon, 8 Nov 2021 18:59:59 +0100 Subject: [PATCH 335/516] updated --- .../com/messagebird/objects/AccessKey.java | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/AccessKey.java b/api/src/main/java/com/messagebird/objects/AccessKey.java index d03a23d3..e98106f0 100644 --- a/api/src/main/java/com/messagebird/objects/AccessKey.java +++ b/api/src/main/java/com/messagebird/objects/AccessKey.java @@ -10,9 +10,12 @@ public class AccessKey { private String accessKey; private String mod; private String description; - private int core_user_id; - private int user_id; - private int external_id; + @JsonProperty("core_user_id") + private int coreUserId; + @JsonProperty("user_id") + private int userId; + @JsonProperty("external_id") + private int externalId; private List roles; public String getId() { @@ -47,28 +50,28 @@ public void setDescription(String description) { this.description = description; } - public int getCore_user_id() { - return core_user_id; + public int getCoreUserId() { + return coreUserId; } - public void setCore_user_id(int core_user_id) { - this.core_user_id = core_user_id; + public void setCoreUserId(int coreUserId) { + this.coreUserId = coreUserId; } - public int getUser_id() { - return user_id; + public int getUserId() { + return userId; } - public void setUser_id(int user_id) { - this.user_id = user_id; + public void setUserId(int userId) { + this.userId = userId; } - public int getExternal_id() { - return external_id; + public int getExternalId() { + return externalId; } - public void setExternal_id(int external_id) { - this.external_id = external_id; + public void setExternalId(int externalId) { + this.externalId = externalId; } public List getRoles() { @@ -86,9 +89,9 @@ public String toString() { ", access_key='" + accessKey + '\'' + ", mod='" + mod + '\'' + ", description='" + description + '\'' + - ", core_user_id=" + core_user_id + - ", user_id=" + user_id + - ", external_id=" + external_id + + ", core_user_id=" + coreUserId + + ", user_id=" + userId + + ", external_id=" + externalId + ", roles=" + roles + '}'; } From 673677b5b9ddceb97c77913ce001eb61d7831024 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Mon, 8 Nov 2021 19:46:09 +0100 Subject: [PATCH 336/516] updated for a new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index d56811e3..2da56990 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.4 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index b941ea0f..5c025928 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -74,7 +74,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.1.4"; + private final String clientVersion = "3.1.5"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index c551756a..6aabbb55 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.1.4 + 3.1.5 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.1.4 + 3.1.5 compile From d00a6584804b75fc3cfabd9be0374b7f9eb84447 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Mon, 8 Nov 2021 19:47:16 +0100 Subject: [PATCH 337/516] [maven-release-plugin] prepare release v3.1.5 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 2da56990..023f3d77 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.5-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.1.5 From 04e4383e08cfc4f87ff2c3467430dff16d3ad815 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Mon, 8 Nov 2021 19:47:19 +0100 Subject: [PATCH 338/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 023f3d77..e0b0981c 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.5 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.1.5 + HEAD From f1624f768dd4493b4571dca070411034921bd7df Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Tue, 9 Nov 2021 09:15:52 +0100 Subject: [PATCH 339/516] updated for a new verrsion --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index e0b0981c..8ad1aa5c 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.6-SNAPSHOT From 36f5eeca985c8ffe39402259f8e3ba84d3d25a0e Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Tue, 9 Nov 2021 10:51:37 +0100 Subject: [PATCH 340/516] updated a field in AccessKey class --- .../main/java/com/messagebird/objects/AccessKey.java | 12 ++++++------ .../java/com/messagebird/MessageBirdClientTest.java | 2 +- api/src/test/java/com/messagebird/TestUtil.java | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/AccessKey.java b/api/src/main/java/com/messagebird/objects/AccessKey.java index e98106f0..4d529711 100644 --- a/api/src/main/java/com/messagebird/objects/AccessKey.java +++ b/api/src/main/java/com/messagebird/objects/AccessKey.java @@ -8,7 +8,7 @@ public class AccessKey { private String id; @JsonProperty("access_key") private String accessKey; - private String mod; + private String mode; private String description; @JsonProperty("core_user_id") private int coreUserId; @@ -34,12 +34,12 @@ public void setAccessKey(String accessKey) { this.accessKey = accessKey; } - public String getMod() { - return mod; + public String getMode() { + return mode; } - public void setMod(String mod) { - this.mod = mod; + public void setMode(String mode) { + this.mode = mode; } public String getDescription() { @@ -87,7 +87,7 @@ public String toString() { return "AccessKey{" + "id='" + id + '\'' + ", access_key='" + accessKey + '\'' + - ", mod='" + mod + '\'' + + ", mod='" + mode + '\'' + ", description='" + description + '\'' + ", core_user_id=" + coreUserId + ", user_id=" + userId + diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index af9c170f..67eb3c47 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -1241,7 +1241,7 @@ public void testCreateChildAccounts() throws GeneralException, UnauthorizedExcep assertEquals(response.getSigningKey(), childAccountCreateResponse.getSigningKey()); assertEquals(response.getAccessKeys().get(0).getId(), childAccountCreateResponse.getAccessKeys().get(0).getId()); assertEquals(response.getAccessKeys().get(0).getAccessKey(), childAccountCreateResponse.getAccessKeys().get(0).getAccessKey()); - assertEquals(response.getAccessKeys().get(0).getMod(), childAccountCreateResponse.getAccessKeys().get(0).getMod()); + assertEquals(response.getAccessKeys().get(0).getMode(), childAccountCreateResponse.getAccessKeys().get(0).getMode()); } @Test diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index 19c30c46..d5cf47a9 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -354,7 +354,7 @@ public static ChildAccountCreateResponse createChildAccountCreateResponse() { final AccessKey accessKey = new AccessKey(); accessKey.setId("ANY_ID"); accessKey.setAccessKey("ANY_KEY"); - accessKey.setMod("ANY_MOD"); + accessKey.setMode("ANY_MOD"); final ChildAccountCreateResponse childAccountCreateResponse = new ChildAccountCreateResponse(); childAccountCreateResponse.setId("ANY_ID"); From 5fdde1165b4f506643860047809978d9b1c5b788 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Tue, 9 Nov 2021 11:04:03 +0100 Subject: [PATCH 341/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 8ad1aa5c..e0b0981c 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.5 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 5c025928..8e0b5976 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -74,7 +74,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.1.5"; + private final String clientVersion = "3.1.6"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 6aabbb55..821e40fa 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.1.5 + 3.1.6 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.1.5 + 3.1.6 compile From 2cbd643ad79fb77ce3a0d62a026babe007f55fd6 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Tue, 9 Nov 2021 11:05:08 +0100 Subject: [PATCH 342/516] [maven-release-plugin] prepare release v3.1.6 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index e0b0981c..5a84584b 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.6-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.1.6 From b891023571f970cdb8277d770ba25153e5d57db4 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Tue, 9 Nov 2021 11:05:12 +0100 Subject: [PATCH 343/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 5a84584b..c9c15b88 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.6 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.1.6 + HEAD From 265c9d112e11f405890e9920c5e6810337045c9a Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Tue, 9 Nov 2021 16:53:47 +0100 Subject: [PATCH 344/516] updated --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index c9c15b88..f23a8bd8 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.7-SNAPSHOT From fd2e3055cf0e5e8c3a55f84edc83339d5170881f Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Thu, 11 Nov 2021 10:57:27 +0100 Subject: [PATCH 345/516] added new fields on MessageResponse class --- .../messagebird/objects/MessageResponse.java | 70 ++++++++++++++++++- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/MessageResponse.java b/api/src/main/java/com/messagebird/objects/MessageResponse.java index 8b480e25..91d4d6da 100644 --- a/api/src/main/java/com/messagebird/objects/MessageResponse.java +++ b/api/src/main/java/com/messagebird/objects/MessageResponse.java @@ -196,7 +196,7 @@ public Map getTypeDetails() { static public class Recipients implements Serializable { private static final long serialVersionUID = 547164972757802213L; - + private Integer totalCount; private Integer totalSentCount; private Integer totalDeliveredCount; private Integer totalDeliveryFailedCount; @@ -208,13 +208,18 @@ public Recipients() { @Override public String toString() { return "Recipients{" + - "totalSentCount=" + totalSentCount + + "totalCount=" + totalCount + + ", totalSentCount=" + totalSentCount + ", totalDeliveredCount=" + totalDeliveredCount + ", totalDeliveryFailedCount=" + totalDeliveryFailedCount + ", items=" + items + '}'; } + public Integer getTotalCount() { + return totalCount; + } + /** * The count of recipients that have the message pending (status sent, and buffered). * @@ -260,10 +265,20 @@ static public class Items implements Serializable { private static final long serialVersionUID = -4104837036540050532L; private BigInteger recipient; + private BigInteger originator; private String status; private Date statusDatetime; + private String recipientCountry; + private Integer recipientCountryPrefix; + private String recipientOperator; + private Integer messageLength; + private String statusReason; @Nullable private Price price; + private String mccmnc; + private String mcc; + private String mnc; + private int messagePartCount; public Items() { } @@ -272,10 +287,20 @@ public Items() { public String toString() { return "Items{" + "recipient=" + recipient + + ", originator=" + originator + ", status='" + status + '\'' + ", statusDatetime=" + statusDatetime + + ", recipientCountry='" + recipientCountry + '\'' + + ", recipientCountryPrefix=" + recipientCountryPrefix + + ", recipientOperator='" + recipientOperator + '\'' + + ", messageLength=" + messageLength + + ", statusReason='" + statusReason + '\'' + ", price=" + price + - "}"; + ", mccmnc='" + mccmnc + '\'' + + ", mcc='" + mcc + '\'' + + ", mnc='" + mnc + '\'' + + ", messagePartCount=" + messagePartCount + + '}'; } /** @@ -309,6 +334,45 @@ public Price getPrice() { return price; } + public BigInteger getOriginator() { + return originator; + } + + public String getRecipientCountry() { + return recipientCountry; + } + + public Integer getRecipientCountryPrefix() { + return recipientCountryPrefix; + } + + public String getRecipientOperator() { + return recipientOperator; + } + + public Integer getMessageLength() { + return messageLength; + } + + public String getStatusReason() { + return statusReason; + } + + public String getMccmnc() { + return mccmnc; + } + + public String getMcc() { + return mcc; + } + + public String getMnc() { + return mnc; + } + + public int getMessagePartCount() { + return messagePartCount; + } } /** From 72796a9c3a524528e7f36c346305669f8723681e Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Thu, 11 Nov 2021 11:11:03 +0100 Subject: [PATCH 346/516] preparing a new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index f23a8bd8..c9c15b88 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.6 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 8e0b5976..69e6f220 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -74,7 +74,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.1.6"; + private final String clientVersion = "3.1.7"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 821e40fa..3353a261 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.1.6 + 3.1.7 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.1.6 + 3.1.7 compile From 09be655286f498155cf34cef6627c486911541bf Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Thu, 11 Nov 2021 11:12:43 +0100 Subject: [PATCH 347/516] [maven-release-plugin] prepare release v3.1.7 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index c9c15b88..e14eec8c 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.7-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.1.7 From aee2c719d4f41a962532ab8b09d5e67f71ad22c6 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Thu, 11 Nov 2021 11:12:46 +0100 Subject: [PATCH 348/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index e14eec8c..1c1e9b3c 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.7 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.1.7 + HEAD From fffb40ba17b7b1aca65ecffd20f2c1456737dc66 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Thu, 11 Nov 2021 17:44:20 +0100 Subject: [PATCH 349/516] updated pom --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 1c1e9b3c..f7a7fb61 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.8-SNAPSHOT From 13c2c247abab54fe77048941e003a5eb0c16d078 Mon Sep 17 00:00:00 2001 From: Leandro Pinto Date: Fri, 17 Dec 2021 11:44:55 +0100 Subject: [PATCH 350/516] Adding support to the new sipResponseCode filed in the VoiceCallLeg object. --- .../messagebird/objects/voicecalls/VoiceCallLeg.java | 11 ++++++++--- .../test/java/com/messagebird/VoiceCallingTest.java | 3 ++- api/src/test/resources/fixtures/call_legs_list.json | 1 + examples/src/main/java/ExampleViewVoiceCallLegs.java | 2 +- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallLeg.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallLeg.java index 93dc0fa2..d09b7bdf 100644 --- a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallLeg.java +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallLeg.java @@ -28,6 +28,7 @@ public class VoiceCallLeg { public final Date updatedAt; public final Date answeredAt; public final Date endedAt; + public final SipResponseCode sipResponseCode; @JsonCreator @@ -44,7 +45,8 @@ public VoiceCallLeg( @JsonProperty("createdAt") Date createdAt, @JsonProperty("updatedAt") Date updatedAt, @JsonProperty("answeredAt") Date answeredAt, - @JsonProperty("endedAt") Date endedAt + @JsonProperty("endedAt") Date endedAt, + @JsonProperty("sipResponseCode") SipResponseCode sipResponseCode ) { this.id = id; this.callID = callID; @@ -59,6 +61,7 @@ public VoiceCallLeg( this.updatedAt = updatedAt; this.answeredAt = answeredAt; this.endedAt = endedAt; + this.sipResponseCode = sipResponseCode; } @Override @@ -77,6 +80,7 @@ public String toString() { ", updatedAt='" + updatedAt + '\'' + ", answeredAt='" + answeredAt + '\'' + ", endedAt='" + endedAt + '\'' + + ", sipResponseCode='" + sipResponseCode + '\'' + '}'; } @@ -97,11 +101,12 @@ public boolean equals(Object o) { Objects.equals(createdAt, that.createdAt) && Objects.equals(updatedAt, that.updatedAt) && Objects.equals(answeredAt, that.answeredAt) && - Objects.equals(endedAt, that.endedAt); + Objects.equals(endedAt, that.endedAt) && + Objects.equals(sipResponseCode, that.sipResponseCode); } @Override public int hashCode() { - return Objects.hash(id, callID, source, destination, status, direction, cost, currency, duration, createdAt, updatedAt, answeredAt, endedAt); + return Objects.hash(id, callID, source, destination, status, direction, cost, currency, duration, createdAt, updatedAt, answeredAt, endedAt, sipResponseCode); } } diff --git a/api/src/test/java/com/messagebird/VoiceCallingTest.java b/api/src/test/java/com/messagebird/VoiceCallingTest.java index 778f9b1c..cc8ae90e 100644 --- a/api/src/test/java/com/messagebird/VoiceCallingTest.java +++ b/api/src/test/java/com/messagebird/VoiceCallingTest.java @@ -3,6 +3,7 @@ import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.voicecalls.SipResponseCode; import com.messagebird.objects.voicecalls.VoiceCall; import com.messagebird.objects.voicecalls.VoiceLegDirection; import com.messagebird.objects.voicecalls.VoiceLegStatus; @@ -100,7 +101,7 @@ public void testGetLeg() throws IOException, GeneralException, UnauthorizedExcep VoiceLegStatus.Hangup, VoiceLegDirection.Outgoing, new BigDecimal("0.001519"), "EUR", 7, parseDate("2019-01-10T16:12:54Z"), parseDate("2019-01-10T16:13:54Z"), - parseDate("2019-01-10T16:13:24Z"), parseDate("2019-01-10T16:13:30Z") + parseDate("2019-01-10T16:13:24Z"), parseDate("2019-01-10T16:13:30Z"), SipResponseCode.OK ); private static Date parseDate(String input) { diff --git a/api/src/test/resources/fixtures/call_legs_list.json b/api/src/test/resources/fixtures/call_legs_list.json index 53a20f71..0ea233f6 100644 --- a/api/src/test/resources/fixtures/call_legs_list.json +++ b/api/src/test/resources/fixtures/call_legs_list.json @@ -14,6 +14,7 @@ "updatedAt":"2019-01-10T16:13:54Z", "answeredAt":"2019-01-10T16:13:24Z", "endedAt":"2019-01-10T16:13:30Z", + "sipResponseCode": 200, "_links":{ "self":"/calls/unforgiven-call/legs/first-leg-of-unforgiven-call" } diff --git a/examples/src/main/java/ExampleViewVoiceCallLegs.java b/examples/src/main/java/ExampleViewVoiceCallLegs.java index 00713686..8429d57c 100644 --- a/examples/src/main/java/ExampleViewVoiceCallLegs.java +++ b/examples/src/main/java/ExampleViewVoiceCallLegs.java @@ -34,7 +34,7 @@ public static void main(String[] args) { messageBirdClient.viewCallLegsByCallId(voiceCall.getId(), null, null); //Display voice call leg response object for (VoiceCallLeg callLeg : voiceCallLegResponse.getData()) { - System.out.printf("\t\t%s -> %s, %s [%s]\n", callLeg.source, callLeg.destination, callLeg.direction, callLeg.status); + System.out.printf("\t\t%s -> %s, %s [status: %s sipResponseCode: %s] \n", callLeg.source, callLeg.destination, callLeg.direction, callLeg.status, callLeg.sipResponseCode); } } From 3ade8bed0120bf033f44d6c9fbc6abfe0aba2220 Mon Sep 17 00:00:00 2001 From: Leandro Pinto Date: Fri, 17 Dec 2021 12:08:27 +0100 Subject: [PATCH 351/516] Adding missing class for SipResponseCode --- .../objects/voicecalls/SipResponseCode.java | 73 +++++++++++++++++++ .../resources/fixtures/call_legs_get.json | 3 +- 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 api/src/main/java/com/messagebird/objects/voicecalls/SipResponseCode.java diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/SipResponseCode.java b/api/src/main/java/com/messagebird/objects/voicecalls/SipResponseCode.java new file mode 100644 index 00000000..7061c8fe --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/voicecalls/SipResponseCode.java @@ -0,0 +1,73 @@ +package com.messagebird.objects.voicecalls; + +import com.fasterxml.jackson.annotation.JsonCreator; + + +/** + * More details, including additional descriptions and common caused can be found here: https://developers.messagebird.com/api/voice-calling/#sip-status-codes + * @author leandropinto + * + */ +public enum SipResponseCode { + //Successful + OK, + //The server understood the request, but is refusing to fulfill it. + FORBIDDEN, + //The server has definitive information that the user does not exist at the domain specified in the Request-URI. + NOT_FOUND, + //Couldn't find the user in time. + REQUEST_TIMEOUT, + //The user existed once, but is not available here any more. + GONE, + //Callee currently unavailable. + TEMPORARILY_UNAVAILABLE, + //Request-URI incomplete. + ADDRESS_INCOMPLETE, + //Callee is busy. + BUSY_HERE, + //Some aspect of the session description or the Request-URI is not acceptable. + NOT_ACCEPTABLE_HERE, + //The server could not fulfill the request due to some unexpected condition. + INTERNAL_SERVER_ERROR, + //The server does not have the ability to fulfill the request, such as because it does not recognize the request method. + NOT_IMPLEMENTED, + //The server is acting as a gateway or proxy, and received an invalid response from a downstream server while attempting to fulfill the request. + BAD_GATEWAY, + //The server is undergoing maintenance or is temporarily overloaded and so cannot process the request. + SERVICE_UNAVAILABLE; + + @JsonCreator + public static SipResponseCode forValue(Integer value) { + switch (value) { + case 200: + return OK; + case 403: + return FORBIDDEN; + case 404: + return NOT_FOUND; + case 408: + return REQUEST_TIMEOUT; + case 410: + return GONE; + case 480: + return TEMPORARILY_UNAVAILABLE; + case 484: + return ADDRESS_INCOMPLETE; + case 486: + return BUSY_HERE; + case 488: + return NOT_ACCEPTABLE_HERE; + case 500: + return INTERNAL_SERVER_ERROR; + case 501: + return NOT_IMPLEMENTED; + case 502: + return BAD_GATEWAY; + case 503: + return SERVICE_UNAVAILABLE; + + default: + throw new IllegalArgumentException("Unknown sip response code: " + value); + } + } +} \ No newline at end of file diff --git a/api/src/test/resources/fixtures/call_legs_get.json b/api/src/test/resources/fixtures/call_legs_get.json index 64d5f65b..23670a0a 100644 --- a/api/src/test/resources/fixtures/call_legs_get.json +++ b/api/src/test/resources/fixtures/call_legs_get.json @@ -13,7 +13,8 @@ "createdAt": "2019-01-10T16:12:54Z", "updatedAt": "2019-01-10T16:13:54Z", "answeredAt": "2019-01-10T16:13:24Z", - "endedAt": "2019-01-10T16:13:30Z" + "endedAt": "2019-01-10T16:13:30Z", + "sipResponseCode": 200 } ], "_links": { From 9f9842f45b6b83d66a1232312af8de87c94d03c3 Mon Sep 17 00:00:00 2001 From: "deniz@messagebird.com" Date: Sat, 18 Dec 2021 12:33:56 +0100 Subject: [PATCH 352/516] new version update --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index f7a7fb61..cbf8a706 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.7 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 69e6f220..7acc804c 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -74,7 +74,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.1.7"; + private final String clientVersion = "3.1.10"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 3353a261..546c0c25 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.1.7 + 3.1.10 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.1.7 + 3.1.10 compile From 0a7ae99f38a1f9263dfc1b13313dee20fff8a36f Mon Sep 17 00:00:00 2001 From: denizkilic Date: Tue, 28 Dec 2021 15:52:08 +0100 Subject: [PATCH 353/516] typo fix in enum type --- .../messagebird/objects/conversations/MessageComponentType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java b/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java index 073b5735..842f49f1 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java +++ b/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java @@ -8,7 +8,7 @@ public enum MessageComponentType { HEADER("header"), BODY("body"), FOOTER("footer"), - BUTTONS("buttons"); + BUTTONS("button"); private final String type; From 2b557e450f3456cf4274ee4d269695e061c30231 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Tue, 28 Dec 2021 16:08:23 +0100 Subject: [PATCH 354/516] updated enum name and value --- .../messagebird/objects/conversations/MessageComponentType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java b/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java index 842f49f1..327525fd 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java +++ b/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java @@ -8,7 +8,7 @@ public enum MessageComponentType { HEADER("header"), BODY("body"), FOOTER("footer"), - BUTTONS("button"); + BUTTON("button"); private final String type; From 7649823d134d91e8b2967d7b5bc4c7558549c40a Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 3 Jan 2022 13:24:25 +0100 Subject: [PATCH 355/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index cbf8a706..b70108b6 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.1.10 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 7acc804c..65c7cda8 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -74,7 +74,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.1.10"; + private final String clientVersion = "3.2.0"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 546c0c25..bee96a05 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.1.10 + 3.2.0 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.1.10 + 3.2.0 compile From 71e230f0a52a54f9ea46811f5c641187ab038453 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 3 Jan 2022 13:26:05 +0100 Subject: [PATCH 356/516] [maven-release-plugin] prepare release v3.2.0 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index b70108b6..abffb03a 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.0-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.2.0 From 7389148fe692020127b02d11a9ec71be349d8d23 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 3 Jan 2022 13:26:09 +0100 Subject: [PATCH 357/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index abffb03a..da6230ea 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.0 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.2.0 + HEAD From e9b47c7d603321b6a8f13f81a7c227c80871aeef Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 3 Jan 2022 17:38:42 +0100 Subject: [PATCH 358/516] updated version --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index da6230ea..04fc1a99 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.1-SNAPSHOT From e5767a7683f9428ea20e6ec104a38c9d5375c04f Mon Sep 17 00:00:00 2001 From: cemturker Date: Fri, 14 Jan 2022 12:45:40 +0100 Subject: [PATCH 359/516] Use string instead of HSMRejectedReason enum --- .../integrations/HSMRejectedReason.java | 51 ------------------- .../integrations/TemplateResponse.java | 6 +-- 2 files changed, 3 insertions(+), 54 deletions(-) delete mode 100644 api/src/main/java/com/messagebird/objects/integrations/HSMRejectedReason.java diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMRejectedReason.java b/api/src/main/java/com/messagebird/objects/integrations/HSMRejectedReason.java deleted file mode 100644 index 55937ef4..00000000 --- a/api/src/main/java/com/messagebird/objects/integrations/HSMRejectedReason.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.messagebird.objects.integrations; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; - -/** - * An enum class for HSMRejectedReason - * - * @see HSMRejectedReason object - * @author ssk910 - */ -public enum HSMRejectedReason { - - ABUSIVE_CONTENT("ABUSIVE_CONTENT"), - INVALID_FORMAT("INVALID_FORMAT"), - NONE("NONE"), - PROMOTIONAL("PROMOTIONAL"), - TAG_CONTENT_MISMATCH("TAG_CONTENT_MISMATCH"), - NON_TRANSIENT_ERROR("NON_TRANSIENT_ERROR"); - - private final String rejectedReason; - - HSMRejectedReason(String rejectedReason) { - this.rejectedReason = rejectedReason; - } - - @JsonCreator - public static HSMRejectedReason forValue(String value) { - for (HSMRejectedReason hsmRejectedReason : HSMRejectedReason.values()) { - if (hsmRejectedReason.getRejectedReason().equals(value)) { - return hsmRejectedReason; - } - } - - return null; - } - - @JsonValue - public String toJson() { - return getRejectedReason(); - } - - public String getRejectedReason() { - return rejectedReason; - } - - @Override - public String toString() { - return getRejectedReason(); - } -} diff --git a/api/src/main/java/com/messagebird/objects/integrations/TemplateResponse.java b/api/src/main/java/com/messagebird/objects/integrations/TemplateResponse.java index ac34efd0..bce35f82 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/TemplateResponse.java +++ b/api/src/main/java/com/messagebird/objects/integrations/TemplateResponse.java @@ -17,7 +17,7 @@ public class TemplateResponse implements Serializable { private HSMCategory category; private List components; private HSMStatus status; - private HSMRejectedReason rejectedReason; + private String rejectedReason; private Date createdAt; private Date updatedAt; @@ -65,11 +65,11 @@ public void setStatus(HSMStatus status) { this.status = status; } - public HSMRejectedReason getRejectedReason() { + public String getRejectedReason() { return rejectedReason; } - public void setRejectedReason(HSMRejectedReason rejectedReason) { + public void setRejectedReason(String rejectedReason) { this.rejectedReason = rejectedReason; } From 16fa1303c2309be61d98dc29b906ed142badd9bb Mon Sep 17 00:00:00 2001 From: denizkilic Date: Wed, 19 Jan 2022 11:04:48 +0100 Subject: [PATCH 360/516] creating a new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 04fc1a99..da6230ea 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.0 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 65c7cda8..211ef6ad 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -74,7 +74,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.2.0"; + private final String clientVersion = "3.2.1"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index bee96a05..9ba1af9d 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.2.0 + 3.2.1 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.2.0 + 3.2.1 compile From f27ed5c7bded0beb71ce0b1b65c6c880878c6a9e Mon Sep 17 00:00:00 2001 From: denizkilic Date: Wed, 19 Jan 2022 11:06:02 +0100 Subject: [PATCH 361/516] [maven-release-plugin] prepare release v3.2.1 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index da6230ea..33da8e48 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.1-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.2.1 From 75fb03b3de7206157f599d4956d6273be5fe4531 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Wed, 19 Jan 2022 11:06:07 +0100 Subject: [PATCH 362/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 33da8e48..123a333a 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.1 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.2.1 + HEAD From 5890056f7114cc2ddce39294c79f753fc5e2de61 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Wed, 19 Jan 2022 17:29:43 +0100 Subject: [PATCH 363/516] new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 123a333a..d585c62c 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.2-SNAPSHOT From 80e5732d694b3857e76038bb28b4e7431aded0e6 Mon Sep 17 00:00:00 2001 From: Ryan Rupp <3022260+ryanrupp@users.noreply.github.com> Date: Wed, 16 Mar 2022 12:59:13 -0500 Subject: [PATCH 364/516] Make JetBrains annotations "provided" to avoid runtime transitive dependency These are annotations used for static analysis at development time only and not needed at runtime --- api/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/api/pom.xml b/api/pom.xml index d585c62c..1093e786 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -117,6 +117,7 @@ org.jetbrains annotations 13.0 + provided From 7de8e9e4ef2ef332c5bbfdd004749103ae3a656f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Apr 2022 13:57:09 +0000 Subject: [PATCH 365/516] Bump jackson-databind from 2.11.0 to 2.12.6.1 in /api Bumps [jackson-databind](https://github.com/FasterXML/jackson) from 2.11.0 to 2.12.6.1. - [Release notes](https://github.com/FasterXML/jackson/releases) - [Commits](https://github.com/FasterXML/jackson/commits) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 1093e786..932b50e7 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -88,7 +88,7 @@ com.fasterxml.jackson.core jackson-databind - 2.11.0 + 2.12.6.1 com.auth0 From 18e150c3d9fcecb8152cb4494a4b9e9b0315b9f3 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 4 Apr 2022 16:38:58 +0200 Subject: [PATCH 366/516] lastest versions of jackson libs --- api/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 932b50e7..62d4997b 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -83,12 +83,12 @@ com.fasterxml.jackson.core jackson-annotations - 2.11.0 + 2.13.2 com.fasterxml.jackson.core jackson-databind - 2.12.6.1 + 2.13.2.2 com.auth0 @@ -117,7 +117,7 @@ org.jetbrains annotations 13.0 - provided + From 043ec405363f4b3448daf5eee9e578b13bb2cb28 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 4 Apr 2022 16:45:48 +0200 Subject: [PATCH 367/516] fixed pom file --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 62d4997b..e2ca079b 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -117,7 +117,7 @@ org.jetbrains annotations 13.0 - + provided From 2f4783c9e4b3181787cccf7eb37899c047c5d16c Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 4 Apr 2022 16:51:37 +0200 Subject: [PATCH 368/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index e2ca079b..1e2d5a67 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.1 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 211ef6ad..892db5c6 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -74,7 +74,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.2.1"; + private final String clientVersion = "3.2.2"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 9ba1af9d..c94c0398 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.2.1 + 3.2.2 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.2.1 + 3.2.2 compile From 1aa500acb4b4302834ab9fa9057d92357f97df7f Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 4 Apr 2022 16:53:27 +0200 Subject: [PATCH 369/516] [maven-release-plugin] prepare release v3.2.2 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 1e2d5a67..bfd7e70e 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.2-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.2.2 From a12c952f4c95d6d80591a7d123dadac8f667940d Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 4 Apr 2022 16:53:31 +0200 Subject: [PATCH 370/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index bfd7e70e..9b63ea2d 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.2 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.2.2 + HEAD From 97fc992421c7363bb93052bc2301531ddc75c192 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Tue, 5 Apr 2022 10:05:35 +0200 Subject: [PATCH 371/516] new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 9b63ea2d..5e2288db 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.3-SNAPSHOT From 5aa59d91b66fadce39c4ab064c9d0419d9ddc7b5 Mon Sep 17 00:00:00 2001 From: Daniel Morales Date: Thu, 21 Apr 2022 14:27:36 +0100 Subject: [PATCH 372/516] Added the trackId and ttl fields to conversations request objects. --- .../conversations/ConversationMessage.java | 13 +- .../ConversationMessageRequest.java | 20 ++- .../ConversationSendRequest.java | 23 +++- .../ConversationStartRequest.java | 14 ++- .../messagebird/MessageBirdClientTest.java | 116 +++++++++++------- 5 files changed, 133 insertions(+), 53 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessage.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessage.java index 82c935dd..637f355e 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessage.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessage.java @@ -13,6 +13,7 @@ public class ConversationMessage { private String id; private String conversationId; private String channelId; + private String trackId; private ConversationMessageDirection direction; private ConversationMessageStatus status; private ConversationContentType type; @@ -122,6 +123,15 @@ public void setPlatform(String platform) { this.platform = platform; } + public String getTrackId() { + return trackId; + } + + public void setTrackId(String trackId) { + this.trackId = trackId; + } + + @Override public String toString() { return "ConversationMessage{" + @@ -131,6 +141,7 @@ public String toString() { ", direction=" + direction + ", status=" + status + ", type=" + type + + ", trackID=" + trackId + ", content=" + content + ", createdDatetime=" + createdDatetime + ", updatedDatetime=" + updatedDatetime + @@ -139,4 +150,4 @@ public String toString() { ", platform='" + platform + '\'' + '}'; } -} +} \ No newline at end of file diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageRequest.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageRequest.java index 626e6075..044bba68 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageRequest.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageRequest.java @@ -11,6 +11,8 @@ public class ConversationMessageRequest { private ConversationContent content; private String channelId; private String reportUrl; + private String trackId; + private String ttl; private Map source; public ConversationContentType getType() { @@ -53,6 +55,20 @@ public void setSource(Map source) { this.source = source; } + public String getTrackId() { + return trackId; + } + + public void setTrackId(String trackId) { + this.trackId = trackId; + } + public String getTtl() { + return ttl; + } + + public void setTtl(String ttl) { + this.ttl = ttl; + } @Override public String toString() { return "ConversationMessageRequest{" + @@ -61,6 +77,8 @@ public String toString() { ", channelId='" + channelId + '\'' + ", reportUrl='" + reportUrl + '\'' + ", source=" + source + + ", trackID=" + trackId + + ", ttl=" + ttl + '}'; } -} +} \ No newline at end of file diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationSendRequest.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationSendRequest.java index f0f9fd5c..40ace8d7 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationSendRequest.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationSendRequest.java @@ -8,6 +8,8 @@ public class ConversationSendRequest { private ConversationContent content; private String from; private String reportUrl; + private String trackId; + private String ttl; private ConversationFallbackOption fallback; private Map source; private ConversationMessageTag tag; @@ -90,6 +92,21 @@ public void setTag(ConversationMessageTag tag) { this.tag = tag; } + public void setTrackId(String trackId) { + this.trackId = trackId; + } + + public String getTrackId() { + return trackId; + } + + public String getTtl() { + return ttl; + } + + public void setTtl(String ttl) { + this.ttl = ttl; + } @Override public String toString() { return "ConversationSendRequest{" + @@ -98,11 +115,11 @@ public String toString() { ", content=" + content + ", from='" + from + '\'' + ", reportUrl='" + reportUrl + '\'' + + ", trackId='" + trackId + '\'' + + ", ttl='" + ttl + '\'' + ", fallback=" + fallback + '\'' + ", tags=" + tag + ", source='" + source + '\'' + '}'; } -} - - +} \ No newline at end of file diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationStartRequest.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationStartRequest.java index 36ebc68a..6f7c84fe 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationStartRequest.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationStartRequest.java @@ -14,6 +14,8 @@ public class ConversationStartRequest { private ConversationMessageTag tag; private String channelId; private String reportUrl; + private String trackId; + private String ttl; public ConversationStartRequest( final String to, @@ -91,6 +93,14 @@ public void setTag(ConversationMessageTag tag) { this.tag = tag; } + public String getTrackId() { + return trackId; + } + + public void setTrackId(String trackId) { + this.trackId = trackId; + } + @Override public String toString() { return "ConversationStartRequest{" + @@ -101,6 +111,8 @@ public String toString() { ", tag=" + tag + ", channelId='" + channelId + '\'' + ", reportUrl='" + reportUrl + '\'' + + ", trackId='" + trackId + '\'' + + ", ttl='" + ttl + '\'' + '}'; } -} +} \ No newline at end of file diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 67eb3c47..1dedcece 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -4,6 +4,7 @@ import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; import com.messagebird.objects.*; +import com.messagebird.objects.conversations.*; import com.messagebird.objects.integrations.Template; import com.messagebird.objects.integrations.TemplateList; import com.messagebird.objects.integrations.TemplateResponse; @@ -63,6 +64,27 @@ public void testGetBalance() throws Exception { assertNotNull(balance.getPayment()); } + @Test + public void testConversationMessage()throws Exception { + + ConversationContent conversationContent = new ConversationContent(); + conversationContent.setText("test"); + ConversationSendRequest request = new ConversationSendRequest(); + request.setFrom("channelid"); + request.setTo("+34123123123"); + request.setTtl("15s"); + request.setType(ConversationContentType.TEXT); + request.setContent(conversationContent); + request.setTrackId("mycampaign"); + ConversationSendResponse conversationSendResponse = messageBirdClient.sendMessage(request); + ConversationMessage conversationMessageResponse = messageBirdClient.viewConversationMessage(conversationSendResponse.getId()); + assertEquals(request.getFrom(),conversationMessageResponse.getChannelId()); + assertEquals(ConversationContentType.TEXT,conversationMessageResponse.getType()); + assertEquals(request.getTrackId(),conversationMessageResponse.getTrackId()); + assertNotNull(conversationMessageResponse.getStatus()); + } + + @Test public void testGetHlr() throws Exception { final Hlr hlr = messageBirdClient.getRequestHlr(messageBirdMSISDN, "Test Reference " + messageBirdMSISDN); @@ -124,7 +146,7 @@ public void testListScheduledMessages() throws Exception { filters.put("status", "scheduled"); when(messageBirdServiceMock.requestList("/messages", filters, null, null, MessageList.class)) - .thenReturn(mockedResponse); + .thenReturn(mockedResponse); final MessageList response = messageBirdClientMock.listMessagesFiltered(null, null, filters); assertNotNull(response); @@ -813,7 +835,7 @@ public void testListNumbersForPurchase() throws IllegalArgumentException, Genera MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); when(messageBirdServiceMock.requestByID(url, "NL", PhoneNumbersResponse.class)) - .thenReturn(mockedResponse); + .thenReturn(mockedResponse); final PhoneNumbersResponse response = messageBirdClientMock.listNumbersForPurchase("NL"); verify(messageBirdServiceMock, times(1)).requestByID(url, "NL", PhoneNumbersResponse.class); @@ -838,7 +860,7 @@ public void testListNumbersForPurchaseWithParams() throws IllegalArgumentExcepti options.setSearchPattern(PhoneNumberSearchPattern.START); when(messageBirdServiceMock.requestByID(url, "US", options.toHashMap(), PhoneNumbersResponse.class)) - .thenReturn(mockedResponse); + .thenReturn(mockedResponse); final PhoneNumbersResponse response = messageBirdClientMock.listNumbersForPurchase("US", options); verify(messageBirdServiceMock, times(1)).requestByID(url, "US", options.toHashMap(), PhoneNumbersResponse.class); @@ -861,7 +883,7 @@ public void testPurchaseNumber() throws UnauthorizedException, GeneralException payload.put("billingIntervalMonths", 1); when(messageBirdServiceMock.sendPayLoad(url, payload, PurchasedNumberCreatedResponse.class)) - .thenReturn(purchasedNumberMockData); + .thenReturn(purchasedNumberMockData); final PurchasedNumberCreatedResponse response = messageBirdClientMock.purchaseNumber("15625267429", "US", 1); verify(messageBirdServiceMock, times(1)).sendPayLoad(url, payload, PurchasedNumberCreatedResponse.class); assertNotNull(response); @@ -884,7 +906,7 @@ public void testListPurchasedNumbers() throws UnauthorizedException, GeneralExce filter.addTag("tag"); when(messageBirdServiceMock.requestByID(url, null, filter.toHashMap(), PurchasedNumbersResponse.class)) - .thenReturn(purchasedNumbersMockData); + .thenReturn(purchasedNumbersMockData); final PurchasedNumbersResponse response = messageBirdClientMock.listPurchasedNumbers(filter); @@ -902,7 +924,7 @@ public void testViewPurchasedNumber() throws UnauthorizedException, GeneralExce MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientMock = new MessageBirdClient(messageBirdServiceMock); when(messageBirdServiceMock.requestByID(url, "15625267429", PurchasedNumber.class)) - .thenReturn(purchasedNumberMockData); + .thenReturn(purchasedNumberMockData); final PurchasedNumber response = messageBirdClientMock.viewPurchasedNumber("15625267429"); verify(messageBirdServiceMock, times(1)).requestByID(url, "15625267429", PurchasedNumber.class); @@ -924,7 +946,7 @@ public void updatePurchasedNumber() throws UnauthorizedException, GeneralExcept payload.put("tags", Collections.singletonList("tag")); when(messageBirdServiceMock.sendPayLoad("PATCH", url, payload, PurchasedNumber.class)) - .thenReturn(updatedNumberMock); + .thenReturn(updatedNumberMock); final PurchasedNumber response = messageBirdClientMock.updateNumber(phoneNumber, "tag"); verify(messageBirdServiceMock, times(1)).sendPayLoad("PATCH", url, payload, PurchasedNumber.class); assertNotNull(response); @@ -1062,14 +1084,14 @@ public void testCreateWhatsAppTemplate() throws UnauthorizedException, GeneralEx MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); String url = String.format( - "%s%s%s", - INTEGRATIONS_BASE_URL_V2, - INTEGRATIONS_WHATSAPP_PATH, - TEMPLATES_PATH + "%s%s%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH ); when(messageBirdServiceMock.sendPayLoad(url, template, TemplateResponse.class)) - .thenReturn(templateResponse); + .thenReturn(templateResponse); final TemplateResponse response = messageBirdClientInjectMock.createWhatsAppTemplate(template); @@ -1097,14 +1119,14 @@ public void testListWhatsAppTemplates() throws UnauthorizedException, GeneralExc MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); String url = String.format( - "%s%s%s", - INTEGRATIONS_BASE_URL_V3, - INTEGRATIONS_WHATSAPP_PATH, - TEMPLATES_PATH + "%s%s%s", + INTEGRATIONS_BASE_URL_V3, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH ); when(messageBirdServiceMock.requestList(url, 0, 0, TemplateList.class)) - .thenReturn(templateList); + .thenReturn(templateList); final TemplateList response = messageBirdClientInjectMock.listWhatsAppTemplates(0, 0); verify(messageBirdServiceMock, times(1)).requestList(url, 0, 0, TemplateList.class); @@ -1116,7 +1138,7 @@ public void testListWhatsAppTemplates() throws UnauthorizedException, GeneralExc @Test public void testGetWhatsAppTemplatesBy() - throws GeneralException, UnauthorizedException, NotFoundException, ClassNotFoundException { + throws GeneralException, UnauthorizedException, NotFoundException, ClassNotFoundException { final String templateName = "sample_template_name"; final TemplateResponse templateResponse1 = TestUtil.createWhatsAppTemplateResponse(templateName, "en_US"); final TemplateResponse templateResponse2 = TestUtil.createWhatsAppTemplateResponse("another_template", "en_US"); @@ -1128,14 +1150,14 @@ public void testGetWhatsAppTemplatesBy() MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); String url = String.format( - "%s%s%s", - INTEGRATIONS_BASE_URL_V2, - INTEGRATIONS_WHATSAPP_PATH, - TEMPLATES_PATH + "%s%s%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH ); when(messageBirdServiceMock.requestByIdAsList(url, templateName, TemplateResponse.class)) - .thenReturn(templateList); + .thenReturn(templateList); final List response = messageBirdClientInjectMock.getWhatsAppTemplatesBy(templateName); verify(messageBirdServiceMock, times(1)).requestByIdAsList(url, templateName, TemplateResponse.class); @@ -1148,7 +1170,7 @@ public void testGetWhatsAppTemplatesBy() @Test public void testFetchWhatsAppTemplateBy() - throws UnauthorizedException, GeneralException, NotFoundException { + throws UnauthorizedException, GeneralException, NotFoundException { final String templateName = "sample_template_name"; final String language = "ko"; final TemplateResponse template = TestUtil.createWhatsAppTemplateResponse(templateName, language); @@ -1157,16 +1179,16 @@ public void testFetchWhatsAppTemplateBy() MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); String url = String.format( - "%s%s%s/%s/%s", - INTEGRATIONS_BASE_URL_V2, - INTEGRATIONS_WHATSAPP_PATH, - TEMPLATES_PATH, - templateName, - language + "%s%s%s/%s/%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH, + templateName, + language ); when(messageBirdServiceMock.request(url, TemplateResponse.class)) - .thenReturn(template); + .thenReturn(template); final TemplateResponse response = messageBirdClientInjectMock.fetchWhatsAppTemplateBy(templateName, language); verify(messageBirdServiceMock, times(1)).request(url, TemplateResponse.class); @@ -1179,18 +1201,18 @@ public void testFetchWhatsAppTemplateBy() @Test public void testDeleteTemplatesByName() - throws UnauthorizedException, GeneralException, NotFoundException { + throws UnauthorizedException, GeneralException, NotFoundException { final String templateName = "sample_template_name"; MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); String url = String.format( - "%s%s%s/%s", - INTEGRATIONS_BASE_URL_V2, - INTEGRATIONS_WHATSAPP_PATH, - TEMPLATES_PATH, - templateName + "%s%s%s/%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH, + templateName ); when(messageBirdServiceMock.delete(url, null)).thenReturn(null); @@ -1200,7 +1222,7 @@ public void testDeleteTemplatesByName() @Test public void testDeleteTemplatesByNameAndLanguage() - throws UnauthorizedException, GeneralException, NotFoundException { + throws UnauthorizedException, GeneralException, NotFoundException { final String templateName = "sample_template_name"; final String language = "en_US"; @@ -1208,12 +1230,12 @@ public void testDeleteTemplatesByNameAndLanguage() MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); String url = String.format( - "%s%s%s/%s/%s", - INTEGRATIONS_BASE_URL_V2, - INTEGRATIONS_WHATSAPP_PATH, - TEMPLATES_PATH, - templateName, - language + "%s%s%s/%s/%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH, + templateName, + language ); when(messageBirdServiceMock.delete(url, null)).thenReturn(null); @@ -1229,11 +1251,11 @@ public void testCreateChildAccounts() throws GeneralException, UnauthorizedExcep ChildAccountRequest childAccountRequest = new ChildAccountRequest(); childAccountRequest.setName("name"); when(messageBirdServiceMock.sendPayLoad(PARTNER_ACCOUNTS_BASE_URL + "/child-accounts" , childAccountRequest, ChildAccountCreateResponse.class)) - .thenReturn(childAccountCreateResponse); + .thenReturn(childAccountCreateResponse); final ChildAccountCreateResponse response = messageBirdClientInjectMock.createChildAccount(childAccountRequest); verify(messageBirdServiceMock, times(1)) - .sendPayLoad(PARTNER_ACCOUNTS_BASE_URL + "/child-accounts" , childAccountRequest, ChildAccountCreateResponse.class); + .sendPayLoad(PARTNER_ACCOUNTS_BASE_URL + "/child-accounts" , childAccountRequest, ChildAccountCreateResponse.class); assertNotNull(response); assertEquals(response.getId(), childAccountCreateResponse.getId()); assertEquals(response.getName(), childAccountCreateResponse.getName()); @@ -1302,4 +1324,4 @@ public void testDeleteChildAccount() throws GeneralException, UnauthorizedExcept doNothing().when(messageBirdServiceMock).deleteByID(url, "ANY_ID"); messageBirdClientInjectMock.deleteChildAccount("id"); } -} +} \ No newline at end of file From c092689cc4ffc5108f77266c9559f5408a8ce74b Mon Sep 17 00:00:00 2001 From: Daniel Morales Date: Thu, 21 Apr 2022 15:46:29 +0100 Subject: [PATCH 373/516] Corrected formating in the MessageBirdClientTest to bring consistency and corrected asserts arguments order. --- .../conversations/ConversationMessage.java | 1 - .../ConversationMessageRequest.java | 1 + .../messagebird/MessageBirdClientTest.java | 83 +++++++------------ 3 files changed, 33 insertions(+), 52 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessage.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessage.java index 637f355e..2be027be 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessage.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessage.java @@ -131,7 +131,6 @@ public void setTrackId(String trackId) { this.trackId = trackId; } - @Override public String toString() { return "ConversationMessage{" + diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageRequest.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageRequest.java index 044bba68..420213e3 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageRequest.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageRequest.java @@ -69,6 +69,7 @@ public String getTtl() { public void setTtl(String ttl) { this.ttl = ttl; } + @Override public String toString() { return "ConversationMessageRequest{" + diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 1dedcece..82bc36f4 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -15,7 +15,6 @@ import org.junit.Test; import org.mockito.Mockito; -import java.io.*; import java.math.BigInteger; import java.util.Collections; import java.util.HashMap; @@ -64,27 +63,6 @@ public void testGetBalance() throws Exception { assertNotNull(balance.getPayment()); } - @Test - public void testConversationMessage()throws Exception { - - ConversationContent conversationContent = new ConversationContent(); - conversationContent.setText("test"); - ConversationSendRequest request = new ConversationSendRequest(); - request.setFrom("channelid"); - request.setTo("+34123123123"); - request.setTtl("15s"); - request.setType(ConversationContentType.TEXT); - request.setContent(conversationContent); - request.setTrackId("mycampaign"); - ConversationSendResponse conversationSendResponse = messageBirdClient.sendMessage(request); - ConversationMessage conversationMessageResponse = messageBirdClient.viewConversationMessage(conversationSendResponse.getId()); - assertEquals(request.getFrom(),conversationMessageResponse.getChannelId()); - assertEquals(ConversationContentType.TEXT,conversationMessageResponse.getType()); - assertEquals(request.getTrackId(),conversationMessageResponse.getTrackId()); - assertNotNull(conversationMessageResponse.getStatus()); - } - - @Test public void testGetHlr() throws Exception { final Hlr hlr = messageBirdClient.getRequestHlr(messageBirdMSISDN, "Test Reference " + messageBirdMSISDN); @@ -175,7 +153,7 @@ public void testSendDeleteMessage() throws Exception { assertNotNull(mr.getId()); assertEquals(mr.getReference(), reference); assertEquals(mr.getBody(), body); - assertEquals(mr.getDatacoding(), DataCodingType.plain); + assertEquals(DataCodingType.plain,mr.getDatacoding()); // Deleting of a message is not yet supported in test mode // Thread.sleep(1000); @@ -245,8 +223,8 @@ public void testSendDeleteFlashMessage() throws Exception { final String body = "Body test message Über € " + messageBirdMSISDN; final MessageResponse mr = messageBirdClient.sendFlashMessage("originator", body, Collections.singletonList(messageBirdMSISDN)); assertNotNull(mr.getId()); - assertSame(mr.getType(), MsgType.flash); - assertSame(mr.getMclass(), MClassType.flash); + assertSame(MsgType.flash,mr.getType() ); + assertSame(MClassType.flash, mr.getMclass()); // Deleting of a message is not yet supported in test mode // Thread.sleep(1000); @@ -317,8 +295,8 @@ public void testSendVoiceMessage() throws Exception { final VoiceMessageResponse mr = messageBirdClient.sendVoiceMessage(vm); assertNotNull(mr.getId()); assertEquals(mr.getBody(), body); - assertSame(mr.getIfMachine(), IfMachineType.hangup); - assertSame(mr.getVoice(), VoiceType.male); + assertSame(IfMachineType.hangup, mr.getIfMachine() ); + assertSame(VoiceType.male, mr.getVoice()); // Deleting of a message is not yet supported in test mode // Thread.sleep(1000); @@ -345,17 +323,6 @@ public void testSendVoiceMessage2() throws Exception { assertNotNull(mr.getId()); assertEquals(mr.getBody(), body); assertEquals(mr.getReference(), reference); - - Thread.sleep(500); - // Viewing of a message is not yet supported in test mode - // final VoiceMessageResponse mr2 = messageBirdClient.viewVoiceMessage(mr.getId()); - // assertTrue(mr2.getId() != null); - // assertTrue(mr2.getBody().equals(body)); - // assertTrue(mr2.getReference().equals(reference)); - - // Deleting of a message is not yet supported in test mode - // Thread.sleep(1000); - // Gives 404 messageBirdClient.deleteVoiceMessage(mr.getId()); } /** @@ -390,7 +357,7 @@ public void testSendVerifyToken1() throws UnauthorizedException, GeneralExceptio } @Test - public void testSendVerifyTokenAndGetVerifyObject() throws UnauthorizedException, GeneralException, NotFoundException { + public void testSendVerifyTokenAndGetVerifyObject() throws UnauthorizedException, GeneralException { Verify verify = messageBirdClient.sendVerifyToken(messageBirdMSISDN.toString()); assertFalse("href is empty", verify.getHref().isEmpty()); assertFalse("id is empty", verify.getId().isEmpty()); @@ -404,7 +371,7 @@ public void testSendVerifyTokenAndGetVerifyObject() throws UnauthorizedException } @Test - public void testVerifyToken() throws UnauthorizedException, GeneralException, UnsupportedEncodingException { + public void testVerifyToken() throws UnauthorizedException, GeneralException { Verify verify = messageBirdClient.sendVerifyToken(messageBirdMSISDN.toString()); assertFalse("href is empty", verify.getHref().isEmpty()); @@ -420,7 +387,7 @@ public void testVerifyToken() throws UnauthorizedException, GeneralException, Un } @Test - public void testDeleteVerifyToken() throws UnauthorizedException, GeneralException, NotFoundException, UnsupportedEncodingException { + public void testDeleteVerifyToken() throws UnauthorizedException, GeneralException { Verify verify = messageBirdClient.sendVerifyToken(messageBirdMSISDN.toString()); assertFalse("href is empty", verify.getHref().isEmpty()); try { @@ -474,8 +441,7 @@ public void shouldThrowIllegalArgumentExceptionWhenSourceOfVoiceCallIsMissing() } @Test(expected = IllegalArgumentException.class) - public void shouldThrowIllegalArgumentExceptionWhenDestinationOfVoiceCallIsMissing() throws UnauthorizedException, - GeneralException { + public void shouldThrowIllegalArgumentExceptionWhenDestinationOfVoiceCallIsMissing() throws UnauthorizedException, GeneralException { final VoiceCall voiceCall = new VoiceCall(); voiceCall.setSource("ANY_SOURCE"); @@ -527,8 +493,7 @@ public void testViewVoiceCall() throws UnauthorizedException, GeneralException, } @Test - public void testDeleteVoiceCall() throws UnauthorizedException, - GeneralException, NotFoundException { + public void testDeleteVoiceCall() throws UnauthorizedException, GeneralException, NotFoundException { MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); @@ -1137,8 +1102,7 @@ public void testListWhatsAppTemplates() throws UnauthorizedException, GeneralExc } @Test - public void testGetWhatsAppTemplatesBy() - throws GeneralException, UnauthorizedException, NotFoundException, ClassNotFoundException { + public void testGetWhatsAppTemplatesBy() throws GeneralException, UnauthorizedException, NotFoundException { final String templateName = "sample_template_name"; final TemplateResponse templateResponse1 = TestUtil.createWhatsAppTemplateResponse(templateName, "en_US"); final TemplateResponse templateResponse2 = TestUtil.createWhatsAppTemplateResponse("another_template", "en_US"); @@ -1169,8 +1133,7 @@ public void testGetWhatsAppTemplatesBy() } @Test - public void testFetchWhatsAppTemplateBy() - throws UnauthorizedException, GeneralException, NotFoundException { + public void testFetchWhatsAppTemplateBy() throws UnauthorizedException, GeneralException, NotFoundException { final String templateName = "sample_template_name"; final String language = "ko"; final TemplateResponse template = TestUtil.createWhatsAppTemplateResponse(templateName, language); @@ -1200,8 +1163,7 @@ public void testFetchWhatsAppTemplateBy() } @Test - public void testDeleteTemplatesByName() - throws UnauthorizedException, GeneralException, NotFoundException { + public void testDeleteTemplatesByName() throws UnauthorizedException, GeneralException, NotFoundException { final String templateName = "sample_template_name"; MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); @@ -1324,4 +1286,23 @@ public void testDeleteChildAccount() throws GeneralException, UnauthorizedExcept doNothing().when(messageBirdServiceMock).deleteByID(url, "ANY_ID"); messageBirdClientInjectMock.deleteChildAccount("id"); } + + @Test + public void testConversationMessage() throws Exception { + ConversationContent conversationContent = new ConversationContent(); + conversationContent.setText("test"); + ConversationSendRequest request = new ConversationSendRequest(); + request.setFrom("channelid"); + request.setTo("+34123123123"); + request.setTtl("15s"); + request.setType(ConversationContentType.TEXT); + request.setContent(conversationContent); + request.setTrackId("mycampaign"); + ConversationSendResponse conversationSendResponse = messageBirdClient.sendMessage(request); + ConversationMessage conversationMessageResponse = messageBirdClient.viewConversationMessage(conversationSendResponse.getId()); + assertEquals(request.getFrom(),conversationMessageResponse.getChannelId()); + assertEquals(ConversationContentType.TEXT,conversationMessageResponse.getType()); + assertEquals(request.getTrackId(),conversationMessageResponse.getTrackId()); + assertNotNull(conversationMessageResponse.getStatus()); + } } \ No newline at end of file From f12279df32a48b184bd1f59df7327c487c92142c Mon Sep 17 00:00:00 2001 From: Daniel Morales Date: Thu, 21 Apr 2022 18:41:25 +0100 Subject: [PATCH 374/516] Refactor testConversationMessage to use mocking. --- .../com/messagebird/MessageBirdClient.java | 10 +++---- .../messagebird/MessageBirdClientTest.java | 30 +++++++++++++++---- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 0e4f9ce2..4a2859a4 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -72,7 +72,7 @@ public class MessageBirdClient { * can, however, override this behaviour by providing absolute URLs * ourselves. */ - private static final String CONVERSATIONS_BASE_URL = "https://conversations.messagebird.com/v1"; + static final String CONVERSATIONS_BASE_URL = "https://conversations.messagebird.com/v1"; static final String VOICE_CALLS_BASE_URL = "https://voice.messagebird.com"; static final String NUMBERS_CALLS_BASE_URL = "https://numbers.messagebird.com/v1"; static final String MESSAGING_BASE_URL = "https://messaging.messagebird.com/v1"; @@ -91,10 +91,10 @@ public class MessageBirdClient { private static final String VERIFYPATH = "/verify"; private static final String VERIFYEMAILPATH = "/verify/messages/email"; private static final String VOICEMESSAGESPATH = "/voicemessages"; - private static final String CONVERSATION_PATH = "/conversations"; - private static final String CONVERSATION_SEND_PATH = "/send"; - private static final String CONVERSATION_MESSAGE_PATH = "/messages"; - private static final String CONVERSATION_WEBHOOK_PATH = "/webhooks"; + static final String CONVERSATION_PATH = "/conversations"; + static final String CONVERSATION_SEND_PATH = "/send"; + static final String CONVERSATION_MESSAGE_PATH = "/messages"; + static final String CONVERSATION_WEBHOOK_PATH = "/webhooks"; static final String INTEGRATIONS_WHATSAPP_PATH = "/platforms/whatsapp"; static final String VOICECALLSPATH = "/calls"; static final String LEGSPATH = "/legs"; diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 82bc36f4..11113319 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -10,6 +10,8 @@ import com.messagebird.objects.integrations.TemplateResponse; import com.messagebird.objects.voicecalls.*; import java.util.ArrayList; + +import org.jetbrains.annotations.NotNull; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -1289,6 +1291,25 @@ public void testDeleteChildAccount() throws GeneralException, UnauthorizedExcept @Test public void testConversationMessage() throws Exception { + ConversationSendRequest request = createDummyConversationRequest(); + ConversationSendResponse conversationSendResponse = new ConversationSendResponse(); + conversationSendResponse.setStatus("ACCEPTED"); + conversationSendResponse.setId("1234"); + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + + when(messageBirdServiceMock.sendPayLoad( CONVERSATIONS_BASE_URL + CONVERSATION_SEND_PATH, request, ConversationSendResponse.class)) + .thenReturn(conversationSendResponse); + ConversationSendResponse response = messageBirdClientInjectMock.sendMessage(request); + + verify(messageBirdServiceMock, times(1)) + .sendPayLoad(CONVERSATIONS_BASE_URL + CONVERSATION_SEND_PATH, request, ConversationSendResponse.class); + assertNotNull(response.getId()); + assertNotNull(response.getStatus()); + } + + private ConversationSendRequest createDummyConversationRequest() { ConversationContent conversationContent = new ConversationContent(); conversationContent.setText("test"); ConversationSendRequest request = new ConversationSendRequest(); @@ -1298,11 +1319,8 @@ public void testConversationMessage() throws Exception { request.setType(ConversationContentType.TEXT); request.setContent(conversationContent); request.setTrackId("mycampaign"); - ConversationSendResponse conversationSendResponse = messageBirdClient.sendMessage(request); - ConversationMessage conversationMessageResponse = messageBirdClient.viewConversationMessage(conversationSendResponse.getId()); - assertEquals(request.getFrom(),conversationMessageResponse.getChannelId()); - assertEquals(ConversationContentType.TEXT,conversationMessageResponse.getType()); - assertEquals(request.getTrackId(),conversationMessageResponse.getTrackId()); - assertNotNull(conversationMessageResponse.getStatus()); + return request; } + + } \ No newline at end of file From 11ceaec6735322504d6c1439d0401a4ff44fce8b Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 22 Apr 2022 10:36:56 +0200 Subject: [PATCH 375/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 5e2288db..9b63ea2d 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.2 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 892db5c6..319c41f7 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -74,7 +74,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.2.2"; + private final String clientVersion = "3.2.3"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index c94c0398..7bb2024e 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.2.2 + 3.2.3 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.2.2 + 3.2.3 compile From 255131d6af6af28e891d9dc90611b666d033dee4 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 22 Apr 2022 10:38:28 +0200 Subject: [PATCH 376/516] [maven-release-plugin] prepare release v3.2.3 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 9b63ea2d..cb28ba58 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.3-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.2.3 From 1b33f078473746395670f6186a2bcc9b1c3bf986 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 22 Apr 2022 10:38:32 +0200 Subject: [PATCH 377/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index cb28ba58..2d138391 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.3 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.2.3 + HEAD From 66d65263deb7e29b1a830fa40f9e8c5aee5d3d70 Mon Sep 17 00:00:00 2001 From: Yury Gargay Date: Fri, 22 Apr 2022 15:21:39 +0200 Subject: [PATCH 378/516] Deprecate CallFlow Title usage This field is deprecated now although users still can send and receive it. --- .../messagebird/MessageBirdServiceImpl.java | 2 +- .../objects/voicecalls/VoiceCallFlow.java | 2 + .../voicecalls/VoiceCallFlowRequest.java | 2 + .../messagebird/MessageBirdClientTest.java | 2 - .../test/java/com/messagebird/SpyService.java | 2 +- .../test/java/com/messagebird/TestUtil.java | 2 - .../com/messagebird/VoiceCallFlowTest.java | 24 ++++++++++- .../fixtures/call_flow_update_response.json | 1 - .../resources/fixtures/call_flow_view.json | 1 - .../fixtures/call_flow_view_title.json | 41 +++++++++++++++++++ .../resources/fixtures/call_flows_list.json | 1 - .../resources/fixtures/call_flows_post.json | 1 - .../main/java/ExampleCreateVoiceCallFlow.java | 1 - .../src/main/java/ExampleSendVoiceCall.java | 2 - .../main/java/ExampleUpdateVoiceCallFlow.java | 1 - 15 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 api/src/test/resources/fixtures/call_flow_view_title.json diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 892db5c6..b1b97c3d 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -363,7 +363,7 @@ private void handleHttpFailStatuses(final int status, String body) throws Unauth

APIResponse doRequest(final String method, final String url, final Map headers, final P payload) throws GeneralException { HttpURLConnection connection = null; InputStream inputStream = null; - + if (METHOD_PATCH.equalsIgnoreCase(method)) { // It'd perhaps be cleaner to call this in the constructor, but // we'd then need to throw GeneralExceptions from there. This means diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java index d64f0d2c..9554ac58 100644 --- a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java @@ -37,10 +37,12 @@ public void setId(String id) { this.id = id; } + @Deprecated public String getTitle() { return title; } + @Deprecated public void setTitle(String title) { this.title = title; } diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowRequest.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowRequest.java index 3990cfb2..e447d9d9 100644 --- a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowRequest.java +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlowRequest.java @@ -36,10 +36,12 @@ public void setId(String id) { this.id = id; } + @Deprecated public String getTitle() { return title; } + @Deprecated public void setTitle(String title) { this.title = title; } diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 11113319..bfc254aa 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -427,7 +427,6 @@ public void shouldThrowIllegalArgumentExceptionWhenSourceOfVoiceCallIsMissing() voiceCall.setDestination("ANY_DESTINATION"); final VoiceCallFlow voiceCallFlow = new VoiceCallFlow(); - voiceCallFlow.setTitle("Test title"); VoiceStep voiceStep = new VoiceStep(); voiceStep.setAction("say"); @@ -448,7 +447,6 @@ public void shouldThrowIllegalArgumentExceptionWhenDestinationOfVoiceCallIsMissi voiceCall.setSource("ANY_SOURCE"); final VoiceCallFlow voiceCallFlow = new VoiceCallFlow(); - voiceCallFlow.setTitle("Test title"); VoiceStep voiceStep = new VoiceStep(); voiceStep.setAction("say"); diff --git a/api/src/test/java/com/messagebird/SpyService.java b/api/src/test/java/com/messagebird/SpyService.java index 7b741e9f..2922b1b4 100644 --- a/api/src/test/java/com/messagebird/SpyService.java +++ b/api/src/test/java/com/messagebird/SpyService.java @@ -70,7 +70,7 @@ static

SpyService expects(final String method, final String url, final P pay service.method = method; service.url = url; service.payload = payload; - + return service; } diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index d5cf47a9..9bf28eb8 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -28,7 +28,6 @@ static VoiceCall createVoiceCall(String destination) { voiceCall.setDestination(destination); final VoiceCallFlow voiceCallFlow = new VoiceCallFlow(); - voiceCallFlow.setTitle("Test title"); VoiceStep voiceStep = new VoiceStep(); voiceStep.setAction("say"); @@ -211,7 +210,6 @@ public static VoiceStep createVoiceStep() { public static VoiceCallFlowRequest createVoiceCallFlowRequest() { final VoiceCallFlowRequest voiceCallFlow = new VoiceCallFlowRequest(); - voiceCallFlow.setTitle("ANY_TITLE"); voiceCallFlow.setRecord(true); voiceCallFlow.setSteps(Collections.singletonList(createVoiceStep())); voiceCallFlow.setDefaultCall(true); diff --git a/api/src/test/java/com/messagebird/VoiceCallFlowTest.java b/api/src/test/java/com/messagebird/VoiceCallFlowTest.java index 9767e223..c38c0c7f 100644 --- a/api/src/test/java/com/messagebird/VoiceCallFlowTest.java +++ b/api/src/test/java/com/messagebird/VoiceCallFlowTest.java @@ -64,6 +64,21 @@ public void testView() throws GeneralException, UnauthorizedException, NotFoundE this.testVoiceCallFlowAgainstFixture(voiceCallFlow); } + @Test + public void testViewTitlePresent() throws GeneralException, UnauthorizedException, NotFoundException { + String responseFixture = Resources.readResourceText("/fixtures/call_flow_view_title.json"); + MessageBirdService messageBirdService = SpyService + .expects("GET", "call-flows/e781a76f-14ad-45b0-8490-409300244e20") + .withVoiceCallAPIBaseURL() + .andReturns(new APIResponse(responseFixture)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + VoiceCallFlow voiceCallFlow = messageBirdClient + .viewVoiceCallFlow("e781a76f-14ad-45b0-8490-409300244e20") + .getData() + .get(0); + this.testVoiceCallFlowAgainstFixture(voiceCallFlow, true); + } + @Test (expected = IllegalArgumentException.class) public void testViewShouldThrowInvalidArgumentException() throws NotFoundException, GeneralException, UnauthorizedException { String responseFixture = Resources.readResourceText("/fixtures/call_flow_view.json"); @@ -81,7 +96,6 @@ public void testUpdate() throws GeneralException, UnauthorizedException, NotFoun String responseFixture = Resources.readResourceText("/fixtures/call_flow_update_response.json"); VoiceCallFlowRequest voiceCallFlowRequest = new VoiceCallFlowRequest("e781a76f-14ad-45b0-8490-409300244e20"); - voiceCallFlowRequest.setTitle("Forward call to 316123456782"); voiceCallFlowRequest.setDefaultCall(true); voiceCallFlowRequest.setRecord(true); voiceCallFlowRequest.setSteps( @@ -220,9 +234,15 @@ public void testDeleteIllegalArgumentException() throws NotFoundException, Gener * In order to reuse this method for further tests you need to make sure that the fixtures * match the date in this test. See call_flows_post.json */ + private void testVoiceCallFlowAgainstFixture(VoiceCallFlow voiceCallFlow) { + testVoiceCallFlowAgainstFixture(voiceCallFlow, false); + } + + private void testVoiceCallFlowAgainstFixture(VoiceCallFlow voiceCallFlow, boolean hasTitle) { assertEquals(voiceCallFlow.getId(), "e781a76f-14ad-45b0-8490-409300244e20"); - assertEquals(voiceCallFlow.getTitle(), "Forward call to 31612345678"); + if (!hasTitle) assertEquals(voiceCallFlow.getTitle(), null); + if (hasTitle) assertNotEquals(voiceCallFlow.getTitle(), null); assertEquals(voiceCallFlow.isRecord(), true); assertEquals(voiceCallFlow.isDefaultCall(), false); assertEquals(voiceCallFlow.getCreatedAt().toString(), "Tue Aug 06 16:13:06 CEST 2019"); diff --git a/api/src/test/resources/fixtures/call_flow_update_response.json b/api/src/test/resources/fixtures/call_flow_update_response.json index 13663211..1a7c1f21 100644 --- a/api/src/test/resources/fixtures/call_flow_update_response.json +++ b/api/src/test/resources/fixtures/call_flow_update_response.json @@ -2,7 +2,6 @@ "data": [ { "id": "e781a76f-14ad-45b0-8490-409300244e20", - "title": "Forward call to 31612345678", "steps": [ { "id": "a8e44a38-b935-482f-b17f-ed3472c6292c", diff --git a/api/src/test/resources/fixtures/call_flow_view.json b/api/src/test/resources/fixtures/call_flow_view.json index 247d7cb5..7546da2b 100644 --- a/api/src/test/resources/fixtures/call_flow_view.json +++ b/api/src/test/resources/fixtures/call_flow_view.json @@ -2,7 +2,6 @@ "data": [ { "id": "e781a76f-14ad-45b0-8490-409300244e20", - "title": "Forward call to 31612345678", "steps": [ { "id": "a8e44a38-b935-482f-b17f-ed3472c6292c", diff --git a/api/src/test/resources/fixtures/call_flow_view_title.json b/api/src/test/resources/fixtures/call_flow_view_title.json new file mode 100644 index 00000000..1640484d --- /dev/null +++ b/api/src/test/resources/fixtures/call_flow_view_title.json @@ -0,0 +1,41 @@ +{ + "data": [ + { + "title": "Call title", + "id": "e781a76f-14ad-45b0-8490-409300244e20", + "steps": [ + { + "id": "a8e44a38-b935-482f-b17f-ed3472c6292c", + "action": "transfer", + "options": { + "destination" : "31612345678", + "payload" : "Test payload", + "language" : "en-GB", + "voice" : "male", + "repeat" : 1, + "media" : "test.mp3", + "length" : 1, + "maxLength" : 2, + "timeout" : 3, + "finishOnKey" : "1", + "transcribe" : "false", + "transcribeLanguage" : "en-GB", + "record" : "both", + "url" : "http://", + "ifMachine" : "ifMachine", + "machineTimeout" : 200, + "onFinish" : "http://", + "mask" : false + } + } + ], + "record": true, + "default": false, + "createdAt": "2019-08-06T14:13:06Z", + "updatedAt": "2019-08-06T14:13:06Z" + } + ], + "_links": { + "self": "/call-flows/70fbdda2-4f1f-44ce-8792-75af32cf598c" + } +} \ No newline at end of file diff --git a/api/src/test/resources/fixtures/call_flows_list.json b/api/src/test/resources/fixtures/call_flows_list.json index 81d57a2d..0820526d 100644 --- a/api/src/test/resources/fixtures/call_flows_list.json +++ b/api/src/test/resources/fixtures/call_flows_list.json @@ -2,7 +2,6 @@ "data": [ { "id": "e781a76f-14ad-45b0-8490-409300244e20", - "title": "Forward call to 31612345678", "steps": [ { "id": "a8e44a38-b935-482f-b17f-ed3472c6292c", diff --git a/api/src/test/resources/fixtures/call_flows_post.json b/api/src/test/resources/fixtures/call_flows_post.json index 13663211..1a7c1f21 100644 --- a/api/src/test/resources/fixtures/call_flows_post.json +++ b/api/src/test/resources/fixtures/call_flows_post.json @@ -2,7 +2,6 @@ "data": [ { "id": "e781a76f-14ad-45b0-8490-409300244e20", - "title": "Forward call to 31612345678", "steps": [ { "id": "a8e44a38-b935-482f-b17f-ed3472c6292c", diff --git a/examples/src/main/java/ExampleCreateVoiceCallFlow.java b/examples/src/main/java/ExampleCreateVoiceCallFlow.java index 8a39c177..83f265b1 100644 --- a/examples/src/main/java/ExampleCreateVoiceCallFlow.java +++ b/examples/src/main/java/ExampleCreateVoiceCallFlow.java @@ -24,7 +24,6 @@ public static void main(String[] args) { final VoiceCallFlowRequest voiceCallFlowRequest = new VoiceCallFlowRequest(); - voiceCallFlowRequest.setTitle(args[1]); voiceCallFlowRequest.setRecord(true); // Can be false as well, see docs VoiceStep voiceStep = new VoiceStep(); voiceCallFlowRequest.setSteps(Collections.singletonList(voiceStep)); // VoiceStep Object diff --git a/examples/src/main/java/ExampleSendVoiceCall.java b/examples/src/main/java/ExampleSendVoiceCall.java index 64617a47..c61fddd0 100644 --- a/examples/src/main/java/ExampleSendVoiceCall.java +++ b/examples/src/main/java/ExampleSendVoiceCall.java @@ -33,9 +33,7 @@ public static void main(String[] args) { voiceCall.setDestination(args[1]); voiceCall.setWebhook("https://example.com/","foobar"); - //Title and steps are required fields for creating callFlow final VoiceCallFlow voiceCallFlow = new VoiceCallFlow(); - voiceCallFlow.setTitle("Test title"); //action is required VoiceStep voiceStep = new VoiceStep(); voiceStep.setAction("say"); diff --git a/examples/src/main/java/ExampleUpdateVoiceCallFlow.java b/examples/src/main/java/ExampleUpdateVoiceCallFlow.java index d653c37e..4a6bcf1c 100644 --- a/examples/src/main/java/ExampleUpdateVoiceCallFlow.java +++ b/examples/src/main/java/ExampleUpdateVoiceCallFlow.java @@ -24,7 +24,6 @@ public static void main(String[] args) { final VoiceCallFlowRequest voiceCallFlowRequest = new VoiceCallFlowRequest(); - voiceCallFlowRequest.setTitle(args[2]); voiceCallFlowRequest.setRecord(true); // Can be false as well, see docs VoiceStep voiceStep = new VoiceStep(); voiceCallFlowRequest.setSteps(Collections.singletonList(voiceStep)); // VoiceStep Object From 09526621efe2ebc9be64c468e1e142f9deb57b8b Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 22 Apr 2022 18:26:11 +0200 Subject: [PATCH 379/516] updated for a new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 2d138391..dc4f2338 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.4-SNAPSHOT From fb9afeec0dba3e773eec624f865fffe06f5ea8ac Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 28 Apr 2022 11:26:10 +0200 Subject: [PATCH 380/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index dc4f2338..2d138391 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.3 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index bc47f267..d4e10264 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -74,7 +74,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.2.3"; + private final String clientVersion = "3.2.4"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 7bb2024e..56f51d0c 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.2.3 + 3.2.4 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.2.3 + 3.2.4 compile From 5e1f69d451835f95e4c12de163f9b117a3e77318 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 28 Apr 2022 11:27:23 +0200 Subject: [PATCH 381/516] [maven-release-plugin] prepare release v3.2.4 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 2d138391..ad401ff4 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.4-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.2.4 From bd0a2e18e485a59e147c23f564315f704adce1d0 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 28 Apr 2022 11:27:27 +0200 Subject: [PATCH 382/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index ad401ff4..86e2177a 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.4 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.2.4 + HEAD From db6fffbcf6f3ffece709867d73b5d5b642a35edb Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 28 Apr 2022 17:46:17 +0200 Subject: [PATCH 383/516] updated release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 86e2177a..72b15cdb 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.5-SNAPSHOT From b6369495d679957a51090a4bf499e77937392039 Mon Sep 17 00:00:00 2001 From: cemturker Date: Tue, 3 May 2022 14:31:58 +0200 Subject: [PATCH 384/516] Add missing conversation message statuses --- .../ConversationMessageStatus.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageStatus.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageStatus.java index 475c7b74..aee5c5f5 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageStatus.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageStatus.java @@ -15,7 +15,25 @@ public enum ConversationMessageStatus { READ("read"), RECEIVED("received"), SENT("sent"), - UNSUPPORTED("unsupported"); + UNSUPPORTED("unsupported"), + ACCEPTED("accepted"), + REJECTED("rejected"), + UNKNOWN("unknown"), + //WA specific statuses + TRANSMITTED("transmitted"), + //SMS specific statuses + DELIVERY_FAILED("delivery_failed"), + BUFFERED("buffered"), + EXPIRED("expired"), + //Email specific statuses + CLICKED("clicked"), + OPENED("opened"), + BOUNCE("bounce"), + SPAM_COMPLAINT("spam_complaint"), + OUT_OF_BOUNDED("out_of_bounded"), + DELAYED("delayed"), + LIST_UNSUBSCRIBE("list_unsubscribe"), + DISPATCHED("dispatched"); private final String status; From 088ecbe1c9086f225cdf4a3ca3bd6a5998d53d5d Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 12 May 2022 17:56:13 +0200 Subject: [PATCH 385/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 72b15cdb..86e2177a 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.4 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index d4e10264..717b40d9 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -74,7 +74,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.2.4"; + private final String clientVersion = "3.2.5"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 56f51d0c..ae536533 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.2.4 + 3.2.5 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.2.4 + 3.2.5 compile From 383e8a2c2adf43ce91de14ec242cb6911c241675 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 12 May 2022 17:57:31 +0200 Subject: [PATCH 386/516] [maven-release-plugin] prepare release v3.2.5 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 86e2177a..470a3be1 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.5-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.2.5 From 3bdbf7fc6dd54dc12944ab96868f561a3ccdaf94 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 12 May 2022 17:57:35 +0200 Subject: [PATCH 387/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 470a3be1..826bd34b 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.5 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.2.5 + HEAD From c031aefd099fbc5079c61b6ca80818591bc28e63 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 13 May 2022 09:40:47 +0200 Subject: [PATCH 388/516] new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 826bd34b..2389c9be 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.6-SNAPSHOT From 0e3738f9434290f173ce35f138700f174269bab3 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 1 Aug 2022 14:01:32 +0200 Subject: [PATCH 389/516] added video enum on TemplateMediaType --- .../com/messagebird/objects/conversations/TemplateMediaType.java | 1 + 1 file changed, 1 insertion(+) diff --git a/api/src/main/java/com/messagebird/objects/conversations/TemplateMediaType.java b/api/src/main/java/com/messagebird/objects/conversations/TemplateMediaType.java index 51afa594..fe5494fd 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/TemplateMediaType.java +++ b/api/src/main/java/com/messagebird/objects/conversations/TemplateMediaType.java @@ -7,6 +7,7 @@ public enum TemplateMediaType { IMAGE("image"), DOCUMENT("document"), + VIDEO("video"), TEXT("text"), CURRENCY("currency"), DATETIME("date_time"), From 9600f6cd05a8efc5a4d7b9457f2300822ed05d5c Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 1 Aug 2022 14:34:28 +0200 Subject: [PATCH 390/516] updated after review --- .../objects/conversations/MessageParam.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java b/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java index 8de37ab7..9776f2be 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java +++ b/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java @@ -9,6 +9,7 @@ public class MessageParam { private String dateTime; private Media document; private Media image; + private Media voice; public TemplateMediaType getType() { return type; @@ -66,16 +67,21 @@ public void setImage(Media image) { this.image = image; } + public Media getVoice() { return voice; } + + public void setVoice(Media voice) { this.voice = voice; } + @Override public String toString() { return "MessageParam{" + - "type=" + type + + "type=" + type + '\'' + ", text='" + text + '\'' + ", payload='" + payload + '\'' + - ", currency=" + currency + + ", currency=" + currency + '\'' + ", dateTime='" + dateTime + '\'' + - ", document=" + document + - ", image=" + image + + ", document=" + document + '\'' + + ", image=" + image + '\'' + + ", voice=" + voice + '}'; } } From b1a999ce1e33931a63275f0222bfd2eed7ef72f3 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 1 Aug 2022 14:40:48 +0200 Subject: [PATCH 391/516] renamed voice field as video --- .../messagebird/objects/conversations/MessageParam.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java b/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java index 9776f2be..069c3f62 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java +++ b/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java @@ -9,7 +9,7 @@ public class MessageParam { private String dateTime; private Media document; private Media image; - private Media voice; + private Media video; public TemplateMediaType getType() { return type; @@ -67,9 +67,9 @@ public void setImage(Media image) { this.image = image; } - public Media getVoice() { return voice; } + public Media getVideo() { return video; } - public void setVoice(Media voice) { this.voice = voice; } + public void setVideo(Media video) { this.video = video; } @Override public String toString() { @@ -81,7 +81,7 @@ public String toString() { ", dateTime='" + dateTime + '\'' + ", document=" + document + '\'' + ", image=" + image + '\'' + - ", voice=" + voice + + ", video=" + video + '}'; } } From 859cfd79f322496ddfaeafec9852618118d93455 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 1 Aug 2022 14:49:45 +0200 Subject: [PATCH 392/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 2389c9be..826bd34b 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.5 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 717b40d9..a6cf289a 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -74,7 +74,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.2.5"; + private final String clientVersion = "3.2.6"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index ae536533..43716020 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.2.5 + 3.2.6 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.2.5 + 3.2.6 compile From 3e530e3a0c7ff1ac8731f40c69e19d7eebaea700 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 1 Aug 2022 14:51:17 +0200 Subject: [PATCH 393/516] [maven-release-plugin] prepare release v3.2.6 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 826bd34b..de1ece52 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.6-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v3.2.6 From e871bfa9a33b668fa7512283b013a75575405995 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 1 Aug 2022 14:51:21 +0200 Subject: [PATCH 394/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index de1ece52..249992ab 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.6 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v3.2.6 + HEAD From e7262051995e2530ca515fd7b5b5d46401208f1e Mon Sep 17 00:00:00 2001 From: denizkilic Date: Tue, 2 Aug 2022 09:30:47 +0200 Subject: [PATCH 395/516] new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 249992ab..49fff0fb 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.7-SNAPSHOT From 72cb9447ded08e87af13fa76e83e9415ce23bb80 Mon Sep 17 00:00:00 2001 From: David Oberholzer Date: Wed, 17 Aug 2022 16:14:38 +0200 Subject: [PATCH 396/516] WhatsApp Templates updated with WABA ID attribute and client methods updated. Version bumped to 4.0.0 due to non-backwards compatible changes. --- .../com/messagebird/MessageBirdClient.java | 171 +++++++++++--- .../messagebird/MessageBirdServiceImpl.java | 2 +- .../objects/integrations/Template.java | 29 ++- .../integrations/TemplateResponse.java | 20 ++ .../messagebird/MessageBirdClientTest.java | 220 +++++++++++++++++- .../test/java/com/messagebird/TestUtil.java | 5 + examples/pom.xml | 4 +- .../src/main/java/ExampleCreateTemplate.java | 7 +- ...xampleDeleteTemplateByNameAndLanguage.java | 40 ---- ...ExampleFetchTemplateByNameAndLanguage.java | 75 +++++- .../main/java/ExampleListTemplatesByName.java | 75 +++++- .../ExampleListTemplatesByWABAOrChannel.java | 66 ++++++ 12 files changed, 619 insertions(+), 95 deletions(-) delete mode 100644 examples/src/main/java/ExampleDeleteTemplateByNameAndLanguage.java create mode 100644 examples/src/main/java/ExampleListTemplatesByWABAOrChannel.java diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 4a2859a4..276ba3c8 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1894,6 +1894,34 @@ public TemplateList listWhatsAppTemplates(final int offset, final int limit) return messageBirdService.requestList(url, offset, limit, TemplateList.class); } + /** + * Gets a WhatsAppTemplate listing with specified pagination options and a wabaID or channelID filter. + * + * @param offset Number of objects to skip. + * @param limit Number of objects to take. + * @param wabaID The WABA ID to filter templates by. + * @param channelID A channel ID filter to return only templates that can be sent via that channel. + * @return List of templates. + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + * @throws IllegalArgumentException if the provided arguments are not valid + */ + public TemplateList listWhatsAppTemplates(final int offset, final int limit, final String wabaID, final String channelID) + throws UnauthorizedException, GeneralException, IllegalArgumentException { + validateWABAIDAndChannelIDArguments(wabaID, channelID); + + Map map = new LinkedHashMap<>(); + if (wabaID != null) map.put("wabaId", wabaID); + if (channelID != null) map.put("channelId", channelID); + String url = String.format( + "%s%s%s", + INTEGRATIONS_BASE_URL_V3, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH + ); + return messageBirdService.requestList(url, map, offset, limit, TemplateList.class); + } + /** * Gets a template listing with default pagination options. * @@ -1913,12 +1941,13 @@ public TemplateList listWhatsAppTemplates() throws UnauthorizedException, Genera * * @param templateName A name as returned by getWhatsAppTemplateBy in the name variable * @return {@code List} template list - * @throws UnauthorizedException if client is unauthorized - * @throws GeneralException general exception - * @throws NotFoundException if template name is not found + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + * @throws NotFoundException if template name is not found + * @throws IllegalArgumentException if the provided arguments are not valid */ public List getWhatsAppTemplatesBy(final String templateName) - throws GeneralException, UnauthorizedException, NotFoundException { + throws GeneralException, UnauthorizedException, NotFoundException, IllegalArgumentException { if (templateName == null) { throw new IllegalArgumentException("Template name must be specified."); } @@ -1933,19 +1962,50 @@ public List getWhatsAppTemplatesBy(final String templateName) return messageBirdService.requestByIdAsList(url, templateName, TemplateResponse.class); } + /** + * Retrieves the template of an existing template name. + * + * @param templateName A name as returned by getWhatsAppTemplateBy in the name variable + * @param wabaID An optional WABA ID to look for the template ID under. + * @param channelID An optional channel ID to specify. If the template can be sent via the channel, it will return the template. + * + * @return {@code List} template list + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + * @throws NotFoundException if template name is not found under the given WABA or cannot be sent under the supplied channel ID + * @throws IllegalArgumentException if the provided arguments are not valid + */ + public List getWhatsAppTemplatesBy(final String templateName, final String wabaID, final String channelID) + throws GeneralException, UnauthorizedException, NotFoundException, IllegalArgumentException { + if (templateName == null) { + throw new IllegalArgumentException("Template name must be specified."); + } + + String id = String.format("%s%s", templateName, getWabaIDOrChannelIDQuery(wabaID, channelID)); + String url = String.format( + "%s%s%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH + ); + + return messageBirdService.requestByIdAsList(url, id, TemplateResponse.class); + } + /** - * Retrieves the template of an existing template name and language. + * Retrieves the template of an existing template name and language under the first waba connected to the requesting user. * * @param templateName A name as returned by getWhatsAppTemplateBy in the name variable * @param language A language code as returned by getWhatsAppTemplateBy in the language variable * - * @return {@code TemplateResponse} template list + * @return {@code TemplateResponse} template * @throws UnauthorizedException if client is unauthorized * @throws GeneralException general exception - * @throws NotFoundException if template name and language are not found + * @throws NotFoundException if template name and language are not found under the first waba connected to the requesting user. + * @throws IllegalArgumentException if the provided arguments are not valid */ public TemplateResponse fetchWhatsAppTemplateBy(final String templateName, final String language) - throws GeneralException, UnauthorizedException, NotFoundException { + throws GeneralException, UnauthorizedException, NotFoundException, IllegalArgumentException { if (templateName == null || language == null) { throw new IllegalArgumentException("Template name and language must be specified."); } @@ -1962,51 +2022,98 @@ public TemplateResponse fetchWhatsAppTemplateBy(final String templateName, final } /** - * Delete templates of an existing template name. + * Retrieves the template of an existing template name and language under a WABA or for a channel. * - * @param templateName A template name which is created on the MessageBird platform - * @throws UnauthorizedException if client is unauthorized - * @throws GeneralException general exception - * @throws NotFoundException if template name is not found + * @param templateName A name as returned by getWhatsAppTemplateBy in the name variable + * @param language A language code as returned by getWhatsAppTemplateBy in the language variable + * @param wabaID An optional WABA ID to look for the template ID under. + * @param channelID An optional channel ID to specify. If the template can be sent via the channel, it will return the template. + * + * @return {@code TemplateResponse} template + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + * @throws NotFoundException if template name and language are not found under the given WABA or cannot be sent under the supplied channel ID. + * @throws IllegalArgumentException if the provided arguments are not valid */ - public void deleteTemplatesBy(final String templateName) - throws UnauthorizedException, GeneralException, NotFoundException { - if (templateName == null) { - throw new IllegalArgumentException("Template name must be specified."); + public TemplateResponse fetchWhatsAppTemplateBy(final String templateName, final String language, final String wabaID, final String channelID) + throws GeneralException, UnauthorizedException, NotFoundException, IllegalArgumentException { + if (templateName == null || language == null) { + throw new IllegalArgumentException("Template name and language must be specified."); } String url = String.format( - "%s%s%s/%s", - INTEGRATIONS_BASE_URL_V2, - INTEGRATIONS_WHATSAPP_PATH, - TEMPLATES_PATH, - templateName + "%s%s%s/%s/%s%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH, + templateName, + language, + getWabaIDOrChannelIDQuery(wabaID, channelID) ); - messageBirdService.delete(url, null); + return messageBirdService.request(url, TemplateResponse.class); } /** - * Delete template of an existing template name and language. + * Validates the WABA ID and Channel ID argument pair. + * + * @param wabaID A WABA ID. + * @param channelID A channel ID. + * @throws IllegalArgumentException if the argument pair is invalid. + */ + private void validateWABAIDAndChannelIDArguments(String wabaID, String channelID) + throws IllegalArgumentException { + if (wabaID == null && channelID == null) { + throw new IllegalArgumentException("wabaID or channelID must be specified"); + } + + if (wabaID != null && channelID != null) { + throw new IllegalArgumentException("only supply wabaID or channelID - not both"); + } + } + + /** + * Validates the WABA ID and Channel ID argument pair and returns a valid query parameter string. + * + * @param wabaID A WABA ID. + * @param channelID A channel ID. + * @throws IllegalArgumentException if the argument pair is invalid. + */ + private String getWabaIDOrChannelIDQuery(String wabaID, String channelID) + throws IllegalArgumentException { + validateWABAIDAndChannelIDArguments(wabaID, channelID); + + String query = ""; + + if (wabaID != null) { + query = String.format("?wabaId=%s", wabaID); + } + if (channelID != null) { + query = String.format("?channelId=%s", channelID); + } + + return query; + } + + /** + * Delete templates of an existing template name. * * @param templateName A template name which is created on the MessageBird platform - * @param language A language which is created on the MessageBird platform * @throws UnauthorizedException if client is unauthorized * @throws GeneralException general exception - * @throws NotFoundException if template name or language are not found + * @throws NotFoundException if template name is not found */ - public void deleteTemplatesBy(final String templateName, final String language) + public void deleteTemplatesBy(final String templateName) throws UnauthorizedException, GeneralException, NotFoundException { - if (templateName == null || language == null) { - throw new IllegalArgumentException("Template name and language must be specified."); + if (templateName == null) { + throw new IllegalArgumentException("Template name must be specified."); } String url = String.format( - "%s%s%s/%s/%s", + "%s%s%s/%s", INTEGRATIONS_BASE_URL_V2, INTEGRATIONS_WHATSAPP_PATH, TEMPLATES_PATH, - templateName, - language + templateName ); messageBirdService.delete(url, null); } diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index a6cf289a..d8cc63ce 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -74,7 +74,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.2.6"; + private final String clientVersion = "4.0.0"; private final String userAgentString; private Proxy proxy = null; diff --git a/api/src/main/java/com/messagebird/objects/integrations/Template.java b/api/src/main/java/com/messagebird/objects/integrations/Template.java index 715aeb48..333c7ec3 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/Template.java +++ b/api/src/main/java/com/messagebird/objects/integrations/Template.java @@ -12,16 +12,18 @@ public class Template { private String name; private String language; + private String wabaID; private List components; private HSMCategory category; public Template() { } - public Template(String name, String language, - List components, HSMCategory category) { + public Template(String name, String language, String wabaID, + List components, HSMCategory category) { this.name = name; this.language = language; + this.wabaID = wabaID; this.components = components; this.category = category; } @@ -42,6 +44,14 @@ public void setLanguage(String language) { this.language = language; } + public String getWabaID() { + return wabaID; + } + + public void setWabaID(String wabaID) { + this.wabaID = wabaID; + } + public List getComponents() { return components; } @@ -63,6 +73,7 @@ public String toString() { return "WhatsAppTemplate{" + "name='" + name + '\'' + ", language='" + language + '\'' + + ", wabaID='" + wabaID + '\'' + ", components=" + components + ", category='" + category + '\'' + '}'; @@ -77,6 +88,7 @@ public void validate() throws IllegalArgumentException { this.validateComponents(); this.validateName(); this.validateLanguage(); + this.validateWABAID(); this.validateCategory(); } @@ -123,6 +135,19 @@ private void validateLanguage() { } } + /** + * Check if wabaID field is valid. + * + * @throws IllegalArgumentException If wabaID field is null or empty string. + */ + private void validateWABAID() { + if (this.wabaID == null) { + throw new IllegalArgumentException("A \"wabaID\" field is required."); + } else if (this.wabaID.length() == 0) { + throw new IllegalArgumentException("A \"wabaID\" field can not be an empty string."); + } + } + /** * Check if category field is valid. * diff --git a/api/src/main/java/com/messagebird/objects/integrations/TemplateResponse.java b/api/src/main/java/com/messagebird/objects/integrations/TemplateResponse.java index bce35f82..426ae64a 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/TemplateResponse.java +++ b/api/src/main/java/com/messagebird/objects/integrations/TemplateResponse.java @@ -18,6 +18,8 @@ public class TemplateResponse implements Serializable { private List components; private HSMStatus status; private String rejectedReason; + private String wabaID; + private String namespace; private Date createdAt; private Date updatedAt; @@ -73,6 +75,22 @@ public void setRejectedReason(String rejectedReason) { this.rejectedReason = rejectedReason; } + public String getWabaID() { + return wabaID; + } + + public void setWabaID(String wabaID) { + this.wabaID = wabaID; + } + + public String getNamespace() { + return namespace; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; + } + public Date getCreatedAt() { return createdAt; } @@ -98,6 +116,8 @@ public String toString() { ", components=" + components + ", status='" + status + '\'' + ", rejectedReason='" + rejectedReason + '\'' + + ", wabaID='" + wabaID + '\'' + + ", namespace='" + namespace + '\'' + ", createdAt=" + createdAt + ", updatedAt=" + updatedAt + '}'; diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index bfc254aa..50459497 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -1066,6 +1066,7 @@ public void testCreateWhatsAppTemplate() throws UnauthorizedException, GeneralEx assertEquals(response.getLanguage(), templateResponse.getLanguage()); assertEquals(response.getCategory(), templateResponse.getCategory()); assertEquals(response.getStatus(), templateResponse.getStatus()); + assertEquals(response.getWabaID(), templateResponse.getWabaID()); assertEquals(response.getCreatedAt(), templateResponse.getCreatedAt()); assertEquals(response.getUpdatedAt(), templateResponse.getUpdatedAt()); @@ -1101,6 +1102,86 @@ public void testListWhatsAppTemplates() throws UnauthorizedException, GeneralExc } } + @Test + public void testListWhatsAppTemplatesDefault() throws UnauthorizedException, GeneralException { + final TemplateList templateList = TestUtil.createWhatsAppTemplateList("sample_template_name"); + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + + String url = String.format( + "%s%s%s", + INTEGRATIONS_BASE_URL_V3, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH + ); + + when(messageBirdServiceMock.requestList(url, 0, 10, TemplateList.class)) + .thenReturn(templateList); + + final TemplateList response = messageBirdClientInjectMock.listWhatsAppTemplates(); + verify(messageBirdServiceMock, times(1)).requestList(url, 0, 10, TemplateList.class); + assertNotNull(response); + for(int i = 0; i < response.getItems().size() ; i++) { + assertReflectionEquals(response.getItems().get(i), templateList.getItems().get(i)); + } + } + + @Test + public void testListWhatsAppTemplatesByWABAID() throws UnauthorizedException, GeneralException { + final TemplateList templateList = TestUtil.createWhatsAppTemplateList("sample_template_name"); + final String wabaID = "testWABAID"; + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + + String url = String.format( + "%s%s%s", + INTEGRATIONS_BASE_URL_V3, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH + ); + + Map map = new LinkedHashMap<>(); + map.put("wabaId", wabaID); + + when(messageBirdServiceMock.requestList(url, map, 0, 0, TemplateList.class)) + .thenReturn(templateList); + + final TemplateList response = messageBirdClientInjectMock.listWhatsAppTemplates(0, 0, wabaID, null); + verify(messageBirdServiceMock, times(1)).requestList(url, map, 0, 0, TemplateList.class); + assertNotNull(response); + for(int i = 0; i < response.getItems().size() ; i++) { + assertReflectionEquals(response.getItems().get(i), templateList.getItems().get(i)); + } + } + + @Test + public void testListWhatsAppTemplatesByChannelID() throws UnauthorizedException, GeneralException { + final TemplateList templateList = TestUtil.createWhatsAppTemplateList("sample_template_name"); + final String channelID = "channel-id"; + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + + String url = String.format( + "%s%s%s", + INTEGRATIONS_BASE_URL_V3, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH + ); + + Map map = new LinkedHashMap<>(); + map.put("channelId", channelID); + + when(messageBirdServiceMock.requestList(url, map, 0, 0, TemplateList.class)) + .thenReturn(templateList); + + final TemplateList response = messageBirdClientInjectMock.listWhatsAppTemplates(0, 0, null, channelID); + verify(messageBirdServiceMock, times(1)).requestList(url, map, 0, 0, TemplateList.class); + assertNotNull(response); + for(int i = 0; i < response.getItems().size() ; i++) { + assertReflectionEquals(response.getItems().get(i), templateList.getItems().get(i)); + } + } + @Test public void testGetWhatsAppTemplatesBy() throws GeneralException, UnauthorizedException, NotFoundException { final String templateName = "sample_template_name"; @@ -1132,6 +1213,80 @@ public void testGetWhatsAppTemplatesBy() throws GeneralException, UnauthorizedEx } } + @Test + public void testGetWhatsAppTemplatesByNameAndWABAID() throws GeneralException, UnauthorizedException, NotFoundException { + final String templateName = "sample_template_name"; + final String wabaID = "testWABAID"; + final TemplateResponse templateResponse1 = TestUtil.createWhatsAppTemplateResponse(templateName, "en_US"); + final TemplateResponse templateResponse2 = TestUtil.createWhatsAppTemplateResponse("another_template", "en_US"); + final List templateList = new ArrayList<>(); + templateList.add(templateResponse1); + templateList.add(templateResponse2); + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + + String url = String.format( + "%s%s%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH + ); + String id = String.format( + "%s?wabaId=%s", + templateName, + wabaID + ); + + when(messageBirdServiceMock.requestByIdAsList(url, id, TemplateResponse.class)) + .thenReturn(templateList); + + final List response = messageBirdClientInjectMock.getWhatsAppTemplatesBy(templateName, wabaID, null); + verify(messageBirdServiceMock, times(1)).requestByIdAsList(url, id, TemplateResponse.class); + assertNotNull(response); + assertEquals(response.size(), templateList.size()); + for(int i = 0; i < response.size() ; i++) { + assertReflectionEquals(response.get(i), templateList.get(i)); + } + } + + @Test + public void testGetWhatsAppTemplatesByNameForChannelID() throws GeneralException, UnauthorizedException, NotFoundException { + final String templateName = "sample_template_name"; + final String channelID = "channel-id"; + final TemplateResponse templateResponse1 = TestUtil.createWhatsAppTemplateResponse(templateName, "en_US"); + final TemplateResponse templateResponse2 = TestUtil.createWhatsAppTemplateResponse("another_template", "en_US"); + final List templateList = new ArrayList<>(); + templateList.add(templateResponse1); + templateList.add(templateResponse2); + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + + String url = String.format( + "%s%s%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH + ); + String id = String.format( + "%s?channelId=%s", + templateName, + channelID + ); + + when(messageBirdServiceMock.requestByIdAsList(url, id, TemplateResponse.class)) + .thenReturn(templateList); + + final List response = messageBirdClientInjectMock.getWhatsAppTemplatesBy(templateName, null, channelID); + verify(messageBirdServiceMock, times(1)).requestByIdAsList(url, id, TemplateResponse.class); + assertNotNull(response); + assertEquals(response.size(), templateList.size()); + for(int i = 0; i < response.size() ; i++) { + assertReflectionEquals(response.get(i), templateList.get(i)); + } + } + @Test public void testFetchWhatsAppTemplateBy() throws UnauthorizedException, GeneralException, NotFoundException { final String templateName = "sample_template_name"; @@ -1163,45 +1318,86 @@ public void testFetchWhatsAppTemplateBy() throws UnauthorizedException, GeneralE } @Test - public void testDeleteTemplatesByName() throws UnauthorizedException, GeneralException, NotFoundException { + public void testFetchWhatsAppTemplateByNameAndLanguageAndWABAID() throws UnauthorizedException, GeneralException, NotFoundException { final String templateName = "sample_template_name"; + final String language = "ko"; + final String wabaID = "testWABAID"; + final TemplateResponse template = TestUtil.createWhatsAppTemplateResponse(templateName, language); MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); String url = String.format( - "%s%s%s/%s", + "%s%s%s/%s/%s?wabaId=%s", INTEGRATIONS_BASE_URL_V2, INTEGRATIONS_WHATSAPP_PATH, TEMPLATES_PATH, - templateName + templateName, + language, + wabaID ); - when(messageBirdServiceMock.delete(url, null)).thenReturn(null); - messageBirdClientInjectMock.deleteTemplatesBy(templateName); - verify(messageBirdServiceMock).delete(url, null); + when(messageBirdServiceMock.request(url, TemplateResponse.class)) + .thenReturn(template); + + final TemplateResponse response = messageBirdClientInjectMock.fetchWhatsAppTemplateBy(templateName, language, wabaID, null); + verify(messageBirdServiceMock, times(1)).request(url, TemplateResponse.class); + assertNotNull(response); + assertEquals(response.getName(), template.getName()); + assertEquals(response.getLanguage(), template.getLanguage()); + assertEquals(response.getStatus(), template.getStatus()); + assertReflectionEquals(response.getComponents(), template.getComponents()); } @Test - public void testDeleteTemplatesByNameAndLanguage() - throws UnauthorizedException, GeneralException, NotFoundException { + public void testFetchWhatsAppTemplateByNameAndLanguageForChannelID() throws UnauthorizedException, GeneralException, NotFoundException { final String templateName = "sample_template_name"; - final String language = "en_US"; + final String language = "ko"; + final String channelID = "channel-id"; + final TemplateResponse template = TestUtil.createWhatsAppTemplateResponse(templateName, language); MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); String url = String.format( - "%s%s%s/%s/%s", + "%s%s%s/%s/%s?channelId=%s", INTEGRATIONS_BASE_URL_V2, INTEGRATIONS_WHATSAPP_PATH, TEMPLATES_PATH, templateName, - language + language, + channelID + ); + + when(messageBirdServiceMock.request(url, TemplateResponse.class)) + .thenReturn(template); + + final TemplateResponse response = messageBirdClientInjectMock.fetchWhatsAppTemplateBy(templateName, language, null, channelID); + verify(messageBirdServiceMock, times(1)).request(url, TemplateResponse.class); + assertNotNull(response); + assertEquals(response.getName(), template.getName()); + assertEquals(response.getLanguage(), template.getLanguage()); + assertEquals(response.getStatus(), template.getStatus()); + assertReflectionEquals(response.getComponents(), template.getComponents()); + } + + @Test + public void testDeleteTemplatesByName() throws UnauthorizedException, GeneralException, NotFoundException { + final String templateName = "sample_template_name"; + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + + String url = String.format( + "%s%s%s/%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH, + templateName ); when(messageBirdServiceMock.delete(url, null)).thenReturn(null); - messageBirdClientInjectMock.deleteTemplatesBy(templateName, language); + messageBirdClientInjectMock.deleteTemplatesBy(templateName); verify(messageBirdServiceMock).delete(url, null); } diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index 9bf28eb8..f8d8fb43 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -316,6 +316,9 @@ public static TemplateResponse createWhatsAppTemplateResponse(final String templ components.add(createHSMComponentButton()); templateResponse.setComponents(components); + templateResponse.setWabaID("testWABAID"); + templateResponse.setNamespace("testNamespace"); + return templateResponse; } @@ -332,6 +335,8 @@ public static Template createWhatsAppTemplate(final String templateName, final S components.add(createHSMComponentButton()); template.setComponents(components); + template.setWabaID("testWABAID"); + return template; } diff --git a/examples/pom.xml b/examples/pom.xml index 43716020..020e33d4 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.2.6 + 4.0.0 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.2.6 + 4.0.0 compile diff --git a/examples/src/main/java/ExampleCreateTemplate.java b/examples/src/main/java/ExampleCreateTemplate.java index 8e2d9887..fe18ea22 100644 --- a/examples/src/main/java/ExampleCreateTemplate.java +++ b/examples/src/main/java/ExampleCreateTemplate.java @@ -25,8 +25,8 @@ public class ExampleCreateTemplate { public static void main(String[] args) { - if (args.length < 2) { - System.out.println("Please specify your access key and a template name example : java -jar test_accesskey \"My template name\""); + if (args.length < 3) { + System.out.println("Please specify your access key and a template name and WABA ID example : java -jar test_accesskey \"My template name\" \"WABA ID\""); return; } @@ -84,13 +84,14 @@ public static void main(String[] args) { template.setName(args[1]); template.setLanguage("en_US"); + template.setWABAID(args[2]) template.setComponents(components); template.setCategory(HSMCategory.ACCOUNT_UPDATE); try { TemplateResponse response = messageBirdClient.createWhatsAppTemplate(template); System.out.println(response.toString()); - } catch (GeneralException | UnauthorizedException exception) { + } catch (GeneralException | UnauthorizedException | IllegalArgumentException exception) { exception.printStackTrace(); } } diff --git a/examples/src/main/java/ExampleDeleteTemplateByNameAndLanguage.java b/examples/src/main/java/ExampleDeleteTemplateByNameAndLanguage.java deleted file mode 100644 index 1b215f10..00000000 --- a/examples/src/main/java/ExampleDeleteTemplateByNameAndLanguage.java +++ /dev/null @@ -1,40 +0,0 @@ -import com.messagebird.MessageBirdClient; -import com.messagebird.MessageBirdService; -import com.messagebird.MessageBirdServiceImpl; -import com.messagebird.exceptions.GeneralException; -import com.messagebird.exceptions.NotFoundException; -import com.messagebird.exceptions.UnauthorizedException; - -/** - * Delete template by name and language - * - * @see Delete template by name and language - * @author ssk910 - */ -public class ExampleDeleteTemplateByNameAndLanguage { - - public static void main(String[] args) { - if (args.length < 3) { - System.out.println("Please specify your access key and a template name example : java -jar test_accesskey \"My template name\" \"Template language\""); - return; - } - - // First create your service object - final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); - - // Add the service to the client - final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); - - // template name and langugae from input - final String templateName = args[1]; - final String language = args[2]; - - try { - System.out.println("Deleting WhatsApp Template list by {name: " + templateName + ", language: " + language + "}"); - messageBirdClient.deleteTemplatesBy(templateName, language); - System.out.println("Deleted {name: " + templateName + ", language: " + language + "}"); - } catch (GeneralException | UnauthorizedException | NotFoundException exception) { - exception.printStackTrace(); - } - } -} diff --git a/examples/src/main/java/ExampleFetchTemplateByNameAndLanguage.java b/examples/src/main/java/ExampleFetchTemplateByNameAndLanguage.java index 02377ed0..219ee36d 100644 --- a/examples/src/main/java/ExampleFetchTemplateByNameAndLanguage.java +++ b/examples/src/main/java/ExampleFetchTemplateByNameAndLanguage.java @@ -26,7 +26,7 @@ public static void main(String[] args) { // Add the service to the client final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); - // template name and langugae from input + // template name and language from input final String templateName = args[1]; final String language = args[2]; @@ -34,7 +34,78 @@ public static void main(String[] args) { System.out.println("Fetching WhatsApp Template list by {name: " + templateName + ", language: " + language + "}"); final TemplateResponse template = messageBirdClient.fetchWhatsAppTemplateBy(templateName, language); System.out.println(template.toString()); - } catch (GeneralException | UnauthorizedException | NotFoundException exception) { + } catch (GeneralException | UnauthorizedException | NotFoundException | IllegalArgumentException exception) { + exception.printStackTrace(); + } + } +} + +/** + * Fetch template by name and language by WABA ID + * + * @see Fetch template by name and language by WABA ID + * @author ssk910 + */ +public class ExampleFetchTemplateByNameAndLanguage { + + public static void main(String[] args) { + if (args.length < 4) { + System.out.println("Please specify your access key, template name, language and WABA ID example : java -jar test_accesskey \"My template name\" \"Template language\" \"WABA ID\""); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + // template name, language and waba ID from input + final String templateName = args[1]; + final String language = args[2]; + final String wabaID = args[3]; + + try { + System.out.println("Fetching WhatsApp Template list by {name: " + templateName + ", language: " + language + ", wabaID: " + wabaID + "}"); + final TemplateResponse template = messageBirdClient.fetchWhatsAppTemplateBy(templateName, language, wabaID, null); + System.out.println(template.toString()); + } catch (GeneralException | UnauthorizedException | NotFoundException | IllegalArgumentException exception) { + exception.printStackTrace(); + } + } +} + +/** + * Fetch template by name and language for Channel ID + * + * @see Fetch template by name and language for Channel ID + * @author ssk910 + */ +public class ExampleFetchTemplateByNameAndLanguage { + + public static void main(String[] args) { + if (args.length < 4) { + System.out.println("Please specify your access key, template name, language and Channel ID example : java -jar test_accesskey \"My template name\" \"Template language\" \"Channel ID\""); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + // template name, language and the channel ID from input + final String templateName = args[1]; + final String language = args[2]; + final String channelID = args[3]; + + // Will return a template only if the channel belongs to the same WABA that the template belongs to. + try { + System.out.println("Fetching WhatsApp Template list by {name: " + templateName + ", language: " + language + ", channelID: " + channelID + "}"); + final TemplateResponse template = messageBirdClient.fetchWhatsAppTemplateBy(templateName, language, null, channelID); + System.out.println(template.toString()); + } catch (GeneralException | UnauthorizedException | NotFoundException | IllegalArgumentException exception) { exception.printStackTrace(); } } diff --git a/examples/src/main/java/ExampleListTemplatesByName.java b/examples/src/main/java/ExampleListTemplatesByName.java index 36159796..67fb2936 100644 --- a/examples/src/main/java/ExampleListTemplatesByName.java +++ b/examples/src/main/java/ExampleListTemplatesByName.java @@ -34,7 +34,80 @@ public static void main(String[] args) { System.out.println("Retrieving WhatsApp Template list by name : " + templateName); final List templateList = messageBirdClient.getWhatsAppTemplatesBy(templateName); System.out.println(templateList.toString()); - } catch (GeneralException | UnauthorizedException | NotFoundException exception) { + } catch (GeneralException | UnauthorizedException | NotFoundException | IllegalArgumentException exception) { + exception.printStackTrace(); + } + } +} + +/** + * List templates by name and WABA ID + * + * @see List templates by name and WABA ID + * @author ssk910 + */ +public class ExampleListTemplatesByNameAndWABAID { + + public static void main(String[] args) { + if (args.length < 3) { + System.out.println("Please specify your access key, template name and WABA ID example : java -jar test_accesskey \"My template name\" \"WABA ID\""); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + // template name from input + final String templateName = args[1]; + + // WABA ID from input + final String wabaID = args[2]; + + try { + System.out.println("Retrieving WhatsApp Template list by name '" + templateName + "' and WABA ID '" + wabaID + "'"); + final List templateList = messageBirdClient.getWhatsAppTemplatesBy(templateName, wabaID, null); + System.out.println(templateList.toString()); + } catch (GeneralException | UnauthorizedException | NotFoundException | IllegalArgumentException exception) { + exception.printStackTrace(); + } + } +} + +/** + * List templates by name and for channel ID + * + * @see List templates by name and for channel ID + * @author ssk910 + */ +public class ExampleListTemplatesByNameAndForChannelID { + + public static void main(String[] args) { + if (args.length < 3) { + System.out.println("Please specify your access key, template name and channel ID example : java -jar test_accesskey \"My template name\" \"Channel ID\""); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + // template name from input + final String templateName = args[1]; + + // Channel ID from input + final String channelID = args[2]; + + // Will return templates only if the channel belongs to the same WABA that the templates belongs to. + try { + System.out.println("Retrieving WhatsApp Template list by name '" + templateName + "' and channel ID '" + channelID + "'"); + final List templateList = messageBirdClient.getWhatsAppTemplatesBy(templateName, null, channelID); + System.out.println(templateList.toString()); + } catch (GeneralException | UnauthorizedException | NotFoundException | IllegalArgumentException exception) { exception.printStackTrace(); } } diff --git a/examples/src/main/java/ExampleListTemplatesByWABAOrChannel.java b/examples/src/main/java/ExampleListTemplatesByWABAOrChannel.java new file mode 100644 index 00000000..e4971182 --- /dev/null +++ b/examples/src/main/java/ExampleListTemplatesByWABAOrChannel.java @@ -0,0 +1,66 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.integrations.TemplateList; + +/** + * List templates by WABA ID + * + * @see List templates by WABA ID + * @author ssk910 + */ +public class ExampleListTemplatesByWABAID { + + public static void main(String[] args) { + if (args.length == 0) { + System.out.println("Please specify your access key and WABA ID example : java -jar test_accesskey \"WABA ID\""); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + System.out.println("Retrieving WhatsApp Template list by WABA"); + final TemplateList templateList = messageBirdClient.listWhatsAppTemplates(0, 25, "your-waba-id", null); + System.out.println(templateList.toString()); + } catch (GeneralException | UnauthorizedException | IllegalArgumentException exception) { + exception.printStackTrace(); + } + } +} + +/** + * List templates for Channel ID + * + * @see List templates for Channel ID + * @author ssk910 + */ +public class ExampleListTemplatesForChannelID { + + public static void main(String[] args) { + if (args.length == 0) { + System.out.println("Please specify your access key example : java -jar test_accesskey"); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + System.out.println("Retrieving WhatsApp Template list for a channel"); + final TemplateList templateList = messageBirdClient.listWhatsAppTemplates(0, 25, null, "channel-id"); + System.out.println(templateList.toString()); + } catch (GeneralException | UnauthorizedException | IllegalArgumentException exception) { + exception.printStackTrace(); + } + } +} From f1a1c97ce5455f6702cbebbae27c0b67da9bf859 Mon Sep 17 00:00:00 2001 From: David Oberholzer Date: Fri, 19 Aug 2022 11:00:40 +0200 Subject: [PATCH 397/516] Remove version change in this PR --- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index d8cc63ce..a6cf289a 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -74,7 +74,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "4.0.0"; + private final String clientVersion = "3.2.6"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 020e33d4..43716020 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 4.0.0 + 3.2.6 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 4.0.0 + 3.2.6 compile From fd2ef082d70c39db7c72bbd8c5a1139b7fff3347 Mon Sep 17 00:00:00 2001 From: David Oberholzer Date: Fri, 19 Aug 2022 11:35:29 +0200 Subject: [PATCH 398/516] Examples fixed --- .../objects/integrations/Template.java | 4 +- .../test/java/com/messagebird/TestUtil.java | 2 +- .../src/main/java/ExampleCreateTemplate.java | 2 +- ...ExampleFetchTemplateByNameAndLanguage.java | 71 ------------------ ...tchTemplateByNameAndLanguageAndWABAID.java | 42 +++++++++++ ...TemplateByNameAndLanguageForChannelID.java | 43 +++++++++++ .../main/java/ExampleListTemplatesByName.java | 73 ------------------- ...pleListTemplatesByNameAndForChannelID.java | 45 ++++++++++++ .../ExampleListTemplatesByNameAndWABAID.java | 44 +++++++++++ ...java => ExampleListTemplatesByWABAID.java} | 36 +-------- .../ExampleListTemplatesForChannelID.java | 36 +++++++++ 11 files changed, 217 insertions(+), 181 deletions(-) create mode 100644 examples/src/main/java/ExampleFetchTemplateByNameAndLanguageAndWABAID.java create mode 100644 examples/src/main/java/ExampleFetchTemplateByNameAndLanguageForChannelID.java create mode 100644 examples/src/main/java/ExampleListTemplatesByNameAndForChannelID.java create mode 100644 examples/src/main/java/ExampleListTemplatesByNameAndWABAID.java rename examples/src/main/java/{ExampleListTemplatesByWABAOrChannel.java => ExampleListTemplatesByWABAID.java} (52%) create mode 100644 examples/src/main/java/ExampleListTemplatesForChannelID.java diff --git a/api/src/main/java/com/messagebird/objects/integrations/Template.java b/api/src/main/java/com/messagebird/objects/integrations/Template.java index 333c7ec3..a61741f5 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/Template.java +++ b/api/src/main/java/com/messagebird/objects/integrations/Template.java @@ -44,11 +44,11 @@ public void setLanguage(String language) { this.language = language; } - public String getWabaID() { + public String getWABAID() { return wabaID; } - public void setWabaID(String wabaID) { + public void setWABAID(String wabaID) { this.wabaID = wabaID; } diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index f8d8fb43..34b6afc1 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -335,7 +335,7 @@ public static Template createWhatsAppTemplate(final String templateName, final S components.add(createHSMComponentButton()); template.setComponents(components); - template.setWabaID("testWABAID"); + template.setWABAID("testWABAID"); return template; } diff --git a/examples/src/main/java/ExampleCreateTemplate.java b/examples/src/main/java/ExampleCreateTemplate.java index fe18ea22..5ca63530 100644 --- a/examples/src/main/java/ExampleCreateTemplate.java +++ b/examples/src/main/java/ExampleCreateTemplate.java @@ -84,7 +84,7 @@ public static void main(String[] args) { template.setName(args[1]); template.setLanguage("en_US"); - template.setWABAID(args[2]) + template.setWABAID(args[2]); template.setComponents(components); template.setCategory(HSMCategory.ACCOUNT_UPDATE); diff --git a/examples/src/main/java/ExampleFetchTemplateByNameAndLanguage.java b/examples/src/main/java/ExampleFetchTemplateByNameAndLanguage.java index 219ee36d..c28d124c 100644 --- a/examples/src/main/java/ExampleFetchTemplateByNameAndLanguage.java +++ b/examples/src/main/java/ExampleFetchTemplateByNameAndLanguage.java @@ -39,74 +39,3 @@ public static void main(String[] args) { } } } - -/** - * Fetch template by name and language by WABA ID - * - * @see Fetch template by name and language by WABA ID - * @author ssk910 - */ -public class ExampleFetchTemplateByNameAndLanguage { - - public static void main(String[] args) { - if (args.length < 4) { - System.out.println("Please specify your access key, template name, language and WABA ID example : java -jar test_accesskey \"My template name\" \"Template language\" \"WABA ID\""); - return; - } - - // First create your service object - final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); - - // Add the service to the client - final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); - - // template name, language and waba ID from input - final String templateName = args[1]; - final String language = args[2]; - final String wabaID = args[3]; - - try { - System.out.println("Fetching WhatsApp Template list by {name: " + templateName + ", language: " + language + ", wabaID: " + wabaID + "}"); - final TemplateResponse template = messageBirdClient.fetchWhatsAppTemplateBy(templateName, language, wabaID, null); - System.out.println(template.toString()); - } catch (GeneralException | UnauthorizedException | NotFoundException | IllegalArgumentException exception) { - exception.printStackTrace(); - } - } -} - -/** - * Fetch template by name and language for Channel ID - * - * @see Fetch template by name and language for Channel ID - * @author ssk910 - */ -public class ExampleFetchTemplateByNameAndLanguage { - - public static void main(String[] args) { - if (args.length < 4) { - System.out.println("Please specify your access key, template name, language and Channel ID example : java -jar test_accesskey \"My template name\" \"Template language\" \"Channel ID\""); - return; - } - - // First create your service object - final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); - - // Add the service to the client - final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); - - // template name, language and the channel ID from input - final String templateName = args[1]; - final String language = args[2]; - final String channelID = args[3]; - - // Will return a template only if the channel belongs to the same WABA that the template belongs to. - try { - System.out.println("Fetching WhatsApp Template list by {name: " + templateName + ", language: " + language + ", channelID: " + channelID + "}"); - final TemplateResponse template = messageBirdClient.fetchWhatsAppTemplateBy(templateName, language, null, channelID); - System.out.println(template.toString()); - } catch (GeneralException | UnauthorizedException | NotFoundException | IllegalArgumentException exception) { - exception.printStackTrace(); - } - } -} diff --git a/examples/src/main/java/ExampleFetchTemplateByNameAndLanguageAndWABAID.java b/examples/src/main/java/ExampleFetchTemplateByNameAndLanguageAndWABAID.java new file mode 100644 index 00000000..deb12bf8 --- /dev/null +++ b/examples/src/main/java/ExampleFetchTemplateByNameAndLanguageAndWABAID.java @@ -0,0 +1,42 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.integrations.TemplateResponse; + +/** + * Fetch template by name and language by WABA ID + * + * @see Fetch template by name and language by WABA ID + * @author ssk910 + */ +public class ExampleFetchTemplateByNameAndLanguageAndWABAID { + + public static void main(String[] args) { + if (args.length < 4) { + System.out.println("Please specify your access key, template name, language and WABA ID example : java -jar test_accesskey \"My template name\" \"Template language\" \"WABA ID\""); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + // template name, language and waba ID from input + final String templateName = args[1]; + final String language = args[2]; + final String wabaID = args[3]; + + try { + System.out.println("Fetching WhatsApp Template list by {name: " + templateName + ", language: " + language + ", wabaID: " + wabaID + "}"); + final TemplateResponse template = messageBirdClient.fetchWhatsAppTemplateBy(templateName, language, wabaID, null); + System.out.println(template.toString()); + } catch (GeneralException | UnauthorizedException | NotFoundException | IllegalArgumentException exception) { + exception.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/examples/src/main/java/ExampleFetchTemplateByNameAndLanguageForChannelID.java b/examples/src/main/java/ExampleFetchTemplateByNameAndLanguageForChannelID.java new file mode 100644 index 00000000..639370e2 --- /dev/null +++ b/examples/src/main/java/ExampleFetchTemplateByNameAndLanguageForChannelID.java @@ -0,0 +1,43 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.integrations.TemplateResponse; + +/** + * Fetch template by name and language for Channel ID + * + * @see Fetch template by name and language for Channel ID + * @author ssk910 + */ +public class ExampleFetchTemplateByNameAndLanguageForChannelID { + + public static void main(String[] args) { + if (args.length < 4) { + System.out.println("Please specify your access key, template name, language and Channel ID example : java -jar test_accesskey \"My template name\" \"Template language\" \"Channel ID\""); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + // template name, language and the channel ID from input + final String templateName = args[1]; + final String language = args[2]; + final String channelID = args[3]; + + // Will return a template only if the channel belongs to the same WABA that the template belongs to. + try { + System.out.println("Fetching WhatsApp Template list by {name: " + templateName + ", language: " + language + ", channelID: " + channelID + "}"); + final TemplateResponse template = messageBirdClient.fetchWhatsAppTemplateBy(templateName, language, null, channelID); + System.out.println(template.toString()); + } catch (GeneralException | UnauthorizedException | NotFoundException | IllegalArgumentException exception) { + exception.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/examples/src/main/java/ExampleListTemplatesByName.java b/examples/src/main/java/ExampleListTemplatesByName.java index 67fb2936..33241ca6 100644 --- a/examples/src/main/java/ExampleListTemplatesByName.java +++ b/examples/src/main/java/ExampleListTemplatesByName.java @@ -39,76 +39,3 @@ public static void main(String[] args) { } } } - -/** - * List templates by name and WABA ID - * - * @see List templates by name and WABA ID - * @author ssk910 - */ -public class ExampleListTemplatesByNameAndWABAID { - - public static void main(String[] args) { - if (args.length < 3) { - System.out.println("Please specify your access key, template name and WABA ID example : java -jar test_accesskey \"My template name\" \"WABA ID\""); - return; - } - - // First create your service object - final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); - - // Add the service to the client - final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); - - // template name from input - final String templateName = args[1]; - - // WABA ID from input - final String wabaID = args[2]; - - try { - System.out.println("Retrieving WhatsApp Template list by name '" + templateName + "' and WABA ID '" + wabaID + "'"); - final List templateList = messageBirdClient.getWhatsAppTemplatesBy(templateName, wabaID, null); - System.out.println(templateList.toString()); - } catch (GeneralException | UnauthorizedException | NotFoundException | IllegalArgumentException exception) { - exception.printStackTrace(); - } - } -} - -/** - * List templates by name and for channel ID - * - * @see List templates by name and for channel ID - * @author ssk910 - */ -public class ExampleListTemplatesByNameAndForChannelID { - - public static void main(String[] args) { - if (args.length < 3) { - System.out.println("Please specify your access key, template name and channel ID example : java -jar test_accesskey \"My template name\" \"Channel ID\""); - return; - } - - // First create your service object - final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); - - // Add the service to the client - final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); - - // template name from input - final String templateName = args[1]; - - // Channel ID from input - final String channelID = args[2]; - - // Will return templates only if the channel belongs to the same WABA that the templates belongs to. - try { - System.out.println("Retrieving WhatsApp Template list by name '" + templateName + "' and channel ID '" + channelID + "'"); - final List templateList = messageBirdClient.getWhatsAppTemplatesBy(templateName, null, channelID); - System.out.println(templateList.toString()); - } catch (GeneralException | UnauthorizedException | NotFoundException | IllegalArgumentException exception) { - exception.printStackTrace(); - } - } -} diff --git a/examples/src/main/java/ExampleListTemplatesByNameAndForChannelID.java b/examples/src/main/java/ExampleListTemplatesByNameAndForChannelID.java new file mode 100644 index 00000000..02f2377b --- /dev/null +++ b/examples/src/main/java/ExampleListTemplatesByNameAndForChannelID.java @@ -0,0 +1,45 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.integrations.TemplateResponse; +import java.util.List; + +/** + * List templates by name and for channel ID + * + * @see List templates by name and for channel ID + * @author ssk910 + */ +public class ExampleListTemplatesByNameAndForChannelID { + + public static void main(String[] args) { + if (args.length < 3) { + System.out.println("Please specify your access key, template name and channel ID example : java -jar test_accesskey \"My template name\" \"Channel ID\""); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + // template name from input + final String templateName = args[1]; + + // Channel ID from input + final String channelID = args[2]; + + // Will return templates only if the channel belongs to the same WABA that the templates belongs to. + try { + System.out.println("Retrieving WhatsApp Template list by name '" + templateName + "' and channel ID '" + channelID + "'"); + final List templateList = messageBirdClient.getWhatsAppTemplatesBy(templateName, null, channelID); + System.out.println(templateList.toString()); + } catch (GeneralException | UnauthorizedException | NotFoundException | IllegalArgumentException exception) { + exception.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/examples/src/main/java/ExampleListTemplatesByNameAndWABAID.java b/examples/src/main/java/ExampleListTemplatesByNameAndWABAID.java new file mode 100644 index 00000000..6bb8fd3f --- /dev/null +++ b/examples/src/main/java/ExampleListTemplatesByNameAndWABAID.java @@ -0,0 +1,44 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.integrations.TemplateResponse; +import java.util.List; + +/** + * List templates by name and WABA ID + * + * @see List templates by name and WABA ID + * @author ssk910 + */ +public class ExampleListTemplatesByNameAndWABAID { + + public static void main(String[] args) { + if (args.length < 3) { + System.out.println("Please specify your access key, template name and WABA ID example : java -jar test_accesskey \"My template name\" \"WABA ID\""); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + // template name from input + final String templateName = args[1]; + + // WABA ID from input + final String wabaID = args[2]; + + try { + System.out.println("Retrieving WhatsApp Template list by name '" + templateName + "' and WABA ID '" + wabaID + "'"); + final List templateList = messageBirdClient.getWhatsAppTemplatesBy(templateName, wabaID, null); + System.out.println(templateList.toString()); + } catch (GeneralException | UnauthorizedException | NotFoundException | IllegalArgumentException exception) { + exception.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/examples/src/main/java/ExampleListTemplatesByWABAOrChannel.java b/examples/src/main/java/ExampleListTemplatesByWABAID.java similarity index 52% rename from examples/src/main/java/ExampleListTemplatesByWABAOrChannel.java rename to examples/src/main/java/ExampleListTemplatesByWABAID.java index e4971182..a11ed37f 100644 --- a/examples/src/main/java/ExampleListTemplatesByWABAOrChannel.java +++ b/examples/src/main/java/ExampleListTemplatesByWABAID.java @@ -14,7 +14,7 @@ public class ExampleListTemplatesByWABAID { public static void main(String[] args) { - if (args.length == 0) { + if (args.length < 2) { System.out.println("Please specify your access key and WABA ID example : java -jar test_accesskey \"WABA ID\""); return; } @@ -27,40 +27,10 @@ public static void main(String[] args) { try { System.out.println("Retrieving WhatsApp Template list by WABA"); - final TemplateList templateList = messageBirdClient.listWhatsAppTemplates(0, 25, "your-waba-id", null); + final TemplateList templateList = messageBirdClient.listWhatsAppTemplates(0, 25, args[1], null); System.out.println(templateList.toString()); } catch (GeneralException | UnauthorizedException | IllegalArgumentException exception) { exception.printStackTrace(); } } -} - -/** - * List templates for Channel ID - * - * @see List templates for Channel ID - * @author ssk910 - */ -public class ExampleListTemplatesForChannelID { - - public static void main(String[] args) { - if (args.length == 0) { - System.out.println("Please specify your access key example : java -jar test_accesskey"); - return; - } - - // First create your service object - final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); - - // Add the service to the client - final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); - - try { - System.out.println("Retrieving WhatsApp Template list for a channel"); - final TemplateList templateList = messageBirdClient.listWhatsAppTemplates(0, 25, null, "channel-id"); - System.out.println(templateList.toString()); - } catch (GeneralException | UnauthorizedException | IllegalArgumentException exception) { - exception.printStackTrace(); - } - } -} +} \ No newline at end of file diff --git a/examples/src/main/java/ExampleListTemplatesForChannelID.java b/examples/src/main/java/ExampleListTemplatesForChannelID.java new file mode 100644 index 00000000..4a2bdda9 --- /dev/null +++ b/examples/src/main/java/ExampleListTemplatesForChannelID.java @@ -0,0 +1,36 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.integrations.TemplateList; + +/** + * List templates for Channel ID + * + * @see List templates for Channel ID + * @author ssk910 + */ +public class ExampleListTemplatesForChannelID { + + public static void main(String[] args) { + if (args.length < 2) { + System.out.println("Please specify your access key and channel ID example : java -jar test_accesskey"); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + try { + System.out.println("Retrieving WhatsApp Template list for a channel"); + final TemplateList templateList = messageBirdClient.listWhatsAppTemplates(0, 25, null, args[1]); + System.out.println(templateList.toString()); + } catch (GeneralException | UnauthorizedException | IllegalArgumentException exception) { + exception.printStackTrace(); + } + } +} From 9f0b0e9dee1fe6ce207dfc0750823d7a82c886a2 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 19 Aug 2022 13:01:55 +0200 Subject: [PATCH 399/516] new release preparation --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 49fff0fb..6b18e845 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 3.2.6 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index a6cf289a..d8cc63ce 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -74,7 +74,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "3.2.6"; + private final String clientVersion = "4.0.0"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 43716020..020e33d4 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 3.2.6 + 4.0.0 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 3.2.6 + 4.0.0 compile From 296b5dd01479d7dcdf2afcfb805211f0132c0caa Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 19 Aug 2022 13:03:44 +0200 Subject: [PATCH 400/516] [maven-release-plugin] prepare release v4.0.0 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 6b18e845..60059d6f 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 4.0.0-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v4.0.0 From 267d48a4e2b2088f01a08dadf3332745d2b8484a Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 19 Aug 2022 13:03:48 +0200 Subject: [PATCH 401/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 60059d6f..78215a0d 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 4.0.0 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v4.0.0 + HEAD From 2140b1cc40c0f50edcfa538d282e2e87473539b1 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 19 Aug 2022 17:39:30 +0200 Subject: [PATCH 402/516] new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 78215a0d..32aff34d 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 4.0.1-SNAPSHOT From e4521a3bdf04ad4560ad8f9b2f012d1f3c38e8fd Mon Sep 17 00:00:00 2001 From: David Oberholzer Date: Wed, 28 Sep 2022 09:31:31 +0200 Subject: [PATCH 403/516] WhatsApp Template deprecated categories replaced with new categories. --- .../objects/integrations/HSMCategory.java | 13 +++---------- api/src/test/java/com/messagebird/TestUtil.java | 4 ++-- examples/src/main/java/ExampleCreateTemplate.java | 2 +- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMCategory.java b/api/src/main/java/com/messagebird/objects/integrations/HSMCategory.java index 15f4d31d..c88d974b 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/HSMCategory.java +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMCategory.java @@ -11,16 +11,9 @@ */ public enum HSMCategory { - ACCOUNT_UPDATE("ACCOUNT_UPDATE"), - PAYMENT_UPDATE("PAYMENT_UPDATE"), - PERSONAL_FINANCE_UPDATE("PERSONAL_FINANCE_UPDATE"), - SHIPPING_UPDATE("SHIPPING_UPDATE"), - RESERVATION_UPDATE("RESERVATION_UPDATE"), - ISSUE_RESOLUTION("ISSUE_RESOLUTION"), - APPOINTMENT_UPDATE("APPOINTMENT_UPDATE"), - TRANSPORTATION_UPDATE("TRANSPORTATION_UPDATE"), - TICKET_UPDATE("TICKET_UPDATE"), - ALERT_UPDATE("ALERT_UPDATE"); + OTP("OTP"), + TRANSACTIONAL("TRANSACTIONAL"), + MARKETING("MARKETING"); private final String category; diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index 34b6afc1..e3852308 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -304,7 +304,7 @@ public static TemplateResponse createWhatsAppTemplateResponse(final String templ final TemplateResponse templateResponse = new TemplateResponse(); templateResponse.setName(templateName); templateResponse.setLanguage(language); - templateResponse.setCategory(HSMCategory.ACCOUNT_UPDATE); + templateResponse.setCategory(HSMCategory.OTP); templateResponse.setStatus(HSMStatus.NEW); templateResponse.setCreatedAt(new Date()); templateResponse.setUpdatedAt(new Date()); @@ -326,7 +326,7 @@ public static Template createWhatsAppTemplate(final String templateName, final S final Template template = new Template(); template.setName(templateName); template.setLanguage(language); - template.setCategory(HSMCategory.ACCOUNT_UPDATE); + template.setCategory(HSMCategory.OTP); final List components = new ArrayList<>(); components.add(createHSMComponentHeader()); diff --git a/examples/src/main/java/ExampleCreateTemplate.java b/examples/src/main/java/ExampleCreateTemplate.java index 5ca63530..9e8a1e96 100644 --- a/examples/src/main/java/ExampleCreateTemplate.java +++ b/examples/src/main/java/ExampleCreateTemplate.java @@ -86,7 +86,7 @@ public static void main(String[] args) { template.setLanguage("en_US"); template.setWABAID(args[2]); template.setComponents(components); - template.setCategory(HSMCategory.ACCOUNT_UPDATE); + template.setCategory(HSMCategory.OTP); try { TemplateResponse response = messageBirdClient.createWhatsAppTemplate(template); From 9085aaf849d7b376330ad56078fc37d6b2b9c0b4 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Wed, 28 Sep 2022 18:31:37 +0200 Subject: [PATCH 404/516] new release of Java SDK --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 32aff34d..0304d53d 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 4.0.0 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index d8cc63ce..996c7074 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -74,7 +74,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "4.0.0"; + private final String clientVersion = "5.0.0"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 020e33d4..7319771f 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 4.0.0 + 5.0.0 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 4.0.0 + 5.0.0 compile From 61753b2921d75a115df7c3a20b7ad2d63838c92b Mon Sep 17 00:00:00 2001 From: denizkilic Date: Wed, 28 Sep 2022 18:34:24 +0200 Subject: [PATCH 405/516] [maven-release-plugin] prepare release v5.0.0 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 0304d53d..054ac061 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.0.0-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v5.0.0 From d86c45b99603f927fa3404e120392b1c51ec4148 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Wed, 28 Sep 2022 18:34:28 +0200 Subject: [PATCH 406/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 054ac061..d49d31ed 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.0.0 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v5.0.0 + HEAD From b01593187ea42dfe3cb76d6630ae86622a771909 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 29 Sep 2022 09:29:10 +0200 Subject: [PATCH 407/516] new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index d49d31ed..f949f38b 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.0.1-SNAPSHOT From 22822d0fca6a11cc3c2a826d0bb5922e172ca439 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 7 Oct 2022 16:34:22 +0200 Subject: [PATCH 408/516] upgrade jackson databind lib version --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index f949f38b..1f56d018 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -88,7 +88,7 @@ com.fasterxml.jackson.core jackson-databind - 2.13.2.2 + 2.14.0-rc1 com.auth0 From a041af4e362a10d6f5d265cd8f297ac3721d7de1 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 7 Oct 2022 16:47:25 +0200 Subject: [PATCH 409/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 1f56d018..5cc0907c 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.0.0 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 996c7074..8ada8c7c 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -74,7 +74,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "5.0.0"; + private final String clientVersion = "5.1.0"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 7319771f..933b414d 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 5.0.0 + 5.1.0 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 5.0.0 + 5.1.0 compile From b23f968781b8053d1e1587c44d3dcd57305f87f6 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 7 Oct 2022 16:49:40 +0200 Subject: [PATCH 410/516] [maven-release-plugin] prepare release v5.1.0 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 5cc0907c..de68c260 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.1.0-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v5.1.0 From 21d8096d48a0fcbb76bbeb3d8b9789e7cdcbd371 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 7 Oct 2022 16:49:44 +0200 Subject: [PATCH 411/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index de68c260..48fe2a36 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.1.0 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v5.1.0 + HEAD From 76f4329e587286c8b4283df81426ca6a3d83af65 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 4 Nov 2022 16:08:48 +0100 Subject: [PATCH 412/516] WhatsApp Template message with buttons example is created --- ...onversationSendHSMTemplateWithButtons.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 examples/src/main/java/ExampleConversationSendHSMTemplateWithButtons.java diff --git a/examples/src/main/java/ExampleConversationSendHSMTemplateWithButtons.java b/examples/src/main/java/ExampleConversationSendHSMTemplateWithButtons.java new file mode 100644 index 00000000..40202a26 --- /dev/null +++ b/examples/src/main/java/ExampleConversationSendHSMTemplateWithButtons.java @@ -0,0 +1,63 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.conversations.*; + +import java.util.Collections; + +public class ExampleConversationSendHSMTemplateWithButtons { + + // Reference Example: https://developers.messagebird.com/quickstarts/whatsapp/send-message-with-buttons/ + public static void main(String[] args) { + + if (args.length < 4) { + System.out.println("Please at least specify your access key, the channel id and destination address.\n" + + "Usage : java -jar test_accesskey(Required) channel_id(Required) from(Required) to(Required)"); + return; + } + + //First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + //Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + ConversationContent conversationContent = new ConversationContent(); + ConversationContentHsm conversationContentHsm = new ConversationContentHsm(); + conversationContentHsm.setNamespace("20332cd4_f095_b080_d255_35677159aaff"); + conversationContentHsm.setTemplateName("33172012024_ship_img_but_1"); + ConversationHsmLanguage language = new ConversationHsmLanguage(); + language.setCode("en"); + conversationContentHsm.setLanguage(language); + + //Define component with button + MessageComponent messageButtonComponent = new MessageComponent(); + messageButtonComponent.setType(MessageComponentType.BUTTON); + messageButtonComponent.setSub_type("url"); + MessageParam textParam = new MessageParam(); + textParam.setType(TemplateMediaType.TEXT); + textParam.setText("23493282245"); + + messageButtonComponent.setParameters(Collections.singletonList(textParam)); + conversationContentHsm.setComponents(Collections.singletonList(messageButtonComponent)); + conversationContent.setHsm(conversationContentHsm); + ConversationSendRequest request = new ConversationSendRequest( + args[2], + ConversationContentType.HSM, + conversationContent, + args[1], + "", + null, + null, + null); + + try { + ConversationSendResponse sendResponse = messageBirdClient.sendMessage(request); + System.out.println(sendResponse.toString()); + + } catch (GeneralException | UnauthorizedException exception) { + exception.printStackTrace(); + } + } +} From 64183ca3b2a4b5dcb9a435ec5cc91daa674c6532 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 4 Nov 2022 17:41:47 +0100 Subject: [PATCH 413/516] resolves issue #213 --- .../main/java/com/messagebird/MessageBirdServiceImpl.java | 6 ++---- api/src/main/java/com/messagebird/objects/Language.java | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 8ada8c7c..32e1349d 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -2,10 +2,7 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.MapperFeature; -import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.*; import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; @@ -593,6 +590,7 @@ public

HttpURLConnection getConnection(final String serviceUrl, final P body connection.setRequestProperty("Content-Type", "application/json"); ObjectMapper mapper = new ObjectMapper(); mapper.setSerializationInclusion(Include.NON_NULL); + mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING); // Specifically set the date format for POST requests so scheduled // messages and other things relying on specific date formats don't // fail when sending. diff --git a/api/src/main/java/com/messagebird/objects/Language.java b/api/src/main/java/com/messagebird/objects/Language.java index 6ce76027..9fedb2f2 100644 --- a/api/src/main/java/com/messagebird/objects/Language.java +++ b/api/src/main/java/com/messagebird/objects/Language.java @@ -11,7 +11,7 @@ public enum Language { EN_US("en-us"), ES_ES("es-es"), FR_FR("fr-fr"), - RU_RU("ru_ru"), + RU_RU("ru-ru"), ZH_CN("zh-cn"), EN_AU("en-au"), ES_MX("es-mx"), From 41028194bb700ffb6505cc9e8e54dbbf927b4c39 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Tue, 15 Nov 2022 12:11:26 +0100 Subject: [PATCH 414/516] new release with minor changes --- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 32e1349d..56314ab8 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -71,7 +71,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "5.1.0"; + private final String clientVersion = "5.1.1"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 933b414d..91323182 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 5.1.0 + 5.1.1 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 5.1.0 + 5.1.1 compile From 307d7e42dc653206f5e6cde5358e1dcd3b2f853b Mon Sep 17 00:00:00 2001 From: denizkilic Date: Tue, 15 Nov 2022 12:13:24 +0100 Subject: [PATCH 415/516] [maven-release-plugin] prepare release v5.1.1 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 48fe2a36..69ba409a 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.1.1-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v5.1.1 From 407b8c42cb3e5d5dd808c9d5f5f914183171ce27 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Tue, 15 Nov 2022 12:13:29 +0100 Subject: [PATCH 416/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 69ba409a..afb138cf 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.1.1 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v5.1.1 + HEAD From 3db7d443d38e2c62d739c8d4ac6a4623aea232f8 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Wed, 16 Nov 2022 10:20:34 +0100 Subject: [PATCH 417/516] updated --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index afb138cf..2208a7c9 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.1.2-SNAPSHOT From 4e41c0c5b5a931b06cf1e448c4ed00d2f9d69dd0 Mon Sep 17 00:00:00 2001 From: Aivis Olsteins Date: Wed, 23 Nov 2022 13:31:54 +0000 Subject: [PATCH 418/516] Voice call flow optional maxDuration --- .../com/messagebird/objects/voicecalls/VoiceCallFlow.java | 8 ++++++++ api/src/test/java/com/messagebird/TestUtil.java | 1 + examples/src/main/java/ExampleSendVoiceCall.java | 1 + 3 files changed, 10 insertions(+) diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java index 9554ac58..53130c77 100644 --- a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCallFlow.java @@ -23,6 +23,9 @@ public class VoiceCallFlow implements Serializable { @JsonProperty("default") private boolean defaultCall; + @JsonProperty("maxDuration") + private Integer maxDuration; + private Date createdAt; private Date updatedAt; @@ -71,6 +74,10 @@ public void setDefaultCall(boolean defaultCall) { this.defaultCall = defaultCall; } + public Integer getMaxDuration() { return maxDuration; } + + public void setMaxDuration(Integer maxDuration) { this.maxDuration = maxDuration; } + public Date getCreatedAt() { return createdAt; } @@ -103,6 +110,7 @@ public String toString() { ", record=" + record + ", steps=" + steps + ", default=" + defaultCall + + ", maxDuration=" + maxDuration + ", createdAt=" + createdAt + ", updatedAt=" + updatedAt + '}'; diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index e3852308..1c3f5c07 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -30,6 +30,7 @@ static VoiceCall createVoiceCall(String destination) { final VoiceCallFlow voiceCallFlow = new VoiceCallFlow(); VoiceStep voiceStep = new VoiceStep(); voiceStep.setAction("say"); + voiceCallFlow.setMaxDuration(28800); final VoiceStepOption voiceStepOption = new VoiceStepOption(); voiceStepOption.setPayload("This is a journey into sound. Good bye!"); diff --git a/examples/src/main/java/ExampleSendVoiceCall.java b/examples/src/main/java/ExampleSendVoiceCall.java index c61fddd0..13381ca9 100644 --- a/examples/src/main/java/ExampleSendVoiceCall.java +++ b/examples/src/main/java/ExampleSendVoiceCall.java @@ -46,6 +46,7 @@ public static void main(String[] args) { voiceStep.setOptions(voiceStepOption); voiceCallFlow.setSteps(Collections.singletonList(voiceStep)); + voiceCallFlow.setMaxDuration(28800); voiceCall.setCallFlow(voiceCallFlow); //Sending request to client final VoiceCallResponse response = messageBirdClient.sendVoiceCall(voiceCall); From b616084bf5b9f4ea0489df42f42dd64c8b59b3ab Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 24 Nov 2022 11:37:20 +0100 Subject: [PATCH 419/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 2208a7c9..afb138cf 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.1.1 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 56314ab8..ab7fb34c 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -71,7 +71,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "5.1.1"; + private final String clientVersion = "5.1.2"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 91323182..5081bea0 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 5.1.1 + 5.1.2 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 5.1.1 + 5.1.2 compile From ae6ac2ee7e6325ad95d4968dc7892493dc9664ce Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 24 Nov 2022 11:38:29 +0100 Subject: [PATCH 420/516] [maven-release-plugin] prepare release v5.1.2 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index afb138cf..8a61cbd9 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.1.2-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v5.1.2 From 7bc982aed171c4aa84cdb7c554ab9aa54952830c Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 24 Nov 2022 11:38:33 +0100 Subject: [PATCH 421/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 8a61cbd9..37752bf5 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.1.2 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v5.1.2 + HEAD From b01905e52ae257ff29a481f1814938a39ec6fc68 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 24 Nov 2022 22:23:25 +0100 Subject: [PATCH 422/516] new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 37752bf5..574f1379 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.1.3-SNAPSHOT From 507d49af680570aae7d3f96778a21d4f3f961e9c Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 2 Dec 2022 10:44:15 +0100 Subject: [PATCH 423/516] removed objectmapper serialization feature and updated Language enum class --- .../com/messagebird/MessageBirdServiceImpl.java | 1 - .../java/com/messagebird/objects/Language.java | 14 ++++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index ab7fb34c..2ee65699 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -590,7 +590,6 @@ public

HttpURLConnection getConnection(final String serviceUrl, final P body connection.setRequestProperty("Content-Type", "application/json"); ObjectMapper mapper = new ObjectMapper(); mapper.setSerializationInclusion(Include.NON_NULL); - mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING); // Specifically set the date format for POST requests so scheduled // messages and other things relying on specific date formats don't // fail when sending. diff --git a/api/src/main/java/com/messagebird/objects/Language.java b/api/src/main/java/com/messagebird/objects/Language.java index 9fedb2f2..ccb63351 100644 --- a/api/src/main/java/com/messagebird/objects/Language.java +++ b/api/src/main/java/com/messagebird/objects/Language.java @@ -1,5 +1,7 @@ package com.messagebird.objects; +import com.fasterxml.jackson.annotation.JsonValue; + /** * Created by faizan on 09/12/15. */ @@ -25,13 +27,21 @@ public enum Language { PT_BR("pt-br"), RO_RO("ro-ro"); - private String code; + final String code; Language(String code) { this.code = code; } + @JsonValue + public String getCode() { + return code; + } + + @Override public String toString() { - return this.code; + return "Language{" + + "code='" + code + '\'' + + '}'; } } From bd91eb76e5621def75e60da2db9ae51a5706aef3 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 2 Dec 2022 10:59:10 +0100 Subject: [PATCH 424/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 574f1379..6759f94f 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.1.2 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 2ee65699..c15a2e3e 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -71,7 +71,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "5.1.2"; + private final String clientVersion = "5.3.0"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 5081bea0..e656f597 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 5.1.2 + 5.3.0 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 5.1.2 + 5.3.0 compile From 76556c8d89edb473efffdf47246c7e14fc0a0f29 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 2 Dec 2022 11:00:32 +0100 Subject: [PATCH 425/516] [maven-release-plugin] prepare release v5.3.0 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 6759f94f..1da18cf1 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.3.0-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v5.3.0 From 881064e8baf9426802bfd0d74d653bddd050d47e Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 2 Dec 2022 11:00:37 +0100 Subject: [PATCH 426/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 1da18cf1..c3102b86 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.3.0 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v5.3.0 + HEAD From eee5ef8922d705861284a0ffee72df5d61b32463 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 2 Dec 2022 17:05:58 +0100 Subject: [PATCH 427/516] new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index c3102b86..6de456fb 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.3.1-SNAPSHOT From 6cfe2e7351ed3bc33ece92fbab046c4e9f707a65 Mon Sep 17 00:00:00 2001 From: Daniel Morales Date: Fri, 9 Dec 2022 11:43:33 +0000 Subject: [PATCH 428/516] Added the two new template status DISABLED and PAUSED --- .../java/com/messagebird/objects/integrations/HSMStatus.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMStatus.java b/api/src/main/java/com/messagebird/objects/integrations/HSMStatus.java index fa179b0f..1b1980f1 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/HSMStatus.java +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMStatus.java @@ -16,7 +16,9 @@ public enum HSMStatus { PENDING("PENDING"), REJECTED("REJECTED"), PENDING_DELETION("PENDING_DELETION"), - DELETED("DELETED"); + DELETED("DELETED"), + DISABLED("DISABLED"), + PAUSED("PAUSED"); private final String status; From f8599d46c6c4a4a87a9be152afe7a936b59b075c Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 9 Dec 2022 13:36:32 +0100 Subject: [PATCH 429/516] new release with HSM template changes --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 6de456fb..c3102b86 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.3.0 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index c15a2e3e..13b4bc95 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -71,7 +71,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "5.3.0"; + private final String clientVersion = "5.3.1"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index e656f597..a78c2f6e 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 5.3.0 + 5.3.1 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 5.3.0 + 5.3.1 compile From bcc8653fc3bcd416b20fc61c5cd14a1473334717 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 9 Dec 2022 13:38:00 +0100 Subject: [PATCH 430/516] [maven-release-plugin] prepare release v5.3.1 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index c3102b86..6afbfd2a 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.3.1-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v5.3.1 From 5449d58da8a5e83bfb0e1c47daf729779418fac0 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 9 Dec 2022 13:38:04 +0100 Subject: [PATCH 431/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 6afbfd2a..1c0e436e 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.3.1 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v5.3.1 + HEAD From 5b00aa09a5a931dd1eb1cf01e5134041dcb0b681 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 12 Dec 2022 09:25:58 +0100 Subject: [PATCH 432/516] new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 1c0e436e..650fa9ca 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.3.2-SNAPSHOT From 29461f076061302effabc7b6a6975d212d612608 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 16 Mar 2023 15:38:21 +0100 Subject: [PATCH 433/516] added json ignore to disable setting webhook --- .../java/com/messagebird/objects/voicecalls/VoiceCall.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCall.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCall.java index 8ece36ec..816e1f12 100644 --- a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCall.java +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCall.java @@ -63,10 +63,12 @@ public Webhook getWebhook() { return webhook; } + @JsonIgnore public void setWebhook(String url) { this.setWebhook(url, null); } + @JsonIgnore public void setWebhook(String url, String token) { this.webhook.setUrl(url); this.webhook.setToken(token); @@ -102,7 +104,6 @@ public String toString() { "source='" + source + '\'' + ", destination='" + destination + '\'' + ", callFlow=" + callFlow + - ", webhook=" + webhook + '}'; } } From 6a7d304511e0d6c4cea6fca1b375994db00d0d2b Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 17 Mar 2023 10:41:54 +0100 Subject: [PATCH 434/516] updated --- .../main/java/com/messagebird/objects/voicecalls/VoiceCall.java | 1 + 1 file changed, 1 insertion(+) diff --git a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCall.java b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCall.java index 816e1f12..573b42be 100644 --- a/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCall.java +++ b/api/src/main/java/com/messagebird/objects/voicecalls/VoiceCall.java @@ -104,6 +104,7 @@ public String toString() { "source='" + source + '\'' + ", destination='" + destination + '\'' + ", callFlow=" + callFlow + + ", webhook=" + webhook + '}'; } } From df495e98e30966403e4500694f53234084a5a63d Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 17 Mar 2023 10:48:16 +0100 Subject: [PATCH 435/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 650fa9ca..1c0e436e 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.3.1 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 13b4bc95..13ecc56e 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -71,7 +71,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "5.3.1"; + private final String clientVersion = "5.3.2"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index a78c2f6e..24c63c7a 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 5.3.1 + 5.3.2 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 5.3.1 + 5.3.2 compile From 4c73809b81b0f1651ba1beb659d8a26cf7835c91 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 17 Mar 2023 10:51:04 +0100 Subject: [PATCH 436/516] [maven-release-plugin] prepare release v5.3.2 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 1c0e436e..bc74d0bd 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.3.2-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v5.3.2 From 6b2bdfa8af6d5e459899ecdd5d4dcac9e4aeac38 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 17 Mar 2023 10:51:09 +0100 Subject: [PATCH 437/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index bc74d0bd..a07eb2e7 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.3.2 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v5.3.2 + HEAD From 52c02b198aa4ed8d20c499bc34221f385b48bd3f Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 17 Mar 2023 11:31:41 +0100 Subject: [PATCH 438/516] updated --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index a07eb2e7..92f912fb 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.3.3-SNAPSHOT From d9854473ab885a932dd0349b19150383a0b5ed59 Mon Sep 17 00:00:00 2001 From: Jon Chambers Date: Tue, 21 Mar 2023 12:16:11 -0400 Subject: [PATCH 439/516] Make `MessageBirdClient#getVerifyObject` public --- api/src/main/java/com/messagebird/MessageBirdClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 276ba3c8..be7a8fa5 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -470,7 +470,7 @@ public Verify verifyToken(String id, String token) throws NotFoundException, Gen * @throws UnauthorizedException if client is unauthorized * @throws GeneralException general exception */ - Verify getVerifyObject(String id) throws NotFoundException, GeneralException, UnauthorizedException { + public Verify getVerifyObject(String id) throws NotFoundException, GeneralException, UnauthorizedException { if (id == null || id.isEmpty()) { throw new IllegalArgumentException("ID cannot be empty for verify"); } From da083253d51a05d00b08916b164d32b023131408 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 27 Mar 2023 18:17:35 +0200 Subject: [PATCH 440/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 92f912fb..a07eb2e7 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.3.2 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 13ecc56e..85d169fb 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -71,7 +71,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "5.3.2"; + private final String clientVersion = "5.3.3"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 24c63c7a..8ca96bbb 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 5.3.2 + 5.3.3 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 5.3.2 + 5.3.3 compile From c8ab481596f757a4160be0f0f63bb416ac8253af Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 27 Mar 2023 18:20:28 +0200 Subject: [PATCH 441/516] [maven-release-plugin] prepare release v5.3.3 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index a07eb2e7..922f2822 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.3.3-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v5.3.3 From 8e4287fbfd920bcc7a9b2bbc1705a964b31e5865 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 27 Mar 2023 18:20:32 +0200 Subject: [PATCH 442/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 922f2822..5bcc495f 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.3.3 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v5.3.3 + HEAD From 6ea1fe172e853bc648587cfe166cd9654f617efc Mon Sep 17 00:00:00 2001 From: denizkilic Date: Tue, 28 Mar 2023 09:19:24 +0200 Subject: [PATCH 443/516] new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 5bcc495f..0d2ab9f2 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.3.4-SNAPSHOT From ff3460343ec2dad52d9201ed49f11754b2a332ec Mon Sep 17 00:00:00 2001 From: Jon Chambers Date: Wed, 5 Apr 2023 10:43:52 -0400 Subject: [PATCH 444/516] Represent prices as `BigDecimal` --- .../main/java/com/messagebird/objects/MessageResponse.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/objects/MessageResponse.java b/api/src/main/java/com/messagebird/objects/MessageResponse.java index 91d4d6da..aa104e52 100644 --- a/api/src/main/java/com/messagebird/objects/MessageResponse.java +++ b/api/src/main/java/com/messagebird/objects/MessageResponse.java @@ -3,6 +3,7 @@ import org.jetbrains.annotations.Nullable; import java.io.Serializable; +import java.math.BigDecimal; import java.math.BigInteger; import java.util.Date; import java.util.List; @@ -382,7 +383,7 @@ static public class Price implements Serializable { private static final long serialVersionUID = -4104837036540050532L; - private float amount; + private BigDecimal amount; private String currency; public Price() { @@ -397,6 +398,10 @@ public String toString() { } public float getAmount() { + return amount.floatValue(); + } + + public BigDecimal getAmountDecimal() { return amount; } From 73609399c9679a2dc2db878d3241fcceadd98ad2 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 7 Apr 2023 16:46:35 +0200 Subject: [PATCH 445/516] preparation of a new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 0d2ab9f2..5bcc495f 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.3.3 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 85d169fb..45e0548d 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -71,7 +71,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "5.3.3"; + private final String clientVersion = "5.3.4"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 8ca96bbb..b5c54efa 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 5.3.3 + 5.3.4 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 5.3.3 + 5.3.4 compile From d685f52ab28c2fa12cb77694e022fc94946c6d1a Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 7 Apr 2023 16:48:31 +0200 Subject: [PATCH 446/516] [maven-release-plugin] prepare release v5.3.4 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 5bcc495f..338bc5d6 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.3.4-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v5.3.4 From b4c87886675afdedb03fc511b920006697830869 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 7 Apr 2023 16:48:35 +0200 Subject: [PATCH 447/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 338bc5d6..871c4840 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.3.4 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v5.3.4 + HEAD From 420d72cb2cf31b0bbd2dabb363b29e250c6d9a4f Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 7 Apr 2023 17:27:43 +0200 Subject: [PATCH 448/516] updated --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 871c4840..081e6601 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.3.5-SNAPSHOT From 9b5503c8c62f1b4387bcb79724aa522771987d65 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 8 May 2023 16:17:14 +0200 Subject: [PATCH 449/516] HSM Category Updated --- .../com/messagebird/objects/integrations/HSMCategory.java | 4 ++-- api/src/test/java/com/messagebird/TestUtil.java | 4 ++-- examples/src/main/java/ExampleCreateTemplate.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMCategory.java b/api/src/main/java/com/messagebird/objects/integrations/HSMCategory.java index c88d974b..3edb1db9 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/HSMCategory.java +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMCategory.java @@ -11,8 +11,8 @@ */ public enum HSMCategory { - OTP("OTP"), - TRANSACTIONAL("TRANSACTIONAL"), + AUTHENTICATION("AUTHENTICATION"), + UTILITY("UTILITY"), MARKETING("MARKETING"); private final String category; diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index 1c3f5c07..29744ba5 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -305,7 +305,7 @@ public static TemplateResponse createWhatsAppTemplateResponse(final String templ final TemplateResponse templateResponse = new TemplateResponse(); templateResponse.setName(templateName); templateResponse.setLanguage(language); - templateResponse.setCategory(HSMCategory.OTP); + templateResponse.setCategory(HSMCategory.AUTHENTICATION); templateResponse.setStatus(HSMStatus.NEW); templateResponse.setCreatedAt(new Date()); templateResponse.setUpdatedAt(new Date()); @@ -327,7 +327,7 @@ public static Template createWhatsAppTemplate(final String templateName, final S final Template template = new Template(); template.setName(templateName); template.setLanguage(language); - template.setCategory(HSMCategory.OTP); + template.setCategory(HSMCategory.AUTHENTICATION); final List components = new ArrayList<>(); components.add(createHSMComponentHeader()); diff --git a/examples/src/main/java/ExampleCreateTemplate.java b/examples/src/main/java/ExampleCreateTemplate.java index 9e8a1e96..336340a6 100644 --- a/examples/src/main/java/ExampleCreateTemplate.java +++ b/examples/src/main/java/ExampleCreateTemplate.java @@ -86,7 +86,7 @@ public static void main(String[] args) { template.setLanguage("en_US"); template.setWABAID(args[2]); template.setComponents(components); - template.setCategory(HSMCategory.OTP); + template.setCategory(HSMCategory.AUTHENTICATION); try { TemplateResponse response = messageBirdClient.createWhatsAppTemplate(template); From c78199f8b9e5c0ba5983881787bc01226f3e5ed5 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 8 May 2023 16:22:01 +0200 Subject: [PATCH 450/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 081e6601..d13082e0 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 5.3.4 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 45e0548d..6d8e69c7 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -71,7 +71,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "5.3.4"; + private final String clientVersion = "6.0.0"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index b5c54efa..7416aedc 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 5.3.4 + 6.0.0 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 5.3.4 + 6.0.0 compile From 7dcae2d371c61505fdac751d57c97446e1c01a08 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 8 May 2023 16:24:09 +0200 Subject: [PATCH 451/516] [maven-release-plugin] prepare release v6.0.0 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index d13082e0..99b27149 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.0.0-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v6.0.0 From 53c79541a5a126deb86aec0c2d0e6ae45a5169d5 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 8 May 2023 16:24:14 +0200 Subject: [PATCH 452/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 99b27149..05cfe86e 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.0.0 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v6.0.0 + HEAD From 22c39cdaff814ce02fbcfbb624d9c939a63abf1a Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 8 May 2023 17:35:15 +0200 Subject: [PATCH 453/516] new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 05cfe86e..6ace8cc1 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.0.1-SNAPSHOT From 99bf12976404544e9b2b65056bcb956074a33919 Mon Sep 17 00:00:00 2001 From: "Daniel A. Morales" Date: Tue, 13 Jun 2023 21:00:12 +0100 Subject: [PATCH 454/516] Added support to create and read the OTP authentification template --- .../objects/integrations/HSMComponent.java | 23 ++- .../integrations/HSMComponentButton.java | 192 +++++++++++------- .../integrations/HSMComponentButtonType.java | 3 +- .../integrations/HSMOTPButtonType.java | 38 ++++ .../main/java/ExampleCreateAuthTemplate.java | 69 +++++++ 5 files changed, 248 insertions(+), 77 deletions(-) create mode 100644 api/src/main/java/com/messagebird/objects/integrations/HSMOTPButtonType.java create mode 100644 examples/src/main/java/ExampleCreateAuthTemplate.java diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java b/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java index 51b7efba..ccda2075 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java @@ -1,5 +1,7 @@ package com.messagebird.objects.integrations; +import com.fasterxml.jackson.annotation.JsonProperty; + import java.util.List; /** @@ -13,7 +15,11 @@ public class HSMComponent { private HSMComponentType type; private HSMComponentFormat format; private String text; - private List buttons; + @JsonProperty("add_security_recommendation") + private Boolean addSecurityRecommendation; + @JsonProperty("code_expiration_minutes") + private Integer codeExpirationMinutes; + private List buttons; private HSMExample example; public HSMComponentType getType() { @@ -56,6 +62,21 @@ public void setExample(HSMExample example) { this.example = example; } + public Boolean getAddSecurityRecommendation() { + return addSecurityRecommendation; + } + + public void setAddSecurityRecommendation(Boolean addSecurityRecommendation) { + this.addSecurityRecommendation = addSecurityRecommendation; + } + + public Integer getCodeExpirationMinutes() { + return codeExpirationMinutes; + } + + public void setCodeExpirationMinutes(Integer codeExpirationMinutes) { + this.codeExpirationMinutes = codeExpirationMinutes; + } @Override public String toString() { return "HSMComponent{" + diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButton.java b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButton.java index 6438f79e..9bb4ffb1 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButton.java +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButton.java @@ -1,5 +1,7 @@ package com.messagebird.objects.integrations; +import com.fasterxml.jackson.annotation.JsonProperty; + import java.util.List; /** @@ -10,79 +12,119 @@ */ public class HSMComponentButton { - private HSMComponentButtonType type; - private String text; - private String url; - private String phone_number; - private List example; - - public HSMComponentButtonType getType() { - return type; - } - - public void setType(HSMComponentButtonType type) { - this.type = type; - } - - public String getText() { - return text; - } - - public void setText(String text) { - this.text = text; - } - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getPhone_number() { - return phone_number; - } - - public void setPhone_number(String phone_number) { - this.phone_number = phone_number; - } - - public List getExample() { - return example; - } - - public void setExample(List example) { - this.example = example; - } - - @Override - public String toString() { - return "HSMComponentButton{" + - "type=" + type + - ", text='" + text + '\'' + - ", url='" + url + '\'' + - ", phone_number='" + phone_number + '\'' + - ", example=" + example + - '}'; - } - - /** - * Check if example field is able to use. - * - * @throws IllegalArgumentException Occurs if button type is not {@code URL} or {@code QUICK_REPLY}. - */ - public void validateButtonExample() throws IllegalArgumentException { - final boolean isExampleEmpty = this.example == null || this.example.isEmpty(); - final boolean isNotProperType = !(this.type.equals(HSMComponentButtonType.URL) - || this.type.equals(HSMComponentButtonType.QUICK_REPLY)); - - if (isExampleEmpty) { - return; - } - - if (isNotProperType) { - throw new IllegalArgumentException("An example field in HSMComponentButton is available for only URL or QUICK_REPLY button types."); - } - } + private HSMComponentButtonType type; + private String text; + private String url; + private String phone_number; + private List example; + + //fields used by the authentification template + @JsonProperty("otp_type") + private HSMOTPButtonType otpType; + @JsonProperty("autofill_text") + private String autofillText; + @JsonProperty("package_name") + private String packageName; + @JsonProperty("signature_hash") + private String signatureHash; + + public HSMComponentButtonType getType() { + return type; + } + + public void setType(HSMComponentButtonType type) { + this.type = type; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getPhone_number() { + return phone_number; + } + + public void setPhone_number(String phone_number) { + this.phone_number = phone_number; + } + + public List getExample() { + return example; + } + + public void setExample(List example) { + this.example = example; + } + public HSMOTPButtonType getOtpType() { + return otpType; + } + + public void setOtpType(HSMOTPButtonType otpType) { + this.otpType = otpType; + } + + public String getAutofillText() { + return autofillText; + } + + public void setAutofillText(String autofillText) { + this.autofillText = autofillText; + } + + public String getPackageName() { + return packageName; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + public String getSignatureHash() { + return signatureHash; + } + + public void setSignatureHash(String signatureHash) { + this.signatureHash = signatureHash; + } + @Override + public String toString() { + return "HSMComponentButton{" + + "type=" + type + + ", text='" + text + '\'' + + ", url='" + url + '\'' + + ", phone_number='" + phone_number + '\'' + + ", example=" + example + + '}'; + } + + /** + * Check if example field is able to use. + * + * @throws IllegalArgumentException Occurs if button type is not {@code URL} or {@code QUICK_REPLY}. + */ + public void validateButtonExample() throws IllegalArgumentException { + final boolean isExampleEmpty = this.example == null || this.example.isEmpty(); + final boolean isNotProperType = !(this.type.equals(HSMComponentButtonType.URL) + || this.type.equals(HSMComponentButtonType.QUICK_REPLY)); + + if (isExampleEmpty) { + return; + } + + if (isNotProperType) { + throw new IllegalArgumentException("An example field in HSMComponentButton is available for only URL or QUICK_REPLY button types."); + } + } } diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButtonType.java b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButtonType.java index 937f6baf..5029fc73 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButtonType.java +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButtonType.java @@ -13,7 +13,8 @@ public enum HSMComponentButtonType { PHONE_NUMBER("PHONE_NUMBER"), URL("URL"), - QUICK_REPLY("QUICK_REPLY"); + QUICK_REPLY("QUICK_REPLY"), + OTP("OTP"); private final String type; diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMOTPButtonType.java b/api/src/main/java/com/messagebird/objects/integrations/HSMOTPButtonType.java new file mode 100644 index 00000000..499ef1f3 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMOTPButtonType.java @@ -0,0 +1,38 @@ +package com.messagebird.objects.integrations; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public enum HSMOTPButtonType { + ONE_TAP("ONE_TAP"), + COPY_CODE("COPY_CODE"); + + private final String type; + + HSMOTPButtonType(String type) { + this.type = type; + } + @JsonCreator + public static HSMOTPButtonType forValue(String value) { + for (HSMOTPButtonType OTPButtonType : HSMOTPButtonType.values()) { + if (OTPButtonType.getType().equals(value)) { + return OTPButtonType; + } + } + return null; + } + + @JsonValue + public String toJson() { + return getType(); + } + + public String getType() { + return type; + } + + @Override + public String toString() { + return getType(); + } +} diff --git a/examples/src/main/java/ExampleCreateAuthTemplate.java b/examples/src/main/java/ExampleCreateAuthTemplate.java new file mode 100644 index 00000000..31b5f415 --- /dev/null +++ b/examples/src/main/java/ExampleCreateAuthTemplate.java @@ -0,0 +1,69 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.integrations.*; + +import java.util.ArrayList; +import java.util.List; + +public class ExampleCreateAuthTemplate { + public static void main(String[] args) { + + if (args.length < 3) { + System.out.println("Please specify your access key and a template name and WABA ID example : java -jar test_accesskey \"My template name\" \"WABA ID\""); + return; + } + + // First create your service object + MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + /* body */ + HSMComponent bodyComponent = new HSMComponent(); + bodyComponent.setType(HSMComponentType.BODY); + bodyComponent.setAddSecurityRecommendation(true); + + /* footer */ + HSMComponent footerComponent = new HSMComponent(); + footerComponent.setType(HSMComponentType.FOOTER); + footerComponent.setCodeExpirationMinutes(8); + + /* button */ + HSMComponent buttonComponent = new HSMComponent(); + List buttons = new ArrayList<>(); + HSMComponentButton otpButton = new HSMComponentButton(); + otpButton.setOtpType(HSMOTPButtonType.ONE_TAP); + otpButton.setText("Copy code"); + otpButton.setAutofillText("Autofill"); + otpButton.setPackageName("com.example.luckyshrub"); + otpButton.setSignatureHash("K8a%2FAINcGX7"); + + buttons.add(otpButton); + buttonComponent.setType(HSMComponentType.BUTTONS); + buttonComponent.setButtons(buttons); + + /* set components */ + Template template = new Template(); + List components = new ArrayList<>(); + components.add(bodyComponent); + components.add(footerComponent); + components.add(buttonComponent); + + template.setName(args[1]); + template.setLanguage("en_US"); + template.setWABAID(args[2]); + template.setComponents(components); + template.setCategory(HSMCategory.AUTHENTICATION); + + try { + TemplateResponse response = messageBirdClient.createWhatsAppTemplate(template); + System.out.println(response.toString()); + } catch (GeneralException | UnauthorizedException | IllegalArgumentException exception) { + exception.printStackTrace(); + } + } +} \ No newline at end of file From e5e5b6350f85bccfd4d89c189787f67b849485c1 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 15 Jun 2023 11:50:17 +0200 Subject: [PATCH 455/516] preperation for the new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 6ace8cc1..04c132c1 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.0.0 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 6d8e69c7..719c0cfd 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -71,7 +71,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "6.0.0"; + private final String clientVersion = "6.1.0"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 7416aedc..e05d8c0e 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 6.0.0 + 6.1.0 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 6.0.0 + 6.1.0 compile From 19ef745550213650cb3072ca56fd0cb33f406a73 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 15 Jun 2023 11:51:46 +0200 Subject: [PATCH 456/516] [maven-release-plugin] prepare release v6.1.0 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 04c132c1..74a71df9 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.0-SNAPSHOT @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v6.1.0 From 13c8625bde5971b5c7c3b7be817389d484c6a17c Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 15 Jun 2023 11:51:51 +0200 Subject: [PATCH 457/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 74a71df9..7d432ca5 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.0 @@ -42,7 +42,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v6.1.0 + HEAD From b2858670c4e38c83d58da1de59a667402aa3d6fb Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 15 Jun 2023 13:28:02 +0200 Subject: [PATCH 458/516] preperation for the new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 7d432ca5..e29537ee 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.1-SNAPSHOT From c3086196a1e25eae1164157c5f6cd33a708b6980 Mon Sep 17 00:00:00 2001 From: Jon Chambers Date: Wed, 16 Aug 2023 10:45:07 -0400 Subject: [PATCH 459/516] Add SMS pricing model objects --- .../messagebird/objects/OutboundSmsPrice.java | 60 +++++++++++++++++++ .../objects/OutboundSmsPriceResponse.java | 36 +++++++++++ 2 files changed, 96 insertions(+) create mode 100644 api/src/main/java/com/messagebird/objects/OutboundSmsPrice.java create mode 100644 api/src/main/java/com/messagebird/objects/OutboundSmsPriceResponse.java diff --git a/api/src/main/java/com/messagebird/objects/OutboundSmsPrice.java b/api/src/main/java/com/messagebird/objects/OutboundSmsPrice.java new file mode 100644 index 00000000..3733cf69 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/OutboundSmsPrice.java @@ -0,0 +1,60 @@ +package com.messagebird.objects; + +import java.math.BigDecimal; + +public class OutboundSmsPrice { + private BigDecimal price; + private String currencyCode; + private String mccmnc; + private String mcc; + private String mnc; + private String countryName; + private String countryIsoCode; + private String operatorName; + + public BigDecimal getPrice() { + return price; + } + + public String getCurrencyCode() { + return currencyCode; + } + + public String getMccmnc() { + return mccmnc; + } + + public String getMcc() { + return mcc; + } + + public String getMnc() { + return mnc; + } + + public String getCountryName() { + return countryName; + } + + public String getCountryIsoCode() { + return countryIsoCode; + } + + public String getOperatorName() { + return operatorName; + } + + @Override + public String toString() { + return "OutboundSmsPrice{" + + "price=" + price + + ", currencyCode='" + currencyCode + '\'' + + ", mccmnc='" + mccmnc + '\'' + + ", mcc='" + mcc + '\'' + + ", mnc='" + mnc + '\'' + + ", countryName='" + countryName + '\'' + + ", countryIsoCode='" + countryIsoCode + '\'' + + ", operatorName='" + operatorName + '\'' + + '}'; + } +} diff --git a/api/src/main/java/com/messagebird/objects/OutboundSmsPriceResponse.java b/api/src/main/java/com/messagebird/objects/OutboundSmsPriceResponse.java new file mode 100644 index 00000000..6d036882 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/OutboundSmsPriceResponse.java @@ -0,0 +1,36 @@ +package com.messagebird.objects; + +import java.util.List; + +public class OutboundSmsPriceResponse { + private int gateway; + private String currencyCode; + private int totalCount; + private List prices; + + public int getGateway() { + return gateway; + } + + public String getCurrencyCode() { + return currencyCode; + } + + public int getTotalCount() { + return totalCount; + } + + public List getPrices() { + return prices; + } + + @Override + public String toString() { + return "OutboundSmsPriceResponse{" + + "gateway=" + gateway + + ", currencyCode='" + currencyCode + '\'' + + ", totalCount=" + totalCount + + ", prices=" + prices + + '}'; + } +} From 20a811d549b72d7943991859d454286a15160922 Mon Sep 17 00:00:00 2001 From: Jon Chambers Date: Wed, 16 Aug 2023 11:16:55 -0400 Subject: [PATCH 460/516] Add client methods for getting outbound SMS prices --- .../com/messagebird/MessageBirdClient.java | 35 +++++++++ .../messagebird/OutboundSmsPricesTest.java | 77 +++++++++++++++++++ .../fixtures/outbound_sms_prices.json | 37 +++++++++ 3 files changed, 149 insertions(+) create mode 100644 api/src/test/java/com/messagebird/OutboundSmsPricesTest.java create mode 100644 api/src/test/resources/fixtures/outbound_sms_prices.json diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index be7a8fa5..6e216fe7 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -105,6 +105,8 @@ public class MessageBirdClient { private static final String VOICELEGS_SUFFIX_PATH = "/legs"; static final String FILES_PATH = "/files"; static final String TEMPLATES_PATH = "/templates"; + static final String OUTBOUND_SMS_PRICING_PATH = "/pricing/sms/outbound"; + static final String OUTBOUND_SMS_PRICING_SMPP_PATH = "/pricing/sms/outbound/smpp/%s"; static final String RECORDING_DOWNLOAD_FORMAT = ".wav"; @@ -2202,4 +2204,37 @@ public void deleteChildAccount(final String id) throws UnauthorizedException, Ge System.out.println("url: " + url); messageBirdService.deleteByID(url, id); } + + /** + * Returns outbound pricing for the default SMS configuration for the authenticated account. + * + * @return outbound pricing for the default SMS configuration for the authenticated account + * + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + * @throws NotFoundException if pricing information could not be found + * + * @see Pricing API + */ + public OutboundSmsPriceResponse getOutboundSmsPrices() throws GeneralException, UnauthorizedException, NotFoundException { + return messageBirdService.request(OUTBOUND_SMS_PRICING_PATH, OutboundSmsPriceResponse.class); + } + + /** + * Returns outbound SMS pricing for a specific SMPP username. + * + * @param smppUsername the SMPP SystemID provided by MessageBird + * + * @return outbound SMS pricing for the given SMPP username + * + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + * @throws NotFoundException if pricing information could not be found for the given SMPP username + * + * @see Pricing API + */ + public OutboundSmsPriceResponse getOutboundSmsPrices(final String smppUsername) throws GeneralException, UnauthorizedException, NotFoundException { + final String url = String.format(OUTBOUND_SMS_PRICING_SMPP_PATH, smppUsername); + return messageBirdService.request(url, OutboundSmsPriceResponse.class); + } } diff --git a/api/src/test/java/com/messagebird/OutboundSmsPricesTest.java b/api/src/test/java/com/messagebird/OutboundSmsPricesTest.java new file mode 100644 index 00000000..60d6b466 --- /dev/null +++ b/api/src/test/java/com/messagebird/OutboundSmsPricesTest.java @@ -0,0 +1,77 @@ +package com.messagebird; + +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.NotFoundException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.OutboundSmsPriceResponse; +import com.messagebird.util.Resources; +import org.junit.Test; + +import java.math.BigDecimal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +public class OutboundSmsPricesTest { + + @Test + public void testGetOutboundSmsPrices() throws GeneralException, UnauthorizedException, NotFoundException { + String responseFixture = Resources.readResourceText("/fixtures/outbound_sms_prices.json"); + + MessageBirdService messageBirdService = SpyService + .expects("GET", "pricing/sms/outbound") + .withRestAPIBaseURL() + .andReturns(new APIResponse(responseFixture, 200)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + + assertReceivedExpectedResponse(messageBirdClient.getOutboundSmsPrices()); + } + + @Test + public void testGetOutboundSmsPricesSmppUsername() throws GeneralException, UnauthorizedException, NotFoundException { + String responseFixture = Resources.readResourceText("/fixtures/outbound_sms_prices.json"); + + MessageBirdService messageBirdService = SpyService + .expects("GET", "pricing/sms/outbound/smpp/test-smpp-user") + .withRestAPIBaseURL() + .andReturns(new APIResponse(responseFixture, 200)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + + assertReceivedExpectedResponse(messageBirdClient.getOutboundSmsPrices("test-smpp-user")); + } + + private static void assertReceivedExpectedResponse(OutboundSmsPriceResponse outboundSmsPriceResponse) { + assertEquals(10, outboundSmsPriceResponse.getGateway()); + assertEquals("EUR", outboundSmsPriceResponse.getCurrencyCode()); + assertEquals(3, outboundSmsPriceResponse.getTotalCount()); + + assertEquals(3, outboundSmsPriceResponse.getPrices().size()); + + assertEquals(new BigDecimal("0.060000"), outboundSmsPriceResponse.getPrices().get(0).getPrice()); + assertEquals("EUR", outboundSmsPriceResponse.getPrices().get(0).getCurrencyCode()); + assertEquals("0", outboundSmsPriceResponse.getPrices().get(0).getMccmnc()); + assertEquals("0", outboundSmsPriceResponse.getPrices().get(0).getMcc()); + assertNull(outboundSmsPriceResponse.getPrices().get(0).getMnc()); + assertEquals("Default Rate", outboundSmsPriceResponse.getPrices().get(0).getCountryName()); + assertEquals("XX", outboundSmsPriceResponse.getPrices().get(0).getCountryIsoCode()); + assertEquals("Default Rate", outboundSmsPriceResponse.getPrices().get(0).getOperatorName()); + + assertEquals(new BigDecimal("0.047000"), outboundSmsPriceResponse.getPrices().get(1).getPrice()); + assertEquals("EUR", outboundSmsPriceResponse.getPrices().get(1).getCurrencyCode()); + assertEquals("202", outboundSmsPriceResponse.getPrices().get(1).getMccmnc()); + assertEquals("202", outboundSmsPriceResponse.getPrices().get(1).getMcc()); + assertNull(outboundSmsPriceResponse.getPrices().get(1).getMnc()); + assertEquals("Greece", outboundSmsPriceResponse.getPrices().get(1).getCountryName()); + assertEquals("GR", outboundSmsPriceResponse.getPrices().get(1).getCountryIsoCode()); + assertNull(outboundSmsPriceResponse.getPrices().get(1).getOperatorName()); + + assertEquals(new BigDecimal("0.045000"), outboundSmsPriceResponse.getPrices().get(2).getPrice()); + assertEquals("EUR", outboundSmsPriceResponse.getPrices().get(2).getCurrencyCode()); + assertEquals("20205", outboundSmsPriceResponse.getPrices().get(2).getMccmnc()); + assertEquals("202", outboundSmsPriceResponse.getPrices().get(2).getMcc()); + assertEquals("05", outboundSmsPriceResponse.getPrices().get(2).getMnc()); + assertEquals("Greece", outboundSmsPriceResponse.getPrices().get(2).getCountryName()); + assertEquals("GR", outboundSmsPriceResponse.getPrices().get(2).getCountryIsoCode()); + assertEquals("Vodafone", outboundSmsPriceResponse.getPrices().get(2).getOperatorName()); + } +} diff --git a/api/src/test/resources/fixtures/outbound_sms_prices.json b/api/src/test/resources/fixtures/outbound_sms_prices.json new file mode 100644 index 00000000..261401d3 --- /dev/null +++ b/api/src/test/resources/fixtures/outbound_sms_prices.json @@ -0,0 +1,37 @@ +{ + "gateway": 10, + "currencyCode": "EUR", + "totalCount": 3, + "prices": [ + { + "price": "0.060000", + "currencyCode": "EUR", + "mccmnc": "0", + "mcc": "0", + "mnc": null, + "countryName": "Default Rate", + "countryIsoCode": "XX", + "operatorName": "Default Rate" + }, + { + "price": "0.047000", + "currencyCode": "EUR", + "mccmnc": "202", + "mcc": "202", + "mnc": null, + "countryName": "Greece", + "countryIsoCode": "GR", + "operatorName": null + }, + { + "price": "0.045000", + "currencyCode": "EUR", + "mccmnc": "20205", + "mcc": "202", + "mnc": "05", + "countryName": "Greece", + "countryIsoCode": "GR", + "operatorName": "Vodafone" + } + ] +} From b6a4f909aab9f7c92064fd76940e3d12b3db2eec Mon Sep 17 00:00:00 2001 From: Jon Chambers Date: Thu, 17 Aug 2023 09:40:51 -0400 Subject: [PATCH 461/516] Guard against `null` `smppUsername` arguments --- api/src/main/java/com/messagebird/MessageBirdClient.java | 4 ++++ .../test/java/com/messagebird/OutboundSmsPricesTest.java | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 6e216fe7..322b1247 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -2234,6 +2234,10 @@ public OutboundSmsPriceResponse getOutboundSmsPrices() throws GeneralException, * @see Pricing API */ public OutboundSmsPriceResponse getOutboundSmsPrices(final String smppUsername) throws GeneralException, UnauthorizedException, NotFoundException { + if (smppUsername == null) { + throw new IllegalArgumentException("SMPP username must be specified."); + } + final String url = String.format(OUTBOUND_SMS_PRICING_SMPP_PATH, smppUsername); return messageBirdService.request(url, OutboundSmsPriceResponse.class); } diff --git a/api/src/test/java/com/messagebird/OutboundSmsPricesTest.java b/api/src/test/java/com/messagebird/OutboundSmsPricesTest.java index 60d6b466..665dba71 100644 --- a/api/src/test/java/com/messagebird/OutboundSmsPricesTest.java +++ b/api/src/test/java/com/messagebird/OutboundSmsPricesTest.java @@ -11,6 +11,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; public class OutboundSmsPricesTest { @@ -40,6 +41,11 @@ public void testGetOutboundSmsPricesSmppUsername() throws GeneralException, Unau assertReceivedExpectedResponse(messageBirdClient.getOutboundSmsPrices("test-smpp-user")); } + @Test(expected = IllegalArgumentException.class) + public void testGetOutboundSmsPricesSmppUsernameNull() throws GeneralException, UnauthorizedException, NotFoundException { + new MessageBirdClient(mock(MessageBirdService.class)).getOutboundSmsPrices(null); + } + private static void assertReceivedExpectedResponse(OutboundSmsPriceResponse outboundSmsPriceResponse) { assertEquals(10, outboundSmsPriceResponse.getGateway()); assertEquals("EUR", outboundSmsPriceResponse.getCurrencyCode()); From 1ccb707792abba5cbbbd362c6be473a900f847d1 Mon Sep 17 00:00:00 2001 From: Jon Chambers Date: Thu, 17 Aug 2023 09:49:00 -0400 Subject: [PATCH 462/516] Add an example of fetching outbound SMS prices --- .../java/ExampleGetOutboundSmsPrices.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 examples/src/main/java/ExampleGetOutboundSmsPrices.java diff --git a/examples/src/main/java/ExampleGetOutboundSmsPrices.java b/examples/src/main/java/ExampleGetOutboundSmsPrices.java new file mode 100644 index 00000000..e90d5151 --- /dev/null +++ b/examples/src/main/java/ExampleGetOutboundSmsPrices.java @@ -0,0 +1,33 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.MessageBirdException; +import com.messagebird.objects.OutboundSmsPriceResponse; + +public class ExampleGetOutboundSmsPrices { + + public static void main(String[] args) { + if (args.length != 1 && args.length != 2) { + System.out.println("Please specify your access key and (optionally) SMPP username"); + return; + } + + final MessageBirdClient messageBirdClient = new MessageBirdClient(new MessageBirdServiceImpl(args[0])); + + try { + System.out.println("Get a list of outbound SMS prices"); + + final OutboundSmsPriceResponse outboundSmsPriceResponse; + + if (args.length == 2) { + final String smppUsername = args[1]; + outboundSmsPriceResponse = messageBirdClient.getOutboundSmsPrices(smppUsername); + } else { + outboundSmsPriceResponse = messageBirdClient.getOutboundSmsPrices(); + } + + System.out.println("response: " + outboundSmsPriceResponse); + } catch (MessageBirdException e) { + e.printStackTrace(); + } + } +} From 5b28fb722584fbbc1d7acf00519ebd930f77fa98 Mon Sep 17 00:00:00 2001 From: Jon Chambers Date: Thu, 17 Aug 2023 09:59:28 -0400 Subject: [PATCH 463/516] Replace `Base64.java` with the JDK-provided `Base64` decoder --- api/pom.xml | 5 +- api/src/main/java/com/messagebird/Base64.java | 512 ------------------ .../java/com/messagebird/RequestSigner.java | 8 +- 3 files changed, 5 insertions(+), 520 deletions(-) delete mode 100644 api/src/main/java/com/messagebird/Base64.java diff --git a/api/pom.xml b/api/pom.xml index e29537ee..1d6f8b2d 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,10 +4,7 @@ com.messagebird messagebird-api - 6.1.0 + 6.1.0 jar ${project.groupId}:${project.artifactId} diff --git a/api/src/main/java/com/messagebird/Base64.java b/api/src/main/java/com/messagebird/Base64.java deleted file mode 100644 index f96ef9fa..00000000 --- a/api/src/main/java/com/messagebird/Base64.java +++ /dev/null @@ -1,512 +0,0 @@ -package com.messagebird; - -/** - * Cutted version of iharder's base64 implementation - * - * @author Robert Harder - * @author rob@iharder.net - * @version 2.3.7 - * @todo replace with actual library on next major bump - * - *

Encodes and decodes to and from Base64 notation.

- *

Homepage: http://iharder.net/base64.

- * - *

- * I am placing this code in the Public Domain. Do with it as you will. - * This software comes with no guarantees or warranties but with - * plenty of well-wishing instead! - * Please visit http://iharder.net/base64 - * periodically to check for updates or to contribute improvements. - *

- * @deprecated This class is being deprecated together with {@link RequestSigner} - */ -@Deprecated -class Base64 { - - /* ******** P U B L I C F I E L D S ******** */ - - - /** - * No options specified. Value is zero. - */ - public final static int NO_OPTIONS = 0; - - /** - * Specify that gzipped data should not be automatically gunzipped. - */ - public final static int DONT_GUNZIP = 4; - - /** - * Encode using Base64-like encoding that is URL- and Filename-safe as described - * in Section 4 of RFC3548: - * http://www.faqs.org/rfcs/rfc3548.html. - * It is important to note that data encoded this way is not officially valid Base64, - * or at the very least should not be called Base64 without also specifying that is - * was encoded using the URL- and Filename-safe dialect. - */ - public final static int URL_SAFE = 16; - - - /** - * Encode using the special "ordered" dialect of Base64 described here: - * http://www.faqs.org/qa/rfcc-1940.html. - */ - public final static int ORDERED = 32; - - - /* ******** P R I V A T E F I E L D S ******** */ - - - /** - * The equals sign (=) as a byte. - */ - private final static byte EQUALS_SIGN = (byte) '='; - - - /** - * Preferred encoding. - */ - private final static String PREFERRED_ENCODING = "US-ASCII"; - - - private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding - private final static byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding - - - /* ******** S T A N D A R D B A S E 6 4 A L P H A B E T ******** */ - - /** - * Translates a Base64 value to either its 6-bit reconstruction value - * or a negative number indicating some other meaning. - **/ - private final static byte[] _STANDARD_DECODABET = { - -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8 - -5, -5, // Whitespace: Tab and Linefeed - -9, -9, // Decimal 11 - 12 - -5, // Whitespace: Carriage Return - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26 - -9, -9, -9, -9, -9, // Decimal 27 - 31 - -5, // Whitespace: Space - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42 - 62, // Plus sign at decimal 43 - -9, -9, -9, // Decimal 44 - 46 - 63, // Slash at decimal 47 - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine - -9, -9, -9, // Decimal 58 - 60 - -1, // Equals sign at decimal 61 - -9, -9, -9, // Decimal 62 - 64 - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N' - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z' - -9, -9, -9, -9, -9, -9, // Decimal 91 - 96 - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm' - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z' - -9, -9, -9, -9, -9 // Decimal 123 - 127 - , -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 128 - 139 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 140 - 152 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 153 - 165 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 166 - 178 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 179 - 191 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 192 - 204 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 205 - 217 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 218 - 230 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 231 - 243 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 // Decimal 244 - 255 - }; - - - /* ******** U R L S A F E B A S E 6 4 A L P H A B E T ******** */ - - /** - * Used in decoding URL- and Filename-safe dialects of Base64. - */ - private final static byte[] _URL_SAFE_DECODABET = { - -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8 - -5, -5, // Whitespace: Tab and Linefeed - -9, -9, // Decimal 11 - 12 - -5, // Whitespace: Carriage Return - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26 - -9, -9, -9, -9, -9, // Decimal 27 - 31 - -5, // Whitespace: Space - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42 - -9, // Plus sign at decimal 43 - -9, // Decimal 44 - 62, // Minus sign at decimal 45 - -9, // Decimal 46 - -9, // Slash at decimal 47 - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine - -9, -9, -9, // Decimal 58 - 60 - -1, // Equals sign at decimal 61 - -9, -9, -9, // Decimal 62 - 64 - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N' - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z' - -9, -9, -9, -9, // Decimal 91 - 94 - 63, // Underscore at decimal 95 - -9, // Decimal 96 - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm' - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z' - -9, -9, -9, -9, -9 // Decimal 123 - 127 - , -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 128 - 139 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 140 - 152 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 153 - 165 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 166 - 178 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 179 - 191 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 192 - 204 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 205 - 217 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 218 - 230 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 231 - 243 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 // Decimal 244 - 255 - }; - - - - /* ******** O R D E R E D B A S E 6 4 A L P H A B E T ******** */ - - /** - * Used in decoding the "ordered" dialect of Base64. - */ - private final static byte[] _ORDERED_DECODABET = { - -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8 - -5, -5, // Whitespace: Tab and Linefeed - -9, -9, // Decimal 11 - 12 - -5, // Whitespace: Carriage Return - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26 - -9, -9, -9, -9, -9, // Decimal 27 - 31 - -5, // Whitespace: Space - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42 - -9, // Plus sign at decimal 43 - -9, // Decimal 44 - 0, // Minus sign at decimal 45 - -9, // Decimal 46 - -9, // Slash at decimal 47 - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // Numbers zero through nine - -9, -9, -9, // Decimal 58 - 60 - -1, // Equals sign at decimal 61 - -9, -9, -9, // Decimal 62 - 64 - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, // Letters 'A' through 'M' - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, // Letters 'N' through 'Z' - -9, -9, -9, -9, // Decimal 91 - 94 - 37, // Underscore at decimal 95 - -9, // Decimal 96 - 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, // Letters 'a' through 'm' - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // Letters 'n' through 'z' - -9, -9, -9, -9, -9 // Decimal 123 - 127 - , -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 128 - 139 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 140 - 152 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 153 - 165 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 166 - 178 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 179 - 191 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 192 - 204 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 205 - 217 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 218 - 230 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 231 - 243 - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 // Decimal 244 - 255 - }; - - - /* ******** D E T E R M I N E W H I C H A L H A B E T ******** */ - - /** - * Returns one of the _SOMETHING_DECODABET byte arrays depending on - * the options specified. - * It's possible, though silly, to specify ORDERED and URL_SAFE - * in which case one of them will be picked, though there is - * no guarantee as to which one will be picked. - */ - private final static byte[] getDecodabet(int options) { - if ((options & URL_SAFE) == URL_SAFE) { - return _URL_SAFE_DECODABET; - } else if ((options & ORDERED) == ORDERED) { - return _ORDERED_DECODABET; - } else { - return _STANDARD_DECODABET; - } - } // end getAlphabet - - - /** - * Defeats instantiation. - */ - private Base64() { - } - - - - /* ******** D E C O D I N G M E T H O D S ******** */ - - - /** - * Decodes four bytes from array source - * and writes the resulting bytes (up to three of them) - * to destination. - * The source and destination arrays can be manipulated - * anywhere along their length by specifying - * srcOffset and destOffset. - * This method does not check to make sure your arrays - * are large enough to accomodate srcOffset + 4 for - * the source array or destOffset + 3 for - * the destination array. - * This method returns the actual number of bytes that - * were converted from the Base64 encoding. - *

This is the lowest level of the decoding methods with - * all possible parameters.

- * - * @param source the array to convert - * @param srcOffset the index where conversion begins - * @param destination the array to hold the conversion - * @param destOffset the index where output will be put - * @param options alphabet type is pulled from this (standard, url-safe, ordered) - * @return the number of decoded bytes converted - * @throws NullPointerException if source or destination arrays are null - * @throws IllegalArgumentException if srcOffset or destOffset are invalid - * or there is not enough room in the array. - * @since 1.3 - */ - private static int decode4to3( - byte[] source, int srcOffset, - byte[] destination, int destOffset, int options) { - - // Lots of error checking and exception throwing - if (source == null) { - throw new NullPointerException("Source array was null."); - } // end if - if (destination == null) { - throw new NullPointerException("Destination array was null."); - } // end if - if (srcOffset < 0 || srcOffset + 3 >= source.length) { - throw new IllegalArgumentException(String.format( - "Source array with length %d cannot have offset of %d and still process four bytes.", source.length, srcOffset)); - } // end if - if (destOffset < 0 || destOffset + 2 >= destination.length) { - throw new IllegalArgumentException(String.format( - "Destination array with length %d cannot have offset of %d and still store three bytes.", destination.length, destOffset)); - } // end if - - - byte[] DECODABET = getDecodabet(options); - - // Example: Dk== - if (source[srcOffset + 2] == EQUALS_SIGN) { - // Two ways to do the same thing. Don't know which way I like best. - //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) - // | ( ( DECODABET[ source[ srcOffset + 1] ] << 24 ) >>> 12 ); - int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18) - | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12); - - destination[destOffset] = (byte) (outBuff >>> 16); - return 1; - } - - // Example: DkL= - else if (source[srcOffset + 3] == EQUALS_SIGN) { - // Two ways to do the same thing. Don't know which way I like best. - //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) - // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) - // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ); - int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18) - | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12) - | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6); - - destination[destOffset] = (byte) (outBuff >>> 16); - destination[destOffset + 1] = (byte) (outBuff >>> 8); - return 2; - } - - // Example: DkLE - else { - // Two ways to do the same thing. Don't know which way I like best. - //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) - // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) - // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ) - // | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 ); - int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18) - | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12) - | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6) - | ((DECODABET[source[srcOffset + 3]] & 0xFF)); - - - destination[destOffset] = (byte) (outBuff >> 16); - destination[destOffset + 1] = (byte) (outBuff >> 8); - destination[destOffset + 2] = (byte) (outBuff); - - return 3; - } - } // end decodeToBytes - - - /** - * Low-level access to decoding ASCII characters in - * the form of a byte array. Ignores GUNZIP option, if - * it's set. This is not generally a recommended method, - * although it is used internally as part of the decoding process. - * Special case: if len = 0, an empty array is returned. Still, - * if you need more speed and reduced memory footprint (and aren't - * gzipping), consider this method. - * - * @param source The Base64 encoded data - * @param off The offset of where to begin decoding - * @param len The length of characters to decode - * @param options Can specify options such as alphabet type to use - * @return decoded data - * @throws java.io.IOException If bogus characters exist in source data - * @since 1.3 - */ - public static byte[] decode(byte[] source, int off, int len, int options) - throws java.io.IOException { - - // Lots of error checking and exception throwing - if (source == null) { - throw new NullPointerException("Cannot decode null source array."); - } // end if - if (off < 0 || off + len > source.length) { - throw new IllegalArgumentException(String.format( - "Source array with length %d cannot have offset of %d and process %d bytes.", source.length, off, len)); - } // end if - - if (len == 0) { - return new byte[0]; - } else if (len < 4) { - throw new IllegalArgumentException( - "Base64-encoded string must have at least four characters, but length specified was " + len); - } // end if - - byte[] DECODABET = getDecodabet(options); - - int len34 = len * 3 / 4; // Estimate on array size - byte[] outBuff = new byte[len34]; // Upper limit on size of output - int outBuffPosn = 0; // Keep track of where we're writing - - byte[] b4 = new byte[4]; // Four byte buffer from source, eliminating white space - int b4Posn = 0; // Keep track of four byte input buffer - int i = 0; // Source array counter - byte sbiDecode = 0; // Special value from DECODABET - - for (i = off; i < off + len; i++) { // Loop through source - - sbiDecode = DECODABET[source[i] & 0xFF]; - - // White space, Equals sign, or legit Base64 character - // Note the values such as -5 and -9 in the - // DECODABETs at the top of the file. - if (sbiDecode >= WHITE_SPACE_ENC) { - if (sbiDecode >= EQUALS_SIGN_ENC) { - b4[b4Posn++] = source[i]; // Save non-whitespace - if (b4Posn > 3) { // Time to decode? - outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, options); - b4Posn = 0; - - // If that was the equals sign, break out of 'for' loop - if (source[i] == EQUALS_SIGN) { - break; - } // end if: equals sign - } // end if: quartet built - } // end if: equals sign or better - } // end if: white space, equals sign or better - else { - // There's a bad input character in the Base64 stream. - throw new java.io.IOException(String.format( - "Bad Base64 input character decimal %d in array position %d", ((int) source[i]) & 0xFF, i)); - } // end else: - } // each input character - - byte[] out = new byte[outBuffPosn]; - System.arraycopy(outBuff, 0, out, 0, outBuffPosn); - return out; - } // end decode - - - /** - * Decodes data from Base64 notation, automatically - * detecting gzip-compressed data and decompressing it. - * - * @param s the string to decode - * @return the decoded data - * @throws java.io.IOException If there is a problem - * @since 1.4 - */ - public static byte[] decode(String s) throws java.io.IOException { - return decode(s, NO_OPTIONS); - } - - - /** - * Decodes data from Base64 notation, automatically - * detecting gzip-compressed data and decompressing it. - * - * @param s the string to decode - * @param options encode options such as URL_SAFE - * @return the decoded data - * @throws java.io.IOException if there is an error - * @throws NullPointerException if s is null - * @since 1.4 - */ - public static byte[] decode(String s, int options) throws java.io.IOException { - - if (s == null) { - throw new NullPointerException("Input string was null."); - } // end if - - byte[] bytes; - try { - bytes = s.getBytes(PREFERRED_ENCODING); - } // end try - catch (java.io.UnsupportedEncodingException uee) { - bytes = s.getBytes(); - } // end catch - // - - // Decode - bytes = decode(bytes, 0, bytes.length, options); - - // Check to see if it's gzip-compressed - // GZIP Magic Two-Byte Number: 0x8b1f (35615) - boolean dontGunzip = (options & DONT_GUNZIP) != 0; - if ((bytes != null) && (bytes.length >= 4) && (!dontGunzip)) { - - int head = ((int) bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00); - if (java.util.zip.GZIPInputStream.GZIP_MAGIC == head) { - java.io.ByteArrayInputStream bais = null; - java.util.zip.GZIPInputStream gzis = null; - java.io.ByteArrayOutputStream baos = null; - byte[] buffer = new byte[2048]; - int length = 0; - - try { - baos = new java.io.ByteArrayOutputStream(); - bais = new java.io.ByteArrayInputStream(bytes); - gzis = new java.util.zip.GZIPInputStream(bais); - - while ((length = gzis.read(buffer)) >= 0) { - baos.write(buffer, 0, length); - } // end while: reading input - - // No error? Get new bytes. - bytes = baos.toByteArray(); - - } // end try - catch (java.io.IOException e) { - e.printStackTrace(); - // Just return originally-decoded bytes - } // end catch - finally { - try { - baos.close(); - } catch (Exception e) { - } - try { - gzis.close(); - } catch (Exception e) { - } - try { - bais.close(); - } catch (Exception e) { - } - } // end finally - - } // end if: gzipped - } // end if: bytes.length >= 2 - - return bytes; - } // end decode - - -} // end class Base64 diff --git a/api/src/main/java/com/messagebird/RequestSigner.java b/api/src/main/java/com/messagebird/RequestSigner.java index 32c257a2..d79e464c 100644 --- a/api/src/main/java/com/messagebird/RequestSigner.java +++ b/api/src/main/java/com/messagebird/RequestSigner.java @@ -4,13 +4,13 @@ import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; -import java.io.IOException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; +import java.util.Base64; /** * RequestSigner is used to verify HTTP requests and is an implementation of: @@ -27,7 +27,7 @@ public class RequestSigner { private static final String ALGORITHM_HMAC_SHA256 = "HmacSHA256"; private static final Charset CHARSET_UTF8 = StandardCharsets.UTF_8; - private SecretKeySpec secret; + private final SecretKeySpec secret; /** * Constructs a new RequestSigner instance. @@ -55,8 +55,8 @@ public RequestSigner(byte[] key) { @Deprecated public boolean isMatch(String expectedSignature, Request request) { try { - return isMatch(Base64.decode(expectedSignature), request); - } catch (IOException e) { + return isMatch(Base64.getDecoder().decode(expectedSignature), request); + } catch (IllegalArgumentException e) { throw new RequestSigningException(e); } } From d442f9d5330443b2bc2946f590c0f390037a2e52 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 17 Aug 2023 17:11:33 +0200 Subject: [PATCH 464/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 1d6f8b2d..5b748aa1 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.0 + 6.1.1-SNAPSHOT jar ${project.groupId}:${project.artifactId} diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 719c0cfd..72665c7e 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -71,7 +71,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "6.1.0"; + private final String clientVersion = "6.1.1"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index e05d8c0e..240cdfac 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 6.1.0 + 6.1.1 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 6.1.0 + 6.1.1 compile From 0236ce4d071d553c58d3d866e6a7d3eafd5ed613 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 17 Aug 2023 17:13:28 +0200 Subject: [PATCH 465/516] [maven-release-plugin] prepare release v6.1.1 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 5b748aa1..50479b1c 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.1-SNAPSHOT + 6.1.1 jar ${project.groupId}:${project.artifactId} @@ -39,7 +39,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v6.1.1 From 35b91d9f08c7a9fa6e1fc3dbdbef9851ad543c78 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 17 Aug 2023 17:13:33 +0200 Subject: [PATCH 466/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 50479b1c..ffc04d29 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.1 + 6.1.2-SNAPSHOT jar ${project.groupId}:${project.artifactId} @@ -39,7 +39,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v6.1.1 + HEAD From e2bb604476a83a26918e9a460dbed6fb7e64e84e Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 17 Aug 2023 17:54:59 +0200 Subject: [PATCH 467/516] updated --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index ffc04d29..7b141482 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.2-SNAPSHOT + 6.1.1 jar ${project.groupId}:${project.artifactId} From 989b09047c82141d78a93ff486ce5aa8e999f89a Mon Sep 17 00:00:00 2001 From: "Daniel A. Morales" Date: Thu, 14 Dec 2023 22:07:19 +0000 Subject: [PATCH 468/516] Added support for updating whatsapp template --- .../com/messagebird/MessageBirdClient.java | 25 ++++++++++++ .../messagebird/MessageBirdClientTest.java | 38 +++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 322b1247..7011ab10 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -1876,6 +1876,31 @@ public TemplateResponse createWhatsAppTemplate(final Template template) return messageBirdService.sendPayLoad(url, template, TemplateResponse.class); } + /** + * Update a WhatsApp message template through MessageBird. + * + * @param template {@link Template} object to be created + * @param templateName A name as returned by getWhatsAppTemplateBy in the name variable + * @param language A language code as returned by getWhatsAppTemplateBy in the language variable + * @return {@link TemplateResponse} response object + * @throws UnauthorizedException if client is unauthorized + * @throws GeneralException general exception + * @throws IllegalArgumentException invalid template format + */ + public TemplateResponse updateWhatsAppTemplate(final Template template, final String templateName, final String language) + throws UnauthorizedException, GeneralException, IllegalArgumentException { + template.validate(); + + String url = String.format( + "%s%s%s/%s/%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH, + templateName, + language); + + return messageBirdService.sendPayLoad("PUT",url, template, TemplateResponse.class); + } /** * Gets a WhatsAppTemplate listing with specified pagination options. * diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 50459497..9c462e9e 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -1077,6 +1077,44 @@ public void testCreateWhatsAppTemplate() throws UnauthorizedException, GeneralEx assertEquals(response.getComponents().get(i).getText(), templateResponse.getComponents().get(i).getText()); } } + @Test + public void testUpdateWhatsAppTemplate() throws UnauthorizedException, GeneralException { + final TemplateResponse templateResponse = TestUtil.createWhatsAppTemplateResponse("sample_template_name", "ko"); + final Template template = TestUtil.createWhatsAppTemplate("sample_template_name", "ko"); + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + + String url = String.format( + "%s%s%s/%s/%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH, + "sample_template_name", + "ko" + ); + + when(messageBirdServiceMock.sendPayLoad("PUT",url, template, TemplateResponse.class)) + .thenReturn(templateResponse); + + final TemplateResponse response = messageBirdClientInjectMock.updateWhatsAppTemplate(template,"sample_template_name","ko"); + verify(messageBirdServiceMock, times(1)).sendPayLoad("PUT",url, template, TemplateResponse.class); + assertNotNull(response); + assertEquals(response.getName(), templateResponse.getName()); + assertEquals(response.getLanguage(), templateResponse.getLanguage()); + assertEquals(response.getCategory(), templateResponse.getCategory()); + assertEquals(response.getStatus(), templateResponse.getStatus()); + assertEquals(response.getWabaID(), templateResponse.getWabaID()); + assertEquals(response.getCreatedAt(), templateResponse.getCreatedAt()); + assertEquals(response.getUpdatedAt(), templateResponse.getUpdatedAt()); + + /* verify components */ + for (int i = 0; i < response.getComponents().size(); i++) { + assertEquals(response.getComponents().get(i).getType(), templateResponse.getComponents().get(i).getType()); + assertEquals(response.getComponents().get(i).getFormat(), templateResponse.getComponents().get(i).getFormat()); + assertEquals(response.getComponents().get(i).getText(), templateResponse.getComponents().get(i).getText()); + } + } @Test public void testListWhatsAppTemplates() throws UnauthorizedException, GeneralException { From edd6fbbcfea18821919d613ca4719e13a68a2619 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 15 Dec 2023 09:49:06 +0100 Subject: [PATCH 469/516] preparing for a new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 7b141482..ffc04d29 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.1 + 6.1.2-SNAPSHOT jar ${project.groupId}:${project.artifactId} diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 72665c7e..8b638bff 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -71,7 +71,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "6.1.1"; + private final String clientVersion = "6.1.2"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 240cdfac..c5a6daf5 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 6.1.1 + 6.1.2 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 6.1.1 + 6.1.2 compile From 9efcce21eff4c5365b5dd48d7f8552acf75f44b3 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 15 Dec 2023 09:51:03 +0100 Subject: [PATCH 470/516] [maven-release-plugin] prepare release v6.1.2 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index ffc04d29..aca0d7ad 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.2-SNAPSHOT + 6.1.2 jar ${project.groupId}:${project.artifactId} @@ -39,7 +39,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v6.1.2 From 28e396cb387040f6a95c70bd741353638bacfdaf Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 15 Dec 2023 09:51:08 +0100 Subject: [PATCH 471/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index aca0d7ad..247fa805 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.2 + 6.1.3-SNAPSHOT jar ${project.groupId}:${project.artifactId} @@ -39,7 +39,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v6.1.2 + HEAD From d73d1c343a0e056784676064d0e754ecad590e75 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Fri, 15 Dec 2023 10:25:49 +0100 Subject: [PATCH 472/516] new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 247fa805..511ade81 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.3-SNAPSHOT + 6.1.2 jar ${project.groupId}:${project.artifactId} From 31f90a4c31ed57f5d056c9b1dbc13ce963719f93 Mon Sep 17 00:00:00 2001 From: Alexander Levintsev <44775486+AlexL-mb@users.noreply.github.com> Date: Mon, 8 Jan 2024 15:48:38 +0100 Subject: [PATCH 473/516] Added support for Carousel and Coupon code WhatsApp template messages. --- .../objects/integrations/HSMComponent.java | 11 ++ .../integrations/HSMComponentButton.java | 4 +- .../integrations/HSMComponentButtonType.java | 3 +- .../integrations/HSMComponentCard.java | 21 ++++ .../integrations/HSMComponentType.java | 3 +- .../messagebird/MessageBirdClientTest.java | 38 ++++++ .../test/java/com/messagebird/TestUtil.java | 56 +++++++++ .../java/ExampleCreateCarouselTemplate.java | 113 ++++++++++++++++++ .../java/ExampleCreateCouponTemplate.java | 80 +++++++++++++ 9 files changed, 326 insertions(+), 3 deletions(-) create mode 100644 api/src/main/java/com/messagebird/objects/integrations/HSMComponentCard.java create mode 100644 examples/src/main/java/ExampleCreateCarouselTemplate.java create mode 100644 examples/src/main/java/ExampleCreateCouponTemplate.java diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java b/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java index ccda2075..c13f2761 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java @@ -20,6 +20,9 @@ public class HSMComponent { @JsonProperty("code_expiration_minutes") private Integer codeExpirationMinutes; private List buttons; + + private List cards; + private HSMExample example; public HSMComponentType getType() { @@ -54,6 +57,14 @@ public void setButtons(List buttons) { this.buttons = buttons; } + public List getCards() { + return cards; + } + + public void setCards(List cards) { + this.cards = cards; + } + public HSMExample getExample() { return example; } diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButton.java b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButton.java index 9bb4ffb1..75204df0 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButton.java +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButton.java @@ -117,7 +117,9 @@ public String toString() { public void validateButtonExample() throws IllegalArgumentException { final boolean isExampleEmpty = this.example == null || this.example.isEmpty(); final boolean isNotProperType = !(this.type.equals(HSMComponentButtonType.URL) - || this.type.equals(HSMComponentButtonType.QUICK_REPLY)); + || this.type.equals(HSMComponentButtonType.QUICK_REPLY) + || this.type.equals(HSMComponentButtonType.COPY_CODE) + ); if (isExampleEmpty) { return; diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButtonType.java b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButtonType.java index 5029fc73..06e6eb91 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButtonType.java +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentButtonType.java @@ -14,7 +14,8 @@ public enum HSMComponentButtonType { PHONE_NUMBER("PHONE_NUMBER"), URL("URL"), QUICK_REPLY("QUICK_REPLY"), - OTP("OTP"); + OTP("OTP"), + COPY_CODE("COPY_CODE"); private final String type; diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMComponentCard.java b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentCard.java new file mode 100644 index 00000000..23411941 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentCard.java @@ -0,0 +1,21 @@ +package com.messagebird.objects.integrations; + +import java.util.List; + +/** + * HSMComponentCard + * + * @author AlexL-mb + * @see HSMComponentCard + */ +public class HSMComponentCard { + private List components; + + public List getComponents() { + return components; + } + + public void setComponents(List components) { + this.components = components; + } +} \ No newline at end of file diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMComponentType.java b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentType.java index 0acda414..eff331dc 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/HSMComponentType.java +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentType.java @@ -12,7 +12,8 @@ public enum HSMComponentType { BODY("BODY"), HEADER("HEADER"), FOOTER("FOOTER"), - BUTTONS("BUTTONS"); + BUTTONS("BUTTONS"), + CAROUSEL("CAROUSEL"); private final String type; diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index 9c462e9e..f1902b5f 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -1077,6 +1077,44 @@ public void testCreateWhatsAppTemplate() throws UnauthorizedException, GeneralEx assertEquals(response.getComponents().get(i).getText(), templateResponse.getComponents().get(i).getText()); } } + @Test + public void testCreateWhatsAppCarouselTemplate() throws UnauthorizedException, GeneralException { + final TemplateResponse templateResponse = TestUtil.createWhatsAppCarouselTemplateResponse("sample_template_name", "ko"); + final Template template = TestUtil.createWhatsAppCarouselTemplate("sample_template_name", "ko"); + + MessageBirdService messageBirdServiceMock = mock(MessageBirdService.class); + MessageBirdClient messageBirdClientInjectMock = new MessageBirdClient(messageBirdServiceMock); + + String url = String.format( + "%s%s%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH + ); + + when(messageBirdServiceMock.sendPayLoad(url, template, TemplateResponse.class)) + .thenReturn(templateResponse); + + final TemplateResponse response = messageBirdClientInjectMock.createWhatsAppTemplate(template); + + verify(messageBirdServiceMock, times(1)).sendPayLoad(url, template, TemplateResponse.class); + assertNotNull(response); + assertEquals(response.getName(), templateResponse.getName()); + assertEquals(response.getLanguage(), templateResponse.getLanguage()); + assertEquals(response.getCategory(), templateResponse.getCategory()); + assertEquals(response.getStatus(), templateResponse.getStatus()); + assertEquals(response.getWabaID(), templateResponse.getWabaID()); + assertEquals(response.getCreatedAt(), templateResponse.getCreatedAt()); + assertEquals(response.getUpdatedAt(), templateResponse.getUpdatedAt()); + + /* verify components */ + for (int i = 0; i < response.getComponents().size(); i++) { + assertEquals(response.getComponents().get(i).getType(), templateResponse.getComponents().get(i).getType()); + assertEquals(response.getComponents().get(i).getFormat(), templateResponse.getComponents().get(i).getFormat()); + assertEquals(response.getComponents().get(i).getText(), templateResponse.getComponents().get(i).getText()); + } + } + @Test public void testUpdateWhatsAppTemplate() throws UnauthorizedException, GeneralException { final TemplateResponse templateResponse = TestUtil.createWhatsAppTemplateResponse("sample_template_name", "ko"); diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index 29744ba5..09883ed3 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -6,6 +6,7 @@ import com.messagebird.objects.integrations.HSMComponent; import com.messagebird.objects.integrations.HSMComponentButton; import com.messagebird.objects.integrations.HSMComponentButtonType; +import com.messagebird.objects.integrations.HSMComponentCard; import com.messagebird.objects.integrations.HSMComponentFormat; import com.messagebird.objects.integrations.HSMComponentType; import com.messagebird.objects.integrations.HSMExample; @@ -301,6 +302,24 @@ private static HSMComponent createHSMComponentButton() { return buttonComponent; } + private static HSMComponent createHSMComponentCarousel() { + final HSMComponent carouselComponent = new HSMComponent(); + carouselComponent.setType(HSMComponentType.CAROUSEL); + + final List cards = new ArrayList<>(); + final HSMComponentCard card = new HSMComponentCard(); + final List cardComponents = new ArrayList<>(); + cardComponents.add(createHSMComponentHeader()); + cardComponents.add(createHSMComponentBody()); + cardComponents.add(createHSMComponentButton()); + card.setComponents(cardComponents); + cards.add(card); + + carouselComponent.setCards(cards); + + return carouselComponent; + } + public static TemplateResponse createWhatsAppTemplateResponse(final String templateName, final String language) { final TemplateResponse templateResponse = new TemplateResponse(); templateResponse.setName(templateName); @@ -341,6 +360,43 @@ public static Template createWhatsAppTemplate(final String templateName, final S return template; } + public static TemplateResponse createWhatsAppCarouselTemplateResponse(final String templateName, final String language) { + final TemplateResponse templateResponse = new TemplateResponse(); + templateResponse.setName(templateName); + templateResponse.setLanguage(language); + templateResponse.setCategory(HSMCategory.MARKETING); + templateResponse.setStatus(HSMStatus.NEW); + templateResponse.setCreatedAt(new Date()); + templateResponse.setUpdatedAt(new Date()); + + final List components = new ArrayList<>(); + components.add(createHSMComponentBody()); + components.add(createHSMComponentCarousel()); + templateResponse.setComponents(components); + + templateResponse.setWabaID("testWABAID"); + templateResponse.setNamespace("testNamespace"); + + return templateResponse; + } + + public static Template createWhatsAppCarouselTemplate(final String templateName, final String language) { + final Template template = new Template(); + template.setName(templateName); + template.setLanguage(language); + template.setCategory(HSMCategory.MARKETING); + + final List components = new ArrayList<>(); + components.add(createHSMComponentBody()); + components.add(createHSMComponentCarousel()); + template.setComponents(components); + + template.setWABAID("testWABAID"); + + return template; + } + + public static TemplateList createWhatsAppTemplateList(final String templateName) { final TemplateResponse template1 = TestUtil.createWhatsAppTemplateResponse(templateName, "en_US"); final TemplateResponse template2 = TestUtil.createWhatsAppTemplateResponse(templateName, "ko"); diff --git a/examples/src/main/java/ExampleCreateCarouselTemplate.java b/examples/src/main/java/ExampleCreateCarouselTemplate.java new file mode 100644 index 00000000..54bea0dd --- /dev/null +++ b/examples/src/main/java/ExampleCreateCarouselTemplate.java @@ -0,0 +1,113 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.integrations.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Create template. + * + * @see Doc - Create template + * @author AlexL-mb + */ +public class ExampleCreateCarouselTemplate { + + public static void main(String[] args) { + if (args.length < 3) { + System.out.println("Please specify your access key and a template name and WABA ID example : java -jar test_accesskey \"My template name\" \"WABA ID\""); + return; + } + + // First create your service object + MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + /* body */ + HSMComponent bodyComponent = new HSMComponent(); + final HSMExample bodyExample = new HSMExample(); + final List> bodyText = new ArrayList<>(); + bodyText.add(Arrays.asList("John")); + bodyExample.setBody_text(bodyText); + bodyComponent.setType(HSMComponentType.BODY); + bodyComponent.setText("Hey {{1}}! This is a sample template from Java."); + bodyComponent.setExample(bodyExample); + + /* carousel */ + final HSMComponent carouselComponent = new HSMComponent(); + carouselComponent.setType(HSMComponentType.CAROUSEL); + + /* cards */ + final List cards = new ArrayList<>(); + /* card 0 */ + final HSMComponentCard card = new HSMComponentCard(); + final List cardComponents = new ArrayList<>(); + + /* card header */ + final HSMComponent headerComponent = new HSMComponent(); + final HSMExample headerExample = new HSMExample(); + headerExample.setHeader_url(Arrays.asList("https://images.freeimages.com/images/small-previews/c5a/colourful-paper-rip-1-1195879.jpg")); + + headerComponent.setType(HSMComponentType.HEADER); + headerComponent.setFormat(HSMComponentFormat.IMAGE); + headerComponent.setExample(headerExample); + cardComponents.add(headerComponent); + + /* card body */ + final HSMComponent cardBodyComponent = new HSMComponent(); + final HSMExample cardBodyExample = new HSMExample(); + final List> cardBodyText = new ArrayList<>(); + cardBodyText.add(Arrays.asList("John")); + cardBodyExample.setBody_text(cardBodyText); + + cardBodyComponent.setType(HSMComponentType.BODY); + cardBodyComponent.setText("Hey {{1}}! This is a sample template from Java."); + cardBodyComponent.setExample(cardBodyExample); + cardComponents.add(cardBodyComponent); + + /* card buttons */ + final HSMComponent buttonComponent = new HSMComponent(); + final List buttons = new ArrayList<>(); + final HSMComponentButton button = new HSMComponentButton(); + button.setType(HSMComponentButtonType.URL); + button.setText("Touch it"); + button.setUrl("https://www.messagebird.com"); + button.setExample(Arrays.asList("https://developers.messagebird.com")); + buttons.add(button); + buttonComponent.setType(HSMComponentType.BUTTONS); + buttonComponent.setButtons(buttons); + cardComponents.add(buttonComponent); + + card.setComponents(cardComponents); + + cards.add(card); + + carouselComponent.setCards(cards); + + /* set components */ + Template template = new Template(); + List components = new ArrayList<>(); + components.add(bodyComponent); + components.add(carouselComponent); + + template.setName(args[1]); + template.setLanguage("en_US"); + template.setWABAID(args[2]); + template.setComponents(components); + template.setCategory(HSMCategory.MARKETING); + + try { + TemplateResponse response = messageBirdClient.createWhatsAppTemplate(template); + System.out.println(response.toString()); + } catch (GeneralException | UnauthorizedException | IllegalArgumentException exception) { + exception.printStackTrace(); + } + + } +} diff --git a/examples/src/main/java/ExampleCreateCouponTemplate.java b/examples/src/main/java/ExampleCreateCouponTemplate.java new file mode 100644 index 00000000..649f7a4c --- /dev/null +++ b/examples/src/main/java/ExampleCreateCouponTemplate.java @@ -0,0 +1,80 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.integrations.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Create template. + * + * @see Doc - Create template + * @author AlexL-mb + */ +public class ExampleCreateCouponTemplate { + + public static void main(String[] args) { + if (args.length < 3) { + System.out.println("Please specify your access key and a template name and WABA ID example : java -jar test_accesskey \"My template name\" \"WABA ID\""); + return; + } + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + /* header */ + final HSMComponent headerComponent = new HSMComponent(); + headerComponent.setType(HSMComponentType.HEADER); + headerComponent.setFormat(HSMComponentFormat.TEXT); + headerComponent.setText("Our Fall Sale is on!"); + + /* body */ + final HSMComponent bodyComponent = new HSMComponent(); + final HSMExample bodyExample = new HSMExample(); + final List> bodyText = new ArrayList<>(); + bodyText.add(Arrays.asList("25OFF", "25%")); + bodyExample.setBody_text(bodyText); + + bodyComponent.setType(HSMComponentType.BODY); + bodyComponent.setText("Shop now through November and use code {{1}} to get {{2}} off of all merchandise!"); + bodyComponent.setExample(bodyExample); + + + /* button */ + final HSMComponent buttonComponent = new HSMComponent(); + final List buttons = new ArrayList<>(); + final HSMComponentButton button = new HSMComponentButton(); + button.setType(HSMComponentButtonType.COPY_CODE); + button.setExample(Arrays.asList("CODE25")); + buttons.add(button); + buttonComponent.setType(HSMComponentType.BUTTONS); + buttonComponent.setButtons(buttons); + + /* set components */ + final Template template = new Template(); + final List components = new ArrayList<>(); + components.add(headerComponent); + components.add(bodyComponent); + components.add(buttonComponent); + + template.setName(args[1]); + template.setLanguage("en_US"); + template.setWABAID(args[2]); + template.setComponents(components); + template.setCategory(HSMCategory.MARKETING); + + try { + TemplateResponse response = messageBirdClient.createWhatsAppTemplate(template); + System.out.println(response.toString()); + } catch (GeneralException | UnauthorizedException | IllegalArgumentException exception) { + exception.printStackTrace(); + } + } +} From 948b772c9c321466775ae27e79761554ceb15100 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Tue, 9 Jan 2024 17:34:05 +0100 Subject: [PATCH 474/516] preparing for a new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 511ade81..247fa805 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.2 + 6.1.3-SNAPSHOT jar ${project.groupId}:${project.artifactId} diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 8b638bff..b4bd19b8 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -71,7 +71,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "6.1.2"; + private final String clientVersion = "6.1.3"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index c5a6daf5..b9a88404 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 6.1.2 + 6.1.3 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 6.1.2 + 6.1.3 compile From ac768b90b75c53f8aeef264b6cfed7d1cf8fa241 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Tue, 9 Jan 2024 17:36:32 +0100 Subject: [PATCH 475/516] [maven-release-plugin] prepare release v6.1.3 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 247fa805..70599c83 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.3-SNAPSHOT + 6.1.3 jar ${project.groupId}:${project.artifactId} @@ -39,7 +39,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v6.1.3 From 83622f5004dfa136faa61aaa6891de931359e7dd Mon Sep 17 00:00:00 2001 From: denizkilic Date: Tue, 9 Jan 2024 17:36:37 +0100 Subject: [PATCH 476/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 70599c83..16954df4 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.3 + 6.1.4-SNAPSHOT jar ${project.groupId}:${project.artifactId} @@ -39,7 +39,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v6.1.3 + HEAD From b7221c953babfa4f795d82cb6537fa92302d5cac Mon Sep 17 00:00:00 2001 From: denizkilic Date: Tue, 9 Jan 2024 18:20:22 +0100 Subject: [PATCH 477/516] preparing for a new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 16954df4..3ba0045a 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.4-SNAPSHOT + 6.1.3 jar ${project.groupId}:${project.artifactId} From 46489bb26f4a44ab5c5a2c04c88601f6ea49b334 Mon Sep 17 00:00:00 2001 From: Alexander Levintsev <44775486+AlexL-mb@users.noreply.github.com> Date: Sat, 27 Jan 2024 15:42:27 +0100 Subject: [PATCH 478/516] Added support for CTAURLLinkTrackingOptedOut and QualityScore in WhatsApp templates. --- .../objects/integrations/HSMQualityScore.java | 42 +++++++++++++++++++ .../objects/integrations/Template.java | 14 ++++++- .../integrations/TemplateResponse.java | 24 +++++++++++ .../test/java/com/messagebird/TestUtil.java | 1 + .../java/ExampleCreateCouponTemplate.java | 1 + 5 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 api/src/main/java/com/messagebird/objects/integrations/HSMQualityScore.java diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMQualityScore.java b/api/src/main/java/com/messagebird/objects/integrations/HSMQualityScore.java new file mode 100644 index 00000000..112492fd --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMQualityScore.java @@ -0,0 +1,42 @@ +package com.messagebird.objects.integrations; + +import java.util.List; + +public class HSMQualityScore { + private String score; + private long date; + private List reasons; + + public String getScore() { + return score; + } + + public void setScore(String score) { + this.score = score; + } + + public long getDate() { + return date; + } + + public void setDate(long date) { + this.date = date; + } + + public List getReasons() { + return reasons; + } + + public void setReasons(List reasons) { + this.reasons = reasons; + } + + @Override + public String toString() { + return "HSMQualityScore{" + + "score='" + score + '\'' + + ", date=" + date + + ", reasons=" + reasons + + '}'; + } +} diff --git a/api/src/main/java/com/messagebird/objects/integrations/Template.java b/api/src/main/java/com/messagebird/objects/integrations/Template.java index a61741f5..f6a83e93 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/Template.java +++ b/api/src/main/java/com/messagebird/objects/integrations/Template.java @@ -15,17 +15,20 @@ public class Template { private String wabaID; private List components; private HSMCategory category; + private boolean ctaURLLinkTrackingOptedOut; public Template() { } + public Template(String name, String language, String wabaID, - List components, HSMCategory category) { + List components, HSMCategory category, boolean ctaURLLinkTrackingOptedOut) { this.name = name; this.language = language; this.wabaID = wabaID; this.components = components; this.category = category; + this.ctaURLLinkTrackingOptedOut = ctaURLLinkTrackingOptedOut; } public String getName() { @@ -68,6 +71,14 @@ public void setCategory(HSMCategory category) { this.category = category; } + public void setCtaURLLinkTrackingOptedOut (boolean ctaURLLinkTrackingOptedOut) { + this.ctaURLLinkTrackingOptedOut = ctaURLLinkTrackingOptedOut; + } + + public boolean getCtaURLLinkTrackingOptedOut () { + return ctaURLLinkTrackingOptedOut; + } + @Override public String toString() { return "WhatsAppTemplate{" + @@ -76,6 +87,7 @@ public String toString() { ", wabaID='" + wabaID + '\'' + ", components=" + components + ", category='" + category + '\'' + + ", ctaURLLinkTrackingOptedOut='" + ctaURLLinkTrackingOptedOut + '\'' + '}'; } diff --git a/api/src/main/java/com/messagebird/objects/integrations/TemplateResponse.java b/api/src/main/java/com/messagebird/objects/integrations/TemplateResponse.java index 426ae64a..3c75fabe 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/TemplateResponse.java +++ b/api/src/main/java/com/messagebird/objects/integrations/TemplateResponse.java @@ -20,6 +20,11 @@ public class TemplateResponse implements Serializable { private String rejectedReason; private String wabaID; private String namespace; + + private boolean ctaURLLinkTrackingOptedOut; + + private HSMQualityScore qualityScore; + private Date createdAt; private Date updatedAt; @@ -107,6 +112,22 @@ public void setUpdatedAt(Date updatedAt) { this.updatedAt = updatedAt; } + public boolean isCtaURLLinkTrackingOptedOut() { + return ctaURLLinkTrackingOptedOut; + } + + public void setCtaURLLinkTrackingOptedOut(boolean ctaURLLinkTrackingOptedOut) { + this.ctaURLLinkTrackingOptedOut = ctaURLLinkTrackingOptedOut; + } + + public HSMQualityScore getQualityScore() { + return qualityScore; + } + + public void setQualityScore(HSMQualityScore qualityScore) { + this.qualityScore = qualityScore; + } + @Override public String toString() { return "WhatsAppTemplateResponse{" + @@ -118,8 +139,11 @@ public String toString() { ", rejectedReason='" + rejectedReason + '\'' + ", wabaID='" + wabaID + '\'' + ", namespace='" + namespace + '\'' + + ", ctaURLLinkTrackingOptedOut='" + ctaURLLinkTrackingOptedOut + '\'' + + ", qualityScore='" + qualityScore + '\'' + ", createdAt=" + createdAt + ", updatedAt=" + updatedAt + '}'; } + } diff --git a/api/src/test/java/com/messagebird/TestUtil.java b/api/src/test/java/com/messagebird/TestUtil.java index 09883ed3..3e9c5a33 100644 --- a/api/src/test/java/com/messagebird/TestUtil.java +++ b/api/src/test/java/com/messagebird/TestUtil.java @@ -326,6 +326,7 @@ public static TemplateResponse createWhatsAppTemplateResponse(final String templ templateResponse.setLanguage(language); templateResponse.setCategory(HSMCategory.AUTHENTICATION); templateResponse.setStatus(HSMStatus.NEW); + templateResponse.setCtaURLLinkTrackingOptedOut(true); templateResponse.setCreatedAt(new Date()); templateResponse.setUpdatedAt(new Date()); diff --git a/examples/src/main/java/ExampleCreateCouponTemplate.java b/examples/src/main/java/ExampleCreateCouponTemplate.java index 649f7a4c..f5480434 100644 --- a/examples/src/main/java/ExampleCreateCouponTemplate.java +++ b/examples/src/main/java/ExampleCreateCouponTemplate.java @@ -69,6 +69,7 @@ public static void main(String[] args) { template.setWABAID(args[2]); template.setComponents(components); template.setCategory(HSMCategory.MARKETING); + template.setCtaURLLinkTrackingOptedOut(true); try { TemplateResponse response = messageBirdClient.createWhatsAppTemplate(template); From ba96d005f62992d904e393a0e6260b9da1213406 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Tue, 30 Jan 2024 15:39:04 +0100 Subject: [PATCH 479/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 3ba0045a..16954df4 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.3 + 6.1.4-SNAPSHOT jar ${project.groupId}:${project.artifactId} diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index b4bd19b8..35b2a705 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -71,7 +71,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "6.1.3"; + private final String clientVersion = "6.1.4"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index b9a88404..7c103dc4 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 6.1.3 + 6.1.4 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 6.1.3 + 6.1.4 compile From 9262fc34ff84b58518383417a6e03670df88a734 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Tue, 30 Jan 2024 15:40:33 +0100 Subject: [PATCH 480/516] [maven-release-plugin] prepare release v6.1.4 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 16954df4..6298ecfe 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.4-SNAPSHOT + 6.1.4 jar ${project.groupId}:${project.artifactId} @@ -39,7 +39,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v6.1.4 From c9129c62fcc1c2335b07f08ca7109dc9cbe5f4f1 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Tue, 30 Jan 2024 15:40:38 +0100 Subject: [PATCH 481/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 6298ecfe..eec90102 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.4 + 6.1.5-SNAPSHOT jar ${project.groupId}:${project.artifactId} @@ -39,7 +39,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v6.1.4 + HEAD From 37e2545ce96afdb9fe73d5979060a74cf04c66dc Mon Sep 17 00:00:00 2001 From: denizkilic Date: Tue, 30 Jan 2024 15:59:12 +0100 Subject: [PATCH 482/516] updated --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index eec90102..123cbaad 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.5-SNAPSHOT + 6.1.4 jar ${project.groupId}:${project.artifactId} From 350009d6890fbc6218deec2a394851aa9c47c51e Mon Sep 17 00:00:00 2001 From: Alexander Levintsev <44775486+AlexL-mb@users.noreply.github.com> Date: Thu, 7 Mar 2024 12:45:13 +0100 Subject: [PATCH 483/516] Added support for sending Carousel messages --- .../conversations/MessageComponent.java | 39 ++++++++++++++++++- .../conversations/MessageComponentType.java | 4 +- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/conversations/MessageComponent.java b/api/src/main/java/com/messagebird/objects/conversations/MessageComponent.java index 9dd25b3a..6bb9ca79 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/MessageComponent.java +++ b/api/src/main/java/com/messagebird/objects/conversations/MessageComponent.java @@ -8,6 +8,10 @@ public class MessageComponent { private String sub_type; private int index; private List parameters; + private int card_index; + private List cards; + private MessageComponent card; + private List components; public void setType(MessageComponentType type) { this.type = type; @@ -41,13 +45,46 @@ public void setParameters(List parameters) { this.parameters = parameters; } + public void setCards(List cards) { + this.cards = cards; + } + + public List getCards() { + return cards; + } + + public int getCard_index() { + return card_index; + } + + public void setCard_index(int card_index) { + this.card_index = card_index; + } + + public MessageComponent getCard() { + return card; + } + + public void setCard(MessageComponent card) { + this.card = card; + } + + public List getComponents() { + return components; + } + + public void setComponents(List components) { + this.components = components; + } + @Override public String toString() { return "MessageComponent{" + "type='" + type + '\'' + ", sub_type='" + sub_type + '\'' + ", index=" + index + - ", parameters=" + parameters + + ", parameters=" + parameters + '\'' + + ", cards=" + cards + '}'; } } diff --git a/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java b/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java index 327525fd..c2be69bf 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java +++ b/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java @@ -8,7 +8,9 @@ public enum MessageComponentType { HEADER("header"), BODY("body"), FOOTER("footer"), - BUTTON("button"); + BUTTON("button"), + CARD("card"), + CAROUSEL("carousel"); private final String type; From 7eb58cae36872263c5b7a14ecc6e62a09287d4f9 Mon Sep 17 00:00:00 2001 From: Alexander Levintsev <44775486+AlexL-mb@users.noreply.github.com> Date: Thu, 7 Mar 2024 12:46:00 +0100 Subject: [PATCH 484/516] added sending carousel messages example --- ...ampleConversationSendCarouselTemplate.java | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 examples/src/main/java/ExampleConversationSendCarouselTemplate.java diff --git a/examples/src/main/java/ExampleConversationSendCarouselTemplate.java b/examples/src/main/java/ExampleConversationSendCarouselTemplate.java new file mode 100644 index 00000000..f386917d --- /dev/null +++ b/examples/src/main/java/ExampleConversationSendCarouselTemplate.java @@ -0,0 +1,116 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.conversations.*; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class ExampleConversationSendCarouselTemplate { + + public static void main(String[] args) { + + if (args.length < 3) { + System.out.println("Please at least specify your access key, the channel id and destination address.\n" + + "Usage : java -jar test_accesskey(Required) channel_id(Required) to(Required)"); + return; + } + + //First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(args[0]); + //Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + ConversationContent conversationContent = new ConversationContent(); + ConversationContentHsm conversationContentHsm = new ConversationContentHsm(); + conversationContentHsm.setNamespace("c663a566_a4de_492f_86b2_028cbf612345"); + conversationContentHsm.setTemplateName("carousel_template_test_hello"); + ConversationHsmLanguage language = new ConversationHsmLanguage(); + language.setCode("en_US"); + conversationContentHsm.setLanguage(language); + + + +// card0 components + List card0Components = new ArrayList<>(); +// card0 header + MessageComponent card0HeaderComponent = new MessageComponent(); + card0HeaderComponent.setType(MessageComponentType.HEADER); + MessageParam imageParam = new MessageParam(); + imageParam.setType(TemplateMediaType.IMAGE); + Media media = new Media(); + media.setUrl("https://upload.wikimedia.org/wikipedia/commons/f/f9/Phoenicopterus_ruber_in_S%C3%A3o_Paulo_Zoo.jpg"); + imageParam.setImage(media); + card0HeaderComponent.setParameters(Collections.singletonList(imageParam)); + card0Components.add(card0HeaderComponent); +// card0 body + MessageComponent card0BodyComponent = new MessageComponent(); + card0BodyComponent.setType(MessageComponentType.BODY); + MessageParam textParam = new MessageParam(); + textParam.setType(TemplateMediaType.TEXT); + textParam.setText("dummy text"); + card0BodyComponent.setParameters(Collections.singletonList(textParam)); + card0Components.add(card0BodyComponent); +// card0 button + MessageComponent card0ButtonComponent = new MessageComponent(); + card0ButtonComponent.setType(MessageComponentType.BUTTON); + card0ButtonComponent.setSub_type("quick_reply"); + card0ButtonComponent.setIndex(0); + MessageParam buttonParam = new MessageParam(); + buttonParam.setType(TemplateMediaType.PAYLOAD); + buttonParam.setPayload("dummy button"); + card0ButtonComponent.setParameters(Collections.singletonList(buttonParam)); + card0Components.add(card0ButtonComponent); + +// card0 + MessageComponent card0 = new MessageComponent(); + card0.setType(MessageComponentType.CARD); + card0.setCard_index(0); + card0.setComponents(card0Components); + + +// cards list + List cards = new ArrayList<>(); + cards.add(card0); + +// carousel component + MessageComponent carousel = new MessageComponent(); + carousel.setType(MessageComponentType.CAROUSEL); + carousel.setCards(cards); +// body component + MessageComponent body = new MessageComponent(); + body.setType(MessageComponentType.BODY); + MessageParam bodyParam = new MessageParam(); + bodyParam.setType(TemplateMediaType.TEXT); + bodyParam.setText("Jackson"); + body.setParameters(Collections.singletonList(bodyParam)); + +// set components to message + List messageComponents = new ArrayList<>(); + messageComponents.add(body); + messageComponents.add(carousel); + conversationContentHsm.setComponents(messageComponents); + + conversationContent.setHsm(conversationContentHsm); + ConversationSendRequest request = new ConversationSendRequest( + args[2], + ConversationContentType.HSM, + conversationContent, + args[1], + "", + null, + null, + null); + + try { + ConversationSendResponse sendResponse = messageBirdClient.sendMessage(request); + System.out.println(sendResponse.toString()); + + } catch (GeneralException | UnauthorizedException exception) { + exception.printStackTrace(); + } + } +} From 90e1840c8a3413c1a85ad3a96ec238bb5f3bbbae Mon Sep 17 00:00:00 2001 From: Alexander Levintsev <44775486+AlexL-mb@users.noreply.github.com> Date: Thu, 7 Mar 2024 13:08:01 +0100 Subject: [PATCH 485/516] removed unused private field card from MessageComponent --- .../objects/conversations/MessageComponent.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/conversations/MessageComponent.java b/api/src/main/java/com/messagebird/objects/conversations/MessageComponent.java index 6bb9ca79..d3a7c20b 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/MessageComponent.java +++ b/api/src/main/java/com/messagebird/objects/conversations/MessageComponent.java @@ -10,7 +10,6 @@ public class MessageComponent { private List parameters; private int card_index; private List cards; - private MessageComponent card; private List components; public void setType(MessageComponentType type) { @@ -61,14 +60,6 @@ public void setCard_index(int card_index) { this.card_index = card_index; } - public MessageComponent getCard() { - return card; - } - - public void setCard(MessageComponent card) { - this.card = card; - } - public List getComponents() { return components; } @@ -82,8 +73,9 @@ public String toString() { return "MessageComponent{" + "type='" + type + '\'' + ", sub_type='" + sub_type + '\'' + - ", index=" + index + + ", index=" + index + '\'' + ", parameters=" + parameters + '\'' + + ", components=" + components + '\'' + ", cards=" + cards + '}'; } From e7f9a5b0570081979f03995508b868d883ee06a2 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 7 Mar 2024 13:53:50 +0100 Subject: [PATCH 486/516] new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 123cbaad..eec90102 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.4 + 6.1.5-SNAPSHOT jar ${project.groupId}:${project.artifactId} diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 35b2a705..ca9651fb 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -71,7 +71,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "6.1.4"; + private final String clientVersion = "6.1.5"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 7c103dc4..1f130fb0 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 6.1.4 + 6.1.5 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 6.1.4 + 6.1.5 compile From 2295a5ad2aec69f3e5843d5a9545121561275ac1 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 7 Mar 2024 13:55:18 +0100 Subject: [PATCH 487/516] [maven-release-plugin] prepare release v6.1.5 --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index eec90102..b56694bd 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.5-SNAPSHOT + 6.1.5 jar ${project.groupId}:${project.artifactId} @@ -39,7 +39,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - HEAD + v6.1.5 From bc9b0ffd8bab145bb383b773d0150f5dba5b2f53 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 7 Mar 2024 13:55:23 +0100 Subject: [PATCH 488/516] [maven-release-plugin] prepare for next development iteration --- api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index b56694bd..8934ab77 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.5 + 6.1.6-SNAPSHOT jar ${project.groupId}:${project.artifactId} @@ -39,7 +39,7 @@ scm:git:git@github.com:messagebird/java-rest-api.git scm:git:git@github.com:messagebird/java-rest-api.git git@github.com:messagebird/java-rest-api.git - v6.1.5 + HEAD From c1b872a10bd470b0b2aa2b0ef548722f1bcb0bf9 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Thu, 7 Mar 2024 14:15:22 +0100 Subject: [PATCH 489/516] new release --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 8934ab77..6f1ceec6 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.6-SNAPSHOT + 6.1.5 jar ${project.groupId}:${project.artifactId} From 905a11215646a0505c2de1bfba7bb5fc50b726bc Mon Sep 17 00:00:00 2001 From: Elkhan Eminov Date: Sun, 14 Apr 2024 21:12:49 +0200 Subject: [PATCH 490/516] fix java version parsing --- api/pom.xml | 5 ++ .../messagebird/MessageBirdServiceImpl.java | 54 +++++++------------ 2 files changed, 23 insertions(+), 36 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 6f1ceec6..54cddd64 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -92,6 +92,11 @@ java-jwt 3.17.0 + + org.apache.maven + maven-artifact + 3.9.6 + junit junit diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index ca9651fb..ac84617b 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -8,6 +8,8 @@ import com.messagebird.exceptions.UnauthorizedException; import com.messagebird.objects.ErrorReport; import com.messagebird.objects.PagedPaging; +import org.apache.maven.artifact.versioning.ComparableVersion; + import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -60,8 +62,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private static final String[] PROTOCOL_LISTS = new String[]{"http://", "https://"}; private static final List PROTOCOLS = Arrays.asList(PROTOCOL_LISTS); - // Used when the actual version can not be parsed. - private static final double DEFAULT_JAVA_VERSION = 0.0; + private static final ComparableVersion JAVA_VERSION = getJavaVersion(); // Indicates whether we've overridden HttpURLConnection's behaviour to // allow PATCH requests yet. Also see docs on allowPatchRequestsIfNeeded(). @@ -88,15 +89,17 @@ public MessageBirdServiceImpl(final String accessKey, final String serviceUrl) { } - private String determineUserAgentString() { - double javaVersion = DEFAULT_JAVA_VERSION; + private static ComparableVersion getJavaVersion() { try { - javaVersion = getVersion(); - } catch (GeneralException e) { - // Do nothing: leave the version at its default. + String version = System.getProperty("java.version"); + return new ComparableVersion(version); + } catch (IllegalArgumentException e) { + return new ComparableVersion("0.0"); } + } - return String.format("MessageBird Java/%s ApiClient/%s", javaVersion, clientVersion); + private String determineUserAgentString() { + return String.format("MessageBird Java/%s ApiClient/%s", JAVA_VERSION, clientVersion); } /** @@ -360,7 +363,7 @@ private void handleHttpFailStatuses(final int status, String body) throws Unauth

APIResponse doRequest(final String method, final String url, final Map headers, final P payload) throws GeneralException { HttpURLConnection connection = null; InputStream inputStream = null; - + if (METHOD_PATCH.equalsIgnoreCase(method)) { // It'd perhaps be cleaner to call this in the constructor, but // we'd then need to throw GeneralExceptions from there. This means @@ -473,13 +476,13 @@ private synchronized static void allowPatchRequestsIfNeeded() throws GeneralExce Field modifiersField = Field.class.getDeclaredField("modifiers"); modifiersField.setAccessible(true); modifiersField.setInt(methodsField, methodsField.getModifiers() & ~Modifier.FINAL); - + Object noInstanceBecauseStaticField = null; - + // Determine what methods should be allowed. String[] existingMethods = (String[]) methodsField.get(noInstanceBecauseStaticField); String[] allowedMethods = getAllowedMethods(existingMethods); - + // Override the actual field to allow PATCH. methodsField.set(noInstanceBecauseStaticField, allowedMethods); @@ -631,34 +634,13 @@ private void setAdditionalHeaders(HttpURLConnection connection, Map 1.6) { + ComparableVersion java6 = new ComparableVersion("1.6"); + if (JAVA_VERSION.compareTo(java6) > 0) { return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); } return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZ"); } - private double getVersion() throws GeneralException { - String version = System.getProperty("java.version"); - - try { - int pos = version.indexOf('.'); - pos = version.indexOf('.', pos + 1); - - return Double.parseDouble(version.substring(0, pos)); - } catch (RuntimeException e) { - // Thrown if the index is out of bounds, or when we can't parse a - // double for some reason. - throw new GeneralException(e); - } - } - /** * Get the MessageBird error report data. * @@ -802,7 +784,7 @@ private String getPathVariables(final Map map) { // the value is returned from the next() call bpath.append(encodeKeyValuePair(param.getKey(), iterator.next())); count++; - } + } } else { // If the value is not a collection, create the querystring value directly. bpath.append(encodeKeyValuePair(param.getKey(), param.getValue())); From 45aaecccdbb40082c07c2bb64287189a7e8752f0 Mon Sep 17 00:00:00 2001 From: denizkilic Date: Mon, 15 Apr 2024 18:22:36 +0200 Subject: [PATCH 491/516] maxAttempts param in VerifyRequest --- .../main/java/com/messagebird/objects/VerifyRequest.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/api/src/main/java/com/messagebird/objects/VerifyRequest.java b/api/src/main/java/com/messagebird/objects/VerifyRequest.java index 70de2591..bee684e9 100644 --- a/api/src/main/java/com/messagebird/objects/VerifyRequest.java +++ b/api/src/main/java/com/messagebird/objects/VerifyRequest.java @@ -15,6 +15,7 @@ public class VerifyRequest implements Serializable { private String template; private Integer timeout; private Integer tokenLength; + private Integer maxAttempts; private Gender voice; private Language language; private String subject; @@ -124,4 +125,12 @@ public void setSubject(String subject) { public String getSubject() { return subject; } + + public Integer getMaxAttempts() { + return maxAttempts; + } + + public void setMaxAttempts(Integer maxAttempts) { + this.maxAttempts = maxAttempts; + } } From 61fc3f2857310f8f82e9f0e2fd2b48d72e316821 Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Mon, 15 Apr 2024 19:36:24 +0200 Subject: [PATCH 492/516] Cut 6.1.6 (#255) *release v6.1.6 --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 54cddd64..2f375fdf 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.5 + 6.1.6 jar ${project.groupId}:${project.artifactId} diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index ac84617b..7e11ee5a 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -72,7 +72,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "6.1.5"; + private final String clientVersion = "6.1.6"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 1f130fb0..68637ec2 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 6.1.5 + 6.1.6 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 6.1.5 + 6.1.6 compile From d9af92705c8421be1bdf8821f468010f2417ab2f Mon Sep 17 00:00:00 2001 From: Daniel AM Date: Tue, 28 May 2024 12:03:09 +0100 Subject: [PATCH 493/516] =?UTF-8?q?Issue-256:=20Updated=20the=20checkHeade?= =?UTF-8?q?r=20to=20allow=20header=5Furl=20in=20both=20video=20and=20image?= =?UTF-8?q?=20a=E2=80=A6=20(#257)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * updated the checkHeader to allow header_url in both video and image as it is supported * added document format --------- Co-authored-by: denizkilic --- .../com/messagebird/objects/integrations/HSMComponent.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java b/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java index c13f2761..4e3fe648 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java @@ -166,10 +166,9 @@ private void checkHeaderText() throws IllegalArgumentException { * @throws IllegalArgumentException Occurs when type is not {@code HEADER} and format is not {@code IMAGE}. */ private void checkHeaderUrl() throws IllegalArgumentException { - if (!(type.equals(HSMComponentType.HEADER) - && format.equals(HSMComponentFormat.IMAGE)) - ) { - throw new IllegalArgumentException("\"header_url\" is available for only HEADER type and IMAGE format."); + if (!(type.equals(HSMComponentType.HEADER) && + (format.equals(HSMComponentFormat.IMAGE) || format.equals(HSMComponentFormat.VIDEO) || format.equals(HSMComponentFormat.DOCUMENT)))) { + throw new IllegalArgumentException("\"header_url\" is available for only HEADER type and IMAGE, VIDEO and DOCUMENT format."); } } } From 39145c43883a716e77e01a78ce6b7909a3924f4b Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Tue, 28 May 2024 13:32:24 +0200 Subject: [PATCH 494/516] Release 6.1.7 (#258) * new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 2f375fdf..c6bc186b 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.6 + 6.1.7 jar ${project.groupId}:${project.artifactId} diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 7e11ee5a..f8e30a86 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -72,7 +72,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "6.1.6"; + private final String clientVersion = "6.1.7"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 68637ec2..37e71aa6 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 6.1.6 + 6.1.7 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 6.1.6 + 6.1.7 compile From b742d17839a79ad0859215ed517ac22b40cc300c Mon Sep 17 00:00:00 2001 From: Chris Eager <79161849+eager-signal@users.noreply.github.com> Date: Mon, 23 Sep 2024 04:36:14 -0500 Subject: [PATCH 495/516] Update com.auth0:java-jwt to 4.4.0 (#259) --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/RequestValidator.java | 6 ++++-- .../test/java/com/messagebird/RequestValidatorTest.java | 9 ++++----- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index c6bc186b..a4d2e90a 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -90,7 +90,7 @@ com.auth0 java-jwt - 3.17.0 + 4.4.0 org.apache.maven diff --git a/api/src/main/java/com/messagebird/RequestValidator.java b/api/src/main/java/com/messagebird/RequestValidator.java index f2a4613b..24ae6343 100644 --- a/api/src/main/java/com/messagebird/RequestValidator.java +++ b/api/src/main/java/com/messagebird/RequestValidator.java @@ -5,13 +5,14 @@ import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.exceptions.JWTVerificationException; import com.auth0.jwt.exceptions.SignatureVerificationException; -import com.auth0.jwt.interfaces.Clock; +import com.auth0.jwt.interfaces.Claim; import com.auth0.jwt.interfaces.DecodedJWT; import com.auth0.jwt.interfaces.JWTVerifier; import com.messagebird.exceptions.RequestValidationException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.time.Clock; /** * RequestValidator validates request signature signed by MessageBird services. @@ -128,7 +129,8 @@ public DecodedJWT validateSignature(Clock clock, String signature, String url, b if (!skipURLValidation) builder.withClaim("url_hash", calculateSha256(url.getBytes())); - boolean payloadHashClaimExist = !jwt.getClaim("payload_hash").isNull(); + Claim payloadHashClaim = jwt.getClaim("payload_hash"); + boolean payloadHashClaimExist = !(payloadHashClaim.isNull() || payloadHashClaim.isMissing()); if (requestBody != null && requestBody.length > 0) { if (!payloadHashClaimExist) { throw new RequestValidationException("The Claim 'payload_hash' is not set but payload is present."); diff --git a/api/src/test/java/com/messagebird/RequestValidatorTest.java b/api/src/test/java/com/messagebird/RequestValidatorTest.java index a8d38132..23c64ef0 100644 --- a/api/src/test/java/com/messagebird/RequestValidatorTest.java +++ b/api/src/test/java/com/messagebird/RequestValidatorTest.java @@ -1,6 +1,5 @@ package com.messagebird; -import com.auth0.jwt.interfaces.Clock; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.messagebird.exceptions.RequestValidationException; @@ -13,7 +12,10 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.time.Clock; +import java.time.Instant; import java.time.OffsetDateTime; +import java.time.ZoneId; import java.util.*; import java.util.stream.Collectors; @@ -64,10 +66,7 @@ public static Collection data() throws IOException { public void testWebhookSignature() throws Throwable { RequestValidator validator = new RequestValidator(testCase.secret != null ? testCase.secret : ""); - Clock clock = mock(Clock.class); - Date clockDate = spy(Date.from(OffsetDateTime.parse(testCase.timestamp).toInstant())); - when(clock.getToday()).thenReturn(clockDate); - + Clock clock = Clock.fixed(OffsetDateTime.parse(testCase.timestamp).toInstant(), ZoneId.systemDefault()); ThrowingRunnable runnable = () -> validator.validateSignature(clock, testCase.token, testCase.url, (testCase.payload == null) ? null : testCase.payload.getBytes(StandardCharsets.UTF_8)); From aa7ab0b512e336021ec94593b42dba0c84a51f8d Mon Sep 17 00:00:00 2001 From: Alyona Akulshyn <165909017+alyona007@users.noreply.github.com> Date: Mon, 23 Sep 2024 11:38:48 +0200 Subject: [PATCH 496/516] Add support for LTO templates (#262) Add unpause method support --- .../conversations/MessageComponentType.java | 23 +++-- .../objects/conversations/MessageParam.java | 44 +++++++-- .../conversations/TemplateMediaType.java | 26 +++-- .../objects/integrations/HSMComponent.java | 52 +++++++--- .../integrations/HSMComponentType.java | 27 ++++-- .../MessageComponentTypeTest.java | 28 ++++++ .../conversations/MessageParamTest.java | 30 ++++++ .../conversations/TemplateMediaTypeTest.java | 27 ++++++ .../integrations/HSMComponentTest.java | 26 +++++ .../integrations/HSMComponentTypeTest.java | 23 +++++ ...sationSendHSMLimitedTimeOfferTemplate.java | 90 ++++++++++++++++++ ...ExampleCreateLimitedTimeOfferTemplate.java | 95 +++++++++++++++++++ 12 files changed, 443 insertions(+), 48 deletions(-) create mode 100644 api/src/test/java/com/messagebird/objects/conversations/MessageComponentTypeTest.java create mode 100644 api/src/test/java/com/messagebird/objects/conversations/MessageParamTest.java create mode 100644 api/src/test/java/com/messagebird/objects/conversations/TemplateMediaTypeTest.java create mode 100644 api/src/test/java/com/messagebird/objects/integrations/HSMComponentTest.java create mode 100644 api/src/test/java/com/messagebird/objects/integrations/HSMComponentTypeTest.java create mode 100644 examples/src/main/java/ExampleConversationSendHSMLimitedTimeOfferTemplate.java create mode 100644 examples/src/main/java/ExampleCreateLimitedTimeOfferTemplate.java diff --git a/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java b/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java index c2be69bf..cdb695cd 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java +++ b/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java @@ -3,6 +3,8 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; +import java.util.*; + public enum MessageComponentType { HEADER("header"), @@ -10,8 +12,18 @@ public enum MessageComponentType { FOOTER("footer"), BUTTON("button"), CARD("card"), - CAROUSEL("carousel"); + CAROUSEL("carousel"), + LIMITED_TIME_OFFER("limited_time_offer"); + + private static final Map TYPE_MAP; + static { + Map map = new HashMap<>(); + for (MessageComponentType componentType : MessageComponentType.values()) { + map.put(componentType.getType().toLowerCase(), componentType); + } + TYPE_MAP = Collections.unmodifiableMap(map); + } private final String type; @@ -21,13 +33,8 @@ public enum MessageComponentType { @JsonCreator public static MessageComponentType forValue(String value) { - for (MessageComponentType componentType: MessageComponentType.values()) { - if (componentType.getType().equals(value)) { - return componentType; - } - } - - return null; + Objects.requireNonNull(value, "Value cannot be null"); + return TYPE_MAP.get(value.toLowerCase(Locale.ROOT)); } @JsonValue diff --git a/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java b/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java index 069c3f62..38ae18f6 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java +++ b/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java @@ -1,5 +1,8 @@ package com.messagebird.objects.conversations; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.commons.lang3.StringUtils; + public class MessageParam { private TemplateMediaType type; @@ -10,6 +13,8 @@ public class MessageParam { private Media document; private Media image; private Media video; + @JsonProperty("expiration_time") + private String expirationTime; public TemplateMediaType getType() { return type; @@ -24,6 +29,9 @@ public String getText() { } public void setText(String text) { + if (StringUtils.isBlank(text)) { + throw new IllegalArgumentException("Text cannot be null or empty"); + } this.text = text; } @@ -48,6 +56,9 @@ public String getDateTime() { } public void setDateTime(String dateTime) { + if (StringUtils.isBlank(dateTime)) { + throw new IllegalArgumentException("dateTime cannot be null or empty"); + } this.dateTime = dateTime; } @@ -71,17 +82,30 @@ public void setImage(Media image) { public void setVideo(Media video) { this.video = video; } + public String getExpirationTime() { + return expirationTime; + } + + public void setExpirationTime(String expirationTime) { + if (StringUtils.isBlank(expirationTime)) { + throw new IllegalArgumentException("expirationTime cannot be null or empty"); + } + this.expirationTime = expirationTime; + } + @Override public String toString() { - return "MessageParam{" + - "type=" + type + '\'' + - ", text='" + text + '\'' + - ", payload='" + payload + '\'' + - ", currency=" + currency + '\'' + - ", dateTime='" + dateTime + '\'' + - ", document=" + document + '\'' + - ", image=" + image + '\'' + - ", video=" + video + - '}'; + StringBuilder sb = new StringBuilder("MessageParam{"); + sb.append("type=").append(type) + .append(", text='").append(text).append('\'') + .append(", payload='").append(payload).append('\'') + .append(", currency=").append(currency) + .append(", dateTime='").append(dateTime).append('\'') + .append(", document=").append(document) + .append(", image=").append(image) + .append(", video=").append(video) + .append(", expirationTime='").append(expirationTime).append('\'') + .append('}'); + return sb.toString(); } } diff --git a/api/src/main/java/com/messagebird/objects/conversations/TemplateMediaType.java b/api/src/main/java/com/messagebird/objects/conversations/TemplateMediaType.java index fe5494fd..fd600ab2 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/TemplateMediaType.java +++ b/api/src/main/java/com/messagebird/objects/conversations/TemplateMediaType.java @@ -2,6 +2,9 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Map; +import java.util.HashMap; +import java.util.Collections; public enum TemplateMediaType { @@ -11,7 +14,19 @@ public enum TemplateMediaType { TEXT("text"), CURRENCY("currency"), DATETIME("date_time"), - PAYLOAD("payload"); + PAYLOAD("payload"), + EXPIRATION_TIME("expiration_time"); + + private static final Map TYPE_MAP; + + static { + Map map = new HashMap<>(); + for (TemplateMediaType templateMediaType : TemplateMediaType.values()) { + map.put(templateMediaType.getType().toLowerCase(), templateMediaType); + } + TYPE_MAP = Collections.unmodifiableMap(map); + } + private final String type; @@ -21,13 +36,10 @@ public enum TemplateMediaType { @JsonCreator public static TemplateMediaType forValue(String value) { - for (TemplateMediaType templateMediaType: TemplateMediaType.values()) { - if (templateMediaType.getType().equals(value)) { - return templateMediaType; - } + if (value == null) { + throw new IllegalArgumentException("Value cannot be null"); } - - return null; + return TYPE_MAP.get(value.toLowerCase()); } @JsonValue diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java b/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java index 4e3fe648..ed93847f 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMComponent.java @@ -1,6 +1,7 @@ package com.messagebird.objects.integrations; import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.commons.lang3.StringUtils; import java.util.List; @@ -20,6 +21,8 @@ public class HSMComponent { @JsonProperty("code_expiration_minutes") private Integer codeExpirationMinutes; private List buttons; + @JsonProperty("has_expiration") + private Boolean hasExpiration; private List cards; @@ -46,6 +49,9 @@ public String getText() { } public void setText(String text) { + if (StringUtils.isBlank(text)) { + throw new IllegalArgumentException("Text cannot be null or empty"); + } this.text = text; } @@ -88,15 +94,29 @@ public Integer getCodeExpirationMinutes() { public void setCodeExpirationMinutes(Integer codeExpirationMinutes) { this.codeExpirationMinutes = codeExpirationMinutes; } + + public Boolean getHasExpiration() { + return hasExpiration; + } + + public void setHasExpiration(Boolean hasExpiration) { + this.hasExpiration = hasExpiration; + } + @Override public String toString() { - return "HSMComponent{" + - "type='" + type + '\'' + - ", format='" + format + '\'' + - ", text='" + text + '\'' + - ", buttons=" + buttons + - ", example=" + example + - '}'; + StringBuilder sb = new StringBuilder("HSMComponent{"); + sb.append("type=").append(type) + .append(", format=").append(format) + .append(", text='").append(text).append('\'') + .append(", addSecurityRecommendation=").append(addSecurityRecommendation) + .append(", codeExpirationMinutes=").append(codeExpirationMinutes) + .append(", buttons=").append(buttons) + .append(", hasExpiration=").append(hasExpiration) + .append(", cards=").append(cards) + .append(", example=").append(example) + .append('}'); + return sb.toString(); } /** @@ -105,8 +125,12 @@ public String toString() { * @throws IllegalArgumentException Occurs when validation is not passed. */ public void validateComponent() throws IllegalArgumentException { - this.validateButtons(); - this.validateComponentExample(); + try { + this.validateButtons(); + this.validateComponentExample(); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Component validation failed: " + e.getMessage(), e); + } } /** @@ -153,9 +177,7 @@ private void validateComponentExample() throws IllegalArgumentException { * @throws IllegalArgumentException Occurs when type is not {@code HEADER} and format is not {@code TEXT}. */ private void checkHeaderText() throws IllegalArgumentException { - if (!(type.equals(HSMComponentType.HEADER) - && format.equals(HSMComponentFormat.TEXT)) - ) { + if (!(HSMComponentType.HEADER.equals(type) && HSMComponentFormat.TEXT.equals(format))) { throw new IllegalArgumentException("\"header_text\" is available for only HEADER type and TEXT format."); } } @@ -166,9 +188,9 @@ private void checkHeaderText() throws IllegalArgumentException { * @throws IllegalArgumentException Occurs when type is not {@code HEADER} and format is not {@code IMAGE}. */ private void checkHeaderUrl() throws IllegalArgumentException { - if (!(type.equals(HSMComponentType.HEADER) && - (format.equals(HSMComponentFormat.IMAGE) || format.equals(HSMComponentFormat.VIDEO) || format.equals(HSMComponentFormat.DOCUMENT)))) { - throw new IllegalArgumentException("\"header_url\" is available for only HEADER type and IMAGE, VIDEO and DOCUMENT format."); + if (!(HSMComponentType.HEADER.equals(type) && + (HSMComponentFormat.IMAGE.equals(format) || HSMComponentFormat.VIDEO.equals(format) || HSMComponentFormat.DOCUMENT.equals(format)))) { + throw new IllegalArgumentException("\"header_url\" is available for only HEADER type and IMAGE, VIDEO, or DOCUMENT formats."); } } } diff --git a/api/src/main/java/com/messagebird/objects/integrations/HSMComponentType.java b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentType.java index eff331dc..8610146a 100644 --- a/api/src/main/java/com/messagebird/objects/integrations/HSMComponentType.java +++ b/api/src/main/java/com/messagebird/objects/integrations/HSMComponentType.java @@ -2,6 +2,11 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; +import java.util.Map; +import java.util.HashMap; +import java.util.Collections; +import java.util.Locale; +import java.util.Objects; /** * An enum for HSMComponentType @@ -13,7 +18,18 @@ public enum HSMComponentType { HEADER("HEADER"), FOOTER("FOOTER"), BUTTONS("BUTTONS"), - CAROUSEL("CAROUSEL"); + CAROUSEL("CAROUSEL"), + LIMITED_TIME_OFFER("LIMITED_TIME_OFFER"); + + private static final Map TYPE_MAP; + + static { + Map map = new HashMap<>(); + for (HSMComponentType hsmComponentType : HSMComponentType.values()) { + map.put(hsmComponentType.getType().toLowerCase(), hsmComponentType); + } + TYPE_MAP = Collections.unmodifiableMap(map); + } private final String type; @@ -23,13 +39,8 @@ public enum HSMComponentType { @JsonCreator public static HSMComponentType forValue(String value) { - for (HSMComponentType hsmComponentType : HSMComponentType.values()) { - if (hsmComponentType.getType().equals(value)) { - return hsmComponentType; - } - } - - return null; + Objects.requireNonNull(value, "Value cannot be null"); + return TYPE_MAP.get(value.toLowerCase(Locale.ROOT)); } @JsonValue diff --git a/api/src/test/java/com/messagebird/objects/conversations/MessageComponentTypeTest.java b/api/src/test/java/com/messagebird/objects/conversations/MessageComponentTypeTest.java new file mode 100644 index 00000000..385b1652 --- /dev/null +++ b/api/src/test/java/com/messagebird/objects/conversations/MessageComponentTypeTest.java @@ -0,0 +1,28 @@ +package com.messagebird.objects.conversations; + +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +public class MessageComponentTypeTest { + @Test + public void testMessageComponentTypeForValueValid() { + assertEquals(MessageComponentType.HEADER, MessageComponentType.forValue("header")); + assertEquals(MessageComponentType.BUTTON, MessageComponentType.forValue("button")); + } + + @Test(expected = NullPointerException.class) + public void testMessageComponentTypeForValueNull() { + MessageComponentType.forValue(null); + } + + @Test + public void testMessageComponentTypeForValueInvalid() { + assertNull(MessageComponentType.forValue("invalid_type")); + } + + @Test + public void testMessageComponentTypeToString() { + assertEquals("header", MessageComponentType.HEADER.toString()); + } +} diff --git a/api/src/test/java/com/messagebird/objects/conversations/MessageParamTest.java b/api/src/test/java/com/messagebird/objects/conversations/MessageParamTest.java new file mode 100644 index 00000000..6ddabad7 --- /dev/null +++ b/api/src/test/java/com/messagebird/objects/conversations/MessageParamTest.java @@ -0,0 +1,30 @@ +package com.messagebird.objects.conversations; + +import org.junit.Test; +import static org.junit.Assert.assertEquals; + +public class MessageParamTest { + @Test + public void testMessageParamToString() { + MessageParam param = new MessageParam(); + param.setType(TemplateMediaType.IMAGE); + param.setText("Sample text"); + param.setPayload("Sample payload"); + + String expected = "MessageParam{type=image, text='Sample text', payload='Sample payload', currency=null, dateTime='null', document=null, image=null, video=null, expirationTime='null'}"; + assertEquals(expected, param.toString()); + } + + @Test(expected = IllegalArgumentException.class) + public void testMessageParamSetTextInvalid() { + MessageParam param = new MessageParam(); + param.setText(""); + } + + @Test + public void testMessageParamSetTextValid() { + MessageParam param = new MessageParam(); + param.setText("Valid text"); + assertEquals("Valid text", param.getText()); + } +} diff --git a/api/src/test/java/com/messagebird/objects/conversations/TemplateMediaTypeTest.java b/api/src/test/java/com/messagebird/objects/conversations/TemplateMediaTypeTest.java new file mode 100644 index 00000000..d30bde28 --- /dev/null +++ b/api/src/test/java/com/messagebird/objects/conversations/TemplateMediaTypeTest.java @@ -0,0 +1,27 @@ +package com.messagebird.objects.conversations; + +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +public class TemplateMediaTypeTest { + @Test + public void testTemplateMediaTypeForValueValid() { + assertEquals(TemplateMediaType.VIDEO, TemplateMediaType.forValue("video")); + } + + @Test(expected = IllegalArgumentException.class) + public void testTemplateMediaTypeForValueNull() { + TemplateMediaType.forValue(null); + } + + @Test + public void testTemplateMediaTypeForValueInvalid() { + assertNull(TemplateMediaType.forValue("non_existing_value")); + } + + @Test + public void testTemplateMediaTypeToString() { + assertEquals("video", TemplateMediaType.VIDEO.toString()); + } +} diff --git a/api/src/test/java/com/messagebird/objects/integrations/HSMComponentTest.java b/api/src/test/java/com/messagebird/objects/integrations/HSMComponentTest.java new file mode 100644 index 00000000..9af4bb64 --- /dev/null +++ b/api/src/test/java/com/messagebird/objects/integrations/HSMComponentTest.java @@ -0,0 +1,26 @@ +package com.messagebird.objects.integrations; + +import org.junit.Test; +import static org.junit.Assert.assertEquals; + +public class HSMComponentTest { + @Test + public void testToString() { + HSMComponent component = new HSMComponent(); + component.setType(HSMComponentType.BODY); + component.setFormat(HSMComponentFormat.TEXT); + component.setText("Test text"); + component.setAddSecurityRecommendation(true); + component.setCodeExpirationMinutes(10); + component.setHasExpiration(true); + + String expected = "HSMComponent{type=BODY, format=TEXT, text='Test text', addSecurityRecommendation=true, codeExpirationMinutes=10, buttons=null, hasExpiration=true, cards=null, example=null}"; + assertEquals(expected, component.toString()); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetTextInvalid() { + HSMComponent component = new HSMComponent(); + component.setText(""); + } +} diff --git a/api/src/test/java/com/messagebird/objects/integrations/HSMComponentTypeTest.java b/api/src/test/java/com/messagebird/objects/integrations/HSMComponentTypeTest.java new file mode 100644 index 00000000..47053509 --- /dev/null +++ b/api/src/test/java/com/messagebird/objects/integrations/HSMComponentTypeTest.java @@ -0,0 +1,23 @@ +package com.messagebird.objects.integrations; + +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +public class HSMComponentTypeTest { + @Test + public void testForValueValid() { + assertEquals(HSMComponentType.BODY, HSMComponentType.forValue("BODY")); + assertEquals(HSMComponentType.BODY, HSMComponentType.forValue("body")); + } + + @Test(expected = NullPointerException.class) + public void testForValueNull() { + HSMComponentType.forValue(null); + } + + @Test + public void testForValueInvalid() { + assertNull(HSMComponentType.forValue("INVALID")); + } +} diff --git a/examples/src/main/java/ExampleConversationSendHSMLimitedTimeOfferTemplate.java b/examples/src/main/java/ExampleConversationSendHSMLimitedTimeOfferTemplate.java new file mode 100644 index 00000000..65b959a8 --- /dev/null +++ b/examples/src/main/java/ExampleConversationSendHSMLimitedTimeOfferTemplate.java @@ -0,0 +1,90 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.conversations.*; + +import java.util.ArrayList; +import java.util.List; + +public class ExampleConversationSendHSMLimitedTimeOfferTemplate { + + public static void main(String[] args) { + if (args.length < 6) { + System.out.println("Please at least specify your access key, the channel id and destination address.\n" + + "Usage : java -jar test_accesskey(Required) channel_id(Required) from(Required) destination(Required) templateName(Required) namespace(Required) expirationTimeInput(Required)"); + return; + } + + final String accessKey = args[0]; + final String from = args[1]; + final String destination = args[2]; + final String templateName = args[3]; + final String namespace = args[4]; + final String expirationTimeInput = args[5]; + + //First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(accessKey); + //Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + ConversationContent conversationContent = new ConversationContent(); + ConversationContentHsm conversationContentHsm = new ConversationContentHsm(); + conversationContentHsm.setNamespace(namespace); + conversationContentHsm.setTemplateName(templateName); + ConversationHsmLanguage language = new ConversationHsmLanguage(); + language.setCode("en"); + conversationContentHsm.setLanguage(language); + List messageComponents = new ArrayList<>(); + + // Add LTO component + MessageComponent messageLTOComponent = new MessageComponent(); + messageLTOComponent.setType(MessageComponentType.LIMITED_TIME_OFFER); + List messageLTOParams = new ArrayList<>(); + + MessageParam expirationTime = new MessageParam(); + expirationTime.setType(TemplateMediaType.EXPIRATION_TIME); + expirationTime.setExpirationTime(expirationTimeInput); + messageLTOParams.add(expirationTime); + + messageLTOComponent.setParameters(messageLTOParams); + + // Add body component + MessageComponent messageBodyComponent = new MessageComponent(); + messageBodyComponent.setType(MessageComponentType.BODY); + List messageBodyParams = new ArrayList<>(); + + MessageParam text = new MessageParam(); + text.setType(TemplateMediaType.TEXT); + text.setText("Bob"); + messageBodyParams.add(text); + + messageBodyComponent.setParameters(messageBodyParams); + + messageComponents.add(messageLTOComponent); + messageComponents.add(messageBodyComponent); + conversationContentHsm.setComponents(messageComponents); + conversationContent.setHsm(conversationContentHsm); + ConversationSendRequest request = new ConversationSendRequest( + destination, + ConversationContentType.HSM, + conversationContent, + from, + "", + null, + null, + null); + + try { + ConversationSendResponse sendResponse = messageBirdClient.sendMessage(request); + System.out.println(sendResponse.toString()); + + } catch (UnauthorizedException e) { + System.err.println("Authorization failed. Please check your access key: " + e.getMessage()); + } catch (GeneralException e) { + System.err.println("An error occurred while sending the message: " + e.getMessage()); + } + } + +} diff --git a/examples/src/main/java/ExampleCreateLimitedTimeOfferTemplate.java b/examples/src/main/java/ExampleCreateLimitedTimeOfferTemplate.java new file mode 100644 index 00000000..dc721f9f --- /dev/null +++ b/examples/src/main/java/ExampleCreateLimitedTimeOfferTemplate.java @@ -0,0 +1,95 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.integrations.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ExampleCreateLimitedTimeOfferTemplate { + + public static void main(String[] args) { + if (args.length < 4) { + System.out.println("Please specify your access key and a template name and WABA ID example : java -jar test_accesskey(Required) templateName(Required) wabaID(required)"); + return; + } + + final String accessKey = args[0]; + final String templateName = args[1]; + final String wabaID = args[2]; + + // First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(accessKey); + + // Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + // header + final HSMComponent headerComponent = new HSMComponent(); + final HSMExample headerExample = new HSMExample(); + headerExample.setHeader_url(Arrays.asList("https://images.freeimages.com/images/small-previews/c5a/colourful-paper-rip-1-1195879.jpg")); + + headerComponent.setType(HSMComponentType.HEADER); + headerComponent.setFormat(HSMComponentFormat.IMAGE); + headerComponent.setExample(headerExample); + + // limited time offer + final HSMComponent ltoComponent = new HSMComponent(); + ltoComponent.setType(HSMComponentType.LIMITED_TIME_OFFER); + ltoComponent.setText("Expiring offer!"); + ltoComponent.setHasExpiration(true); + + // body + final HSMComponent bodyComponent = new HSMComponent(); + final HSMExample bodyExample = new HSMExample(); + final List> bodyText = new ArrayList<>(); + bodyText.add(Arrays.asList("John", "CARIBE25")); + bodyExample.setBody_text(bodyText); + + bodyComponent.setType(HSMComponentType.BODY); + bodyComponent.setText("Good news, {{1}}! Use code {{2}} to get 0% off all packages!"); + bodyComponent.setExample(bodyExample); + + // buttons + final HSMComponent buttonComponent = new HSMComponent(); + final List buttons = new ArrayList<>(); + + final HSMComponentButton buttonCopyCode = new HSMComponentButton(); + buttonCopyCode.setType(HSMComponentButtonType.COPY_CODE); + buttonCopyCode.setExample(Arrays.asList("CARIBE25")); + + final HSMComponentButton buttonBookNow = new HSMComponentButton(); + buttonBookNow.setType(HSMComponentButtonType.URL); + buttonBookNow.setText("Book now!"); + buttonBookNow.setUrl("https://www.bird.com?code={{1}}"); + buttonBookNow.setExample(Arrays.asList("https://www.bird.com?code=CARIBE25")); + + buttons.addAll(Arrays.asList(buttonCopyCode, buttonBookNow)); + buttonComponent.setType(HSMComponentType.BUTTONS); + buttonComponent.setButtons(buttons); + + // set components + final Template template = new Template(); + final List components = new ArrayList<>(); + components.addAll(Arrays.asList(headerComponent, ltoComponent, bodyComponent, buttonComponent)); + + template.setName(templateName); + template.setLanguage("en_US"); + template.setWABAID(wabaID); + template.setComponents(components); + template.setCategory(HSMCategory.MARKETING); + + try { + TemplateResponse response = messageBirdClient.createWhatsAppTemplate(template); + System.out.println(response.toString()); + } catch (UnauthorizedException e) { + System.err.println("Authorization failed. Please check your access key: " + e.getMessage()); + } catch (GeneralException e) { + System.err.println("An error occurred while sending the message: " + e.getMessage()); + } + } + +} From 0418288b73b21139279e3cc5b2f29fa172f3ba4c Mon Sep 17 00:00:00 2001 From: Deniz Kilic Date: Wed, 25 Sep 2024 11:29:08 +0200 Subject: [PATCH 497/516] Cut 6.2.1 (#263) * new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index a4d2e90a..4f732bad 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.1.7 + 6.2.1 jar ${project.groupId}:${project.artifactId} diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index f8e30a86..03d52bea 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -72,7 +72,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "6.1.7"; + private final String clientVersion = "6.2.1"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 37e71aa6..9d56a89f 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 6.1.7 + 6.2.1 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 6.1.7 + 6.2.1 compile From 5a34cd2011cb48d97df23f3bc1516b1324da3ef9 Mon Sep 17 00:00:00 2001 From: Alyona Akulshyn <165909017+alyona007@users.noreply.github.com> Date: Thu, 14 Nov 2024 11:25:45 +0100 Subject: [PATCH 498/516] Add unpause method support (#261) * Add unpause method support --- .../com/messagebird/MessageBirdClient.java | 18 +++++++++++++++ .../messagebird/MessageBirdServiceImpl.java | 3 +++ .../messagebird/MessageBirdClientTest.java | 22 ++++++++++++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdClient.java b/api/src/main/java/com/messagebird/MessageBirdClient.java index 7011ab10..583dcb40 100644 --- a/api/src/main/java/com/messagebird/MessageBirdClient.java +++ b/api/src/main/java/com/messagebird/MessageBirdClient.java @@ -105,6 +105,7 @@ public class MessageBirdClient { private static final String VOICELEGS_SUFFIX_PATH = "/legs"; static final String FILES_PATH = "/files"; static final String TEMPLATES_PATH = "/templates"; + static final String UNPAUSE_TEMAPLATE_PATH = "/unpause"; static final String OUTBOUND_SMS_PRICING_PATH = "/pricing/sms/outbound"; static final String OUTBOUND_SMS_PRICING_SMPP_PATH = "/pricing/sms/outbound/smpp/%s"; @@ -2145,6 +2146,23 @@ public void deleteTemplatesBy(final String templateName) messageBirdService.delete(url, null); } + public void unpauseTemplatesByTemplateName(final String templateName) + throws UnauthorizedException, GeneralException { + if (templateName == null) { + throw new IllegalArgumentException("Template name must be specified."); + } + + String url = String.format( + "%s%s%s%s/%s", + INTEGRATIONS_BASE_URL_V2, + INTEGRATIONS_WHATSAPP_PATH, + TEMPLATES_PATH, + UNPAUSE_TEMAPLATE_PATH, + templateName + ); + messageBirdService.sendPayLoad("POST", url, "", null); + } + /** * Function to create a child account * diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 03d52bea..a16019ef 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -382,6 +382,9 @@

APIResponse doRequest(final String method, final String url, final Map Date: Thu, 14 Nov 2024 13:40:07 +0100 Subject: [PATCH 499/516] Cut 6.2.2 (#264) * new release --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index 4f732bad..2d99afc2 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.2.1 + 6.2.2 jar ${project.groupId}:${project.artifactId} diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index a16019ef..a5e897dd 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -72,7 +72,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "6.2.1"; + private final String clientVersion = "6.2.2"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 9d56a89f..4a98866a 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 6.2.1 + 6.2.2 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 6.2.1 + 6.2.2 compile From be42898afb15ff8e6e29a46b7f15125c328e716b Mon Sep 17 00:00:00 2001 From: Venkateswaran S Date: Wed, 9 Apr 2025 10:31:09 +0200 Subject: [PATCH 500/516] support for copy code --- .../conversations/MessageComponentType.java | 3 +- .../objects/conversations/MessageParam.java | 9 ++ .../conversations/TemplateMediaType.java | 3 +- ...leConversationSendHSMCopyCodeTemplate.java | 92 +++++++++++++++++++ 4 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 examples/src/main/java/ExampleConversationSendHSMCopyCodeTemplate.java diff --git a/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java b/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java index cdb695cd..9f9290cf 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java +++ b/api/src/main/java/com/messagebird/objects/conversations/MessageComponentType.java @@ -13,7 +13,8 @@ public enum MessageComponentType { BUTTON("button"), CARD("card"), CAROUSEL("carousel"), - LIMITED_TIME_OFFER("limited_time_offer"); + LIMITED_TIME_OFFER("limited_time_offer"), + COPY_CODE("copy_code"); private static final Map TYPE_MAP; diff --git a/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java b/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java index 38ae18f6..7772d2cd 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java +++ b/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java @@ -15,6 +15,8 @@ public class MessageParam { private Media video; @JsonProperty("expiration_time") private String expirationTime; + @JsonProperty("coupon_code") + private String couponCode; public TemplateMediaType getType() { return type; @@ -93,6 +95,13 @@ public void setExpirationTime(String expirationTime) { this.expirationTime = expirationTime; } + public void setCouponCode(String couponCode) { + if (StringUtils.isBlank(couponCode)) { + throw new IllegalArgumentException("couponCode cannot be null or empty"); + } + this.couponCode = couponCode; + } + @Override public String toString() { StringBuilder sb = new StringBuilder("MessageParam{"); diff --git a/api/src/main/java/com/messagebird/objects/conversations/TemplateMediaType.java b/api/src/main/java/com/messagebird/objects/conversations/TemplateMediaType.java index fd600ab2..580dcc97 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/TemplateMediaType.java +++ b/api/src/main/java/com/messagebird/objects/conversations/TemplateMediaType.java @@ -15,7 +15,8 @@ public enum TemplateMediaType { CURRENCY("currency"), DATETIME("date_time"), PAYLOAD("payload"), - EXPIRATION_TIME("expiration_time"); + EXPIRATION_TIME("expiration_time"), + COUPON_CODE("coupon_code"); private static final Map TYPE_MAP; diff --git a/examples/src/main/java/ExampleConversationSendHSMCopyCodeTemplate.java b/examples/src/main/java/ExampleConversationSendHSMCopyCodeTemplate.java new file mode 100644 index 00000000..44f482bb --- /dev/null +++ b/examples/src/main/java/ExampleConversationSendHSMCopyCodeTemplate.java @@ -0,0 +1,92 @@ +import com.messagebird.MessageBirdClient; +import com.messagebird.MessageBirdService; +import com.messagebird.MessageBirdServiceImpl; +import com.messagebird.exceptions.GeneralException; +import com.messagebird.exceptions.UnauthorizedException; +import com.messagebird.objects.conversations.*; + +import java.util.ArrayList; +import java.util.List; + +public class ExampleConversationSendHSMCopyCodeTemplate { + + public static void main(String[] args) { + if (args.length < 6) { + System.out.println("Please at least specify your access key, the channel id and destination address.\n" + + "Usage : java -jar test_accesskey(Required) channel_id(Required) from(Required) destination(Required) templateName(Required) namespace(Required) expirationTimeInput(Required)"); + return; + } + + final String accessKey = args[0]; + final String from = args[1]; + final String destination = args[2]; + final String templateName = args[3]; + final String namespace = args[4]; + final String couponCodeInput = args[5]; + + //First create your service object + final MessageBirdService wsr = new MessageBirdServiceImpl(accessKey); + //Add the service to the client + final MessageBirdClient messageBirdClient = new MessageBirdClient(wsr); + + ConversationContent conversationContent = new ConversationContent(); + ConversationContentHsm conversationContentHsm = new ConversationContentHsm(); + conversationContentHsm.setNamespace(namespace); + conversationContentHsm.setTemplateName(templateName); + ConversationHsmLanguage language = new ConversationHsmLanguage(); + language.setCode("en"); + conversationContentHsm.setLanguage(language); + List messageComponents = new ArrayList<>(); + + // Add LTO component + MessageComponent messageCopyCodeComponent = new MessageComponent(); + messageCopyCodeComponent.setType(MessageComponentType.BUTTON); + messageCopyCodeComponent.setSub_type(MessageComponentType.COPY_CODE.toString()); + List messageCCParams = new ArrayList<>(); + + MessageParam couponCodeParam = new MessageParam(); + couponCodeParam.setType(TemplateMediaType.COUPON_CODE); + couponCodeParam.setCouponCode(couponCodeInput); + messageCCParams.add(couponCodeParam); + + messageCopyCodeComponent.setParameters(messageCCParams); + + // Add body component + MessageComponent messageBodyComponent = new MessageComponent(); + messageBodyComponent.setType(MessageComponentType.BODY); + List messageBodyParams = new ArrayList<>(); + + MessageParam text = new MessageParam(); + text.setType(TemplateMediaType.TEXT); + text.setText("Bob"); + messageBodyParams.add(text); + + messageBodyComponent.setParameters(messageBodyParams); + + messageComponents.add(messageCopyCodeComponent); + messageComponents.add(messageBodyComponent); + conversationContentHsm.setComponents(messageComponents); + conversationContent.setHsm(conversationContentHsm); + ConversationSendRequest request = new ConversationSendRequest( + destination, + ConversationContentType.HSM, + conversationContent, + from, + "", + null, + null, + null); + + try { + System.out.println(request.toString()); + ConversationSendResponse sendResponse = messageBirdClient.sendMessage(request); + System.out.println(sendResponse.toString()); + + } catch (UnauthorizedException e) { + System.err.println("Authorization failed. Please check your access key: " + e.getMessage()); + } catch (GeneralException e) { + System.err.println("An error occurred while sending the message: " + e.getMessage()); + } + } + +} From 41052be1a88176e6ea0ce1bb2453baaf7ad5c390 Mon Sep 17 00:00:00 2001 From: Venkat Sankaran Date: Wed, 9 Apr 2025 13:23:02 +0200 Subject: [PATCH 501/516] Update to version 6.2.3 --- api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pom.xml b/api/pom.xml index 2d99afc2..fd0dbced 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.2.2 + 6.2.3 jar ${project.groupId}:${project.artifactId} From edf16851ea6d5c8f6f45fc09dda3cce8778380f1 Mon Sep 17 00:00:00 2001 From: Venkat Sankaran Date: Wed, 9 Apr 2025 13:24:40 +0200 Subject: [PATCH 502/516] Update examples --- examples/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/pom.xml b/examples/pom.xml index 4a98866a..ba4ab890 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 6.2.2 + 6.2.3 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 6.2.2 + 6.2.3 compile From 94e0aee94e3e63d9e247db43d791a75cf53a49fd Mon Sep 17 00:00:00 2001 From: Venkat Sankaran Date: Wed, 9 Apr 2025 13:25:15 +0200 Subject: [PATCH 503/516] Update client version string --- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index a5e897dd..33f6f8e6 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -72,7 +72,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "6.2.2"; + private final String clientVersion = "6.2.3"; private final String userAgentString; private Proxy proxy = null; From 2abd1cdad7b32cf5d10f6cef8cdeaa04320c6822 Mon Sep 17 00:00:00 2001 From: Venkateswaran S Date: Wed, 9 Apr 2025 16:38:43 +0200 Subject: [PATCH 504/516] update to version v6.2.4 --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index fd0dbced..cdfd9969 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.2.3 + 6.2.4 jar ${project.groupId}:${project.artifactId} diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 33f6f8e6..b36427fc 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -72,7 +72,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "6.2.3"; + private final String clientVersion = "6.2.4"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index ba4ab890..4b56224c 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 6.2.3 + 6.2.4 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 6.2.3 + 6.2.4 compile From 51dcd3911fd0855a2f5f8ecc038a442e8fefc0d6 Mon Sep 17 00:00:00 2001 From: Venkateswaran S Date: Thu, 10 Apr 2025 10:53:28 +0200 Subject: [PATCH 505/516] adding venkat to devs --- api/pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/api/pom.xml b/api/pom.xml index cdfd9969..d060594d 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -27,6 +27,12 @@ MessageBird https://www.messagebird.com + + Venkateswaran S + venkat.sankaran@bird.com + MessageBird + https://www.messagebird.com + Sam Wierema sam@messagebird.com From 24b8bdb05553977c5437b903f3ab8b02a2fb4a04 Mon Sep 17 00:00:00 2001 From: Venkateswaran S Date: Fri, 11 Apr 2025 12:17:36 +0200 Subject: [PATCH 506/516] adding helper method to get copyCode --- .../com/messagebird/objects/conversations/MessageParam.java | 5 +++++ .../messagebird/objects/conversations/MessageParamTest.java | 2 +- .../java/ExampleConversationSendHSMCopyCodeTemplate.java | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java b/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java index 7772d2cd..6432369f 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java +++ b/api/src/main/java/com/messagebird/objects/conversations/MessageParam.java @@ -95,6 +95,10 @@ public void setExpirationTime(String expirationTime) { this.expirationTime = expirationTime; } + public String getCouponCode() { + return couponCode; + } + public void setCouponCode(String couponCode) { if (StringUtils.isBlank(couponCode)) { throw new IllegalArgumentException("couponCode cannot be null or empty"); @@ -114,6 +118,7 @@ public String toString() { .append(", image=").append(image) .append(", video=").append(video) .append(", expirationTime='").append(expirationTime).append('\'') + .append(", couponCode='").append(couponCode).append('\'') .append('}'); return sb.toString(); } diff --git a/api/src/test/java/com/messagebird/objects/conversations/MessageParamTest.java b/api/src/test/java/com/messagebird/objects/conversations/MessageParamTest.java index 6ddabad7..f1147d2f 100644 --- a/api/src/test/java/com/messagebird/objects/conversations/MessageParamTest.java +++ b/api/src/test/java/com/messagebird/objects/conversations/MessageParamTest.java @@ -11,7 +11,7 @@ public void testMessageParamToString() { param.setText("Sample text"); param.setPayload("Sample payload"); - String expected = "MessageParam{type=image, text='Sample text', payload='Sample payload', currency=null, dateTime='null', document=null, image=null, video=null, expirationTime='null'}"; + String expected = "MessageParam{type=image, text='Sample text', payload='Sample payload', currency=null, dateTime='null', document=null, image=null, video=null, expirationTime='null', couponCode='null'}"; assertEquals(expected, param.toString()); } diff --git a/examples/src/main/java/ExampleConversationSendHSMCopyCodeTemplate.java b/examples/src/main/java/ExampleConversationSendHSMCopyCodeTemplate.java index 44f482bb..4d5dcd3f 100644 --- a/examples/src/main/java/ExampleConversationSendHSMCopyCodeTemplate.java +++ b/examples/src/main/java/ExampleConversationSendHSMCopyCodeTemplate.java @@ -13,7 +13,7 @@ public class ExampleConversationSendHSMCopyCodeTemplate { public static void main(String[] args) { if (args.length < 6) { System.out.println("Please at least specify your access key, the channel id and destination address.\n" + - "Usage : java -jar test_accesskey(Required) channel_id(Required) from(Required) destination(Required) templateName(Required) namespace(Required) expirationTimeInput(Required)"); + "Usage : java -jar test_accesskey(Required) channel_id(Required) from(Required) destination(Required) templateName(Required) namespace(Required) couponCodeInput(Required)"); return; } From 5746f75677b0e0fd81cf966428bb5b28ad451db4 Mon Sep 17 00:00:00 2001 From: Venkateswaran S Date: Fri, 11 Apr 2025 12:28:38 +0200 Subject: [PATCH 507/516] update version 6.2.5 --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- examples/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index d060594d..e17d2358 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.2.4 + 6.2.5 jar ${project.groupId}:${project.artifactId} diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index b36427fc..3cc1f25e 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -72,7 +72,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "6.2.4"; + private final String clientVersion = "6.2.5"; private final String userAgentString; private Proxy proxy = null; diff --git a/examples/pom.xml b/examples/pom.xml index 4b56224c..a0089732 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 6.2.4 + 6.2.5 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 6.2.4 + 6.2.5 compile From 8ec864ea95ae45c6b00150d46c442136fa4832fb Mon Sep 17 00:00:00 2001 From: Chris Casey Date: Thu, 21 May 2026 10:44:53 +0100 Subject: [PATCH 508/516] feat: add WhatsApp BSUID support and split test/integration profiles - Add ConversationMessageMetadata, ConversationSenderMetadata, and ConversationStatusMessageMetadata to model BSUID webhook payloads - Add metadata field to ConversationMessage - Split Maven test/integration profiles so unit tests run without credentials - Fix ContactTest and MessageBirdClientTest to skip gracefully via assumeNotNull - Bump version to 6.3.0 Co-Authored-By: Claude Sonnet 4.6 --- api/pom.xml | 38 ++++++++- .../messagebird/MessageBirdServiceImpl.java | 2 +- .../conversations/ConversationMessage.java | 10 +++ .../ConversationMessageMetadata.java | 39 +++++++++ .../ConversationSenderMetadata.java | 47 +++++++++++ .../ConversationStatusMessageMetadata.java | 79 +++++++++++++++++++ .../java/com/messagebird/ContactTest.java | 2 + .../com/messagebird/ConversationsTest.java | 1 + .../messagebird/MessageBirdClientTest.java | 6 +- 9 files changed, 219 insertions(+), 5 deletions(-) create mode 100644 api/src/main/java/com/messagebird/objects/conversations/ConversationMessageMetadata.java create mode 100644 api/src/main/java/com/messagebird/objects/conversations/ConversationSenderMetadata.java create mode 100644 api/src/main/java/com/messagebird/objects/conversations/ConversationStatusMessageMetadata.java diff --git a/api/pom.xml b/api/pom.xml index e17d2358..fb65b2b0 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.2.5 + 6.3.0 jar ${project.groupId}:${project.artifactId} @@ -62,19 +62,51 @@ + test false + + + UTF-8 + + + + + org.apache.maven.plugins + maven-surefire-plugin + + false + + **/ContactTest.java + **/MessageBirdClientTest.java + + + + + + + + + integration + + false + UTF-8 + disable-doclint - [8,11,) + [1.8,11) none - true UTF-8 diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index 3cc1f25e..ce3c10e7 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -72,7 +72,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "6.2.5"; + private final String clientVersion = "6.3.0"; private final String userAgentString; private Proxy proxy = null; diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessage.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessage.java index 2be027be..1dea8280 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessage.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessage.java @@ -22,6 +22,7 @@ public class ConversationMessage { private Date updatedDatetime; private Map source; private ConversationMessageTag tag; + private ConversationMessageMetadata metadata; /** * See: {@link ConversationPlatformConstants} */ @@ -115,6 +116,14 @@ public void setTag(ConversationMessageTag tag) { this.tag = tag; } + public ConversationMessageMetadata getMetadata() { + return metadata; + } + + public void setMetadata(ConversationMessageMetadata metadata) { + this.metadata = metadata; + } + public String getPlatform() { return platform; } @@ -146,6 +155,7 @@ public String toString() { ", updatedDatetime=" + updatedDatetime + ", source=" + source + ", tag=" + tag + + ", metadata=" + metadata + ", platform='" + platform + '\'' + '}'; } diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageMetadata.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageMetadata.java new file mode 100644 index 00000000..7d908e6a --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageMetadata.java @@ -0,0 +1,39 @@ +package com.messagebird.objects.conversations; + +import java.util.Date; + +/** + * Inner metadata attached to a conversation message. Present on both incoming + * messages and status webhook payloads. {@code sender.userId} always contains + * the BSUID when Meta provides one. When both identifiers exist, the phone + * number appears in the parent {@code from} field, not in this object. + */ +public class ConversationMessageMetadata { + + private ConversationSenderMetadata sender; + private Date receivedAt; + + public ConversationSenderMetadata getSender() { + return sender; + } + + public void setSender(ConversationSenderMetadata sender) { + this.sender = sender; + } + + public Date getReceivedAt() { + return receivedAt; + } + + public void setReceivedAt(Date receivedAt) { + this.receivedAt = receivedAt; + } + + @Override + public String toString() { + return "ConversationMessageMetadata{" + + "sender=" + sender + + ", receivedAt=" + receivedAt + + '}'; + } +} diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationSenderMetadata.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationSenderMetadata.java new file mode 100644 index 00000000..33d7e225 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationSenderMetadata.java @@ -0,0 +1,47 @@ +package com.messagebird.objects.conversations; + +/** + * Metadata about the sender of a WhatsApp message. {@code userId} always + * contains the BSUID (e.g. "US.13491208655302741918") when Meta supplies one. + * When both a phone number and a BSUID are available, the phone number appears + * in the parent message's {@code from} field — not here. + */ +public class ConversationSenderMetadata { + + private String userId; + private String username; + private String displayName; + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + @Override + public String toString() { + return "ConversationSenderMetadata{" + + "userId='" + userId + '\'' + + ", username='" + username + '\'' + + ", displayName='" + displayName + '\'' + + '}'; + } +} diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationStatusMessageMetadata.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationStatusMessageMetadata.java new file mode 100644 index 00000000..ce5635ae --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationStatusMessageMetadata.java @@ -0,0 +1,79 @@ +package com.messagebird.objects.conversations; + +/** + * The {@code messageMetadata} block delivered in status webhook events (e.g. + * {@code statusSent}). Reflects the original message that triggered the status. + * + *

Both {@code from} and {@code to} accept either a phone number or a + * WhatsApp Business-Scoped User ID (BSUID, e.g. "US.13491208655302741918"). + * The BSUID is also available via {@code metadata.sender.userId}. + */ +public class ConversationStatusMessageMetadata { + + private String id; + private String from; + private String to; + private String type; + private ConversationContent content; + private ConversationMessageMetadata metadata; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public String getTo() { + return to; + } + + public void setTo(String to) { + this.to = to; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public ConversationContent getContent() { + return content; + } + + public void setContent(ConversationContent content) { + this.content = content; + } + + public ConversationMessageMetadata getMetadata() { + return metadata; + } + + public void setMetadata(ConversationMessageMetadata metadata) { + this.metadata = metadata; + } + + @Override + public String toString() { + return "ConversationStatusMessageMetadata{" + + "id='" + id + '\'' + + ", from='" + from + '\'' + + ", to='" + to + '\'' + + ", type='" + type + '\'' + + ", content=" + content + + ", metadata=" + metadata + + '}'; + } +} diff --git a/api/src/test/java/com/messagebird/ContactTest.java b/api/src/test/java/com/messagebird/ContactTest.java index 2377733d..5dfdea38 100644 --- a/api/src/test/java/com/messagebird/ContactTest.java +++ b/api/src/test/java/com/messagebird/ContactTest.java @@ -8,6 +8,7 @@ import org.mockito.Mockito; import static org.junit.Assert.*; import static org.mockito.Mockito.*; +import static org.junit.Assume.assumeNotNull; import static org.unitils.reflectionassert.ReflectionAssert.assertReflectionEquals; /** @@ -30,6 +31,7 @@ public class ContactTest { @BeforeClass public static void setUpClass() throws UnauthorizedException, GeneralException { String accessKey = System.getProperty("messageBirdAccessKey"); + assumeNotNull("Integration test skipped: set -DmessageBirdAccessKey to run", accessKey); msisdn = generateMsisdn(); diff --git a/api/src/test/java/com/messagebird/ConversationsTest.java b/api/src/test/java/com/messagebird/ConversationsTest.java index 4e7624e8..e08f0175 100644 --- a/api/src/test/java/com/messagebird/ConversationsTest.java +++ b/api/src/test/java/com/messagebird/ConversationsTest.java @@ -17,6 +17,7 @@ public class ConversationsTest { private static final String JSON_CONVERSATION = "{\"id\": \"convid\",\"contactId\": \"contid\",\"contact\": {\"id\": \"contid\",\"href\": \"https://chat.messagebird.com/1/contacts/contid\",\"msisdn\": 31612345678,\"firstName\": \"Foo\",\"lastName\": \"Bar\",\"customDetails\": {\"avatar\": \"https://example.com/assets/image.jpg\",\"firstName\": \"Foo\",\"lastName\": \"Bar\",\"userId\": 12345678 },\"createdDatetime\": \"2018-08-22T15:47:32Z\",\"updatedDatetime\": null},\"channels\": [{\"id\": \"chid\",\"name\": \"chname\",\"platformId\": \"telegram\",\"status\": \"active\",\"createdDatetime\": \"2018-08-22T15:18:11Z\",\"updatedDatetime\": \"2018-08-22T15:18:13Z\"}],\"status\": \"active\",\"createdDatetime\": \"2018-08-22T15:47:34Z\",\"updatedDatetime\": \"2018-08-22T16:05:15Z\",\"lastReceivedDatetime\": \"2018-08-22T15:47:34Z\",\"lastUsedChannelId\": \"chid\",\"messages\": {\"totalCount\": 1,\"href\": \"https://conversations.messagebird.com/v1/conversations/convid/messages\"}}"; private static final String JSON_CONVERSATION_LIST = "{\"offset\": 20,\"limit\": 10,\"count\": 1,\"totalCount\": 1,\"items\": [{\"id\": \"convid\",\"contactId\": \"contid\",\"contact\": {\"id\": \"contid\",\"href\": \"https://chat.messagebird.com/1/contacts/contid\",\"msisdn\": 31612345678,\"firstName\": \"Foo\",\"lastName\": \"Bar\",\"customDetails\": {\"avatar\": \"https://s3-eu-west-1.amazonaws.com/messagebird-chat/telegram/0d1dae7t5b7d7eb4531c14n04328336/6de655at5b7d859309f821n60607065/d0b705dt5b7d859309f987n05372263.jpg\",\"firstName\": \"Foo\",\"lastName\": \"Bar\",\"userId\": 12345678},\"createdDatetime\": \"2018-08-22T15:47:32Z\",\"updatedDatetime\": null},\"channels\": [{\"id\": \"chid\",\"name\": \"TestChannel\",\"platformId\": \"telegram\",\"status\": \"active\",\"createdDatetime\": \"2018-08-22T15:18:11Z\",\"updatedDatetime\": \"2018-08-22T15:18:13Z\"}],\"status\": \"active\",\"createdDatetime\": \"2018-08-22T15:47:34Z\",\"updatedDatetime\": \"2018-08-24T09:49:01Z\",\"lastReceivedDatetime\": \"2018-08-24T09:49:01Z\",\"lastUsedChannelId\": \"chid\",\"messages\": {\"totalCount\": 3,\"href\": \"https://conversations.messagebird.com/v1/conversations/convid/messages\"}}]}"; private static final String JSON_UNAUTHORIZED_ERROR = "{\"errors\": [{\"code\": 2,\"description\": \"Request was not authenticated\"}]}"; + // Status-update payload where Meta supplies both a phone number and a BSUID on the contact. @Test(expected = UnauthorizedException.class) public void testItThrowsErrors() throws GeneralException, UnauthorizedException { diff --git a/api/src/test/java/com/messagebird/MessageBirdClientTest.java b/api/src/test/java/com/messagebird/MessageBirdClientTest.java index ee2dc890..b11c2f54 100644 --- a/api/src/test/java/com/messagebird/MessageBirdClientTest.java +++ b/api/src/test/java/com/messagebird/MessageBirdClientTest.java @@ -16,6 +16,7 @@ import org.junit.BeforeClass; import org.junit.Test; import org.mockito.Mockito; +import static org.junit.Assume.assumeNotNull; import java.math.BigInteger; import java.util.Collections; @@ -44,7 +45,10 @@ public class MessageBirdClientTest { @BeforeClass public static void setUpClass() { messageBirdAccessKey = System.getProperty("messageBirdAccessKey"); - messageBirdMSISDN = new BigInteger(System.getProperty("messageBirdMSISDN")); + String msisdn = System.getProperty("messageBirdMSISDN"); + assumeNotNull("Integration test skipped: set -DmessageBirdAccessKey and -DmessageBirdMSISDN to run", + messageBirdAccessKey, msisdn); + messageBirdMSISDN = new BigInteger(msisdn); } @Before From fa2a89860e0647accd1c4653a429ab99915dfa3b Mon Sep 17 00:00:00 2001 From: Chris Casey Date: Thu, 21 May 2026 12:18:24 +0100 Subject: [PATCH 509/516] test: add deserialization tests for BSUID metadata; refine status metadata javadoc - Add JSON round-trip tests covering ConversationMessage.metadata and ConversationStatusMessageMetadata so the new types are exercised. - Clarify in javadoc that ConversationStatusMessageMetadata is a standalone POJO for consumers parsing incoming webhook payloads (not produced by any SDK request). - Remove dangling code comment in ConversationsTest. Co-Authored-By: Claude Sonnet 4.6 --- .../ConversationStatusMessageMetadata.java | 9 ++++- .../messagebird/ConversationMessagesTest.java | 39 +++++++++++++++++++ .../com/messagebird/ConversationsTest.java | 1 - 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationStatusMessageMetadata.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationStatusMessageMetadata.java index ce5635ae..df7feebf 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationStatusMessageMetadata.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationStatusMessageMetadata.java @@ -1,8 +1,13 @@ package com.messagebird.objects.conversations; /** - * The {@code messageMetadata} block delivered in status webhook events (e.g. - * {@code statusSent}). Reflects the original message that triggered the status. + * The {@code messageMetadata} block delivered inside status webhook payloads + * (e.g. {@code statusSent}, {@code statusDelivered}). Reflects the original + * message that triggered the status update. + * + *

This class is not produced by any SDK request — it is a standalone POJO + * intended for consumers who deserialize incoming webhook payloads in their + * own HTTP handlers. Use it via {@code ObjectMapper.readValue(body, ...)}. * *

Both {@code from} and {@code to} accept either a phone number or a * WhatsApp Business-Scoped User ID (BSUID, e.g. "US.13491208655302741918"). diff --git a/api/src/test/java/com/messagebird/ConversationMessagesTest.java b/api/src/test/java/com/messagebird/ConversationMessagesTest.java index 81357f88..5bd0a5c5 100644 --- a/api/src/test/java/com/messagebird/ConversationMessagesTest.java +++ b/api/src/test/java/com/messagebird/ConversationMessagesTest.java @@ -1,5 +1,7 @@ package com.messagebird; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.NotFoundException; import com.messagebird.exceptions.UnauthorizedException; @@ -23,6 +25,8 @@ public class ConversationMessagesTest { private static final String JSON_CONVERSATION_MESSAGE_TEXT = "{\"id\": \"mesid\",\"conversationId\": \"convid\",\"channelId\": \"chanid\",\"status\": \"received\",\"type\": \"text\",\"direction\": \"received\",\"content\": {\"text\": \"Hello\"},\"createdDatetime\": \"2018-08-29T11:49:16Z\",\"updatedDatetime\": \"2018-08-29T11:49:16Z\"}"; private static final String JSON_CONVERSATION_MESSAGE_VIDEO = "{\"id\": \"mesid\",\"conversationId\": \"convid\",\"channelId\": \"chanid\",\"status\": \"received\",\"type\": \"video\",\"direction\": \"received\",\"content\": {\"video\": { \"url\": \"https://example.com/video.mp4\" } },\"createdDatetime\": \"2018-08-29T11:49:16Z\",\"updatedDatetime\": \"2018-08-29T11:49:16Z\"}"; private static final String JSON_CONVERSATION_SEND_MESSAGE_RESPONSE = "{\"id\":\"mesid\",\"status\":\"accepted\",\"fallback\":{\"id\":\"mesid\"}}"; + private static final String JSON_CONVERSATION_MESSAGE_BSUID = "{\"id\": \"mesid\",\"conversationId\": \"convid\",\"channelId\": \"chanid\",\"status\": \"received\",\"type\": \"text\",\"direction\": \"received\",\"content\": {\"text\": \"Hello\"},\"metadata\": {\"sender\": {\"displayName\": \"Alice\",\"username\": \"alice_shop\",\"userId\": \"US.13491208655302741918\"},\"receivedAt\": \"2025-04-15T16:00:00Z\"},\"createdDatetime\": \"2025-04-15T16:00:00Z\",\"updatedDatetime\": \"2025-04-15T16:00:00Z\"}"; + private static final String JSON_STATUS_MESSAGE_METADATA = "{\"id\": \"e5f6a7b8-c9d0-1234-ef01-23456789abcd\",\"from\": \"15551234567\",\"to\": \"US.13491208655302741918\",\"type\": \"text\",\"content\": {\"text\": \"Hello! Your order has been shipped.\"},\"metadata\": {\"sender\": {\"userId\": \"US.13491208655302741918\"},\"receivedAt\": \"0001-01-01T00:00:00Z\"}}"; /** * Epsilon to use when checking two latitudes or longitudes for equality. @@ -183,6 +187,41 @@ public void testViewConversationMessageLocation() throws GeneralException, NotFo assertEquals(4.911627, location.getLongitude(), EPSILON_LOCATION_EQUALITY); } + @Test + public void testViewConversationMessageWithBsuidMetadata() throws GeneralException, NotFoundException, UnauthorizedException { + MessageBirdService messageBirdService = SpyService + .expects("GET", "messages/mesid") + .withConversationsAPIBaseURL() + .andReturns(new APIResponse(JSON_CONVERSATION_MESSAGE_BSUID)); + MessageBirdClient messageBirdClient = new MessageBirdClient(messageBirdService); + + ConversationMessage message = messageBirdClient.viewConversationMessage("mesid"); + + ConversationMessageMetadata metadata = message.getMetadata(); + assertNotNull(metadata); + assertNotNull(metadata.getReceivedAt()); + ConversationSenderMetadata sender = metadata.getSender(); + assertEquals("Alice", sender.getDisplayName()); + assertEquals("alice_shop", sender.getUsername()); + assertEquals("US.13491208655302741918", sender.getUserId()); + } + + @Test + public void testStatusMessageMetadataDeserializes() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + + ConversationStatusMessageMetadata md = mapper.readValue( + JSON_STATUS_MESSAGE_METADATA, ConversationStatusMessageMetadata.class); + + assertEquals("e5f6a7b8-c9d0-1234-ef01-23456789abcd", md.getId()); + assertEquals("15551234567", md.getFrom()); + assertEquals("US.13491208655302741918", md.getTo()); + assertEquals("text", md.getType()); + assertEquals("Hello! Your order has been shipped.", md.getContent().getText()); + assertEquals("US.13491208655302741918", md.getMetadata().getSender().getUserId()); + } + @Test public void testViewConversationMessageText() throws GeneralException, NotFoundException, UnauthorizedException { MessageBirdService messageBirdService = SpyService diff --git a/api/src/test/java/com/messagebird/ConversationsTest.java b/api/src/test/java/com/messagebird/ConversationsTest.java index e08f0175..4e7624e8 100644 --- a/api/src/test/java/com/messagebird/ConversationsTest.java +++ b/api/src/test/java/com/messagebird/ConversationsTest.java @@ -17,7 +17,6 @@ public class ConversationsTest { private static final String JSON_CONVERSATION = "{\"id\": \"convid\",\"contactId\": \"contid\",\"contact\": {\"id\": \"contid\",\"href\": \"https://chat.messagebird.com/1/contacts/contid\",\"msisdn\": 31612345678,\"firstName\": \"Foo\",\"lastName\": \"Bar\",\"customDetails\": {\"avatar\": \"https://example.com/assets/image.jpg\",\"firstName\": \"Foo\",\"lastName\": \"Bar\",\"userId\": 12345678 },\"createdDatetime\": \"2018-08-22T15:47:32Z\",\"updatedDatetime\": null},\"channels\": [{\"id\": \"chid\",\"name\": \"chname\",\"platformId\": \"telegram\",\"status\": \"active\",\"createdDatetime\": \"2018-08-22T15:18:11Z\",\"updatedDatetime\": \"2018-08-22T15:18:13Z\"}],\"status\": \"active\",\"createdDatetime\": \"2018-08-22T15:47:34Z\",\"updatedDatetime\": \"2018-08-22T16:05:15Z\",\"lastReceivedDatetime\": \"2018-08-22T15:47:34Z\",\"lastUsedChannelId\": \"chid\",\"messages\": {\"totalCount\": 1,\"href\": \"https://conversations.messagebird.com/v1/conversations/convid/messages\"}}"; private static final String JSON_CONVERSATION_LIST = "{\"offset\": 20,\"limit\": 10,\"count\": 1,\"totalCount\": 1,\"items\": [{\"id\": \"convid\",\"contactId\": \"contid\",\"contact\": {\"id\": \"contid\",\"href\": \"https://chat.messagebird.com/1/contacts/contid\",\"msisdn\": 31612345678,\"firstName\": \"Foo\",\"lastName\": \"Bar\",\"customDetails\": {\"avatar\": \"https://s3-eu-west-1.amazonaws.com/messagebird-chat/telegram/0d1dae7t5b7d7eb4531c14n04328336/6de655at5b7d859309f821n60607065/d0b705dt5b7d859309f987n05372263.jpg\",\"firstName\": \"Foo\",\"lastName\": \"Bar\",\"userId\": 12345678},\"createdDatetime\": \"2018-08-22T15:47:32Z\",\"updatedDatetime\": null},\"channels\": [{\"id\": \"chid\",\"name\": \"TestChannel\",\"platformId\": \"telegram\",\"status\": \"active\",\"createdDatetime\": \"2018-08-22T15:18:11Z\",\"updatedDatetime\": \"2018-08-22T15:18:13Z\"}],\"status\": \"active\",\"createdDatetime\": \"2018-08-22T15:47:34Z\",\"updatedDatetime\": \"2018-08-24T09:49:01Z\",\"lastReceivedDatetime\": \"2018-08-24T09:49:01Z\",\"lastUsedChannelId\": \"chid\",\"messages\": {\"totalCount\": 3,\"href\": \"https://conversations.messagebird.com/v1/conversations/convid/messages\"}}]}"; private static final String JSON_UNAUTHORIZED_ERROR = "{\"errors\": [{\"code\": 2,\"description\": \"Request was not authenticated\"}]}"; - // Status-update payload where Meta supplies both a phone number and a BSUID on the contact. @Test(expected = UnauthorizedException.class) public void testItThrowsErrors() throws GeneralException, UnauthorizedException { From 805aa5af470ab14924e389648c6383e4d449bb94 Mon Sep 17 00:00:00 2001 From: Chris Casey Date: Thu, 28 May 2026 16:37:05 +0100 Subject: [PATCH 510/516] chore: migrate deploy plugin from OSSRH to Sonatype Central Portal OSSRH (oss.sonatype.org) was sunset in March 2025. Replace nexus-staging-maven-plugin with central-publishing-maven-plugin and drop the now-unused snapshotRepository distributionManagement block. autoPublish=false keeps the manual review/release behaviour the old config had via autoReleaseAfterClose=false. Co-Authored-By: Claude Sonnet 4.6 --- api/pom.xml | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index fb65b2b0..37e4f157 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -161,13 +161,6 @@ - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - @@ -262,14 +255,22 @@ - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.7 + + org.sonatype.central + central-publishing-maven-plugin + 0.7.0 true - ossrh - https://oss.sonatype.org/ - false + central + false + validated From 365e12ffcc27b1ae7aef325506f0d5a54241b1f3 Mon Sep 17 00:00:00 2001 From: Michal Date: Mon, 20 Jul 2026 11:24:04 +0200 Subject: [PATCH 511/516] fix(deps): pin plexus-utils to 3.6.1 to resolve CVE-2025-67030 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit maven-artifact:3.9.6 (used only for ComparableVersion) transitively pulls plexus-utils:3.5.1, which is affected by CVE-2025-67030 — a directory traversal / Zip Slip in org.codehaus.plexus.util.Expand.extractFile (CVSS 8.8). The vulnerable code is not reachable from this client, but the jar is flagged by SCA scanners. Add a dependencyManagement pin forcing the patched plexus-utils 3.6.1. Staying on the 3.x line avoids the plexus-xml package split introduced in 4.x. dependency:tree confirms plexus-utils now resolves to 3.6.1 and the build/tests are unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) --- api/pom.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/api/pom.xml b/api/pom.xml index 37e4f157..bb736110 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -114,6 +114,17 @@ + + + + + org.codehaus.plexus + plexus-utils + 3.6.1 + + + + com.fasterxml.jackson.core From d330cbfc725ef50eb55a2e1b8af817ddeafb4c8f Mon Sep 17 00:00:00 2001 From: Michal Date: Mon, 20 Jul 2026 12:53:44 +0200 Subject: [PATCH 512/516] chore(release): bump version to 6.3.1 Release the CVE-2025-67030 plexus-utils fix as a patch. Bumps the Maven artifact version and the hardcoded clientVersion used in the User-Agent header to keep them in sync. Co-Authored-By: Claude Opus 4.8 (1M context) --- api/pom.xml | 2 +- api/src/main/java/com/messagebird/MessageBirdServiceImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index bb736110..d9c1f273 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.3.0 + 6.3.1 jar ${project.groupId}:${project.artifactId} diff --git a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java index ce3c10e7..ef179b45 100644 --- a/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java +++ b/api/src/main/java/com/messagebird/MessageBirdServiceImpl.java @@ -72,7 +72,7 @@ public class MessageBirdServiceImpl implements MessageBirdService { private final String accessKey; private final String serviceUrl; - private final String clientVersion = "6.3.0"; + private final String clientVersion = "6.3.1"; private final String userAgentString; private Proxy proxy = null; From 6b39ec409ce9c5d0e17d80b27a02d57ac54e6303 Mon Sep 17 00:00:00 2001 From: Michal Date: Mon, 20 Jul 2026 13:02:52 +0200 Subject: [PATCH 513/516] chore(release): bump examples module to 6.3.1 The examples module was left at 6.2.5 (missed in the 6.3.0 release). Bring its own version and its messagebird-api dependency in line with the 6.3.1 release, matching the convention in #275. Co-Authored-By: Claude Opus 4.8 (1M context) --- examples/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/pom.xml b/examples/pom.xml index a0089732..9ffe9f18 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 6.2.5 + 6.3.1 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 6.2.5 + 6.3.1 compile From c53da1787dca061d66c9d3c4bd6d2022991b017d Mon Sep 17 00:00:00 2001 From: Chris Casey Date: Fri, 31 Jul 2026 12:08:06 +0100 Subject: [PATCH 514/516] feat: model recipient BSUIDs on WhatsApp status webhooks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Meta's parent business-scoped user ID rollout adds two identifiers our webhooks now forward, neither of which the SDK could express. - ConversationSenderMetadata gains parentUserId, the sender's parent BSUID (from Meta's messages[].from_parent_user_id). - ConversationRecipientMetadata is new, modelling status.metadata.recipient.{userId,parentUserId}. Status payloads did not carry the recipient's own identity before — messageMetadata.to is only an echo of the address the customer addressed — so this is the first way to learn a contact's BSUID from a status webhook. - ConversationStatusMetadata is new, modelling the enclosing status.metadata block. pricing and conversation stay raw maps: they are near-verbatim passthroughs of Meta's objects and keep their snake_case keys, while recipient is ours and is camelCase. Unmodelled keys (e.g. biz_opaque_callback_data) are collected rather than dropped. Both new types parse under a plain ObjectMapper, so consumers need not disable FAIL_ON_UNKNOWN_PROPERTIES. recipient is absent from payloads for accounts that receive no BSUIDs, and deserialises to null there. Co-Authored-By: Claude Opus 5 --- .../ConversationRecipientMetadata.java | 50 +++++++++++ .../ConversationSenderMetadata.java | 16 ++++ .../ConversationStatusMessageMetadata.java | 5 ++ .../ConversationStatusMetadata.java | 85 +++++++++++++++++++ .../messagebird/ConversationMessagesTest.java | 50 ++++++++++- 5 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 api/src/main/java/com/messagebird/objects/conversations/ConversationRecipientMetadata.java create mode 100644 api/src/main/java/com/messagebird/objects/conversations/ConversationStatusMetadata.java diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationRecipientMetadata.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationRecipientMetadata.java new file mode 100644 index 00000000..7537da85 --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationRecipientMetadata.java @@ -0,0 +1,50 @@ +package com.messagebird.objects.conversations; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +/** + * Identifies the recipient of an outbound WhatsApp message, as reported back on + * status webhook payloads under {@code status.metadata.recipient}. Mirrors + * {@link ConversationSenderMetadata} on the inbound side. + * + *

{@code userId} is the recipient's BSUID (e.g. "US.13491208655302741918"); + * {@code parentUserId} is the parent business-scoped user ID of the enterprise + * that owns the business portfolio it was scoped against (e.g. + * "US.ENT.11815799212886844830"). + * + *

Either field may be {@code null}: Meta only supplies them for accounts + * enrolled in the BSUID rollout, and the enclosing {@code recipient} object is + * omitted entirely when neither is present. This is the only place a status + * payload carries the recipient's own identity — {@code messageMetadata.to} is + * an echo of the address the message was addressed to. + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class ConversationRecipientMetadata { + + private String userId; + private String parentUserId; + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getParentUserId() { + return parentUserId; + } + + public void setParentUserId(String parentUserId) { + this.parentUserId = parentUserId; + } + + @Override + public String toString() { + return "ConversationRecipientMetadata{" + + "userId='" + userId + '\'' + + ", parentUserId='" + parentUserId + '\'' + + '}'; + } +} diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationSenderMetadata.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationSenderMetadata.java index 33d7e225..d7f60b9f 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationSenderMetadata.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationSenderMetadata.java @@ -5,10 +5,17 @@ * contains the BSUID (e.g. "US.13491208655302741918") when Meta supplies one. * When both a phone number and a BSUID are available, the phone number appears * in the parent message's {@code from} field — not here. + * + *

{@code parentUserId} carries the sender's parent business-scoped user ID + * (e.g. "US.ENT.11815799212886844830"), which identifies the enterprise that + * owns the business portfolio the {@code userId} was scoped against. It is only + * present for accounts enrolled in Meta's parent-BSUID rollout; for everyone + * else it stays {@code null}. */ public class ConversationSenderMetadata { private String userId; + private String parentUserId; private String username; private String displayName; @@ -20,6 +27,14 @@ public void setUserId(String userId) { this.userId = userId; } + public String getParentUserId() { + return parentUserId; + } + + public void setParentUserId(String parentUserId) { + this.parentUserId = parentUserId; + } + public String getUsername() { return username; } @@ -40,6 +55,7 @@ public void setDisplayName(String displayName) { public String toString() { return "ConversationSenderMetadata{" + "userId='" + userId + '\'' + + ", parentUserId='" + parentUserId + '\'' + ", username='" + username + '\'' + ", displayName='" + displayName + '\'' + '}'; diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationStatusMessageMetadata.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationStatusMessageMetadata.java index df7feebf..537ad7bb 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationStatusMessageMetadata.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationStatusMessageMetadata.java @@ -12,6 +12,11 @@ *

Both {@code from} and {@code to} accept either a phone number or a * WhatsApp Business-Scoped User ID (BSUID, e.g. "US.13491208655302741918"). * The BSUID is also available via {@code metadata.sender.userId}. + * + *

{@code to} echoes back the address the message was originally addressed + * to, so it is not a reliable source of the recipient's BSUID. That identity + * lives alongside this block, under {@code status.metadata.recipient} — see + * {@link ConversationStatusMetadata}. */ public class ConversationStatusMessageMetadata { diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationStatusMetadata.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationStatusMetadata.java new file mode 100644 index 00000000..0b4d5f7f --- /dev/null +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationStatusMetadata.java @@ -0,0 +1,85 @@ +package com.messagebird.objects.conversations; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * The {@code status.metadata} block delivered inside status webhook payloads + * (e.g. {@code statusSent}, {@code statusDelivered}). + * + *

This class is not produced by any SDK request — it is a standalone POJO + * intended for consumers who deserialize incoming webhook payloads in their own + * HTTP handlers. Use it via {@code ObjectMapper.readValue(body, ...)}. + * + *

Note the mixed casing of this object. {@code pricing} and + * {@code conversation} are near-verbatim passthroughs of Meta's own objects and + * so keep their snake_case keys ({@code pricing_model}, {@code category}, …); + * they are exposed here as raw maps rather than modelled types, because their + * contents track Meta's schema rather than ours. {@code recipient} is ours and + * follows the camelCase convention used everywhere else in the API. Any other + * key present on the payload — for example {@code biz_opaque_callback_data} — + * is collected into {@link #getAdditionalProperties()} rather than dropped. + * + *

{@code recipient} is absent from payloads for accounts that never receive + * BSUIDs, in which case {@link #getRecipient()} returns {@code null}. + */ +public class ConversationStatusMetadata { + + private Map pricing; + private Map conversation; + private ConversationRecipientMetadata recipient; + private final Map additionalProperties = new LinkedHashMap<>(); + + public Map getPricing() { + return pricing; + } + + public void setPricing(Map pricing) { + this.pricing = pricing; + } + + public Map getConversation() { + return conversation; + } + + public void setConversation(Map conversation) { + this.conversation = conversation; + } + + public ConversationRecipientMetadata getRecipient() { + return recipient; + } + + public void setRecipient(ConversationRecipientMetadata recipient) { + this.recipient = recipient; + } + + /** + * Every key on the payload that has no dedicated accessor above, in the + * order it was encountered. Empty when the payload holds nothing else. + * + * @return the unmodelled remainder of the metadata object + */ + @JsonAnyGetter + public Map getAdditionalProperties() { + return additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + additionalProperties.put(name, value); + } + + @Override + public String toString() { + return "ConversationStatusMetadata{" + + "pricing=" + pricing + + ", conversation=" + conversation + + ", recipient=" + recipient + + ", additionalProperties=" + additionalProperties + + '}'; + } +} diff --git a/api/src/test/java/com/messagebird/ConversationMessagesTest.java b/api/src/test/java/com/messagebird/ConversationMessagesTest.java index 5bd0a5c5..da670fca 100644 --- a/api/src/test/java/com/messagebird/ConversationMessagesTest.java +++ b/api/src/test/java/com/messagebird/ConversationMessagesTest.java @@ -25,9 +25,13 @@ public class ConversationMessagesTest { private static final String JSON_CONVERSATION_MESSAGE_TEXT = "{\"id\": \"mesid\",\"conversationId\": \"convid\",\"channelId\": \"chanid\",\"status\": \"received\",\"type\": \"text\",\"direction\": \"received\",\"content\": {\"text\": \"Hello\"},\"createdDatetime\": \"2018-08-29T11:49:16Z\",\"updatedDatetime\": \"2018-08-29T11:49:16Z\"}"; private static final String JSON_CONVERSATION_MESSAGE_VIDEO = "{\"id\": \"mesid\",\"conversationId\": \"convid\",\"channelId\": \"chanid\",\"status\": \"received\",\"type\": \"video\",\"direction\": \"received\",\"content\": {\"video\": { \"url\": \"https://example.com/video.mp4\" } },\"createdDatetime\": \"2018-08-29T11:49:16Z\",\"updatedDatetime\": \"2018-08-29T11:49:16Z\"}"; private static final String JSON_CONVERSATION_SEND_MESSAGE_RESPONSE = "{\"id\":\"mesid\",\"status\":\"accepted\",\"fallback\":{\"id\":\"mesid\"}}"; - private static final String JSON_CONVERSATION_MESSAGE_BSUID = "{\"id\": \"mesid\",\"conversationId\": \"convid\",\"channelId\": \"chanid\",\"status\": \"received\",\"type\": \"text\",\"direction\": \"received\",\"content\": {\"text\": \"Hello\"},\"metadata\": {\"sender\": {\"displayName\": \"Alice\",\"username\": \"alice_shop\",\"userId\": \"US.13491208655302741918\"},\"receivedAt\": \"2025-04-15T16:00:00Z\"},\"createdDatetime\": \"2025-04-15T16:00:00Z\",\"updatedDatetime\": \"2025-04-15T16:00:00Z\"}"; + private static final String JSON_CONVERSATION_MESSAGE_BSUID = "{\"id\": \"mesid\",\"conversationId\": \"convid\",\"channelId\": \"chanid\",\"status\": \"received\",\"type\": \"text\",\"direction\": \"received\",\"content\": {\"text\": \"Hello\"},\"metadata\": {\"sender\": {\"displayName\": \"Alice\",\"username\": \"alice_shop\",\"userId\": \"US.13491208655302741918\",\"parentUserId\": \"US.ENT.11815799212886844830\"},\"receivedAt\": \"2025-04-15T16:00:00Z\"},\"createdDatetime\": \"2025-04-15T16:00:00Z\",\"updatedDatetime\": \"2025-04-15T16:00:00Z\"}"; private static final String JSON_STATUS_MESSAGE_METADATA = "{\"id\": \"e5f6a7b8-c9d0-1234-ef01-23456789abcd\",\"from\": \"15551234567\",\"to\": \"US.13491208655302741918\",\"type\": \"text\",\"content\": {\"text\": \"Hello! Your order has been shipped.\"},\"metadata\": {\"sender\": {\"userId\": \"US.13491208655302741918\"},\"receivedAt\": \"0001-01-01T00:00:00Z\"}}"; + private static final String JSON_STATUS_METADATA_WITH_RECIPIENT = "{\"pricing\": {\"billable\": true,\"pricing_model\": \"CBP\",\"category\": \"utility\"},\"conversation\": {\"id\": \"a1b2c3d4\",\"origin\": {\"type\": \"utility\"}},\"biz_opaque_callback_data\": \"order-1234\",\"recipient\": {\"userId\": \"US.13491208655302741918\",\"parentUserId\": \"US.ENT.11815799212886844830\"}}"; + private static final String JSON_STATUS_METADATA_WITHOUT_RECIPIENT = "{\"pricing\": {\"billable\": true,\"pricing_model\": \"CBP\",\"category\": \"utility\"},\"conversation\": {\"id\": \"a1b2c3d4\",\"origin\": {\"type\": \"utility\"}}}"; + private static final String JSON_STATUS_METADATA_PARENT_ONLY = "{\"recipient\": {\"parentUserId\": \"US.ENT.11815799212886844830\"}}"; + /** * Epsilon to use when checking two latitudes or longitudes for equality. */ @@ -204,6 +208,50 @@ public void testViewConversationMessageWithBsuidMetadata() throws GeneralExcepti assertEquals("Alice", sender.getDisplayName()); assertEquals("alice_shop", sender.getUsername()); assertEquals("US.13491208655302741918", sender.getUserId()); + assertEquals("US.ENT.11815799212886844830", sender.getParentUserId()); + } + + @Test + public void testStatusMetadataDeserializesRecipient() throws Exception { + // A plain mapper: these payload POJOs must not require the caller to + // disable FAIL_ON_UNKNOWN_PROPERTIES. + ConversationStatusMetadata metadata = new ObjectMapper().readValue( + JSON_STATUS_METADATA_WITH_RECIPIENT, ConversationStatusMetadata.class); + + ConversationRecipientMetadata recipient = metadata.getRecipient(); + assertNotNull(recipient); + assertEquals("US.13491208655302741918", recipient.getUserId()); + assertEquals("US.ENT.11815799212886844830", recipient.getParentUserId()); + + // Meta's own objects pass through untouched, snake_case keys and all. + assertEquals("CBP", metadata.getPricing().get("pricing_model")); + assertEquals("a1b2c3d4", metadata.getConversation().get("id")); + + // Anything else on the payload is kept rather than dropped. + assertEquals("order-1234", metadata.getAdditionalProperties().get("biz_opaque_callback_data")); + } + + @Test + public void testStatusMetadataWithoutRecipientIsNull() throws Exception { + ConversationStatusMetadata metadata = new ObjectMapper().readValue( + JSON_STATUS_METADATA_WITHOUT_RECIPIENT, ConversationStatusMetadata.class); + + // Accounts that never receive BSUIDs get payloads with no recipient key + // at all — the rest of the metadata must still parse. + assertNull(metadata.getRecipient()); + assertEquals("CBP", metadata.getPricing().get("pricing_model")); + assertTrue(metadata.getAdditionalProperties().isEmpty()); + } + + @Test + public void testStatusMetadataRecipientWithParentOnly() throws Exception { + ConversationStatusMetadata metadata = new ObjectMapper().readValue( + JSON_STATUS_METADATA_PARENT_ONLY, ConversationStatusMetadata.class); + + ConversationRecipientMetadata recipient = metadata.getRecipient(); + assertNotNull(recipient); + assertNull(recipient.getUserId()); + assertEquals("US.ENT.11815799212886844830", recipient.getParentUserId()); } @Test From 59d1fc22f6b35a82ccb914648af5f50b917b7572 Mon Sep 17 00:00:00 2001 From: Chris Casey Date: Fri, 31 Jul 2026 12:24:32 +0100 Subject: [PATCH 515/516] fix: tolerate unknown fields on webhook payload POJOs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The payload types added in 6.3.0 are meant to be deserialized by consumers in their own HTTP handlers, but only parsed under a mapper with FAIL_ON_UNKNOWN_PROPERTIES disabled — which the SDK's internal mapper does and a plain ObjectMapper does not. A consumer following the javadoc got an UnrecognizedPropertyException, and would get one again every time the platform adds a field to a payload they already parse. Adds @JsonIgnoreProperties(ignoreUnknown = true) to the four types on the status payload path: ConversationStatusMessageMetadata, ConversationMessageMetadata, ConversationSenderMetadata and ConversationContent. This matches the new types added alongside it and makes the webhook-parsing story uniform. Deserialization only loosens, so nothing that parsed before stops parsing; serialization is untouched, which the existing send-request tests cover. The 6.3.0 test no longer needs to disable the feature by hand, and a new test parses a payload carrying unknown keys at every nesting level under a plain mapper. Co-Authored-By: Claude Opus 5 --- .../conversations/ConversationContent.java | 7 +++++ .../ConversationMessageMetadata.java | 3 +++ .../ConversationSenderMetadata.java | 3 +++ .../ConversationStatusMessageMetadata.java | 3 +++ .../messagebird/ConversationMessagesTest.java | 27 +++++++++++++++---- 5 files changed, 38 insertions(+), 5 deletions(-) diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationContent.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationContent.java index 9ba82bd8..8b4fe164 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationContent.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationContent.java @@ -1,9 +1,16 @@ package com.messagebird.objects.conversations; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + /** * ConversationContent wraps actual content. The field that should be set here * is indicated by ConversationContentType. + * + *

Unknown keys are ignored on deserialization so that consumers parsing + * webhook payloads in their own handlers are not broken by content fields added + * after their SDK version. Serialization is unaffected. */ +@JsonIgnoreProperties(ignoreUnknown = true) public class ConversationContent { private ConversationContentMedia audio; diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageMetadata.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageMetadata.java index 7d908e6a..c41e814b 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageMetadata.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationMessageMetadata.java @@ -1,5 +1,7 @@ package com.messagebird.objects.conversations; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + import java.util.Date; /** @@ -8,6 +10,7 @@ * the BSUID when Meta provides one. When both identifiers exist, the phone * number appears in the parent {@code from} field, not in this object. */ +@JsonIgnoreProperties(ignoreUnknown = true) public class ConversationMessageMetadata { private ConversationSenderMetadata sender; diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationSenderMetadata.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationSenderMetadata.java index d7f60b9f..b7fdcbb0 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationSenderMetadata.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationSenderMetadata.java @@ -1,5 +1,7 @@ package com.messagebird.objects.conversations; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + /** * Metadata about the sender of a WhatsApp message. {@code userId} always * contains the BSUID (e.g. "US.13491208655302741918") when Meta supplies one. @@ -12,6 +14,7 @@ * present for accounts enrolled in Meta's parent-BSUID rollout; for everyone * else it stays {@code null}. */ +@JsonIgnoreProperties(ignoreUnknown = true) public class ConversationSenderMetadata { private String userId; diff --git a/api/src/main/java/com/messagebird/objects/conversations/ConversationStatusMessageMetadata.java b/api/src/main/java/com/messagebird/objects/conversations/ConversationStatusMessageMetadata.java index 537ad7bb..47a4a8d1 100644 --- a/api/src/main/java/com/messagebird/objects/conversations/ConversationStatusMessageMetadata.java +++ b/api/src/main/java/com/messagebird/objects/conversations/ConversationStatusMessageMetadata.java @@ -1,5 +1,7 @@ package com.messagebird.objects.conversations; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + /** * The {@code messageMetadata} block delivered inside status webhook payloads * (e.g. {@code statusSent}, {@code statusDelivered}). Reflects the original @@ -18,6 +20,7 @@ * lives alongside this block, under {@code status.metadata.recipient} — see * {@link ConversationStatusMetadata}. */ +@JsonIgnoreProperties(ignoreUnknown = true) public class ConversationStatusMessageMetadata { private String id; diff --git a/api/src/test/java/com/messagebird/ConversationMessagesTest.java b/api/src/test/java/com/messagebird/ConversationMessagesTest.java index da670fca..beac543a 100644 --- a/api/src/test/java/com/messagebird/ConversationMessagesTest.java +++ b/api/src/test/java/com/messagebird/ConversationMessagesTest.java @@ -1,6 +1,5 @@ package com.messagebird; -import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.messagebird.exceptions.GeneralException; import com.messagebird.exceptions.NotFoundException; @@ -32,6 +31,13 @@ public class ConversationMessagesTest { private static final String JSON_STATUS_METADATA_WITHOUT_RECIPIENT = "{\"pricing\": {\"billable\": true,\"pricing_model\": \"CBP\",\"category\": \"utility\"},\"conversation\": {\"id\": \"a1b2c3d4\",\"origin\": {\"type\": \"utility\"}}}"; private static final String JSON_STATUS_METADATA_PARENT_ONLY = "{\"recipient\": {\"parentUserId\": \"US.ENT.11815799212886844830\"}}"; + /** + * The same payload as JSON_STATUS_MESSAGE_METADATA with an unrecognised key + * added at every nesting level, standing in for fields the platform adds + * after this SDK version ships. + */ + private static final String JSON_STATUS_MESSAGE_METADATA_UNKNOWN_FIELDS = "{\"id\": \"e5f6a7b8-c9d0-1234-ef01-23456789abcd\",\"from\": \"15551234567\",\"to\": \"US.13491208655302741918\",\"type\": \"text\",\"futureTopLevelField\": \"ignored\",\"content\": {\"text\": \"Hello! Your order has been shipped.\",\"futureContentField\": \"ignored\"},\"metadata\": {\"sender\": {\"userId\": \"US.13491208655302741918\",\"futureSenderField\": \"ignored\"},\"receivedAt\": \"0001-01-01T00:00:00Z\",\"futureMetadataField\": \"ignored\"}}"; + /** * Epsilon to use when checking two latitudes or longitudes for equality. */ @@ -211,6 +217,20 @@ public void testViewConversationMessageWithBsuidMetadata() throws GeneralExcepti assertEquals("US.ENT.11815799212886844830", sender.getParentUserId()); } + @Test + public void testStatusMessageMetadataToleratesUnknownFields() throws Exception { + // A plain mapper, and unknown keys at every level: webhook payload POJOs + // must not force consumers to disable FAIL_ON_UNKNOWN_PROPERTIES, and + // must survive fields the platform adds after this version ships. + ConversationStatusMessageMetadata md = new ObjectMapper().readValue( + JSON_STATUS_MESSAGE_METADATA_UNKNOWN_FIELDS, ConversationStatusMessageMetadata.class); + + assertEquals("e5f6a7b8-c9d0-1234-ef01-23456789abcd", md.getId()); + assertEquals("Hello! Your order has been shipped.", md.getContent().getText()); + assertEquals("US.13491208655302741918", md.getMetadata().getSender().getUserId()); + assertNotNull(md.getMetadata().getReceivedAt()); + } + @Test public void testStatusMetadataDeserializesRecipient() throws Exception { // A plain mapper: these payload POJOs must not require the caller to @@ -256,10 +276,7 @@ public void testStatusMetadataRecipientWithParentOnly() throws Exception { @Test public void testStatusMessageMetadataDeserializes() throws Exception { - ObjectMapper mapper = new ObjectMapper(); - mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); - - ConversationStatusMessageMetadata md = mapper.readValue( + ConversationStatusMessageMetadata md = new ObjectMapper().readValue( JSON_STATUS_MESSAGE_METADATA, ConversationStatusMessageMetadata.class); assertEquals("e5f6a7b8-c9d0-1234-ef01-23456789abcd", md.getId()); From 4f1152db6a4a2c267a8e06b4f5c2a78cfdf36b49 Mon Sep 17 00:00:00 2001 From: Chris Casey Date: Fri, 31 Jul 2026 12:08:06 +0100 Subject: [PATCH 516/516] chore(release): bump version to 6.4.0 Co-Authored-By: Claude Opus 5 --- api/pom.xml | 2 +- examples/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index d9c1f273..b64ee8b0 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ com.messagebird messagebird-api - 6.3.1 + 6.4.0 jar ${project.groupId}:${project.artifactId} diff --git a/examples/pom.xml b/examples/pom.xml index 9ffe9f18..cb9b7489 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.messagebird examples - 6.3.1 + 6.4.0 @@ -20,7 +20,7 @@ com.messagebird messagebird-api - 6.3.1 + 6.4.0 compile