Create and Save Outlook e-mail in Java Jacob library - java

HI I'm trying to create Outlook e-mail from Java
I'm working with Windows 10 and Outlook 365 desktop version
I'm able to do it with AposeEmail
https://docs.aspose.com/email/#asposeemail-for-java
and with
jotlmsg
https://github.com/ctabin/jotlmsg
But there are limitations.
Apose E-mial is not free. Only evaluation version is free.
Jotlmsg doesn't support html e-mails.
There’s also another possibility to use methods from dynamic libraries. There is library Jacob for this
Jacob Outlook example
However I don't know how to find way to do it in Jacob. Examples which I found on Stackoverflow or in other places doesn't work.
I have following VBA code which works.
Any idea how to do the same / similar thing in Jacob?
Alternative solution.
Do you know free JAVA library which supports .msg e-mail with HTML format?
Public Sub CreateEmail()
Dim objMsg As MailItem
Set objMsg = Application.CreateItem(olMailItem)
With objMsg
.To = Alias#domain.com
.CC = Alias2#domain.com
.BCC = Alias3#domain.com
.Subject = "This is the subject"
.Categories = "Test"
.VotingOptions = "Yes;No;Maybe;"
.BodyFormat = olFormatPlain ' send plain text message
.Importance = olImportanceHigh
.Sensitivity = olConfidential
.Attachments.Add ("path-to-file.docx")
' Calculate a date using DateAdd or enter an explicit date
.ExpiryTime = DateAdd("m", 6, Now) '6 months from now
.DeferredDeliveryTime = #8/1/2012 6:00:00 PM#
.Display
End With
Set objMsg = Nothing
End Sub
I tried AposeE-mail and Jotlmsg but they don't satisfy fully my needs.

I have found example
Jacob Outlook Sample
and modified:
/**
* JACOB Outlook sample contributed by
* Christopher Brind <christopher.brind#morse.com>
* Modified by PawDob https://stackoverflow.com/users/16168586/pawdob
*/
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
/**
* sample class to show simple outlook manipulation
*/
public class JacobOutlookEmail {
private ActiveXComponent ol;
private Dispatch oOutlook;
private Object email[] = new Object[1];
/**
* standard run loop
*
* #param asArgs command line arguments
* #throws Exception
*/
public static void main(String asArgs[]) throws Exception {
System.out.println("Outlook: IN");
JacobOutlookEmail jacobOutlook = new JacobOutlookEmail();
ActiveXComponent axOutlook = new ActiveXComponent("Outlook.Application");
try {
System.out.println("version=" + axOutlook.getProperty("Version"));
jacobOutlook.oOutlook = axOutlook.getObject();
System.out.println("version=" + Dispatch.get(jacobOutlook.oOutlook, "Version"));
Dispatch oNameSpace = axOutlook.getProperty("Session").toDispatch();
System.out.println("oNameSpace=" + oNameSpace);
String emailBody = "<HTML><BODY><p><b>Bold text</b></p>" +
"<p><i>Italic text</i></p>" +
"<p>Normal text</p>" +
"</BODY></HTML>";
String emailSubject = "Email demo using Jacob";
String recipientTo = "Alias#domain.com";
String recipientCC = "Alias2#domain.com";
String recipientBCC = "Alias3#domain.com";
String[] attachments = new String[]{"D:\\temp.txt"};
jacobOutlook.createEmail(emailSubject, recipientTo, recipientCC, recipientBCC, emailBody, attachments);
} finally {
// Uncomment if you want close outlook after job is done
// axOutlook.invoke("Quit", new Variant[]{});
}
}
public void createEmail(String subject, String recipientTo, String recipientCC, String recipientBCC, String body, String[] attachments) {
Dispatch mail = Dispatch.call(oOutlook, "CreateItem", email).toDispatch();
Dispatch.put(mail, "Subject", subject);
Dispatch.put(mail, "To", recipientTo);
Dispatch.put(mail, "CC", recipientCC);
Dispatch.put(mail, "BCC", recipientBCC);
// Use if sample text is used
// Dispatch.put(mail, "Body", body);
Dispatch.put(mail, "HTMLBody", body);
if (attachments.length > 0) {
Dispatch attachs = Dispatch.get(mail, "Attachments").toDispatch();
for (Object attachment : attachments) {
Dispatch.call(attachs, "Add", attachment);
}
}
// Save on D drive
Dispatch.call(mail, "SaveAs","D:\\JacobEmail.msg");
// Display in outlook
Dispatch.call(mail, "Display");
}
}
And finally it is working
Sometimes you have ask to find solution yourself :-)

