/****************************************************************************** * * Copyright 2014 Paphus Solutions Inc. * * Licensed under the Eclipse Public License, Version 1.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ package org.botlibre.sense.email; import java.io.StringWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.logging.Level; import javax.mail.Address; import javax.mail.BodyPart; import javax.mail.Flags; import javax.mail.Folder; import javax.mail.Message; import javax.mail.Message.RecipientType; import javax.mail.MessagingException; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Store; import javax.mail.Transport; import javax.mail.URLName; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import javax.mail.search.FlagTerm; import org.botlibre.Bot; import org.botlibre.BotException; import org.botlibre.api.knowledge.Network; import org.botlibre.api.knowledge.Vertex; import org.botlibre.knowledge.Primitive; import org.botlibre.self.SelfCompiler; import org.botlibre.sense.BasicSense; import org.botlibre.thought.language.Language; import org.botlibre.util.TextStream; import org.botlibre.util.Utils; import com.sun.mail.imap.IMAPSSLStore; import com.sun.mail.pop3.POP3SSLStore; /** * Receive and respond to incoming email. * Can use any pop mail server, such as gmail. */ public class Email extends BasicSense { public static int SLEEP = 1000 * 60 * 10; // 10 minutes. public static String SIGNATURE = "\n\n----------\nThis is an automated message\n"; /** Signature to apply to emails. */ protected String signature = SIGNATURE; /** Email address. */ protected String emailAddress = "user@gmail.com"; /** POP info. */ protected String incomingHost = "imap.gmail.com"; protected int incomingPort = 993; protected String outgoingHost = "smtp.gmail.com"; protected int outgoingPort = 587; protected String username = "user@gmail.com"; protected String password = ""; protected String protocol = "imaps"; protected boolean isSSLRequired = false; protected int maxEmails = 100; protected int emails = 0; protected int emailsProcessed = 0; protected boolean initProperties; /** Email checker thread. */ protected Runnable emailChecker; public Email() { this.isEnabled = false; if (isEnabled()) { //startCheckingEmail(); } } /** * Start sensing. */ @Override public void awake() { } /** * Migrate to new properties system. */ public void migrateProperties() { Network memory = getBot().memory().newMemory(); Vertex sense = memory.createVertex(getPrimitive()); Vertex property = sense.getRelationship(Primitive.USER); if (property != null) { this.username = (String)property.getData(); } property = sense.getRelationship(Primitive.PASSWORD); if ((property != null) && (this.username != null)) { String data = (String)property.getData(); // Check if encrypted from && prefix. if (data.startsWith("&&")) { try { this.password = Utils.decrypt(Utils.KEY, data.substring(2, data.length())); } catch (Exception exception) { this.password = Utils.decrypt(this.username, data); } } else { this.password = Utils.decrypt(this.username, data); } } property = sense.getRelationship(Primitive.EMAILADDRESS); if (property != null) { this.emailAddress = (String)property.getData(); setIsEnabled(true); } property = sense.getRelationship(Primitive.SSL); if (property != null) { this.isSSLRequired = (Boolean)property.getData(); } property = sense.getRelationship(Primitive.SIGNATURE); if (property != null) { this.signature = (String)property.getData(); } property = sense.getRelationship(Primitive.INCOMINGHOST); if (property != null) { this.incomingHost = (String)property.getData(); } property = sense.getRelationship(Primitive.INCOMINGPORT); if (property != null) { this.incomingPort = ((Number)property.getData()).intValue(); } property = sense.getRelationship(Primitive.OUTGOINGHOST); if (property != null) { this.outgoingHost = (String)property.getData(); } property = sense.getRelationship(Primitive.OUTGOINGPORT); if (property != null) { this.outgoingPort = ((Number)property.getData()).intValue(); } property = sense.getRelationship(Primitive.PROTOCOL); if (property != null) { this.protocol = (String)property.getData(); } // Remove old properties. sense.internalRemoveRelationships(Primitive.USER); sense.internalRemoveRelationships(Primitive.PASSWORD); sense.internalRemoveRelationships(Primitive.EMAILADDRESS); sense.internalRemoveRelationships(Primitive.SSL); sense.internalRemoveRelationships(Primitive.SIGNATURE); sense.internalRemoveRelationships(Primitive.INCOMINGHOST); sense.internalRemoveRelationships(Primitive.INCOMINGPORT); sense.internalRemoveRelationships(Primitive.OUTGOINGHOST); sense.internalRemoveRelationships(Primitive.OUTGOINGPORT); sense.internalRemoveRelationships(Primitive.PROTOCOL); memory.save(); saveProperties(); } /** * Load settings. */ public void initProperties() { if (this.initProperties) { return; } synchronized (this) { if (this.initProperties) { return; } getBot().memory().loadProperties("Email"); String property = this.bot.memory().getProperty("Email.user"); if (property != null) { this.username = property; } property = this.bot.memory().getProperty("Email.password"); if ((property != null) && (this.username != null)) { // Check if encrypted from && prefix. if (property.startsWith("&&")) { try { this.password = Utils.decrypt(Utils.KEY, property.substring(2, property.length())); } catch (Exception exception) { this.password = Utils.decrypt(this.username, property); } } else { this.password = Utils.decrypt(this.username, property); } } property = this.bot.memory().getProperty("Email.emailAddress"); if (property != null) { this.emailAddress = property; setIsEnabled(true); } property = this.bot.memory().getProperty("Email.ssl"); if (property != null) { this.isSSLRequired = Boolean.valueOf(property); } property = this.bot.memory().getProperty("Email.signature"); if (property != null) { this.signature = property; } property = this.bot.memory().getProperty("Email.incomingHost"); if (property != null) { this.incomingHost = property; } property = this.bot.memory().getProperty("Email.incomingPort"); if (property != null) { this.incomingPort = Integer.valueOf(property); } property = this.bot.memory().getProperty("Email.outgoingHost"); if (property != null) { this.outgoingHost = property; } property = this.bot.memory().getProperty("Email.outgoingPort"); if (property != null) { this.outgoingPort = Integer.valueOf(property); } property = this.bot.memory().getProperty("Email.protocol"); if (property != null) { this.protocol = property; } this.initProperties = true; } } public void saveProperties() { Network memory = getBot().memory().newMemory(); memory.saveProperty("Email.user", this.username, false); memory.saveProperty("Email.password", "&&" + Utils.encrypt(Utils.KEY, this.password), false); memory.saveProperty("Email.emailAddress", this.emailAddress, false); memory.saveProperty("Email.ssl", String.valueOf(this.isSSLRequired), false); memory.saveProperty("Email.signature", this.signature, false); memory.saveProperty("Email.incomingHost", this.incomingHost, false); memory.saveProperty("Email.incomingPort", String.valueOf(this.incomingPort), false); memory.saveProperty("Email.outgoingHost", this.outgoingHost, false); memory.saveProperty("Email.outgoingPort", String.valueOf(this.outgoingPort), false); memory.saveProperty("Email.protocol", this.protocol, false); memory.save(); } @Override public void setIsEnabled(boolean isEnabled) { super.setIsEnabled(isEnabled); if (isEnabled) { if (this.emailChecker == null) { //startCheckingEmail(); } } else { this.emailChecker = null; } } public void startCheckingEmail() { this.emailChecker = new Runnable() { @Override public void run() { try { while (isEnabled()) { checkEmail(); Thread.sleep(SLEEP); } } catch (Exception exception) { log(exception); } } }; Thread thread = new Thread(this.emailChecker); thread.start(); } public Store connectStore() throws MessagingException { initProperties(); if (isSSLRequired()) { return connectStoreSSL(); } Properties properties = new Properties(); properties.put("mail." + getProtocol() + ".timeout", 5000); properties.put("mail." + getProtocol() + ".connectiontimeout", 5000); //properties.setProperty("mail.store.protocol", getProtocol()); Session session = Session.getInstance(properties, null); Store store = session.getStore(getProtocol()); if (getIncomingPort() == 0) { store.connect(getIncomingHost(), getUsername(), getPassword()); } else { store.connect(getIncomingHost(), getIncomingPort(), getUsername(), getPassword()); } return store; } public Store connectStoreSSL() throws MessagingException { Properties properties = System.getProperties(); properties.put("mail." + getProtocol() + ".timeout", 5000); properties.put("mail." + getProtocol() + ".connectiontimeout", 5000); properties.setProperty("mail." + getProtocol() + ".socketFactory.class", "javax.net.ssl.SSLSocketFactory"); properties.setProperty("mail." + getProtocol() + ".socketFactory.fallback", "false"); properties.setProperty("mail." + getProtocol() + ".port", String.valueOf(getIncomingPort())); properties.setProperty("mail." + getProtocol() + ".socketFactory.port", String.valueOf(getIncomingPort())); Session session = Session.getInstance(properties, null); URLName url = new URLName(getProtocol(), getIncomingHost(), getIncomingPort(), "", getUsername(), getPassword()); Store store = null; if (getProtocol().equals("pop3")) { store = new POP3SSLStore(session, url); } else { store = new IMAPSSLStore(session, url); } store.connect(); return store; } /** * Check the inbox for new messages, and process each message. */ public void checkEmail() { try { log("Checking email.", Level.INFO); Store store = connectStore(); Folder inbox = store.getFolder("INBOX"); if (inbox == null) { throw new BotException("Failed to check email, no INBOX."); } inbox.open(Folder.READ_WRITE); Message[] messages = inbox.search(new FlagTerm(new Flags(Flags.Flag.SEEN), false)); inbox.setFlags(messages, new Flags(Flags.Flag.SEEN), true); //Message[] messages = inbox.getMessages(); if ((messages != null) && (messages.length > 0)) { log("Processing emails", Level.INFO, messages.length); Network memory = getBot().memory().newMemory(); Vertex sense = memory.createVertex(getPrimitive()); Vertex vertex = sense.getRelationship(Primitive.LASTMESSAGE); long lastMessage = 0; if (vertex != null) { lastMessage = ((Number)vertex.getData()).longValue(); } long maxMessage = 0; int count = 0; for (int index = 0; index < messages.length; index++) { long recievedTime = 0; if (messages[index].getReceivedDate() == null) { log("Missing received date", Level.FINE, messages[index].getSubject()); recievedTime = messages[index].getSentDate().getTime(); } else { recievedTime = messages[index].getReceivedDate().getTime(); } if ((System.currentTimeMillis() - recievedTime) > DAY) { log("Day old email", Level.INFO, messages[index].getSubject()); continue; } if (recievedTime > lastMessage) { count++; if (count > this.maxEmails) { log("Max email limit reached", Level.WARNING, this.maxEmails); break; } input(messages[index]); Utils.sleep(100); if (recievedTime > maxMessage) { maxMessage = recievedTime; } } } if (maxMessage != 0) { sense.setRelationship(Primitive.LASTMESSAGE, memory.createVertex(maxMessage)); memory.save(); } } log("Done checking email.", Level.INFO); inbox.close(false); store.close(); } catch (MessagingException exception) { log(exception); } } /** * Connect and verify the email settings. */ public void connect() { Store store = null; try { log("Connecting email.", Level.FINER); store = connectStore(); connectSession(); log("Done connecting email.", Level.FINER); } catch (MessagingException messagingException) { BotException exception = new BotException("Failed to connect - " + messagingException.getMessage(), messagingException); log(exception); throw exception; } finally { try { if (store != null) { store.close(); } } catch (Exception ignore) {} } } /** * Return a list in inbox message headers. */ public List<String> getInbox() { List<String> emails = new ArrayList<String>(); Store store = null; Folder inbox = null; try { store = connectStore(); inbox = store.getFolder("INBOX"); if (inbox == null) { log(new BotException("Failed to access inbox, no INBOX.")); } inbox.open(Folder.READ_ONLY); Message[] messages = inbox.search(new FlagTerm(new Flags(Flags.Flag.SEEN), false)); //Message[] messages = inbox.getMessages(1, Math.min(inbox.getMessageCount(), 50)); for (int index = 0; index < 10 && index < messages.length; index++) { emails.add(0, messages[index].getReceivedDate() + " - " + String.valueOf(getFrom(messages[index])) + ": " + messages[index].getSubject()); } inbox.close(false); store.close(); } catch (MessagingException exception) { log(new BotException("Failed to access email: " + exception.getMessage(), exception)); } finally { try { if (inbox != null) { inbox.close(false); } if (store != null) { store.close(); } } catch (Exception ignore) {} } return emails; } /** * Return a list in inbox message headers. */ public List<String> getSent() { List<String> emails = new ArrayList<String>(); try { Store store = connectStore(); Folder sent = null; try { sent = store.getFolder("SENT"); sent.open(Folder.READ_ONLY); } catch (Exception ignore) { sent = null; } if (sent == null) { try { sent = store.getFolder("[Gmail]/Sent Mail"); sent.open(Folder.READ_ONLY); } catch (Exception ignore) { sent = null; } } if (sent == null) { log(new BotException("Failed to access sent, no SENT.")); } else { Message[] messages = sent.getMessages(1, Math.min(sent.getMessageCount(), 12)); for (int index = 0; index < messages.length; index++) { emails.add(0, messages[index].getReceivedDate() + " - " + String.valueOf(getRecipient(messages[index])) + ": " + messages[index].getSubject()); } sent.close(false); } store.close(); } catch (MessagingException exception) { log(new BotException("Failed to access sent - " + exception.getMessage(), exception)); } return emails; } public Session connectSession() { Properties props = new Properties(); Session session = null; if (isSSLRequired()) { props.put("mail.smtp.host", getOutgoingHost()); props.put("mail.smtp.port", getOutgoingPort()); props.put("mail.smtp.socketFactory.port", getOutgoingPort()); props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); props.put("mail.smtp.auth", "true"); session = Session.getDefaultInstance(props, new javax.mail.Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(getUsername(), getPassword()); } }); } else { props.put("mail.smtp.auth", "true"); props.put("mail.smtp.starttls.enable", "true"); props.put("mail.smtp.host", getOutgoingHost()); props.put("mail.smtp.port", getOutgoingPort()); session = Session.getInstance(props, new javax.mail.Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(getUsername(), getPassword()); } }); } return session; } // Self API public void email(Vertex source, Vertex replyTo, Vertex subject, Vertex message) { Network network = source.getNetwork(); if (subject.instanceOf(Primitive.FORMULA)) { Map<Vertex, Vertex> variables = new HashMap<Vertex, Vertex>(); SelfCompiler.addGlobalVariables(network.createInstance(Primitive.INPUT), null, network, variables); subject = getBot().mind().getThought(Language.class).evaluateFormula(subject, variables, network); if (subject == null) { log("Invalid template formula", Level.WARNING, subject); return; } } if (message.instanceOf(Primitive.FORMULA)) { Map<Vertex, Vertex> variables = new HashMap<Vertex, Vertex>(); SelfCompiler.addGlobalVariables(network.createInstance(Primitive.INPUT), null, network, variables); message = getBot().mind().getThought(Language.class).evaluateFormula(message, variables, network); if (message == null) { log("Invalid template formula", Level.WARNING, message); return; } } getBot().stat("email"); sendEmail(message.printString(), subject.printString(), replyTo.printString()); } /** * Send the email reply. */ public void sendEmail(String text, String subject, String replyTo) { log("Sending email:", Level.INFO, replyTo, subject, text); initProperties(); try { //Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()); //props.setProperty("mail.transport.protocol", "smtp"); //props.setProperty("mail.host", getOutgoingHost()); Session session = connectSession(); /*props.put("mail.smtp.auth", "true"); props.put("mail.smtp.port", String.valueOf(getOutgoingPort())); props.put("mail.smtp.socketFactory.port", String.valueOf(getOutgoingPort())); props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); props.put("mail.smtp.socketFactory.fallback", "false"); props.setProperty("mail.smtp.quitwait", "false");*/ MimeMessage message = new MimeMessage(session); message.setFrom(new InternetAddress(getEmailAddress())); message.addRecipient(Message.RecipientType.TO, new InternetAddress(replyTo)); message.setSubject(subject); if (Utils.containsHTML(text)) { MimeMultipart content = new MimeMultipart(); MimeBodyPart htmlPart = new MimeBodyPart(); htmlPart.setContent(text, "text/html"); content.addBodyPart(htmlPart); message.setContent(content); } else { message.setText(text); } // Send message this.emails++; Transport.send(message); } catch (MessagingException exception) { log(new BotException("Failed to send email: " + exception.getMessage(), exception)); } } public String getRecipient(Message message) throws MessagingException { Address to[] = message.getRecipients(RecipientType.TO); if ((to != null) && (to.length > 0) && (to[0] instanceof InternetAddress)) { return ((InternetAddress)to[0]).getAddress(); } return null; } public String getFrom(Message message) throws MessagingException { Address from[] = message.getFrom(); if ((from != null) && (from.length > 0) && (from[0] instanceof InternetAddress)) { return ((InternetAddress)from[0]).getAddress(); } return null; } /** * Process the email message. */ @Override public void input(Object input, Network network) throws Exception { if (!isEnabled()) { return; } Message message = (Message)input; String fromUser = getFrom(message); if (fromUser == null) { fromUser = DEFAULT_SPEAKER; } String subject = message.getSubject(); if (subject == null) { subject = ""; } subject = subject.trim(); if (fromUser.equals(getEmailAddress())) { log("Ignoring email", Bot.FINE, subject, fromUser); return; } if (fromUser.toLowerCase().indexOf("daemon") != -1) { log("Ignoring daemon email", Bot.FINE, subject, fromUser); return; } if (fromUser.toLowerCase().indexOf("twitter.com") != -1) { log("Ignoring twitter email", Bot.FINE, subject, fromUser); return; } if (fromUser.toLowerCase().indexOf("facebook.com") != -1) { log("Ignoring facebook email", Bot.FINE, subject, fromUser); return; } if (fromUser.toLowerCase().indexOf("google.com") != -1) { log("Ignoring google email", Bot.FINE, subject, fromUser); return; } if ((fromUser.toLowerCase().indexOf("noreply") != -1) || (fromUser.toLowerCase().indexOf("donotreply") != -1)) { log("Ignoring noreply email", Bot.FINE, subject, fromUser); return; } if (subject.toLowerCase().indexOf("noreply") != -1) { log("Ignoring noreply email", Bot.FINE, subject, fromUser); return; } this.emailsProcessed++; log("Processing email", Level.INFO, subject, fromUser); String toUser = getRecipient(message); if (toUser == null) { toUser = DEFAULT_SPEAKER; } Object content = message.getContent(); String text = ""; if (content instanceof MimeMultipart) { MimeMultipart parts = (MimeMultipart)content; for (int index = 0; index < parts.getCount(); index++) { BodyPart body = parts.getBodyPart(index); if (body.getContentType().toLowerCase().indexOf("text/plain") != -1) { text = (String)body.getContent(); break; } } if ((text == null) && (parts.getCount() > 0)) { text = (String)parts.getBodyPart(0).getContent(); text = Utils.stripTags(text); } } else if (content instanceof String) { text = (String)content; if (message.getContentType().toLowerCase().contains("html")) { text = Utils.stripTags(text); } } text = text.trim(); log("Processing email body", Level.INFO, subject, fromUser, text); // Parse email chain. TextStream stream = new TextStream(text); StringWriter writer = new StringWriter(); while (!stream.atEnd()) { String nextLine = stream.nextLine(); if ((nextLine.length() > 0) && (nextLine.charAt(0) == '-')) { if (nextLine.indexOf("---") != -1) { // End of message. break; } } if ((nextLine.indexOf("@") != -1) && (nextLine.indexOf("wrote") != -1) && (nextLine.length() > 10) && (nextLine.substring(0, 2).equalsIgnoreCase("on"))) { break; } if ((nextLine.length() > 0) && (nextLine.charAt(0) == '>')) { // Ignore. } else { writer.write(nextLine); } } text = writer.toString(); if (text.length() == 0) { text = subject; } log("Processing email content", Level.INFO, subject, fromUser, text); inputSentence(text.trim(), subject, fromUser, toUser, message, network); } /** * Output the email reply. */ public void output(Vertex output) { if (!isEnabled()) { return; } Vertex sense = output.mostConscious(Primitive.SENSE); // If not output to email, ignore. if ((sense == null) || (!getPrimitive().equals(sense.getData()))) { return; } Vertex target = output.mostConscious(Primitive.TARGET); String replyTo = target.mostConscious(Primitive.WORD).getData().toString(); if ((replyTo.toLowerCase().indexOf("noreply") != -1) || (replyTo.toLowerCase().indexOf("donotreply") != -1)) { return; } String text = null; Vertex response = output.getRelationship(Primitive.INPUT); Vertex input = output.mostConscious(Primitive.QUESTION); Vertex question = input.getRelationship(Primitive.INPUT); if ((question != null) && response.instanceOf(Primitive.PARAGRAPH) && question.instanceOf(Primitive.PARAGRAPH)) { StringWriter writer = new StringWriter(); List<Vertex> sentences = response.orderedRelations(Primitive.SENTENCE); List<Vertex> questions = question.orderedRelations(Primitive.SENTENCE); int index = 0; for (Vertex sentence : sentences) { Vertex questionSentence = null; while (((index < questions.size()) && (questionSentence == null || !questionSentence.instanceOf(Primitive.QUESTION)))) { questionSentence = questions.get(index); index++; } if (questionSentence != null) { writer.write("\n"); String questionText = questionSentence.printString(); if (questionText.contains("\n")) { TextStream stream = new TextStream(questionText); while (!stream.atEnd()) { writer.write("> "); writer.write(stream.nextLine()); } } else { writer.write("> "); writer.write(questionText); } writer.write("\n"); } writer.write(sentence.printString()); writer.write("\n"); } text = writer.toString(); } else { text = printInput(output); } StringWriter writer = new StringWriter(); writer.write(text); writer.write("\n"); writer.write("\n"); writer.write(getSignature()); // Append quoted original email. if (input != null) { String replyText = printInput(input); writer.write("\n"); writer.write("\n"); TextStream stream = new TextStream(replyText); int max = 0; while (!stream.atEnd() && (max < 64)) { String line = stream.nextLine(); writer.write(">"); if ((line.length() > 0) && (line.charAt(0) != '>')) { writer.write(" "); } writer.write(line); } text = writer.toString(); } String subject = output.mostConscious(output.getNetwork().createVertex(Primitive.TOPIC)).getData().toString(); if (!subject.startsWith("RE:") && !subject.startsWith("Re:")) { subject = "RE: " + subject; } sendEmail(text, subject, replyTo); } public String getSignature() { initProperties(); return signature; } public void setSignature(String signature) { initProperties(); this.signature = signature; } public String getEmailAddress() { initProperties(); return emailAddress; } public void setEmailAddress(String emailAddress) { initProperties(); this.emailAddress = emailAddress; } public String getIncomingHost() { initProperties(); return incomingHost; } public void setIncomingHost(String incomingHost) { initProperties(); this.incomingHost = incomingHost; } public int getIncomingPort() { initProperties(); return incomingPort; } public void setIncomingPort(int incomingPort) { initProperties(); this.incomingPort = incomingPort; } public String getOutgoingHost() { initProperties(); return outgoingHost; } public void setOutgoingHost(String outgoingHost) { initProperties(); this.outgoingHost = outgoingHost; } public int getOutgoingPort() { initProperties(); return outgoingPort; } public void setOutgoingPort(int outgoingPort) { initProperties(); this.outgoingPort = outgoingPort; } public String getUsername() { initProperties(); return username; } public void setUsername(String username) { initProperties(); this.username = username; } public String getPassword() { initProperties(); return password; } public void setPassword(String password) { initProperties(); this.password = password; } public String getProtocol() { initProperties(); return protocol; } public void setProtocol(String protocol) { initProperties(); this.protocol = protocol; } public boolean isSSLRequired() { initProperties(); return isSSLRequired; } public void setSSLRequired(boolean isSSLRequired) { initProperties(); this.isSSLRequired = isSSLRequired; } public int getMaxEmails() { return maxEmails; } public void setMaxEmails(int maxEmails) { this.maxEmails = maxEmails; } public int getEmails() { return emails; } public void setEmails(int emails) { this.emails = emails; } public int getEmailsProcessed() { return emailsProcessed; } public void setEmailsProcessed(int emailsProcessed) { this.emailsProcessed = emailsProcessed; } /** * Process the text sentence. */ public void inputSentence(String text, String subject, String userName, String targetUserName, Message message, Network network) throws MessagingException { Vertex input = createInputParagraph(text.trim(), network); Vertex user = network.createSpeaker(userName); input.addRelationship(Primitive.INSTANTIATION, Primitive.EMAIL); input.getRelationship(Primitive.INPUT).addRelationship(Primitive.INSTANTIATION, Primitive.EMAIL); long date = 0; if (message.getReceivedDate() == null) { date = message.getSentDate().getTime(); } else { date = message.getReceivedDate().getTime(); } input.addRelationship(Primitive.CREATEDAT, network.createVertex(date)); input.addRelationship(Primitive.ID, network.createVertex(message.getMessageNumber())); input.addRelationship(Primitive.SPEAKER, user); input.addRelationship(Primitive.TOPIC, network.createSentence(subject)); // TODO, figure out reply chains Vertex conversation = network.createInstance(Primitive.CONVERSATION); Language.addToConversation(input, conversation); conversation.addRelationship(Primitive.SPEAKER, user); conversation.addRelationship(Primitive.TYPE, Primitive.EMAIL); if (targetUserName != null) { Vertex targetUser = null; if (targetUserName.equals(getEmailAddress())) { targetUser = network.createVertex(Primitive.SELF); } else { targetUser = network.createSpeaker(targetUserName); } input.addRelationship(Primitive.TARGET, targetUser); conversation.addRelationship(Primitive.SPEAKER, targetUser); } user.addRelationship(Primitive.INPUT, input); user.addRelationship(Primitive.EMAIL, input); network.save(); getBot().memory().addActiveMemory(input); } }