Smack's FileTransferManager.createOutgoingFileTransfer only accepts full JIDs. How can I determine the full JID of a user in Smack? - xmpp

After hours of debugging and trying to find out why the file transfer was not working using aSmack, while normal messaging was, I finally managed to pin it down to this.
The Openfire server is sending the Rosters' JID missing the / at the end when I follow the method given in the Smack documentation to get a user's Roster list.
Collection<RosterEntry> entries = roster.getEntries();
for (RosterEntry r : entries) {
Log.v("Gabriel","Receiving: " + r.getUser());
}
For example if I receive a message from the user gabriel, I get the "From" as:
gabriel#dragonov/Smack
But the r.getUser() returns to the user as
gabriel#dragonov
Even
connection.getRoster().getPresence(contactName).getFrom()
is returning is as "gabriel#dragonov".
This is causing the File transfer to fail, but oddly not the regular messaging. However when I manually add the /Smack at the end of
OutgoingFileTransfer transferr = manager.createOutgoingFileTransfer(contactJID+"/Smack");
it works.
My question is, how can I receive the full JID with the resource part included or configure the file transfer so that it doesn't fail when using a bare JID?
Edit:
I have tried the following method:
Log.v("Gabriel", entries.size() + " buddy(ies):");
for (RosterEntry r : entries) {
Log.v("Pat","adding: " + r.getType() + " " + r.getName());
contacts.add(r.getUser());
}
for (String contact : contacts){
Iterator<org.jivesoftware.smack.packet.Presence> presences = connection.getRoster().getPresences(contact);
Log.v("Gabriel", contact+" has: ");
while(presences.hasNext()){
Log.v("Gabriel",presences.next().getFrom());
}
}
But I am still getting the bare ID.
The output:
gabriel#dragonov has:
gabriel#dragonov

Use Iterator<Presence> Roster.getPresences(String user) to get the presence information from all known resources of a user. For this Presence instances getFrom() should return a full JID which you can use in FileTransferManager.createOutgoingFileTransfer().
I have created SMACK-430, regarding the use of a full JID in createOutgoingFileTranfer(). It really should throw an exception so that smack users don't have to debug hours to find the reason (although it's stated in the method javadoc). SMACK-430 also explains why FileTransferManager needs a full JID and can not be used with a bare JID.

Related

MVC5 Mailkit send email with incorrect Email address