Related

Jsoup behaves different from my test PC and the server

I'm testing a web crawler with JSoup. The issue comes when I test the crawler on a regular PC, and works as expected, then I export this web crawler as a jar to work in a server in a cron job. This where the things go wrong.
The code is the same, no changes. The data I'm trying to extract is different comments from the users of how they rate a service, the problem is that the web crawler behaves differently when it's executed in the server, for example: the comments are duplicated, something that doesn't happened when I'm testing the program locally.
Also the web crawler differentiates what language the comments are written (I take that info from the URL, .de for German, .es for Spanish, etc). This info get mixed for example, a comment in Spanish is classified as Portuguese one.
Again I repeat the logic behind the crawler is correct, I tested many times with different input.
What could be the problem behind these issues?
Additional notes:
No exceptions/crashes.
I'm using jsoup 1.9.2.
This is how I get the data from the website:
Document doc = Jsoup.connect(link).userAgent(FakeAgentBooking.getAgent()).timeout(60 * 4000).get();
I already tried to use a proxy just in case the server was banned.
System.getProperties().put("https.proxyHost", "PROXY");
System.getProperties().put("https.proxyPort", "PORT");
System.getProperties().put("https.proxyUser", "USER");
System.getProperties().put("https.proxyPassword", "PASSWORD");
This is the code of the cron job:
#Crawler(name = "Booking comments", nameType = "BOOKING_COMMENTS", sentimetal = true, cron = "${cron.booking.comments}")
public class BookingCommentsJob extends MotherCrawler {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(BookingCommentsJob.class);
#Value("${full.booking.comments}")
private String full;
#Autowired
private ComentariosCDMXRepository comentariosCDMXRepository;
#Override
#PostConstruct
public void init() {
setInfo(this.getClass().getAnnotation(Crawler.class));
}
#Override
public void exec(int num) {
// <DEBUG>
String startTime = time.format(new Date());
// </DEBUG>
Set<CrawQuery> li = queryManager.getMeQueries(type, num, threadnum);
Gson gson = new GsonBuilder().create();
for (CrawQuery s : li) {
String query = s.getQuery().get("query");
try {
//the crawling begins here-->
String result = BookingComentarios.crawlBookingComentarios(query, Boolean.parseBoolean(full));
//get the result from json to a standarized class
ComentarioCDMX[] myComments = gson.fromJson(result, ComentarioCDMX[].class);
for (ComentarioCDMX myComment : myComments) {
//evaluates if the comment is positive, neutral or negative.
Integer sentiment = sentimentAnalysis.classifyVector(myComment.getComment());
myComment.setSentiment(sentiment);
myComment.setQuery(query);
/* <Analisis de sentimiento /> */
comentariosCDMXRepository.save(myComment);
}
s.setStatus(true);
} catch (Exception e) {
logger.error(query, e);
s.setStatus(false);
mailSend.add(e);
} finally {
s.setLastUse(new Date());
//Saves data to Solr
crawQueryDao.save(s);
}
}
update();
// <DEBUG>
String endTime = time.format(new Date());
logger.info(name + " " + num + " > Inicio: " + startTime + ", Fin: " + endTime);
// </DEBUG>
}
#Scheduled(cron = "${cron.booking.comments}")
public void curro0() throws InterruptedException {
exec(0);
}
}
and this is when the code should be executed:
cron.booking.comments=00 30 02 * * *
Additional notes:
The test PC OS is Windows 7 and the server OS is linux Debian 3.16.7. and tghe java version in the test PC is 1.7 oracle JDK and on the server is 1.8.0 JRE.

App Engine Backend with Google Cloud Messaging sending message to more than 1000 users

