I have spent the weekend playing with Google App Engine and Google Web Toolkit and have got along pretty well and built a simple app.
The stumbling block seems to be sending e-mails. My code is:
private void sendOffenderMail( OffenceDetails offence )
{
if( offence.email == null || offence.email.equals("") )
{
return;
}
Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);
String msgBody = "You have been added to the list";
if( offence.notes != null && !offence.notes.equals( "" ) )
{
msgBody += "\n\nThe following notes were included:\n\n" + offence.notes;
}
Message msg = new MimeMessage(session);
try {
msg.setFrom( new InternetAddress(<gmail account belonging to project viewer>, "List Admin") );
msg.addRecipient(
Message.RecipientType.TO,
new InternetAddress (offence.email, offence.name )
);
msg.setSubject("You've been added to the list...");
msg.setText(msgBody);
Transport.send(msg);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
}
When I run this on the development server logs get printed out in the console about the mail that would have been sent.
When I deploy to app engine and try there nothing happens, I don't get any mail.
If I look in to the quota details I can see mail api calls there. If I look at the logs there are no errors (but I can't see and of my logs in there...).
It seems odd that I have essentially been charged for sending this (quota used up) but no mails actually got through.
I HAVE checked my spam folder BTW.
It seems that gmail account that you use is a Project Viewer. The docs state that it should be a Developer.
In the end I just used the e-mail address of the currently logged in user - which is always an admin as you can only get to this part of the app if you're an admin.
I could not get it to work using a hardwired address belonging to one of the admins.
Related
IMPORTANT
I have been blocked by hotmail services. There is a control mechanism
called spamhaus which kicked me out. I'm stuck right now.
I am trying to detect an email address is valid and if its valid then check if this email address potentially used (I know that its not certain). For example, lets assume that there is a website with domain myimaginarydomain.com. If I run code below, I guess it won't fail because domain address is valid. But nobody can take an email address with that domain.
Is there any way to find out that email address is valid? (In this case its invalid)
I don't want to send confirmation email
Sending ping may be useful?
public class Application {
private static EmailValidator validator = EmailValidator.getInstance();
public static void main(String[] args) {
while (true) {
Scanner scn = new Scanner(System.in);
String email = scn.nextLine();
boolean isValid = validateEmail(email);
System.out.println("Syntax is : " + isValid);
if (isValid) {
String domain = email.split("#")[1];
try {
int test = doLookup(domain);
System.out.println(domain + " has " + test + " mail servers");
} catch (NamingException e) {
System.out.println(domain + " has 0 mail servers");
}
}
}
}
private static boolean validateEmail(String email) {
return validator.isValid(email);
}
static int doLookup(String hostName) throws NamingException {
Hashtable env = new Hashtable();
env.put("java.naming.factory.initial",
"com.sun.jndi.dns.DnsContextFactory");
DirContext ictx = new InitialDirContext(env);
Attributes attrs =
ictx.getAttributes(hostName, new String[]{"MX"});
Attribute attr = attrs.get("MX");
if (attr == null) return (0);
return (attr.size());
}
}
There is no failsafe way to do this in all cases, but, assuming the server uses SMTP then https://www.labnol.org/software/verify-email-address/18220/ gives quite a good tutorial on one method that may work.
The method used in the tutorial relies on OS tools, so you will need to ensure they exist before using them. a ProcessBuilder may help. Alternatively, you can open a socket directly in code and avoid using OS-dependent tools.
Essentially, you find out what the mail servers are (using nslookup), then telnet to one of the mail servers and start writing an email:
3a: Connect to the mail server:
telnet gmail-smtp-in.l.google.com 25
3b: Say hello to the other server
HELO
3c: Identify yourself with some fictitious email address
mail from:<labnol#labnol.org>
3d: Type the recipient’s email address that you are trying to verify:
rcpt to:<billgates#gmail.com>
The server response for rcpt to command will give you an idea whether an email address is valid or not. You’ll get an “OK” if the address exists else a 550 error
There really is no sensible way except trying to send a notification with a token to the address and ask the other party to confirm it, usually by visiting a web-page:
the recipients MX may be unavailable at the moment but come back online later, so you cannot rely on a lookup in real time;
just because the MX accepts the email doesn't mean that the address is valid, the message could bounce later down the pipe (think UUCP);
if this is some kind of registration service, you need to provide some confirmation step anyway as otherwise it'd become too easy to subscribe random strangers on the internet that do not want your service.
I am integrating Plivo SMS API with my java web application. I want to send messages through my application. I am referring to https://www.plivo.com/docs/getting-started/send-a-single-sms/ link.
Below is the code snippet:
String authId = "{my Auth_id}"; //Your Authentication ID
String authToken = "{my auth Token}"; //Your authentication code
RestAPI api = new RestAPI(authId, authToken, "v1");
LinkedHashMap<String, String> parameters = new LinkedHashMap<String, String>();
parameters.put("src", "+44*******"); // Sender's phone number with country code
parameters.put("dst", "+91*******"); // Receiver's phone number with country code
parameters.put("text", "Hi, text from Plivo"); // Your SMS text message
try {
// Send the message
MessageResponse msgResponse = api.sendMessage(parameters);
// Print the response
System.out.println(msgResponse);
// Print the Api ID
System.out.println("Api ID : " + msgResponse.apiId);
// Print the Response Message
System.out.println("Message : " + msgResponse.message);
if (msgResponse.serverCode == 202) {
// Print the Message UUID
System.out.println("Message UUID : " + msgResponse.messageUuids.get(0).toString());
} else {
System.out.println(msgResponse.error);
}
} catch (PlivoException e) {
System.out.println(e.getLocalizedMessage());
}
I tried to run this code using console application as well as web application.I am getting exception "com.plivo.helper.exception.PlivoException: Connection to https://api.plivo.com refused". What is wrong with my code? Am I missing anything here?
Plivo Sales Engineer here.
Please check your firewall settings to ensure that it's not blocking any traffic. Also, are you using a web proxy? If yes, make sure that your application is using this proxy to handle connections.
I've been using javamail to retrieve mails from IMAP server (currently GMail). Javamail retrieves list of messages (only ids) in a particular folder from server very fast, but when I actually fetch message (only envelop not even contents) it takes around 1 to 2 seconds for each message. What are the techniques should be used for fast retrieval?
here is my code:
try {
IMAPStore store = null;
if(store!=null&&store.isConnected())return;
Properties props = System.getProperties();
Session sessionIMAP = Session.getInstance(props, null);
try {
store = (IMAPStore) sessionIMAP.getStore("imaps");
store.connect("imap.gmail.com",993,"username#gmail.com","password");
} catch (Exception e) {
e.printStackTrace();
}
IMAPFolder folder = (IMAPFolder) store.getFolder("INBOX");
folder.open(Folder.READ_ONLY);
System.out.println("start");
Message[] msgs = folder.getMessages(1,10);
long ftime = System.currentTimeMillis();
FetchProfile fp=new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
folder.fetch(msgs, fp);
long time = System.currentTimeMillis();
System.out.println("fetch: "+(time-ftime));
for (Message message : msgs) {
System.out.println(message.getSubject());
Address[] from = message.getFrom();
for (Address address : from) {
System.out.println(address);
}
Address[] recipients = message.getAllRecipients();
for (Address address : recipients) {
System.out.println(address);
}
}
long newTime = System.currentTimeMillis();
System.out.println("convert: "+(newTime-time));
}catch (Exception e) {
e.printStackTrace();
}
}
I believe that Gmail throttles the IMAP message reads to one every second or so. You might be able to speed it up with multiple IMAP connections.
Please set the Property mail.imap.fetchsize with the required size. the default is 16k.
In case you increase the size of this property, retrieve speed will go up.
props.put("mail.imap.fetchsize", "3000000");
Note that if you're using the "imaps" protocol to access IMAP over SSL, all the properties would be named "mail.imaps.*".
Good Luck.
Yaniv
I'm not sure if this is a Javamail issue as much as it may be a Gmail issue. I have an application that retrieves mail from a number of sources, including Gmail, and Gmail is definitely the slowest. The Javamail api is pretty straightforward, but it would be hard to make suggestions without seeing what you are currently doing.
I'm running into the same thing. After profiling, I noticed that getBody was being called every time I tried to do a message.getFrom() like you are, even though I was only accessing fields that should be covered by the Envelope flag. See https://java.net/projects/javamail/forums/forum/topics/107956-gimap-efficiency-when-only-reading-headers
I am trying to perform a search of my gmail using Java. With JavaMail I can do a message by message search like so:
Properties props = System.getProperties();
props.setProperty("mail.store.protocol", "imaps");
Session session = Session.getDefaultInstance(props, null);
Store store = session.getStore("imaps");
store.connect("imap.gmail.com", "myUsername", "myPassword");
Folder inbox = store.getFolder("Inbox");
inbox.open(Folder.READ_ONLY);
SearchTerm term = new SearchTerm() {
#Override
public boolean match(Message mess) {
try {
return mess.getContent().toString().toLowerCase().indexOf("boston") != -1;
} catch (IOException ex) {
Logger.getLogger(JavaMailTest.class.getName()).log(Level.SEVERE, null, ex);
} catch (MessagingException ex) {
Logger.getLogger(JavaMailTest.class.getName()).log(Level.SEVERE, null, ex);
}
return false;
}
};
Message[] searchResults = inbox.search(term);
for(Message m:searchResults)
System.out.println("MATCHED: " + m.getFrom()[0]);
But this requires downloading each message. Of course I can cache all the results, but this becomes a storage concern with large gmail boxes and also would be very slow (I can only imagine how long it would take to search through gigabytes of text...).
So my question is, is there a way of searching through mail on the server, a la gmail's search field? Maybe through Microsoft Exchange?
Hours of Googling has turned up nothing.
You can let the server do the search for you, with the appropriate IMAP command. The SEARCH command will only get you so far, what you probably need is the SORT command. SORT isn't implemented in JavaMail but the documentation shows how you can implement it yourself:
http://java.sun.com/products/javamail/javadocs/com/sun/mail/imap/IMAPFolder.html#doCommand(com.sun.mail.imap.IMAPFolder.ProtocolCommand)
(I couldn't figure out how to link to a URL with parentheses)
Connect to the Exchange IMAP store and use javax.mail.search.SearchTerm
I'd like to send mail without bothering with the SMTP-Server which is used for delivery.
So JavaMail API doesn't work for me because I have to specify a SMTP server to connect to.
I'd like the library to find out on its own which SMTP server is responsible for which email address by querying the MX record of the mail address domain.
I'm looking for something like Aspirin. Unfortunately I can't use Aspirin itself because the development stopped 2004 and the library fails to communicate with modern spam hardened servers correctly.
An embeddable version of James would do the task. But I haven't found documentation concerning whether this is possible.
Or does anyone know about other libraries I could use?
One possible solution: get the MX record on your own and use JavaMail API.
You can get the MX record using the dnsjava project:
Maven2 dependency:
<dependency>
<groupId>dnsjava</groupId>
<artifactId>dnsjava</artifactId>
<version>2.0.1</version>
</dependency>
Method for MX record retrieval:
public static String getMXRecordsForEmailAddress(String eMailAddress) {
String returnValue = null;
try {
String hostName = getHostNameFromEmailAddress(eMailAddress);
Record[] records = new Lookup(hostName, Type.MX).run();
if (records == null) { throw new RuntimeException("No MX records found for domain " + hostName + "."); }
if (log.isTraceEnabled()) {
// log found entries for debugging purposes
for (int i = 0; i < records.length; i++) {
MXRecord mx = (MXRecord) records[i];
String targetString = mx.getTarget().toString();
log.trace("MX-Record for '" + hostName + "':" + targetString);
}
}
// return first entry (not the best solution)
if (records.length > 0) {
MXRecord mx = (MXRecord) records[0];
returnValue = mx.getTarget().toString();
}
} catch (TextParseException e) {
throw new RuntimeException(e);
}
if (log.isTraceEnabled()) {
log.trace("Using: " + returnValue);
}
return returnValue;
}
private static String getHostNameFromEmailAddress(String mailAddress) throws TextParseException {
String parts[] = mailAddress.split("#");
if (parts.length != 2) throw new TextParseException("Cannot parse E-Mail-Address: '" + mailAddress + "'");
return parts[1];
}
Sending mail via JavaMail code:
public static void sendMail(String toAddress, String fromAddress, String subject, String body) throws AddressException, MessagingException {
String smtpServer = getMXRecordsForEmailAddress(toAddress);
// create session
Properties props = new Properties();
props.put("mail.smtp.host", smtpServer);
Session session = Session.getDefaultInstance(props);
// create message
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(fromAddress));
msg.setRecipient(Message.RecipientType.TO, new InternetAddress(toAddress));
msg.setSubject(subject);
msg.setText(body);
// send message
Transport.send(msg);
}
This is completely the wrong way to handle this.
Anyone connected to the internet will have some kind of "legit" SMTP server available to them to take the submission of email -- your ISP, your office, etc.
You WANT to leverage because they do several things for you.
1) they take your message and the responsibility to handle that message. After you drop it off, it's not your problem anymore.
2) Any mail de-spamming technologies are handled by the server. Even better, when/if those technologies change (Domain keys anyone?), the server handles it, not your code.
3) You, as a client of that sending mail system, already have whatever credentials you need to talk to that server. Main SMTP servers are locked down via authentication, IP range, etc.
4) You're not reinventing the wheel. Leverage the infrastructure you have. Are you writing an application or a mail server? Setting up mail server is an every day task that is typically simple to do. All of those casual "dumb" users on the internet have managed to get email set up.
Don't.
Sending email is much more complex than it seems. Email servers excel at (or should excel at) reliable delivery.
Set up a separate email server if you need to- that will be essentially the same as implementing one in Java (I doubt you will find libraries for this task- they would be essentially complete mail servers), but much more simpler.