How can I get last 20 emails from gmail?
ListMessagesResponse listMessagesResponse = mService.users().messages()
.list(user).setQ("from:----")
.execute();
Currently I am using this but it returns message IDs without any payload. I want to get full email with body. Can it be like get the latest email from specific sender?
As #trajchevska pointed out you can only get the basic details with your code. To get messages in full format you should call mService.users().messages().get(user, messageId).execute() for every message. Best way for this is to create a batch call. So if you want to get all the messages that match specified query you should do something like this.
final ListMessagesResponse response = mService.users().messages().list(user).setQ("from:----").execute();
final List<Message> messages = new ArrayList<Message>();
while (response.getMessages() != null) {
messages.addAll(response.getMessages());
if (response.getNextPageToken() != null) {
String pageToken = response.getNextPageToken();
response = service.users().messages().list(user).setQ("from:----").setPageToken(pageToken).execute();
} else {
break;
}
}
final List<Message> fullMessages = new ArrayList<>();
final JsonBatchCallback<Message> callback = new JsonBatchCallback<Message>() {
public void onSuccess(Message message, HttpHeaders responseHeaders) {
fullMessages.add(message);
}
public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) {
// do what you want if error occurs
}
};
BatchRequest batch = mService.batch();
for (Message message : messages) {
mService.users().messages().get(user, message.getId()).setFormat("full").queue(batch, callback);
}
batch.execute();
Hope this helps.
The list function only returns the list of messages with basic details which is usually the id only. If you want to get the payload or other message details you need to iterate through all messages pulled with list and call the wanted function specifically on the selected object. I only have some basic knowledge in Java, but the logic would be something like this:
messages = listMessagesResponse.getMessages();
for (Message message : messages) {
payload = message.getPayload();
...
}
Check their docs, they have some example that can be helpful.
List Messages
Get Concrete Message
Related
I'm trying to alter a message using a custom class mediator in wso2 esb. What I'm trying to achieve is to add/set the value of an element in the message sent. The message is sent using a REST API, and it goes through the mentioned class (where the transformation happens). However, when I do a full log of the message after the class, I see that the message keeps the same values that had at first (basically the class only alters the message while it's in the class mediator, so when it comes out of the mediator, it goes back to its original input form).
Input:
Body : <soapenv:Body ...><jsonObject><ts>2020-01-13</ts><temp></temp></jsonObject></soapenv:Body>
Desired output:
Body : <soapenv:Body ...><jsonObject><ts>2020-01-13</ts><temp>Hello</temp></jsonObject></soapenv:Body>
Things that I've tried so far and that didn't work:
Get message context, get the desired element and set the text
Use a OMFactory to create an OMElement and put that new element in the message context
Get the new altered envelope and set it as the new message context envelope
Create a new json payload
Any idea of how to get it working ?
You can refer to the following logic which changes the payload
#Override
public boolean mediate(MessageContext messageContext) {
try {
org.apache.axis2.context.MessageContext axis2MessageContext = ((Axis2MessageContext)messageContext).getAxis2MessageContext();
JSONObject jsonBody = new JSONObject();
JSONObject jsonError = new JSONObject();
jsonError.put("error","Authoraization Missing");
jsonError.put("detail","Authoraization Credentials invalid");
jsonError.put("title","Authoraization Error");
jsonBody.put("status", "403");
jsonBody.put("errorMessage", jsonError);
String transformedJson = jsonBody.toString();
JsonUtil.newJsonPayload(axis2MessageContext,transformedJson, true, true);
// change the response type to XML
axis2MessageContext.setProperty("messageType", "application/xml");
axis2MessageContext.setProperty("ContentType", "application/xml");
} catch (Exception e) {
System.err.println("Error: " + e);
return false;
}
return true;
}
If this doesn't help, kindly share your code to have an idea.
I already tried that tutorial #Nirothipan, but didn't work.
My code:
#Override
public boolean mediate(MessageContext mc){
String measure = mc.getEnvelope().getBody().getFirstElement().getFirstChildWithName(new QName("measure")).getText();
mc.getEnvelope().getBody().getFirstElement().getFirstChildWithName(new QName("temp")).setText(measure);
return true;
}
Should be more than enough to modify that element value imo.
I am trying to send a message. Connection with firebase xmpp server is done. I am using latest smack 4.2.
public myClient(String senderId, String serverKey) throws IOException, NotConnectedException, InterruptedException {
Roster.setRosterLoadedAtLoginDefault(false);
Jid jid ;
jid = JidCreate.from(HOST);
final XMPPTCPConnectionConfiguration conf = XMPPTCPConnectionConfiguration.builder()
.setCompressionEnabled(false)
.setSendPresence(false)
.setConnectTimeout(10000)
.setHost(HOST)
.setDebuggerEnabled(false)
.setPort(PORT)
.setXmppDomain((DomainBareJid) jid)
.setSocketFactory(SSLSocketFactory.getDefault())
.setUsernameAndPassword(senderId + "#gcm.googleapis.com", serverKey)
.build();
this.conn = new MyXMPPTCPConnection(conf);
try {
conn.connect();
conn.login();
} catch (XMPPException | InterruptedException | SmackException e) {
throw new IOException(e);
}
Roster roster = Roster.getInstanceFor(conn);
Collection<RosterEntry> entries = roster.getEntries();
for (RosterEntry entry : entries) {
System.out.println(entry);
}
Entity jEntity ;
Jid jid1 = JidCreate.from("text");
EntityBareJid jid21 = JidCreate.entityBareFrom("ak#gcm.googleapis.com");
Chat chat = ChatManager.getInstanceFor(conn)
.createChat(jid21);
Message newMessage = new Message();
String t = "hello this is a test message";
newMessage.setBody(t.toString());
/* ((Object) chat).send(newMessage);*/
chat.sendMessage(newMessage);
StanzaFilter filter = new AndFilter(new StanzaTypeFilter(Message.class));
//PacketCollector myCollector = conn2.createPacketCollector(filter);
// Normally, you'd do something with the collector, like wait for new packets.
StanzaListener myListener = new StanzaListener() {
#Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException {
System.out.println("packet = [" + packet + "]");
}
};
conn.addAsyncStanzaListener(myListener, filter);
while (true) {
}
//conn2.disconnect();
}
When I am running this method got the following error
packet = [hello
this is a test
message25667738-6dd1-4c74-a64b-2fdbac74339bInvalidJson :
MissingPayload]
Jul 26, 2017 12:52:46 PM
org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader parsePackets
INFO: MyXMPPTCPConnection[438277974557#gcm.googleapis.com/41CA77F0]
(0) received closing element. Server wants to terminate the
connection, calling disconnect()
Please review and suggest.
Thanks in advance.
The FCM XMPP Server uses JSON syntax. So you need to use the systax as described for FCM payload in this documentation. Since XMPP uses XML, you need to embed the JSON payload in an xml node with the name gcm as follows:
<gcm xmlns:google:mobile:data>
JSON payload
</gcm>
For e.g, your JSON payload may look like this:
{
"to":"APA91bEXJvW4jUdxxxxx-xxxxxxxx",
"data":{"message":"Hello"},
"priority":"high"
}
For complete details on using the XMPP Connection Server using GCM/FCM, take a look at this documentation.
Using Smack you can create a class with the GcmPacketExtension to create the gcm element with the json payload.
I am adding some headers in my-transformer:
public Message<?> transform(final Message<?> message) {
List<Item> items = doStuff(message);
final MessageBuilder<?> messageBuilder = MessageBuilder
.withPayload(message.getPayload())
.copyHeadersIfAbsent(message.getHeaders());
for (final Item item : items) {
messageBuilder.setHeader(item.getHeaderName(), item.getValue());
}
return messageBuilder.build();
}
And I wrote an integration test to confirm that my header is present on the output channel:
public static class HeaderTest extends TransformerTest {
#Test
public void test() throws Exception {
channels.input().send(new GenericMessage<>(TransformerTest.EXAMPLE_PAYLOAD));
final Message<?> out = this.collector.forChannel(this.channels.output()).poll(10, TimeUnit.SECONDS);
assertThat(out, HeaderMatcher.hasHeader("header-test", notNullValue()));
}
}
But, when I created a stream like:
http --port=1234 | my-transformer | log --expression=toString()
and sent the same EXAMPLE_PAYLOAD I received the following message in the logs log: GenericMessage [payload=..., headers={kafka_offset=0, id=f0a0727c-9351-274c-58b3-edee9ccbf6ce, kafka_receivedPartitionId=0, contentType=text/plain;charset=UTF-8, kafka_receivedTopic=myTopic.my-transformer, timestamp=1485171448947}].
Why isn't my header-test in the message headers?
-- EDIT --
So if I understood correctly I am supposed to do something like:
public class MyTransformer implements Transformer {
private final EmbeddedHeadersMessageConverter converter = new EmbeddedHeadersMessageConverter();
#Override
public Message<?> transform(final Message<?> message) {
List<Item> items = doStuff(message);
final MessageBuilder<byte[]> messageBuilder = MessageBuilder
.withPayload(((String) message.getPayload()).getBytes())
.copyHeadersIfAbsent(message.getHeaders());
final int itemsSize = items.size();
final String[] headerNames = new String[itemsSize];
for (int i = 0; i < itemsSize; i++) {
final Item item = items.get(i);
messageBuilder.setHeader(item.getHeaderName(), item.getValue());
headerNames[i] = item.getHeaderName();
}
final Message<byte[]> msg = messageBuilder.build();
final byte[] rawMessageWithEmbeddedHeaders;
try {
rawMessageWithEmbeddedHeaders = converter.embedHeaders(new MessageValues(msg), headerNames);
} catch (final Exception e) {
throw new HeaderEmbeddingException(String.format("Cannot embed headers from '%s' into message: %s", items, msg), e);
}
return new GenericMessage<>(rawMessageWithEmbeddedHeaders);
}
}
with spring.cloud.stream.bindings.output.producer.headerMode=raw set in application.properties and then convert the message payload on the receiving side? Or can I somehow make the receiving side automatically convert the message payload?
You don't say whether you are using Spring XD or Spring Cloud DataFlow, but the solution is similar in each case.
Since kafka has no native support for headers, we have to embed them in the message payload. Since we don't want to transport unnecessary headers, you have to opt-in for the headers you want transported by setting the header names in servers.yml for Spring XD or application.yml (or .properties) for a Spring Cloud Stream app.
EDIT
Unfortunately, there is no support for patterns. One option would be to use the EmbeddedHeadersMessageConverter yourself, and set the kafka mode to raw (on your transformer's output destination). Raw mode means the binder won't embed headers.
That way, the next app (without mode raw) should be able to decode the headers as if they had been encoded by the binder in your transformer. Javadocs here.
You are limited to 255 headers.
I have just started using Gmail SDK.
I am trying to get all the mail messages from my Gmail account. I tried using this:
ListMessagesResponse response = gmail.users().messages().list(user).execute();
List<Message> messages = response.getMessages();
The problem here is when I try to access the snippet using the code below I get null.
for(Message message : messages) {
System.out.println(message.getSnippet());
}
On the other hand I am being to get to messageId when I try this:
for(Message message : messages) {
System.out.println(message.getId());
}
My query is that am I doing something wrong or is it supposed to return only the messageId?
I have another function to which if you pass a particular messageId returns the message. Using this method I am able to get the Snippet and works perfectly fine.
private Message getMessage(String userId, String messageId) throws IOException {
Message message = gmail.users().messages().get(userId, messageId).execute();
System.out.println("Message snippet: " + message.getSnippet());
return message;
}
Do I have to call this method everytime to get each message? Is there not a way to get all the messages at once?
my application suppose to connect a web service and active some of his functions.
first, the application activate a "Login" function that gets as arguments username and password, the function search the user name and the password in a database and returning me if im logged in or not. and creating a session vars for me like:
Session["Username"] = User.Username;
Session["FullName"] = User.FullName;
and more...
and than i want to active another webservice function - UpdateProfile
that change my profile values on the database.
so, my application has a class with some private classes (asynctasks)
and every asynctask is responsible for one function in the webservice.
for example - the login asynctask:
private class LoginAsyncTask extends AsyncTask<String, String, User>
{
private String METHODNAME = "Login";
private String SOAPACTION = "http://tempuri.org/Login";
and more...
in this login asynctask i parse the comming back cookies like this:
cookies is a HashMap<String, String>();
try
{
//respHeaders = trans.call(SOAPACTION, envelope, null);
reshttpHeaders = trans.call(SOAPACTION, envelope, null);
}
catch (Exception e)
{
//connection error.
e.printStackTrace();
return null;
}
cookies.clear();
if (reshttpHeaders!=null) {
for (int i = 0; i < reshttpHeaders.size(); i++) {
HeaderProperty hp = (HeaderProperty)reshttpHeaders.get(i);
String key = hp.getKey();
String value = hp.getValue();
if (key!=null && value!=null) {
if (key.equalsIgnoreCase("set-cookie")){
String cookieString = value.substring(0,value.indexOf(";") );
cookies.put(cookieString.substring(0, cookieString.indexOf("=")),cookieString.substring(cookieString.indexOf("=")+1) );
break;
}
}
}
}
and than, in another asynctask called UpdateProfileAsynctask
im sending this cookie like this:
List<HeaderProperty> httpHeaders = new ArrayList<HeaderProperty>();
for (String cookie:cookies.keySet()) {
httpHeaders.add(new HeaderProperty("Cookie", cookie + "=" + cookies.get(cookie)));
}
try
{
//trans.call(SOAPACTION, envelope, reqHeaders);
trans.call(SOAPACTION, envelope, httpHeaders);
}
when i try to catch this packets with wireshark i see that the cookie that i get is:
Set-Cookie: ASP.NET_SessionId=kmwn4l2qzc0k1anfk1du4ty1; path=/; HttpOnly\r\n
and my cookie that i send is:
Cookie: ASP.NET_SessionId=kmwn4l2qzc0k1anfk1du4ty1\r\n
The problem is that the webservice dont recognize me (the second request is in the 20 minutes period).
this part of the code in the webservice running:
if (Session["Username"] == null)
return "Cant Update profile now, Your connection seems to be timeout";
and i get this message all time. but its stange that sometimes its working :/
thanks.
I fix my problems after reading your questions, thank you.
My code is like the folloiwng:
HeaderProperty headerPropertySessionId = new HeaderProperty("Cookie", "key1=value1");
List headerPropertyList = new ArrayList();
headerPropertyList.add(headerPropertySessionId);