I am trying to send emails using my MVC5 application. To do this, I have installed Mailkit v 1.22.0 through NuGet package manager. And this is how my code looks like:
var FromAddress = "no-reply#email.com";
var FromAddressTitle = "My Org";
var connection = ConfigurationManager.ConnectionStrings["SmtpServer"].ConnectionString;
var Email = new MimeMessage();
Email.From.Add(new MailboxAddress(FromAddressTitle, FromAddress));
var AddressArray = value.SentTo.Split(';');
foreach (var item in AddressArray)
{
Email.To.Add(new MailboxAddress(item));
}
Email.Subject = value.Subject;
Email.Body = new TextPart("html")
{
Text = value.Content
};
using (var client = new SmtpClient())
{
client.Connect(connection);
client.Send(Email);
}
return "Email Successfully Sent";
which works fine except if a wrong recipient Email address has been entered, the application does not detect if the Email was actually sent or not (client.Send(Email) returns void). Is there a way to know if it really ended up getting sent to the recipient or not? If it is not possible with Mailkit, is there any other NuGet package that can do this?
The reason that SmtpClient.Send() returns void is that the SMTP protocol does not specify whether the message gets delivered successfully. All it can do us tell the client that the messages was accepted by the server or not (in which case MailKit will throw an exception).
If you need to know whether the message was successfully delivered, you will need to check for bounce messages sent to you which could take minutes or even hours.
The first thing you'll have to do, however, is subclass SmtpClient and override the GetEnvelopeId and GetDeliveryStatusNotifications methods.
Then, when you receive a bounce message, the top-level MIME part will typically be a multipart/report (represented by a MultipartReport object when using MimeKit). This multipart/report will then contain a message/delivery-status MIME part (and possibly others), which will have a list of header-like fields that specify the details about the delivery status for 1 or more recipients.
MimeKit will parse a lot of this for you (e.g. it has a MessageDeliveryStatus class which contains a StatusGroups property that you will want to use. However, what MimeKit does not do is parse the individual field values (but they shouldn't be that difficult for you to do, typically a few Split(';')'s should be enough iirc for some quick & dirty parsing).
You will want to read the spec for this at https://www.rfc-editor.org/rfc/rfc3464
The MimeKit docs linked above specify which sections to look closely at (I think 2.2 and 2.3).
I would recommend looking specifically at the Original-Recipient and Action fields.
original-recipient-field =
"Original-Recipient" ":" address-type ";" generic-address
generic-address = *text
action-field = "Action" ":" action-value
action-value =
"failed" / "delayed" / "delivered" / "relayed" / "expanded"
You will also need the Original-Envelope-Id field to figure out which message is being reported on:
original-envelope-id-field =
"Original-Envelope-Id" ":" envelope-id
envelope-id = *text
The envelope-id text will be the same string returned by your GetEnvelopeId implementation in the SmtpClient class.

Is there a way to fetch latest email from "Mail reader sampler" or "Beanshell Sampler"

I am able to fetch email from my email account using POP3 via "Mail Reader Sampler" listener. But its not retrieving latest email.
Is it possible to extract the latest email using Beanshell Sampler. If yes, can you please share the code if this is achievable.
As per below discussion - looks like it is not doable. But, wanted to check if this is achievable using any means?
Stackoverflow Discussion on how to fetch required email
You can do this programmatically, check out the following methods:
Folder.getMessageCount() - Get total number of messages in this Folder
Folder.getMessage(int msgnum) - Get the Message object corresponding to the given message number
According to the JavaDoc
Messages are numbered starting at 1 through the total number of message in the folder.
So the number of the last message will always be the same as the total number of messages in the given folder.
Example code which reads last email using POP3 protocol
import javax.mail.Folder
import javax.mail.Message
import javax.mail.Session
import javax.mail.Store
String host = "host"
String user = "username"
String password = "password"
Properties properties = System.getProperties();
Session session = Session.getDefaultInstance(properties)
Store store = session.getStore("pop3")
store.connect(host, user, password)
Folder inbox = store.getFolder("Inbox")
inbox.open(Folder.READ_ONLY)
int msgCount = inbox.getMessageCount()
Message last = inbox.getMessage(msgCount)
//do what you need with the "last" message
inbox.close(true)
store.close()
I would also recommend forgetting about Beanshell, whenever you need to perform scripting - use JSR223 Elements and Groovy language as Groovy has much better performance, it is more Java-compliant and it has some nice language features. See Apache Groovy - Why and How You Should Use It guide for more details.

"Re-opening" DocuSign "Delivered" envelope in embedded view

My question in a nutshell: Using the SOAP API, is there a way to allow the signer to "Re-open" an envelope that is in Delivered Status (Not expired or completed) in an embedded application?
The details: Using the SalesForce SOAP API examples given here https://github.com/docusign/docusign-soap-sdk (thank you to whoever provided these!), I am having great success creating NEW envelopes. However, using the methods provided in the samples, a brand new envelope is created without regard for existing envelopes. I would like to see if there are any unexpired, delivered envelopes and present that before creating a new one. Unfortunately, I'm not seeing any way to fetch an envelope using an Envelope ID (eg: C87908AD-908E-45F6-B4F9-8B6A514XXXXX) and present that to the signer.
Turns out this was pretty simple. If you know the Envelope ID, you can create a new token that can be used to load the envelope into your app. It looks like this:
try {
token = dsApiSend.RequestRecipientToken(
document_status.dsfs__DocuSign_Envelope_ID__c,'1',contact.FirstName + ' ' + contact.LastName,contact.Email,assert,clientURLs);
} catch ( CalloutException e) {
System.debug('Exception - ' + e );
envelopeId = 'Exception - ' + e;
}

How to monitor delivery of emails sent by salesforce by source code?

I have following questions. Assuming I have following code
public class MessageMaker {
public static void helloMessage() {
System.debug( 'Entry point' );
Case c = new Case();
insert c;
EmailMessage e = new EmailMessage();
System.debug( 'EmailMessage created' );
e.parentid = c.id;
// Set to draft status.
// This status is required
// for sendEmailMessage().
e.Status = '5';
e.TextBody =
'Sample email message.';
e.Subject = 'Apex sample';
e.ToAddress = 'my#mail.com';
insert e;
List<Messaging.SendEmailResult>
results =
Messaging.sendEmailMessage(new ID[]
{ e.id });
System.debug(results.size());
System.debug(results[0].success);
System.debug(results[0].getErrors().size());
System.assertEquals(1, results.size());
System.assertEquals(true, results[0].success);
}
}
1.First question. I want to find out using apex code if the message was really delivered.
Here documentation says http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_calls_sendemail_emailresult.htm
Even if success = true, it does not mean the intended recipients received the email, as it could have bounced or been blocked by a spam blocker. Also, even if the email is successfully accepted for delivery by the message transfer agent, there can still be errors in the error array related to individual addresses within the email.
So I have been trying to send email by apex code and look for results[0].success. It seems it says like it is described in documentation, so success is true even though email address was incorrect.
Also I have tried to check this manually through email logs http://eu2.salesforce.com/help/doc/en/email_logs.htm
And I have found following row in resulting log regarding my email sent to incorrect address
9/2/2013 9:36 66/FC-09306-20B54225 T julfy#i.ia
julfy=i.ua__0-6uvic1ltvun1nf#95mngihd2hpe0w.b-ysubea0.bl.bnc.salesforce.com 1434 005b0000000J7bm
<_0vTJ000000000000000000000000000000000000000000000MSHRSY00W1-CKg3DShWC5xu24ccHFA#sfdc.net>
1 311.627583 421 4.4.0 [internal] no MXs for this domain could be
reached at this time
But I don't know how to access this information by apex code. Any thoughts?
Second question. If message was delivered and recipient forwarded it, is any possibility to monitor that using apex code? Anybody?
You can't do either of those things. APEX runs on Salesforce's servers and when you send an email it leaves that environment. The only time you can monitor a successful response is when you're dealing with an API that generates webhooks.

Smack service discovery without login gives bad-request(400)

I am trying to discover items that a pubsub service provides. When I log into the target server, I can get the response successfully. But when I connect bu do not login, it gives a bad request error.
This is the code:
ConnectionConfiguration config = new ConnectionConfiguration(serverAddress, 5222);
config.setServiceName(serviceName);
connection = new XMPPConnection(config);
connection.connect();
connection.login(userName, password); //!!!when I remove this line, bad request error is received
ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection);
DiscoverItems items;
try {
items = discoManager.discoverItems("pubsubservice." + serverName);
} catch (XMPPException e) {
e.printStackTrace();
}
Is there a way to discover items when the user is not logged in, but the connection is established?
No, you must authenticate to send stanzas to any JID in XMPP (otherwise they would not be able to reply to you, since they wouldn't know your address).
Perhaps one option for you is anonymous authentication. Most servers support it, and it creates a temporary account on the server for you, with a temporary JID. You don't need a password, and login time is quick.
#MattJ is correct and you could try using anon login. That will get you part way there.
Your current request will only get you the nodes though, after which you will have to get the items for each node. It would be simpler to use PubsubManager to get the information you want since it provides convenience methods for accessing/using all things pubsub.
Try the documentation here, the getAffiliations() method is what you are looking for.
BTW, I believe the typical default service name for pubsub is pubsub not pubsubservice. At least this is the case for Openfire.