I want to send a message (e.g. Update available) to all users(~15,000). I have implemented App Engine Backend with Google Cloud Messaging to send message.
I have tested on 2 devices. Got message on both. But as google docs says "GCM is support for up to 1,000 recipients for a single message."
My question is how to send same message to remaining 14,000 users in my
case? Or the code below will take care of it?
Below is the code which sends message
import com.google.android.gcm.server.Constants;
import com.google.android.gcm.server.Message;
import com.google.android.gcm.server.Result;
import com.google.android.gcm.server.Sender;
import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiNamespace;
import java.io.IOException;
import java.util.List;
import java.util.logging.Logger;
import javax.inject.Named;
import static com.example.shani.myapplication.backend.OfyService.ofy;
/**
* An endpoint to send messages to devices registered with the backend
* <p/>
* For more information, see
* https://developers.google.com/appengine/docs/java/endpoints/
* <p/>
* NOTE: This endpoint does not use any form of authorization or
* authentication! If this app is deployed, anyone can access this endpoint! If
* you'd like to add authentication, take a look at the documentation.
*/
#Api(name = "messaging", version = "v1", namespace = #ApiNamespace(ownerDomain = "backend.myapplication.shani.example.com", ownerName = "backend.myapplication.shani.example.com", packagePath = ""))
public class MessagingEndpoint {
private static final Logger log = Logger.getLogger(MessagingEndpoint.class.getName());
/**
* Api Keys can be obtained from the google cloud console
*/
private static final String API_KEY = System.getProperty("gcm.api.key");
/**
* Send to the first 10 devices (You can modify this to send to any number of devices or a specific device)
*
* #param message The message to send
*/
public void sendMessage(#Named("message") String message) throws IOException {
if (message == null || message.trim().length() == 0) {
log.warning("Not sending message because it is empty");
return;
}
// crop longer messages
if (message.length() > 1000) {
message = message.substring(0, 1000) + "[...]";
}
Sender sender = new Sender(API_KEY);
Message msg = new Message.Builder().addData("message", message).build();
List<RegistrationRecord> records = ofy().load().type(RegistrationRecord.class).limit(1000).list();
for (RegistrationRecord record : records) {
Result result = sender.send(msg, record.getRegId(), 5);
if (result.getMessageId() != null) {
log.info("Message sent to " + record.getRegId());
String canonicalRegId = result.getCanonicalRegistrationId();
if (canonicalRegId != null) {
// if the regId changed, we have to update the datastore
log.info("Registration Id changed for " + record.getRegId() + " updating to " + canonicalRegId);
record.setRegId(canonicalRegId);
ofy().save().entity(record).now();
}
} else {
String error = result.getErrorCodeName();
if (error.equals(Constants.ERROR_NOT_REGISTERED)) {
log.warning("Registration Id " + record.getRegId() + " no longer registered with GCM, removing from datastore");
// if the device is no longer registered with Gcm, remove it from the datastore
ofy().delete().entity(record).now();
} else {
log.warning("Error when sending message : " + error);
}
}
}
}
}
I know there are simillar questions but I am using Java language. I found questions which uses php language at backend. so not helpful to me!
Google Cloud Messaging: Send message to "all" users
Sending Push Notification on multiple devices
Is there anyone who has successfully implemented App Engine+Google Cloud Messaging JAVA language?
In the below code line if I replace 1000 with 15,000 Will it solve my problem?
List<RegistrationRecord> records = ofy().load().type(RegistrationRecord.class).limit(1000).list();
Please please help as soon as possible. And very sorry for my English.. If anyone need other details you are welcome to ask.
Thanks for your time.
A few considerations,
1) Sending notifications to a possibly huge number of users might take significant time, consider using Task Queues to queue that work to be done "offline" outside the 60 sec limit.
2) Now as for the GCM limit, if you need to all your users but GCM allow you 1000 at a time just split them in batches of 1000 and send every batch a message separately.
If you combine both recommendations you should have a fairly scalable process where you query for all your users in 1 request , split that list and just queue sending the message to those users 1000 at a time.
Extension to the #jirungaray answer below is code for sending GCM messages to all registered users,
Here I assume that from android you are registering each mobile-devices for GCM services and storing those device tokens in database.
public class GCM {
private final static Logger LOGGER = Logger.getLogger(GCM.class.getName());
private static final String API_KEY = ConstantUtil.GCM_API_KEY;
public static void doSendViaGcm(List<String> tocken,String message) throws IOException {
Sender sender = new Sender(API_KEY);
// Trim message if needed.
if (message.length() > 1000) {
message = message.substring(0, 1000) + "[...]";
}
Message msg = new Message.Builder().addData("message", message).build();
try{
MulticastResult result = sender.send(msg, tocken, 5);
}catch(Exception ex){
LOGGER.severe("error is"+ex.getMessage());
ex.printStackTrace();
}
}
}
In above code snippet API_KEY can be obtain from google console project ,here I assume that you have already created one google console project and enable GCM api,
you can generate API_KEY as follows
your_google_console_project>> Credentials>> Create New Key >> Server
key >> enter ip address Which you want to allow
access to GCM api[i used 0.0.0.0/0]
Now doSendViaGcm(List tocken,String message) of GCM class performs task of sending messages to all register android mobile devices
here List<String> token is array-list of all device token on which messages will be delivered ,remember this list size should not more than 1000 or else http call will fail.
hope this will help you
thanks

