/******************************************************************************* * Copyright (c) 2013 Hani Naguib. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * * Contributors: * Hani Naguib - initial API and implementation ******************************************************************************/ package com.gvmax.server.handlers; import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import com.gvmax.common.model.Email; import com.gvmax.common.model.Stats; import com.gvmax.common.model.User; import com.gvmax.common.relay.GVMaxRelay; import com.gvmax.common.util.MiscUtils; import com.gvmax.common.util.PhoneUtil; import com.gvmax.common.util.TinyURL; import com.gvmax.data.user.UserDAO; import com.gvmax.server.util.ContactUtil; import com.gvmax.server.util.Notifier; public class VoicemailHandler { private static final Logger logger = Logger.getLogger(VoicemailHandler.class); private UserDAO userDAO; private GVMaxRelay relay; private User user; private Voicemail vm; public VoicemailHandler(UserDAO userDAO, GVMaxRelay relay) { this.userDAO = userDAO; this.relay = relay; } public void handle(Email email) { extractInfo(email); if (user == null) { logger.debug("Unable to retrieve user from email: " + email.getTo()); return; } if (vm == null) { logger.debug("Unable to retrieve voicemail from email"); return; } if (!user.isMonitorVM()) { return; } userDAO.incrementVMInCount(user.getEmail()); Notifier notifier = new Notifier(user, userDAO, relay); // Send notifications if (user.isSendProwl()) { String text = "Transcript: " + vm.transcript + "\nLink: " + vm.link; try { notifier.sendProwlNotification("GV VM", vm.contact, text, user.getProwlVMPriority()); } catch (IOException e) { MiscUtils.emptyBlock(); } } if (user.isSendHowl()) { String text = "Transcript: " + vm.transcript + "\nLink: " + vm.link; try { notifier.sendHowlNotification("GV VM", vm.contact, text); } catch (IOException e) { MiscUtils.emptyBlock(); } } if (user.isSendEmail()) { String text = vm.transcript + "\nLink: " + vm.link; notifier.sendEmailNotification(vm.number, "New Voicemail from " + vm.contact, text); } if (user.isSendSMS()) { notifier.sendSMSNotification(vm.number, "vm:" + vm.transcript); } if (user.isSendPost()) { notifier.sendPostNotification("VM", vm.number, vm.contact, vm.transcript, vm.link); } if (user.isSendTwitter()) { notifier.sendTwitterNotification("VM from " + vm.contact + " - " + vm.transcript + " : " + vm.link); } if (user.isSendAutoResponse()) { notifier.sendAutoResponse(vm.number); } if (user.isSendGTalk()) { boolean sent = notifier.sendGTalkNotification(vm.number, vm.contact, "Transcript: " + vm.transcript + "\nLink: " + vm.link); if (sent) { userDAO.clearFallbackCount(user.getEmail()); } if (!sent && notifier.canFallback()) { if (!StringUtils.isBlank(user.getProwlApiKeys())) { String text = "Transcript: " + vm.transcript + "\nLink: " + vm.link; try { logger.warn("Attempting to fallback to prowl"); notifier.sendProwlNotification("GV VM", vm.contact, text, user.getProwlVMPriority()); return; } catch (IOException e) { MiscUtils.emptyBlock(); } } if (!StringUtils.isBlank(user.getHowlUsername())) { String text = "Transcript: " + vm.transcript + "\nLink: " + vm.link; try { logger.warn("Attempting to fallback to howl"); notifier.sendHowlNotification("GV VM", vm.contact, text); return; } catch (IOException e) { MiscUtils.emptyBlock(); } } Stats stats = userDAO.getStats(user.getEmail()); if (stats == null) { logger.error("unable to find stats for user: "+user.getEmail()); return; } logger.warn("Attempting to fallback to email: fbc=" + stats.getFallbackCount()); userDAO.incrementFallbackCount(user.getEmail()); if (stats.getFallbackCount() < 10) { String emailText = vm.transcript + "\nLink: " + vm.link; emailText += "\n\nYou are receiving this email because GVMax was unable to send you a GTalk notification."; emailText += "\nPlease ensure you are logged into GTalk"; notifier.sendEmailNotification(vm.number, "Voicemail from " + vm.contact, emailText); } } } } // ------------------- // EXTRACT INFO // ------------------- static class Voicemail { private String number; private String contact; private String transcript; private String link; } private void extractInfo(Email email) { String pin = email.getTo().substring(0, email.getTo().indexOf('@')); user = userDAO.retrieveByPin(pin); if (user == null) { return; } try { extractVoicemail(email); } catch (Exception e) { vm = null; } } private void extractVoicemail(Email email) throws IOException { parseEmail(email.getText()); if (vm == null || vm.number == null) { vm = null; return; } } private void parseEmail(String text) throws IOException { vm = new Voicemail(); boolean capturingText = false; BufferedReader reader = new BufferedReader(new StringReader(text)); String line = reader.readLine(); while (line != null) { line = line.trim(); if (line.startsWith("You've got new voicemail from")) { int bPos = line.indexOf('('); int dPos = line.indexOf('-'); if (bPos == "You've got new voicemail from ".length()) { vm.number = line.substring(bPos); } else { dPos = line.lastIndexOf('-'); vm.number = line.substring(bPos, dPos); } vm.number = PhoneUtil.normalizeNumber(vm.number.trim()); } if (line.startsWith("Voicemail from")) { // Extract number int bPos = line.indexOf('('); if (bPos == -1) { vm.number = "unknown"; } else { String number = line.substring(bPos); number = number.substring(0, number.indexOf(" at ")); vm.number = PhoneUtil.normalizeNumber(number); } } if (line.startsWith("Play message:")) { // Grab link capturingText = false; vm.link = reader.readLine(); } if (capturingText) { // Capturing transcript 2 vm.transcript = vm.transcript + line + "\n"; } if (line.startsWith("Transcript:")) { // Capturing transcript 1 vm.transcript = line.substring("Transcript:".length()) + "\n"; capturingText = true; } line = reader.readLine(); } if (vm.transcript != null && !"".equals(vm.transcript)) { vm.transcript = vm.transcript.substring(0, vm.transcript.length() - 1); } if (!"unknown".equals(vm.number)) { vm.contact = ContactUtil.getContact(user, vm.number); } if (vm.contact == null) { vm.contact = vm.number; } try { vm.link = TinyURL.getTinyUrl(vm.link); } catch (IOException e) { logger.warn("Unable to create short link"); } } }