diff --git a/README.md b/README.md new file mode 100644 index 0000000..be98c15 --- /dev/null +++ b/README.md @@ -0,0 +1,46 @@ +## @cmdotcom/text-sdk: A helper library to send messages. + +Want to send messages in your Java application? Then you are at the right place. +If you want to get all the functionalities, go to: [CM.com API Docs](https://docs.cmtelecom.com/bulk-sms/v1.0) + + +## Installing + +Add the jar file to your project. + +## Instantiate the client +Use your productToken which authorizes you on the CM platform. Get yours on CM.com + +```cs +MessagingClient client = new MessagingClient("YourproductToken"); +``` + +## Send a message +By calling `SendTextMessage` and providing message text, sender name, recipient phone number(s). + +```cs + MessagingClient client = new MessagingClient("YourProductToken"); + client.sendTextMessage("Message Text", "TestSender", new String[] {"00316012345678"}); + +``` + + +## Sending a rich message +By using the `MessageBuilder` it is possible to create images with media for channels such as WhatsApp and Viber +```cs + MessagingClient client = new MessagingClient("YourProductToken"); + + MessageBuilder builder = new MessageBuilder("Message Text", "TestSender", new String[] {"00316012345678"}); + + builder.WithAllowedChannels(new Channel[] {Channel.Viber}); + + builder.WithRichMessage(new MediaMessage( + "cm.com", + "https://avatars3.githubusercontent.com/u/8234794?s=200&v=4", + "image/png")); + + + Message message = builder.Build(); + + client.sendMessage(message); +``` \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..91a3038 --- /dev/null +++ b/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + text-sdk-java + text-sdk-java + 1.0-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + + 7 + 7 + + + + + + + com.google.code.gson + gson + 2.8.5 + + + \ No newline at end of file diff --git a/src/main/java/Config.java b/src/main/java/Config.java new file mode 100644 index 0000000..0f86337 --- /dev/null +++ b/src/main/java/Config.java @@ -0,0 +1,4 @@ +public class Config { + + public static String ApiUrl = "https://gw.cmtelecom.com/v1.0/message"; +} diff --git a/src/main/java/MessageBuilder.java b/src/main/java/MessageBuilder.java new file mode 100644 index 0000000..3bb42f0 --- /dev/null +++ b/src/main/java/MessageBuilder.java @@ -0,0 +1,107 @@ +import models.Body; +import models.Channel; +import models.Message; +import models.Recipient; +import models.multichannel.IRichMessage; +import models.multichannel.RichContent; +import models.multichannel.Suggestion; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class MessageBuilder { + + private Message message; + private RichContent richContent; + + + /// + /// Creates a new MessageBuilder + /// + /// + /// + /// + public MessageBuilder(String messageText, String from,String[] to) + { + List recipientList = new ArrayList<>(); + for (String number : to) { + Recipient r = new Recipient(); + r.Number = number; + recipientList.add(r); + + } + + this.message = new Message(new Body(messageText), from, recipientList); + + } + + + /// + /// Constructs the message. + /// + /// + public Message Build() + { + this.message.RichContent = this.richContent; + return this.message; + } + + /// + /// Adds the allowed channels field, which forces a message to only use certain routes. + /// You can define a list of which channels you want your message to use. + /// Not defining any channels will be interpreted as allowing all channels. + /// + /// + /// Note that for channels other than SMS, CM needs to configure the out going flows. + /// For those flows to work, we need to be contacted. + /// + public MessageBuilder WithAllowedChannels(Channel[] channels) + { + this.message.AllowedChannels = channels; + return this; + } + + /// + /// Add a reference to the message. + /// + /// + /// + public MessageBuilder WithReference(String reference) + { + this.message.Reference = reference; + return this; + } + + /// + /// Adds a message that replaces the for channels that support + /// rich content (all channels except , + /// and at this moment) + /// + /// + /// + public MessageBuilder WithRichMessage(IRichMessage richMessage) + { + if (this.richContent == null) + this.richContent = new RichContent(); + + this.richContent.AddConversationPart(richMessage); + return this; + } + + /// + /// Adds suggestions to the message. It is dependent on the channel that is used which + /// suggestions are supported. + /// + /// + /// + public MessageBuilder WithSuggestions(Suggestion[] suggestions) + { + if (this.richContent == null) + this.richContent = new RichContent(); + + this.richContent.Suggestions = suggestions; + return this; + } + +} diff --git a/src/main/java/MessagingClient.java b/src/main/java/MessagingClient.java new file mode 100644 index 0000000..ef0f413 --- /dev/null +++ b/src/main/java/MessagingClient.java @@ -0,0 +1,69 @@ +import com.google.gson.Gson; +import models.Channel; +import models.Message; +import models.Request; + +import utils.HttpHelper; + +import java.util.ArrayList; +import java.util.List; + +public class MessagingClient { + + private String productToken; + + public MessagingClient(String productToken){ + this.productToken = productToken; + } + + + public void sendTextMessage(String messageText, String from,String[] to){ + + try{ + MessageBuilder builder = new MessageBuilder(messageText,from, to); + + Message message = builder.Build(); + + String body = GetHttpPostBody(productToken, message); + + HttpHelper.post(Config.ApiUrl, body); + } + + catch (Exception e){ + System.out.println("Please check your request body."); + } + } + + + public void sendMessage(Message message) { + + try{ + String body = GetHttpPostBody(productToken, message); + + HttpHelper.post(Config.ApiUrl, body); + } + + catch (Exception e ){ + System.out.println("Please check your request body."); + } + } + + + /// + /// Gets the HTTP post body. + /// + /// The API key. + /// The message to send. + /// + protected static String GetHttpPostBody(String productToken, Message message) + { + Request.Messages messages = new Request.Messages(); + Request.MessagesEnvelope request = new Request.MessagesEnvelope(); + request.setAuthentication(new Request.Authentication(productToken)); + Message[] msg = new Message[]{message}; + request.setMessages(msg); + messages.setMessages(request); + return new Gson().toJson(messages); + } + +} diff --git a/src/main/java/models/Body.java b/src/main/java/models/Body.java new file mode 100644 index 0000000..d969e65 --- /dev/null +++ b/src/main/java/models/Body.java @@ -0,0 +1,38 @@ +package models; + +import com.google.gson.annotations.SerializedName; + +public class Body { + + /// + /// The actual text body of the message. + /// By default the CM gateway interprets messages as if sent with the standard 7 bit GSM encoding. + /// If you want to send messages using e.g. Arabic, Cyrillic of Greek characters + /// you will need to use the unicode UCS2 encoding. + /// Set the to Auto to let the gateway do the encoding detection. + /// Please note that there are a few limitations to using unicode encoded messages: + /// Unicode messages can contain up to 70 characters. In the case of multipart messages, this becomes 66 characters per + /// part. + /// You will need to POST the XML or JSON file. A HTTP GET request cannot handle the Unicode characters + /// Another note is that not all operators in the world are able to handle Unicode messages, so you will need to test + /// for which operators it works. + /// + @SerializedName("content") + public String Content; + + /// + /// When the type is set to 'auto' then the gateway will do the encoding detection. + /// In case it detects characters that are not part of the GSM character set, + /// the message will be delivered as Unicode. + /// If the message contains more than 70 characters in Unicode format it will be split into a + /// multipart message. + /// You can limit the number of parts by setting the maximum number of message parts. + /// + /// + @SerializedName("type") + public String Type; + + public Body(String content) { + this.Content = content; + } +} diff --git a/src/main/java/models/Channel.java b/src/main/java/models/Channel.java new file mode 100644 index 0000000..05813ba --- /dev/null +++ b/src/main/java/models/Channel.java @@ -0,0 +1,64 @@ +package models; + +public enum Channel { + /// + /// Messages will be sent as SMS text messages + /// + SMS, + + /// + /// Send messages using WhatsApp for business + /// + /// + /// Note that CM needs to configure this for you to work. + /// + WhatsApp, + + /// + /// Sends messages to push using Hybrid messages. + /// See also https://docs.cmtelecom.com/en/hybrid-messaging/v2.0.0 + /// + /// Works only when is set + Push, + + /// + /// Messages will be sent over RCS. + /// + /// + /// Note that CM needs to configure this for you to work. + /// + RCS, + + /// + /// Messages will be sent over Viber. + /// + /// + /// Note that CM needs to configure this for you to work. + /// + Viber, + + /// + /// Messages will be sent using text to speech. + /// + /// + /// Note that CM needs to configure this for you to work. + /// + Voice, + + /// + /// Messages will be sent over Apple Business Chat. + /// + /// + /// Note that CM needs to configure this for you to work. + /// + // ReSharper disable once InconsistentNaming + iMessage, + + /// + /// Messages will be sent over Line. + /// + /// + /// Note that CM needs to configure this for you to work. + /// + Line +} \ No newline at end of file diff --git a/src/main/java/models/Message.java b/src/main/java/models/Message.java new file mode 100644 index 0000000..e533c94 --- /dev/null +++ b/src/main/java/models/Message.java @@ -0,0 +1,124 @@ +package models; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +public class Message { + /// + /// The allowed channels field forces a message to only use certain routes. + /// In this field you can define a list of which channels you want your message to use. + /// Not defining any channels will be interpreted as allowing all channels. + /// + /// + /// Note that for channels other than SMS, CM needs to configure the out going flows. + /// For those flows to work, we need to be contacted. + /// + @SerializedName("allowedChannels") + public Channel[] AllowedChannels; + + /// + /// Required: The actual text body of the message. + /// + @SerializedName("body") + public Body Body ; + + /// + /// The custom grouping field is an optional field that can be used to tag messages. + /// These tags are be used by CM products, like the Transactions API. + /// Applying custom grouping names to messages helps filter your messages. + /// With up to three levels of custom grouping fields that can be set, subsets of messages can be + /// further broken down. The custom grouping name can be up to 100 characters of your choosing. + /// It’s recommended to limit the number of unique custom groupings to 1000. + /// Please contact support in case you would like to exceed this number. + /// + @SerializedName("customGrouping") + public String CustomGrouping; + + /// + /// The custom grouping2 field, like is an optional field that can be used to tag + /// messages. + /// These tags are be used by CM products, like the Transactions API. + /// Applying custom grouping names to messages helps filter your messages. + /// With up to three levels of custom grouping fields that can be set, subsets of messages can be + /// further broken down. The custom grouping name can be up to 100 characters of your choosing. + /// It’s recommended to limit the number of unique custom groupings to 1000. + /// Please contact support in case you would like to exceed this number. + /// + @SerializedName("customGrouping2") + public String CustomGrouping2; + + /// + /// The custom grouping3 field, like and is an optional + /// field that can be used to tag messages. + /// These tags are be used by CM products, like the Transactions API. + /// Applying custom grouping names to messages helps filter your messages. + /// With up to three levels of custom grouping fields that can be set, subsets of messages can be + /// further broken down. The custom grouping name can be up to 100 characters of your choosing. + /// It’s recommended to limit the number of unique custom groupings to 1000. + /// Please contact support in case you would like to exceed this number. + /// + /// Default value within this SDK is + @SerializedName("customGrouping3") + public String CustomGrouping3; + + /// + /// Required: This is the sender name. + /// The maximum length is 11 alphanumerical characters or 16 digits. Example: 'CM Telecom' + /// + @SerializedName("from") + public String From; + + + + /// + /// Used when sending multipart or concatenated SMS messages and always used together with + /// . + /// Indicate the minimum and maximum of message parts that you allow the gateway to send for this + /// message. + /// Technically the gateway will first check if a message is larger than 160 characters, if so, the + /// message will be cut into multiple 153 characters parts limited by these parameters. + /// + @SerializedName("maximumNumberOfMessageParts") + public Integer MaximumNumberOfMessageParts; + + /// + /// Used when sending multipart or concatenated SMS messages and always used together with + /// . + /// Indicate the minimum and maximum of message parts that you allow the gateway to send for this + /// message. + /// Technically the gateway will first check if a message is larger than 160 characters, if so, the + /// message will be cut into multiple 153 characters parts limited by these parameters. + /// + @SerializedName("minimumNumberOfMessageParts") + public Integer MinimumNumberOfMessageParts; + + /// + /// Required: The destination mobile numbers. + /// This value should be in international format. + /// A single mobile number per request. Example: '00447911123456' + /// + @SerializedName("to") + public List Recipients; + + /// + /// Optional: For each message you send, you can set a reference. + /// The given reference will be used in the status reports and MO replies for the message, + /// so you can link the messages to the sent batch. + /// For more information on status reports, see: + /// https://docs.cmtelecom.com/business-messaging/v1.0#/status_report_webhook + /// The given reference must be between 1 - 32 alphanumeric characters, and will not work using demo accounts. + /// + @SerializedName("reference") + public String Reference; + + + public models.multichannel.RichContent RichContent; + + + public Message(Body body, String from, List recipientList) { + this.Body = body; + this.From = from; + this.Recipients = recipientList; + } +} diff --git a/src/main/java/models/Recipient.java b/src/main/java/models/Recipient.java new file mode 100644 index 0000000..0c0c56b --- /dev/null +++ b/src/main/java/models/Recipient.java @@ -0,0 +1,14 @@ +package models; + +import com.google.gson.annotations.SerializedName; + +public class Recipient { + + /// + /// This value should be in international format. + /// A single mobile number per request. Example: '00447911123456' + /// + @SerializedName("number") + public String Number; +} + diff --git a/src/main/java/models/Request.java b/src/main/java/models/Request.java new file mode 100644 index 0000000..17076e7 --- /dev/null +++ b/src/main/java/models/Request.java @@ -0,0 +1,64 @@ +package models; + +import com.google.gson.annotations.SerializedName; + +public class Request { + + public static class Messages + { + @SerializedName("messages") + private MessagesEnvelope messages; + + public MessagesEnvelope getMessages() { + return messages; + } + + public void setMessages(MessagesEnvelope messages) { + this.messages = messages; + } + } + + public static class MessagesEnvelope + { + @SerializedName("authentication") + private Authentication Authentication ; + + @SerializedName("msg") + private Message[] Messages ; + + public Message[] getMessages() { + return Messages; + } + + public void setMessages(Message[] messages) { + Messages = messages; + } + + public Request.Authentication getAuthentication() { + return Authentication; + } + + public void setAuthentication(Request.Authentication authentication) { + Authentication = authentication; + } + } + + public static class Authentication + { + @SerializedName("producttoken") + private String ProductToken ; + + public String getProductToken() { + return ProductToken; + } + + public void setProductToken(String productToken) { + ProductToken = productToken; + } + + public Authentication(String productToken) + { + this.ProductToken = productToken; + } + } +} diff --git a/src/main/java/models/multichannel/Carousel.java b/src/main/java/models/multichannel/Carousel.java new file mode 100644 index 0000000..bdacca5 --- /dev/null +++ b/src/main/java/models/multichannel/Carousel.java @@ -0,0 +1,17 @@ +package models.multichannel; + +import com.google.gson.annotations.SerializedName; + +public class Carousel { + /// + /// The cards of the carousel + /// + @SerializedName("cards") + public RichCard[] Cards; + + /// + /// The width for the items of the carousel + /// + @SerializedName("cardWidth") + public CarouselCardWidth CarouselCardWidth; +} diff --git a/src/main/java/models/multichannel/CarouselCardWidth.java b/src/main/java/models/multichannel/CarouselCardWidth.java new file mode 100644 index 0000000..56b11bf --- /dev/null +++ b/src/main/java/models/multichannel/CarouselCardWidth.java @@ -0,0 +1,13 @@ +package models.multichannel; + +public enum CarouselCardWidth { + /// + /// Small cards + /// + Small, + + /// + /// Medium sized cards + /// + Medium +} diff --git a/src/main/java/models/multichannel/Dial.java b/src/main/java/models/multichannel/Dial.java new file mode 100644 index 0000000..9973e97 --- /dev/null +++ b/src/main/java/models/multichannel/Dial.java @@ -0,0 +1,11 @@ +package models.multichannel; + +import com.google.gson.annotations.SerializedName; + +public class Dial { + /// + /// The number to call (in international format) + /// + @SerializedName("phoneNumber") + public String PhoneNumber; +} diff --git a/src/main/java/models/multichannel/DialSuggestion.java b/src/main/java/models/multichannel/DialSuggestion.java new file mode 100644 index 0000000..32c23c8 --- /dev/null +++ b/src/main/java/models/multichannel/DialSuggestion.java @@ -0,0 +1,22 @@ +package models.multichannel; + +import com.google.gson.annotations.SerializedName; + +/// +/// A suggestion, used in +/// When you want to enable the user can call you, or listen to a recorded spoken message, +/// this suggestion can be applied. When clicked starts a new call. +/// +public class DialSuggestion extends Suggestion { + + /// + /// The dial options + /// + @SerializedName("dial") + public Dial Dial; + + public DialSuggestion(Dial dial) { + this.Action = "reply"; + this.Dial = dial; + } +} diff --git a/src/main/java/models/multichannel/IRichMessage.java b/src/main/java/models/multichannel/IRichMessage.java new file mode 100644 index 0000000..611abd3 --- /dev/null +++ b/src/main/java/models/multichannel/IRichMessage.java @@ -0,0 +1,4 @@ +package models.multichannel; + +public interface IRichMessage { +} diff --git a/src/main/java/models/multichannel/MediaContent.java b/src/main/java/models/multichannel/MediaContent.java new file mode 100644 index 0000000..75beaf9 --- /dev/null +++ b/src/main/java/models/multichannel/MediaContent.java @@ -0,0 +1,39 @@ +package models.multichannel; + +public class MediaContent { + /// + /// The name of the image, audio or video. + /// + public String MediaName; + + /// + /// The location of the image, audio or video. + /// + public String MediaUri; + + /// + /// The mimetype of the image, audio or video. + /// + public String MimeType; + + /// + /// Default constructor + /// + public MediaContent() + { + } + + /// + /// Constructor which sets values + /// + /// + /// + /// + public MediaContent(String mediaName, String mediaUri, String mimeType) + { + this.MediaName = mediaName; + this.MediaUri = mediaUri; + this.MimeType = mimeType; + } + +} diff --git a/src/main/java/models/multichannel/MediaMessage.java b/src/main/java/models/multichannel/MediaMessage.java new file mode 100644 index 0000000..a002ff8 --- /dev/null +++ b/src/main/java/models/multichannel/MediaMessage.java @@ -0,0 +1,29 @@ +package models.multichannel; + +import com.google.gson.annotations.SerializedName; + +public class MediaMessage implements IRichMessage { + /// + /// Default constructor. + /// + public MediaMessage() + { + } + + /// + /// Constructor setting values. + /// + /// + /// + /// + public MediaMessage(String mediaName, String mediaUri, String mimeType) + { + this.Media = new MediaContent(mediaName, mediaUri, mimeType); + } + + /// + /// The image or video of the message. + /// + @SerializedName("media") + public MediaContent Media; +} diff --git a/src/main/java/models/multichannel/OpenUrlSuggestion.java b/src/main/java/models/multichannel/OpenUrlSuggestion.java new file mode 100644 index 0000000..45279c9 --- /dev/null +++ b/src/main/java/models/multichannel/OpenUrlSuggestion.java @@ -0,0 +1,20 @@ +package models.multichannel; + +import com.google.gson.annotations.SerializedName; + +public class OpenUrlSuggestion extends Suggestion { + /// + /// The url of this suggestion + /// + @SerializedName("url") + public String Url; + + + public OpenUrlSuggestion( String label, String url) + { + this.Action = "openUrl"; + this.Label = label; + this.Url = url; + } + +} diff --git a/src/main/java/models/multichannel/ReplySuggestion.java b/src/main/java/models/multichannel/ReplySuggestion.java new file mode 100644 index 0000000..5411fdd --- /dev/null +++ b/src/main/java/models/multichannel/ReplySuggestion.java @@ -0,0 +1,18 @@ +package models.multichannel; + +import com.google.gson.annotations.SerializedName; + +public class ReplySuggestion extends Suggestion { + + /// + /// When the item is selected and the postback data is set, then the Postback data will be + /// sent in a MO instead of the . + /// + @SerializedName("postbackData") + public String PostbackData; + + public ReplySuggestion(String postbackData) { + this.Action = "reply"; + this.PostbackData = postbackData; + } +} diff --git a/src/main/java/models/multichannel/RichCard.java b/src/main/java/models/multichannel/RichCard.java new file mode 100644 index 0000000..7ddc4e4 --- /dev/null +++ b/src/main/java/models/multichannel/RichCard.java @@ -0,0 +1,17 @@ +package models.multichannel; + +import com.google.gson.annotations.SerializedName; + +public class RichCard extends TextMessage{ + // + /// Optional: the header for a rich card + /// + @SerializedName("header") + public String Header; + + /// + /// The image or video of the card. + /// + @SerializedName("media") + public MediaContent Media; +} diff --git a/src/main/java/models/multichannel/RichContent.java b/src/main/java/models/multichannel/RichContent.java new file mode 100644 index 0000000..ce7fb9d --- /dev/null +++ b/src/main/java/models/multichannel/RichContent.java @@ -0,0 +1,62 @@ +package models.multichannel; + +import com.google.gson.annotations.SerializedName; + +import java.util.Arrays; + +public class RichContent { + /// + /// Initializes a rich content object + /// + public RichContent() + { + this.Conversation = null; + this.Suggestions = null; + } + + /// + /// The messages. + /// + @SerializedName("conversation") + public IRichMessage[] Conversation ; + + /// + /// The suggestions + /// + @SerializedName("suggestions") + public Suggestion[] Suggestions; + + /// + /// Adds a message, such as a or . + /// + /// + public void AddConversationPart(IRichMessage part) + { + if (this.Conversation == null) + this.Conversation = new IRichMessage[] {part}; + else + { + IRichMessage[] newArr = this.Conversation; + Arrays.copyOf(newArr, this.Conversation.length + 1 ); + newArr[newArr.length - 1] = part; + this.Conversation = newArr; + } + } + + /// + /// Adds a suggestion + /// + /// + public void AddSuggestion(Suggestion suggestion) + { + if (this.Suggestions == null) + this.Suggestions = new Suggestion[] {suggestion}; + else + { + Suggestion[] newArr = this.Suggestions; + Arrays.copyOf(newArr, this.Conversation.length + 1 ); + newArr[newArr.length - 1] = suggestion; + this.Suggestions = newArr; + } + } +} diff --git a/src/main/java/models/multichannel/Suggestion.java b/src/main/java/models/multichannel/Suggestion.java new file mode 100644 index 0000000..e383213 --- /dev/null +++ b/src/main/java/models/multichannel/Suggestion.java @@ -0,0 +1,18 @@ +package models.multichannel; + +import com.google.gson.annotations.SerializedName; + + +public abstract class Suggestion { + /// + /// The action of this suggestion + /// + @SerializedName("action") + public String Action; + + /// + /// The text the end user will see + /// + @SerializedName("label") + public String Label; +} diff --git a/src/main/java/models/multichannel/TextMessage.java b/src/main/java/models/multichannel/TextMessage.java new file mode 100644 index 0000000..65611be --- /dev/null +++ b/src/main/java/models/multichannel/TextMessage.java @@ -0,0 +1,27 @@ +package models.multichannel; + +import com.google.gson.annotations.SerializedName; + +public class TextMessage implements IRichMessage{ + /// + /// Construct an empty text message. + /// + public TextMessage() + { + } + + /// + /// Construct a text message and initialise the + /// + /// + public TextMessage(String text) + { + this.Text = text; + } + + /// + /// The text to display. + /// + @SerializedName("text") + public String Text; +} diff --git a/src/main/java/models/multichannel/ViewLocationOptions.java b/src/main/java/models/multichannel/ViewLocationOptions.java new file mode 100644 index 0000000..fe4663d --- /dev/null +++ b/src/main/java/models/multichannel/ViewLocationOptions.java @@ -0,0 +1,35 @@ +package models.multichannel; + +import com.google.gson.annotations.SerializedName; + +public class ViewLocationOptions { + /// + /// Optional: The label to display at the pin + /// + @SerializedName("label") + public String Label; + + /// + /// The latitude in degrees + /// + /// 51.603802 + /// Either Latitude and or is required + @SerializedName("latitude") + public String Latitude; + + /// + /// The longitude in degrees + /// + /// 4.770821 + /// Either and Longitude or is required + @SerializedName("longitude") + public String Longitude; + + /// + /// Search for this location instead of using the latitude/longitude. + /// + /// Either and or SearchQuery is required + @SerializedName("searchQuery") + public String SearchQuery; +} + diff --git a/src/main/java/models/multichannel/ViewLocationSuggestion.java b/src/main/java/models/multichannel/ViewLocationSuggestion.java new file mode 100644 index 0000000..49722b0 --- /dev/null +++ b/src/main/java/models/multichannel/ViewLocationSuggestion.java @@ -0,0 +1,18 @@ +package models.multichannel; + +import com.google.gson.annotations.SerializedName; + +public class ViewLocationSuggestion extends Suggestion { + + + /// + /// The location options + /// + @SerializedName("location") + private ViewLocationOptions locationOptions; + + public ViewLocationSuggestion(ViewLocationOptions locationOptions) { + this.Action = "CreateCalendarEvent"; + this.locationOptions = locationOptions; + } +} diff --git a/src/main/java/utils/HttpHelper.java b/src/main/java/utils/HttpHelper.java new file mode 100644 index 0000000..978b918 --- /dev/null +++ b/src/main/java/utils/HttpHelper.java @@ -0,0 +1,56 @@ +package utils; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.InputStreamReader; +import java.net.ConnectException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; + +public class HttpHelper { + private static String sendRequest(String method, String url, String data) { + try { + + URL obj = new URL(url); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + + //add request header + con.setRequestMethod(method); + + con.setRequestProperty("Content-Type", "application/json"); + + System.out.println(data); + + if (data != null) { + // Send request + con.setDoOutput(true); + try (DataOutputStream wr = new DataOutputStream(con.getOutputStream())) { + wr.writeBytes(data); + } + } + + StringBuilder response = new StringBuilder(); + try (BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()))) { + String inputLine; + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + } + + return response.toString(); + } catch (ConnectException ce) { + System.out.println(ce.getMessage()); + return ce.toString(); + } catch (Exception e) { + e.printStackTrace(); + return e.toString(); + } + } + + // HTTP POST request + public static String post(String url, String urlParameters) { + return sendRequest("POST", url, urlParameters); + } + +} diff --git a/text-sdk-java.iml b/text-sdk-java.iml new file mode 100644 index 0000000..a7abcd5 --- /dev/null +++ b/text-sdk-java.iml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file