Good day guys!. I'm having a problem trying to submit an international sms vía SMPP (using Logica Java library). I'm gonna summarize the tests I've done. I'm using WireShark to monitor SMPP related activities.
(Working)
//Connect and stablish session
Connection conn = new TCPIPConnection(providerAddress, port);
Session session = new Session(conn);
BindRequest breq = new BindTransmitter();
breq.setSystemId(user);
breq.setPassword(pass);
breq.setSystemType("CMT");
breq.setInterfaceVersion((byte)34);
breq.setAddressRange((byte)0x01, (byte)0x01,null);
Response resp = session.bind(breq);
//Create message
SubmitSM msg = new SubmitSM();
msg.setDestAddr((byte)1, (byte)1, "58412014XXXX");
msg.setSourceAddr((byte)1, (byte)1, "58412014XXXX");
msg.setShortMessage("Test from tedexis","ISO-8859-1");
//Here we submit message
session.submit(msg);
//Disconnect
session.unbind();
Result: Message is delivered correctly. Here we validate credentials are valid, and notice the source and destination addresses are the same
(Failing) The code remains the same except for the message destination address which is now set for an INTERNATIONAL PHONE NUMBER
msg.setSourceAddr((byte)1, (byte)1, "1321237XXXX");
Result: Fails, checking WireShark I observe the following exception during the submit:
SMPP Submit_sm - resp: "Invalid destination address"
We may think that our credentials are not valid for international deliveries but we are currently using these credentials delivering international messages through their webservice interface.
I must be missing a configuration setting or wrongly setting one already, but I ran out of ideas, if anyone can point me in the right direction I would be glad.
First, you dont have to set your address range since you're binding as a transmitter, because the address range is used to inform the SMSC that this 'receiver' session will handle MO messages from the desired address range.
As for sending to international numbers, i'm not into logica's API but i'm pretty sure that you're missing to set the destination address ton to 1 (international number) and the destination address npi to 0 (Unknown) or 1 (ISDN) and retry the sending.
If the error persists, you'll have to call your provider, it is possible that they gave you the permission to send to international numbers through webservice only.
Related
I have SMPP server, use CloudHoper.
When I get a message I should return a delivery report.
Please, tell me, how I can do it?
At this moment I return SubmitSmResp...
Of course you still need to answer the SubmitSm PDU with a SubmitSmResp PDU as you do now.
A delivery report is a "special" DeliverSm PDU which is generated in your SMPP server and sent additionally to your client. See SMPP 3.4 Appendix B how it is formatted (https://github.com/twitter/cloudhopper-smpp/blob/master/src/etc/SMPP_v3_4_Issue1_2.pdf). You also need to set esmClass of the DeliverSm PDU to 0x04 to indicate it's a delivery report.
If your client is using a transceiver bind, you can use the same session to send the DeliverSm PDU to, otherwise you need use the clients receiver session. If no active session is available you need to queue the DeliverSm PDU.
The main question is when to send the delivery report. First of all, you may send only a delivery report, if the client requested one, by setting the 4th bit of the SubmitSm esmClass.
Although, if your client is using a transceiver connection, don't send it directly in the firePduRequestReceived handler. The client may receive it before it receives the SubmitSmResp. Additionally this delivery report would not have more value than the SubmitSmResp itself.
So there are three cases when you may generate this delivery report and queue it until you have a proper session from your client to send it to:
1) When you receive some external event indicating that the former SubmitSm was actually processed (e.g. delivered) by it's destination.
2) When you are able to forward the SubmitSm to the next processing unit.
3) When you detect any error or the SubmtSm expired
Create a DELIVER_SM for that message and send that to the client.
We tried to send mail using javax.mail. While sending mails we got following exception:
**sendMail - Message Sending Failed: Invalid Addresses;
nested exception is:
javax.mail.SendFailedException: 550 #5.1.0 Address rejected.2013-02-28 13:17:08,236**
What might be the problem?
It means that the receiving server does not recognise the mailbox (the part before the '#') of the e-mail address. It could be that it was misspelled, that it is simply a non-existing name, or it could even be that the receiving server was set to reject a message (e.g. spam) by replying with code 550.
Here is one of many pages that summarises the SMTP reply codes, and gives links to various relevant RFCs: http://www.greenend.org.uk/rjk/tech/smtpreplies.html.
EDIT: I need a bit more space to answer your question than the comments allow.
#RaghuKing, if you look at the Javadoc for javax.mail.SendFailedException, you will notice that you can call 3 methods on such an exception object (inside the catch block):
getInvalidAddresses() to get an array of addresses that are invalid and thus not sent to,
getValidSentAddresses() to get an array of addresses to which this message was sent succesfully, and
getValidUnsentAddresses() to get an array of addresses that are valid but to which the message was not sent to.
(Obviously, if one sends a message to multiple recipients, some may succeed and some fail, but the exception is thrown if there is at least one failure, regardless of how many successes. Obviously also if you are sending to only one address, you will have that one address in only one of these arrays, and it will probably NOT be in the ValidSent list.
These arrays will give you more information how to handle the exception, depending of the type of array an address is in. This will obviously depend on you application, but these might be reasonable suggestions:
Invalid Addresses: tell the user that the message was not sent because the address was wrong, for each invalid address in the list, and provide a way to correct the address, then try to resend to the correct address (or cancel if the user does not provide a different address);
Valid Sent Addresses: Don't resend;
Valid Unsent Addresses: Try to resend to these addresses. Sending probably stopped before getting to these addresses because of a previous incorrect address.
But in the end it is you who has to apply common sense, and perhaps experiment a little with the functions you don't understand until you understand them.
This code can print logs for invalid address(es):
try {
sender.send(message);
}catch (MailSendException me){
detectInvalidAddress(me);
}
private void detectInvalidAddress(MailSendException me) {
Exception[] messageExceptions = me.getMessageExceptions();
if (messageExceptions.length > 0) {
Exception messageException = messageExceptions[0];
if (messageException instanceof SendFailedException) {
SendFailedException sfe = (SendFailedException) messageException;
Address[] invalidAddresses = sfe.getInvalidAddresses();
StringBuilder addressStr = new StringBuilder();
for (Address address : invalidAddresses) {
addressStr.append(address.toString()).append("; ");
}
logger.error("invalid address(es):{}", addressStr);
return;
}
}
logger.error("exception while sending mail.", me);
}
Had experienced this same exception .I realized that i could not send email to unknown users . After consulting , i found out that our SMTP server was not an open mail relay server read Open mail Relay.
I am coding POP3 and SMTP servers using Java for an university project.
I can send emails using my SMTP server via a client (ie: Thunderbird) and my server sends them without any problem.
When an external sender agent, like gmail or hotmail, tries to send an email using my SMTP server, it does not complete the communication because it sends the QUIT command after the MAIL command. Why the external agent does that? Didn't I obey to the SMTP protocol?
The problem is that when I receive a connection from the an external server that wants to send me mail the following happens (me: my SMTP server, sender: sender agent). Here is an example with a gmail agent.
sender: establishes a connection
me: 220 Welcome
sender: HELO agent id
me: 250 Fine
sender: MAIL FROM:<address#gmail.com>
me (after address verification): 250
sender: QUIT
me: 221
Relevant code snippets (full class code is at http://code.google.com/p/sd-mail-server-claudiani-ferrari/source/browse/src/controller/smtp/SMTPCommandHandler.java?repo=mailserver )
private void MAILCommand(CommunicationHandler communicationHandler,
BufferedOutputStream writer,
PersistanceManager persistanceManager,
String clientId,
String argument)
{
String address = getAddressFromArgument(argument);
if (!isValidAddress(address, persistanceManager)) {
communicationHandler.sendResponse(writer,
SMTPCode.SYNTAX_ERROR.toString(),
"Address is not valid.");
return;
}
// Initialize data
persistanceManager.create(StorageLocation.SMTP_TEMP_MESSAGE_STORE,
FieldName.getSMTPTempTableFromFieldOnly(),
clientId, address);
communicationHandler.sendResponse(writer, SMTPCode.OK.toString(), "");
}
private void RCPTCommand(CommunicationHandler communicationHandler,
BufferedOutputStream writer,
PersistanceManager persistanceManager,
String clientId,
String argument)
{
String address = getAddressFromArgument(argument);
// Check the address
if (!isValidAddress(address, persistanceManager)) {
communicationHandler.sendResponse(writer,
SMTPCode.SYNTAX_ERROR.toString(),
"Address is not valid.");
return;
}
persistanceManager.addToSet(StorageLocation.SMTP_TEMP_MESSAGE_STORE,
clientId,
FieldName.SMTP_TEMP_TO_ADDRESSES,
address);
communicationHandler.sendResponse(writer, SMTPCode.OK.toString(), "");
}
private void DATACommand(CommunicationHandler communicationHandler,
BufferedOutputStream writer,
PersistanceManager persistanceManager,
String clientId)
{
communicationHandler.sendResponse(writer,
SMTPCode.INTERMEDIATE_REPLY.toString(),
"Start mail input; end with [CRLF].[CRLF]");
}
Have you tried replying with 250 OK instead of just 250 ? RFC 2821 says that this should be the reply of a MAIL FROM line:
If accepted, the SMTP server returns
a 250 OK reply. If the mailbox specification is not acceptable for
some reason, the server MUST return a reply indicating whether the
Your mail client might be satisfied with seeing 250, while Google/Hotmail might expect 250 OK.
Edit
I think the text string isn't optional in this case, see section 4.2 of RFC 2821:
An SMTP reply consists of a three digit number (transmitted as
three numeric characters) followed by some text unless specified
otherwise in this document.
The current RFC 5321 suggests that clients should accept no text:
An SMTP client MUST determine its actions only by the reply code,
not by the text (except for the "change of address" 251 and 551
and, if necessary, 220, 221, and 421 replies); in the general case,
any text, including no text at all (although senders SHOULD NOT
send bare codes), MUST be acceptable. The space (blank) following
the reply code is considered part of the text. Whenever possible,
a receiver- SMTP SHOULD test the first digit (severity indication)
of the reply code.
I have to send messages to many clients. But many of them bounce back. I want a list of those email addresses. How can I get that list from my Java application?
Make a special email address bounced#yourdomain.com where you will capture all bounced emails for analysis.
Add the following header to your sent emails:
Return-Path: <bounced#yourdomain.com>
Now the emails are going to bounce back to that address.
Read emails at that address from your java program from time to time, for example via IMAP (or depending on your server via a notification interface/whatever), and when you see an email address record it in your database
Note that if you are doing a newsletter app, you should not blacklist the email from the first time, but make count it's bounces, and blacklist it after 3-4 bounces (some people set their email to bounce when they go in vacation and such, so they need special taking care of).
I solve this question using
SMTPMessage msg = new SMTPMessage(getSession());
msg.setEnvelopeFrom(bounceAddr);
Please see the javamail doc and see it:
void com.sun.mail.smtp.SMTPMessage.setEnvelopeFrom(String from)
Set the From address to appear in the SMTP envelope. Note that this is different than the From address that appears in the message itself. The envelope From address is typically used when reporting errors. See RFC 821 for details.
If set, overrides the mail.smtp.from property.
Parameters:
from the envelope From address
When I send out an e-mail and it isn't received, how can I figure out what the cause of the problem is?
My app sends e-mails through SMTP using the Apache commons-mail library. For testing purposes, I am using the gmail SMTP server. (Our production app uses an internal server on our network).
In one case on the test server, I have a batch job that generates 5 e-mails with attachments. Some e-mails are received and others are marked as sent, but never appear in my inbox. There doesn't seem to be a pattern to which e-mails are received and which ones silently vanish.
The code that sends and checks for errors looks like this:
final Mail mail = ...;
//The Mail class is our app's mail object, which provides data used to generate the MIME e-mail and record the results.
final MultiPartEmail email = ...;
try {
email.setSentDate(mail.getDateSent());
email.send();
}
catch (EmailException ee) {
success = false;
mail.setDateSent(null);
getLog().error("Mail not sent: ", ee);
if (ee.getMessage().indexOf("receiver address required") != -1) {
mail.setErrorMessage(ee.getMessage());
getLog().error(mail.toString());
}
}
In the debugger, I determine that no exception is thrown.
My first guess was that the attachment size is too large; but, gmail supposedly supports 25MB attachments, and my largest attachment is 14.3 MB. In some cases when I run the entire batch of 5 e-mails, the e-mail with the largest attachment gets through, and the smaller ones disappear.