How to correctly use google alerts API with java

I'm learning to work with google alerts API.
I want to create an alerts from java code, and when I have alerts put them to my DB
My way:
I'm able to create an new google alert , that would send alerts to my gmail.
Read all the mails with java from my mail.
I parse them and put to my DB.
Is there a better way to do that ?
I saw that google can give me an XML rss , it would be much easier to parse , but I wasn't able to get the rss with java.
Thanks for any help.
Maybe it would be helpful :
Java code to create google alert:
public static void addAlertToUser(String userMail , String password , String query)
{
GAService service;
try {
service = new GAService(userMail, password);
service.doLogin();
Alert alert = new Alert();
alert.setSearchQuery(query);
alert.setHowOften(HowOften.AS_IT_HAPPENS);
//alert.setLanguage(Region.Israel);
//alert.setLanguage(Language.Hebrew);
alert.setHowMany(HowMany.ONLY_THE_BEST_RESULTS);
service.createAlert(alert);
} catch (Exception e) {
e.printStackTrace();
}
}
Code to read the alert from the Gmail:
public static void readGoogleAlretsEmail()
{
Hashtable<String , Alert[]> allAlerts = checkMail("myGmail#gmail.com", "12q3wa4esz");
for(String key : allAlerts.keySet())
{
System.out.println("Key : " + key + "\n");
Alert[] alerts = allAlerts.get(key);
for (int i = 0; i < alerts.length; i++)
{
Alert currentAlret = (Alert)alerts[i];
System.out.println(i + ". " + alerts[i]);
TextAnalysisResults results = TextAnalysis.getResults(currentAlret.title,currentAlret.content);
}
}
}

How to encode nested Python Protobuf

