diff options
Diffstat (limited to 'src/main')
-rw-r--r-- | src/main/java/com/juick/PushComponent.java | 163 | ||||
-rw-r--r-- | src/main/webapp/WEB-INF/juick.conf.example | 1 |
2 files changed, 91 insertions, 73 deletions
diff --git a/src/main/java/com/juick/PushComponent.java b/src/main/java/com/juick/PushComponent.java index 533ca086..4dd78286 100644 --- a/src/main/java/com/juick/PushComponent.java +++ b/src/main/java/com/juick/PushComponent.java @@ -32,6 +32,18 @@ import com.juick.xmpp.StreamComponent; import com.juick.xmpp.extensions.JuickMessage; import com.notnoop.apns.APNS; import com.notnoop.apns.ApnsService; +import org.apache.http.Consts; +import org.apache.http.Header; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import org.json.JSONObject; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; @@ -39,18 +51,12 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.net.HttpURLConnection; import java.net.Socket; -import java.net.URL; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; -import java.util.Properties; +import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.logging.Level; @@ -66,6 +72,7 @@ public class PushComponent implements ServletContextListener, Stream.StreamListe private static Logger logger = Logger.getLogger(PushComponent.class.getName()); private ExecutorService executorService; + String wns_application_sip; String wns_client_secret; Connection sql; Socket socket; @@ -90,6 +97,7 @@ public class PushComponent implements ServletContextListener, Stream.StreamListe conf.getProperty("mysql_password", ""), conf.getProperty("mysql_database", "")); setupXmppComponent(new JID("", conf.getProperty("push_jid"), ""), conf.getProperty("xmpp_host", "localhost"), Integer.parseInt(conf.getProperty("xmpp_port", "5347")), conf.getProperty("push_xmpp_password", "")); + wns_application_sip = conf.getProperty("wns_application_sip", ""); wns_client_secret = conf.getProperty("wns_client_secret", ""); } catch (IOException e) { logger.log(Level.SEVERE, e.getMessage(), e); @@ -232,35 +240,40 @@ public class PushComponent implements ServletContextListener, Stream.StreamListe urls = PushQueries.getWinPhoneSubscribers(sql, senderID); } - if (!urls.isEmpty()) { - String text1 = "@" + jmsg.getUser().getUName(); - if (!jmsg.Tags.isEmpty()) { - text1 += ":" + XmlUtils.escape(jmsg.getTagsString()); - } - String text2 = XmlUtils.escape(jmsg.getText()); - String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" - + "<toast>" - + "<visual>" - + "<binding template=\"ToastText02\">" - + "<text id=\"1\">" + text1 + "</text>" - + "<text id=\"2\">" + text2 + "</text>" - //+ "<image id=\"3\" src=\"http://i.juick.com/as/" + jmsg.User.UID + ".png\" />" // todo: user avatar - + "</binding>" - + "</visual>" - + "<commands>" - + "<command arguments=\"?mid=" + jmsg.getMID() + "\" />" - + "</commands>" - + "</toast>"; - logger.fine(xml); - for (int i = 0; i < urls.size(); i++) { - String url = urls.get(i); - logger.info("WNS: " + url); - sendWNS(url, xml); - } - } else { + + if (urls.isEmpty()) { logger.info("WNS: no recipients"); + } else { + try { + String wnsToken = getWnsAccessToken(); + String text1 = "@" + jmsg.getUser().getUName(); + if (!jmsg.Tags.isEmpty()) { + text1 += ":" + XmlUtils.escape(jmsg.getTagsString()); + } + String text2 = XmlUtils.escape(jmsg.getText()); + String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + + "<toast>" + + "<visual>" + + "<binding template=\"ToastText02\">" + + "<text id=\"1\">" + text1 + "</text>" + + "<text id=\"2\">" + text2 + "</text>" + //+ "<image id=\"3\" src=\"http://i.juick.com/as/" + jmsg.User.UID + ".png\" />" // todo: user avatar + + "</binding>" + + "</visual>" + + "<commands>" + + "<command arguments=\"?mid=" + jmsg.getMID() + "\" />" + + "</commands>" + + "</toast>"; + logger.fine(xml); + for (int i = 0; i < urls.size(); i++) { + String url = urls.get(i); + logger.info("WNS: " + url); + sendWNS(wnsToken, url, xml); + } + } catch (IOException e) { + logger.log(Level.SEVERE, "WNS: ", e); + } } - /*** iOS ***/ List<String> tokens; @@ -286,48 +299,52 @@ public class PushComponent implements ServletContextListener, Stream.StreamListe } } - public boolean sendWNS(String url, String xml) { - boolean ret = false; - try { - HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); - conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8"); - String token = "Bearer " + wns_client_secret; - conn.setRequestProperty("Authorization", token); - conn.setRequestProperty("X-WNS-Type", "wns/toast"); // todo: mb use "wns/badge" or "wns/tile" - conn.setUseCaches(false); - conn.setDoInput(true); - conn.setDoOutput(true); - conn.setRequestMethod("POST"); - conn.connect(); - - OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream()); - wr.write(xml); - wr.close(); - - if (conn.getResponseCode() == 200) { - ret = streamToString(conn.getInputStream()) != null; - } - - conn.disconnect(); - } catch (Exception e) { - logger.log(Level.SEVERE, "sendWNS error: ", e); + String getWnsAccessToken() throws IOException { + HttpClient client = HttpClientBuilder.create().build(); + String url = "https://login.live.com/accesstoken.srf"; + List<NameValuePair> formParams = new ArrayList<NameValuePair>(); + formParams.add(new BasicNameValuePair("grant_type", "client_credentials")); + formParams.add(new BasicNameValuePair("client_id", wns_application_sip)); + formParams.add(new BasicNameValuePair("client_secret", wns_client_secret)); + formParams.add(new BasicNameValuePair("scope", "notify.windows.com")); + UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, Consts.UTF_8); + HttpPost httppost = new HttpPost(url); + httppost.setEntity(entity); + HttpResponse response = client.execute(httppost); + int statusCode = response.getStatusLine().getStatusCode(); + String responseContent = EntityUtils.toString(response.getEntity(), Consts.UTF_8); + JSONObject json = new JSONObject(responseContent); + if(statusCode != 200) { + throw new IOException(json.opt("error") + ": " + json.opt("error_description")); } - return ret; + String tokenType = (String)json.get("token_type"); + if(tokenType.length() >= 1) { + tokenType = Character.toUpperCase(tokenType.charAt(0)) + tokenType.substring(1); + } + return tokenType + " " + json.get("access_token"); } - public String streamToString(InputStream is) { - try { - BufferedReader buf = new BufferedReader(new InputStreamReader(is)); - StringBuilder str = new StringBuilder(); - String line; - do { - line = buf.readLine(); - str.append(line).append("\n"); - } while (line != null); - return str.toString(); - } catch (Exception e) { - logger.severe("streamToString: " + e.toString()); + void sendWNS(String wnsToken, String url, String xml) throws IOException { + HttpClient client = HttpClientBuilder.create().build(); + StringEntity entity = new StringEntity(xml, Consts.UTF_8); + HttpPost httpPost = new HttpPost(url); + httpPost.setHeader("Content-Type", "text/xml"); + httpPost.setHeader("Authorization", wnsToken); + httpPost.setHeader("X-WNS-Type", "wns/toast"); + httpPost.setEntity(entity); + HttpResponse response = client.execute(httpPost); + int statusCode = response.getStatusLine().getStatusCode(); + if(statusCode != 200) { + String headersContent = stringifyWnsHttpHeaders(response.getAllHeaders()); + throw new IOException(headersContent); } - return null; + } + + static String stringifyWnsHttpHeaders(Header[] allHeaders) { + String[] wnsHeaders = Arrays.stream(allHeaders) + .filter(x -> x.getName().startsWith("X-WNS-") || x.getName().startsWith("WWW-")) + .map(x -> x.getName() + ": " + x.getValue()) + .toArray(String[]::new); + return String.join("\n", wnsHeaders); } } diff --git a/src/main/webapp/WEB-INF/juick.conf.example b/src/main/webapp/WEB-INF/juick.conf.example index 8c897f3a..c0812b61 100644 --- a/src/main/webapp/WEB-INF/juick.conf.example +++ b/src/main/webapp/WEB-INF/juick.conf.example @@ -1,4 +1,5 @@ mysql_username=username
xmpp_password=secret
sape_user=usertoken
+wns_application_sip=ms-app://x-1-11-1-1111111111-...
wns_client_secret=secret
\ No newline at end of file |