Been stumped on this for a while and pulling what is left of my hair out.
Sending non-nested Protobufs from Python to Java and Java to Python without
an issue with WebSockets. My problem is sending a nested version over a WebSocket. I believe my issue is on
the Python encoding side.
Your guidance is appreciated.
.proto file
message Response {
// Reflect back to caller
required string service_name = 1;
// Reflect back to caller
required string method_name = 2;
// Who is responding
required string client_id = 3;
// Status Code
required StatusCd status_cd = 4;
// RPC response proto
optional bytes response_proto = 5;
// Was callback invoked
optional bool callback = 6 [default = false];
// Error, if any
optional string error = 7;
//optional string response_desc = 6;
}
message HeartbeatResult {
required string service = 1;
required string timestamp = 2;
required float status_cd = 3;
required string status_summary = 4;
}
A Heartbeat result is supposed to get sent in the reponse_proto field
of the Response Protobuf. I am able to do this in Java to Java but Python
to Java is not working.
I've included two variations of the python code. Neither of which works.
def GetHeartbeat(self):
print "GetHeartbeat called"
import time
ts = time.time()
import datetime
st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
heartbeatResult = rpc_pb2.HeartbeatResult()
heartbeatResult.service = "ALERT_SERVICE"
heartbeatResult.timestamp = st
heartbeatResult.status_cd = rpc_pb2.OK
heartbeatResult.status_summary = "OK"
response = rpc_pb2.Response()
response.service_name = ""
response.method_name = "SendHeartbeatResult"
response.client_id = "ALERT_SERVICE"
response.status_cd = rpc_pb2.OK
response.response_proto = str(heartbeatResult).encode('utf-8')
self.sendMessage(response.SerializeToString())
print "GetHeartbeat finished"
def GetHeartbeat2(self):
print "GetHeartbeat called"
import time
ts = time.time()
import datetime
st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
heartbeatResult = rpc_pb2.HeartbeatResult()
heartbeatResult.service = "ALERT_SERVICE"
heartbeatResult.timestamp = st
heartbeatResult.status_cd = rpc_pb2.OK
heartbeatResult.status_summary = "OK"
response = rpc_pb2.Response()
response.service_name = ""
response.method_name = "SendHeartbeatResult"
response.client_id = "ALERT_SERVICE"
response.status_cd = rpc_pb2.OK
response.response_proto = heartbeatResult.SerializeToString()
self.sendMessage(response.SerializeToString())
print "GetHeartbeat finished"
Errors on the Java server side are:
(GetHeartbeat) Protocol message end-group tag did not match expected tag
and
(GetHeartbeat2)
Message: [org.java_websocket.exceptions.InvalidDataException: java.nio.charset.MalformedInputException: Input length = 1
at org.java_websocket.util.Charsetfunctions.stringUtf8(Charsetfunctions.java:80)
at org.java_websocket.WebSocketImpl.deliverMessage(WebSocketImpl.java:561)
at org.java_websocket.WebSocketImpl.decodeFrames(WebSocketImpl.java:328)
at org.java_websocket.WebSocketImpl.decode(WebSocketImpl.java:149)
at org.java_websocket.server.WebSocketServer$WebSocketWorker.run(WebSocketServer.java:593)
Caused by: java.nio.charset.MalformedInputException: Input length = 1
at java.nio.charset.CoderResult.throwException(CoderResult.java:277)
at java.nio.charset.CharsetDecoder.decode(CharsetDecoder.java:798)
at org.java_websocket.util.Charsetfunctions.stringUtf8(Charsetfunctions.java:77)
Solution
Also posted this question on protobuf group
Credit to Christopher Head and Ilia Mirkin for providing input on the google group
https://groups.google.com/forum/#!topic/protobuf/Cp7zWiWok9I
response.response_proto = base64.b64encode(heartbeatResult.SerializeToString())
self.sendMessage(response.SerializeToString())
FYI, Ilia also suggested base64 encoding the entire message but this seems to be working at the moment.

send Email with multiple attachment and html body which may contain image in java

I want to send email with multiple attachment to multiple recepients / multiple CC recepients / BCC Recepients with formateed html content boy which may contain image.
How to do same ?
please suggest.
This is working example for sending email for yahoo id to any other id from my local machine.
package myWorkingFiles;
import org.apache.commons.mail.DefaultAuthenticator;
import org.apache.commons.mail.EmailAttachment;
import org.apache.commons.mail.HtmlEmail;
import org.apache.commons.mail.MultiPartEmail;
/**
*
* #author xyz
*/
public class YahooEmailWorkingWithAttachment {
public static void main(String[] args) {
String myEmailId = "zz#yahoo.com";
String myPassword = "myPass";
String senderId = "sfdsdf#gmail.com";
String ccId = "dddd#yahoo.com";
String bccId = "ffff#yahoo.com";
try {
MultiPartEmail email = new HtmlEmail();
email.setSmtpPort(587);
email.setAuthenticator(new DefaultAuthenticator(myEmailId, myPassword));
email.setDebug(true);
email.setHostName("smtp.mail.yahoo.com");
email.addTo(senderId);
email.addCc(ccId);
email.addBcc(bccId);
email.setFrom(myEmailId);
email.setSubject("Test Email");
email.setMsg("<font face='verdana' size='3'>Here is the test email in HTML format "
+ "<table>"
+ "<tr><th>id</th><th>Name</th></tr>"
+ "<tr><th>1</th><th>Name 1</th></tr>"
+ "<tr><th>2</th><th>Name 2</th></tr>"
+ "<tr><th>3</th><th>Name 3</th></tr>"
+ "<tr><th>4</th><th>Name 4</th></tr>"
+ "</table>"
+ "</font>");
// add the attachment
EmailAttachment attachment = new EmailAttachment();
attachment.setPath("/Users/alkandari/Desktop/SMART/Fahim/test_small.pdf");
attachment.setDisposition(EmailAttachment.ATTACHMENT);
email.attach(attachment);
attachment = new EmailAttachment();
attachment.setPath("/Users/alkandari/Desktop/SMART/Fahim/test.png");
attachment.setDisposition(EmailAttachment.ATTACHMENT);
email.attach(attachment);
System.out.println("EmailAttachment.ATTACHMENT==" + EmailAttachment.ATTACHMENT);
// send the email
email.send();
System.out.println("email=====" + email + "==");
System.out.println("Mail sent!");
} catch (Exception e) {
System.out.println("Exception :: " + e);
}
}
}
If you want to send from any other you will need to do changes at below two place
email.setSmtpPort(587);
email.setHostName("smtp.mail.yahoo.com");
Edit 1
I am not sure, but if you want to set image as background for email, then I believe you will need to take image live on server and then give the server path for <img src="server.com/images/myImage.png" />
Edit 2
To add more cc, you will need to add N number of cc statement as below.
email.addCc("id1#test.com");
email.addCc("id2#test.com");
email.addCc("id3#test.com");
email.addCc("id4#test.com");
I am not sure about email.addCc("id1#test.com, id2#test.com, id3#test.com");. I think it won't work. You can give a try.
By using java mail API you can achive this.
http://www.tutorialspoint.com/java/java_sending_email.htm
Very clear and simple examples are provided here. Max its enough to solve the problem... :)

Categories