Amazon SES Max Send Rate - email

We're using Amazon SES to send emails, and it says our max send rate is 5 per second.
What happens if we send more than 5 per second? Do they queue or are they rejected?
We have a mailing list that has over 1,000 people on it and they all attempt to send all in one go (and we are approved to use Amazon SES for this purpose).
Here's the code I'm using to send the email:
namespace Amazon
{
public class Emailer
{
/// <summary>
/// Send an email using the Amazon SES service
/// </summary>
public static void SendEmail(String from, String To, String Subject, String HTML = null, String emailReplyTo = null, String returnPath = null)
{
try
{
List<String> to
= To
.Replace(", ", ",")
.Split(',')
.ToList();
var destination = new Destination();
destination.WithToAddresses(to);
var subject = new Content();
subject.WithCharset("UTF-8");
subject.WithData(Subject);
var html = new Content();
html.WithCharset("UTF-8");
html.WithData(HTML);
var body = new Body();
body.WithHtml(html);
var message = new Message();
message.WithBody(body);
message.WithSubject(subject);
var ses = AWSClientFactory.CreateAmazonSimpleEmailServiceClient("xxx", "xxx");
var request = new SendEmailRequest();
request.WithDestination(destination);
request.WithMessage(message);
request.WithSource(from);
if (emailReplyTo != null)
{
List<String> replyto
= emailReplyTo
.Replace(", ", ",")
.Split(',')
.ToList();
request.WithReplyToAddresses(replyto);
}
if (returnPath != null)
request.WithReturnPath(returnPath);
SendEmailResponse response = ses.SendEmail(request);
SendEmailResult result = response.SendEmailResult;
}
catch (Exception e)
{
}
}
}
}

I think that the request are rejected if we are trying to send more messages per second then the allowed limit.
I found this in the SES Blog http://sesblog.amazon.com/post/TxKR75VKOYDS60/How-to-handle-a-quot-Throttling-Maximum-sending-rate-exceeded-quot-error
When you call Amazon SES faster than your maximum allocated send rate, Amazon SES will reject your over the limit requests with a "Throttling – Maximum sending rate exceeded" error.
A "Throttling – Maximum sending rate exceeded" error is retriable. This error is different than other errors returned by Amazon SES, such as sending from an email address that is not verified or sending to an email address that is blacklisted. Those errors indicate that the request will not be accepted in its current form. A request rejected with a "Throttling" error can be retried at a later time and is likely to succeed.
If they would queue the requests this would be a great option but our experience is that they don't. Please let me know if I understand something wrong here.

I've since found out the answer is that they are rejected.

If you attempt to send an email after reaching your daily sending quota (the maximum amount of email you can send in a 24-hour period) or your maximum sending rate (the maximum number of messages you can send per second), Amazon SES drops the message and doesn't attempt to redeliver it.
https://docs.aws.amazon.com/ses/latest/DeveloperGuide/reach-sending-limits.html
I'm getting stuck on this situation and on the way finding the best way for resoling.

Related

UaSerializationException: request exceeds remote max message size: 2434140 > 2097152

I am a rookie, I tried to use the following code for bulk subscription, but something went wrong, how can I solve this problem
OpcUaSubscriptionManager subscriptionManager = opcUaClient.getSubscriptionManager();
UaSubscription subscription = subscriptionManager.createSubscription(publishInterval).get();
List<MonitoredItemCreateRequest> itemsToCreate = new ArrayList<>();
for (Tag tag : tagList) {
NodeId nodeId = new NodeId(nameSpace, tag.getPath());
ReadValueId readValueId = new ReadValueId(nodeId, AttributeId.Value.uid(), null, null);
MonitoringParameters parameters = new MonitoringParameters(
subscription.nextClientHandle(), //
publishInterval, //
null, // filter, null means use default
UInteger.valueOf(queueSize), // queue size
true // discard oldest
);
MonitoredItemCreateRequest request = new MonitoredItemCreateRequest(readValueId,
MonitoringMode.Reporting, parameters);
itemsToCreate.add(request);
}
BiConsumer<UaMonitoredItem, Integer> consumer =(item, id) ->
item.setValueConsumer(this::onSubscriptionValue);
List<UaMonitoredItem> items = subscription.createMonitoredItems(
TimestampsToReturn.Both,
itemsToCreate,
consumer
).get();
for (UaMonitoredItem item : items) {
if (!item.getStatusCode().isGood()) {
log.error("failed to create item for nodeId={} (status={})",item.getReadValueId().getNodeId(), item.getStatusCode());
}
}
How many items are you trying to create?
It seems that the resulting message exceeds the limits set by the server you are connecting to. You may need to break your list up and create the items in smaller chunks.
I do not know the library that you use, but one of the previous steps for a OPC UA client to connect to a server is to negotiate the maximum size of the buffers, the message total size and the max number or chunks a message can be sent, this process is called by the OPC UA documentation as "Handshake".
If your request is too long it should be split and sent in several chunks according to the limits previously negotiated with the server.
And the server will probably also reply in several chunks, all that has to be considered in the programming of an OPC UA client.

How to set up and use the Kin blockchain in a Unity app - Step by step

What is a good step by step explanation on how to use the Kin Unity SDK in an empty project in Unity?
Option 1: Use a pre-made wrapper
Use the wrapper in this 10 minute set up code (client and server) and call it as follows:
kinWrapper.SendPayment(1.00M, "test send", address);
kinWrapper.Balance();
//etc
Here is a detailed tutorial on implmenting the wrapper.
Option 2: Create your own wrapper
The Kin blockchain is a fork of the stellar protocol. As such, operations in your app will boil down to the following:
Creating accounts on the blockchain
Funding accounts on the blockchain
Sending payments
You can clone a sample implementation here - or you can follow the steps below to get a basic understanding.
Installation
Create an empty Unity project, and install the Kin Unity Plugin and modify your gradle file as described here.
NOTE: The SDK only runs on an Android/iOS device or emulator. The SDK will not run in the unity editor or unity remote -so you will need to compile and run the code in an emulator or device.
Implementation
Create an empty MonoBehaviour script - name it KinWrapper, and declare the Kin namespace:
using Kin;
You can also enable blockchain listeners by adding the following to your MonoBehaviour :
public class KinWrapper : MonoBehaviour, IPaymentListener, IBalanceListener
Instantiating
Next declare instances of the Kin Client and Kin Account
private KinClient kinClient;
private KinAccount kinAccount;
The client handles the native code depending on the platform you are using. (Android or iOS). The account is the main interface you will be using.
Creating an account
Before using the account, you first have to instantiate it through the client.
kinClient = new KinClient(Kin.Environment.Test, "appId");
if (!kinClient.HasAccount())
{
kinAccount = kinClient.AddAccount();
}else{
kinAccount = kinClient.GetAccount(0);
}
The code above first checks to see if a local account exists on the device. If it doesn't, it creates an account on the device and returns that as a reference.
NOTE: A 'created account' is simply a public key and private key generated on the device. These local keys enable the device to communicate with the blockchain.
You can now get the public key (client's blockchain address) by calling:
kinAccount.GetPublicAddress();
Onboarding/ Funding an account
Because this key only exists locally, you need to 'on-board' it to the blockchain. In other words, a special function needs to be called, to fund and register it online. Before this step is done, the address is considered invalid on the blockchain, and cannot receive or make transactions. This is part of the stellar protocol to avoid spam and unnecessary account creation.
You can check if the account has been on-boarded and funded by calling the following function:
kinAccount.GetStatus(GetStatusCallback)
void GetStatusCallback(KinException ex, AccountStatus status)
{
if (status == AccountStatus.Created)
{
}
else
{
}
}
To on-board and fund an account on the test blockchain, you have 3 options:
Option 1: You can do this manually by pasting the address on Kin's friend-bot service. This will on-board the account for you automatically.
Option 2: You can call the friend-bot through your code as an http request
https://friendbot-testnet.kininfrastructure.com/?addr=address_here
public static IEnumerator FundAccount( string publicAddress, Action<bool> onComplete = null )
{
var url = "http://friendbot-testnet.kininfrastructure.com/?addr=" + publicAddress;
var req = UnityWebRequest.Get( url );
yield return req.SendWebRequest();
if( req.isNetworkError || req.isHttpError )
{
Debug.Log( req.error );
if( onComplete != null )
onComplete( false );
}
else
{
Debug.Log( "response code: " + req.responseCode );
Debug.Log( req.downloadHandler.text );
if( onComplete != null )
onComplete( true );
}
}
Option 3: You can use server side code to fund it yourself (which you must do in a production environment). Basically, your client will need to call your server and request to be on-boarded. Your server can then use Kin's python SDK or node SDK to perform the on-boarding.
Here is a handy python implementation or Node.js implementation you can use for your server.
Calling the implementation from Unity is as simple as follows:
public IEnumerator FundMe(decimal amount, Action<bool> fundCallback = null)
{
WWWForm form = new WWWForm();
form.AddField("address", kinAccount.GetPublicAddress());
form.AddField("amount", amount.ToString());
reqUrl = "http://address.to.your.server";
var req = UnityWebRequest.Post(reqUrl, form);
yield return req.SendWebRequest();
if (req.isNetworkError || req.isHttpError)
{
Debug.LogError(req.error);
fundCallback(false);
}
else
{
fundCallback(true);
}
}
NOTE: Kin has two blockchains. Production and Test. The test blockchain merely has "play currency" that you can run tests on without incurring costs. The production blockchain has real world value Kin
Calling Other Functions
GetBalance()
account.GetBalance(GetBalanceCallback);
void GetBalanceCallback(KinException ex, decimal balance)
{
if (ex == null)
{
Debug.Log( "Balance: " + balance );
}
else
{
Debug.LogError( "Get Balance Failed. " + ex );
}
}
DeleteAccount()
kinClient.DeleteAccount(0);
NOTE: GetBalance() needs a callback because it's communicating with the blockchain online. DeleteAccount() doesn't because it simply deletes the private and public keys on the client. Once deleted, these keys can not be recovered.
Handling transactions
Transactions have the following parameters:
Memo: an optional string with extra information.
Address: the address of the recipient
Amount: amount of Kin you are sending (excluding fees)
Fee: the fee you will pay for your transaction to be processed by the blockchain. The current fee is 100/100000 KIN. This fee protects the blockchain from spam.
NOTE: The fee is denominated in the smallest unit of Kin. (Quark). Just like the smallest unit of a dollar is a cent. So when calling a transaction, set the fee to 100 (quarks) - which is 100/100000 KIN. Setting the fee tells the blockchain you are explicitly agreeing to pay the transaction fee. If you set the fee too low, your transaction will be rejected.
You can view all transactions on Kin's blockchain at: https://laboratory.kin.org/index.html#explorer?resource=payments
To send a payment, first build the transaction locally :
kinAccount.BuildTransaction(address, amount, fee, memo, BuildTransactionCallBack);
Building a transaction performs several operations on the client to authorise it and sign it. After the transaction is built, use the following callback to send it to Kin's blockchain.
void BuildTransactionCallBack(KinException ex, Transaction transaction)
{
if (ex == null)
{
kinAccount.SendTransaction(transaction, SendTransactionCallback);
}
else
{
Debug.LogError("Build Transaction Failed. " + ex);
}
}
Once you have sent the transaction to Kin's blockchain, you can listen for the response, to make sure it went through correctly. A transaction typically takes less than 10 seconds to complete.
void SendTransactionCallback(KinException ex, String transactionId)
{
if (ex == null)
{
//Success
}
else
{
Debug.LogError("Send Transaction Failed. " + ex);
}
}
NOTE: You should use co-routines for functions that need to wait. This will prevent your code from hanging while waiting for responses, and will create a better user experience.
Sending transactions with zero fees
You can send transactions with zero fees by being whitelisted by the Kin Foundation. To get whitelisted, simply register with the Kin Developer Program. Once approved, you can perform an extra step to let your client send transactions with zero fees.
To send a zero-fee transaction after building the transaction:
The client will need to contact your whitelisted server.
Your server will approve/ sign the transaction and send it back to the client.
The client will then send this approved transaction to Kin's blockchain, and it will be processed for free.
We have already built the transaction, now we whitelist it
void BuildTransactionCallBack(KinException ex, Transaction transaction)
{
if (ex == null)
{
StartCoroutine(WhitelistTransaction(transaction, WhitelistTransactionCallback))
}
else
{
Debug.LogError("Build Transaction Failed. " + ex);
}
}
We are calling our whitelisted server to authorise the transaction
IEnumerator WhitelistTransaction(Transaction transaction, Action<string, string> onComplete)
{
var postDataObj = new WhitelistPostData(transaction);
var postData = JsonUtility.ToJson(postDataObj);
var rawPostData = Encoding.UTF8.GetBytes(postData);
// UnityWebRequest does not work correclty when posting a JSON string so we use a byte[] and a hacky workaround
var req = UnityWebRequest.Post(baseURL + whitelistURL, "POST");
req.SetRequestHeader("Content-Type", "application/json");
req.uploadHandler = new UploadHandlerRaw(rawPostData);
yield return req.SendWebRequest();
if (req.isNetworkError || req.isHttpError)
{
Debug.LogError(req.error);
onComplete(null, null);
}
else
{
onComplete(req.downloadHandler.text, transaction.Id);
}
}
Our server has approved the transaction and sent back a signed string. We now send this signed string to Kin's blockchain
void WhitelistTransactionCallback(string whitelistTransaction, string transactionId)
{
if (whitelistTransaction != null)
{
kinAccount.SendWhitelistTransaction(transactionId, whitelistTransaction, SendTransactionCallback);
}
else
{
Debug.LogError("Whitelisting Transaction Failed. ");
}
}
As usual, we wait to see if the transaction was successful
void SendTransactionCallback(KinException ex, String transactionId)
{
if (ex == null)
{
//Success
}
else
{
Debug.LogError("Send Transaction Failed. " + ex);
}
}
Before your server has been approved for whitelisting, you can use this pre-approved server in the TEST environment. http://34.239.111.38:3000/whitelist.
public static IEnumerator WhitelistTransaction( Transaction transaction, Action<string> onComplete = null )
{
var postDataObj = new WhitelistPostData( transaction );
var postData = JsonUtility.ToJson( postDataObj );
var rawPostData = Encoding.UTF8.GetBytes( postData );
// UnityWebRequest does not work correclty when posting a JSON string so we use a byte[] and a hacky workaround
var url = "http://34.239.111.38:3000/whitelist";
var req = UnityWebRequest.Post( url, "POST" );
req.SetRequestHeader( "Content-Type", "application/json" );
req.uploadHandler = new UploadHandlerRaw( rawPostData );
yield return req.SendWebRequest();
if( req.isNetworkError || req.isHttpError )
{
Debug.Log( req.error );
if( onComplete != null )
onComplete( null );
}
else
{
Debug.Log( "response code: " + req.responseCode );
Debug.Log( req.downloadHandler.text );
if( onComplete != null )
onComplete( req.downloadHandler.text );
}
}
Once approved, you can use the sample python implementation or Node.js implementation to approve transactions on your server. You can also use the node.js SDK.
Listening to events on the blockchain
You can add listeners to prevent your client from over-querying the blockchain. Simply add the following code
kinAccount.AddPaymentListener(this);
kinAccount.AddBalanceListener(this);
public void OnEvent(PaymentInfo data)
{
//Listening for incoming and outgoing payments
}
public void OnEvent(decimal balance)
{
//Listening for changes in client's balance
}
Putting it all together
You can find this code implemented on: https://github.com/hitwill/kin-sdk-unity-tutorial under the MIT license.
Developer Playbook
You can also check this Developer Playbook - for some higher level concepts of creating with Kin.
Best practices
UX
(placeholder)
Server side security
Here is a great writeup on server side security.
Client side security
(placeholder)
Reducing calls to the blockchain
(placeholder)

How to know who received a message in a MUC room

For my thesis, I am using Smack to log a XMPP network that uses the MUC module.
Another software is currently sending IoT sensor data into different MUC rooms.
I'd like to know for every message sent into a MUC room, which users were in that room at the time of the message. Is this possible? I could use a messageListener to every muc room, however the listener only receives a message as an argument. Therefore I could not know who is logged into the room inside the listener method.
you can get all muc message in StanzaListener in xmpp. Please follow few steps to done this
Step 1. Declare as a global variables
ChatManagerListener chatListener;
Chat chat;
StanzaListener packetListener;
Step 2. Use this code in oncreate or in fragment
Note: Make sure you have connected with chat server.
packetListener = new StanzaListener() {
#Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException, InterruptedException {
if (packet instanceof Message) {
final Message message = (Message) packet;
}
}
};
XMPP.getInstance().getConnection(acitiviy)).addAsyncStanzaListener(stanzaListener, null);
ServiceDiscoveryManager sdm = ServiceDiscoveryManager
.getInstanceFor(XMPP.getInstance().getConnection(acitiviy)));
sdm.addFeature("jabber.org/protocol/si");
sdm.addFeature("http://jabber.org/protocol/si");
sdm.addFeature("http://jabber.org/protocol/disco#info");
sdm.addFeature("jabber:iq:privacy");
Step 3. Methods for one to one chat purposer
void sendMessage(String message) {
if (chat != null) {
try {
chat.sendMessage(message);
Message msg = new Message();
msg.setTo(JidCreate.bareFrom(jid));
msg.setFrom(XMPP.getInstance().getConnection(acitiviy)
.getUser());
ChatStateExtension ext = new ChatStateExtension(
ChatState.paused);
msg.addExtension(ext);
lastComposing = System.currentTimeMillis();
chat.sendMessage(msg);
} catch (SmackException.NotConnectedException e) {
} catch (Exception e) {
}
}
}
Step 4. On destroy
XMPP.getInstance().getConnection(acitiviy)).removeAsyncStanzaListener(stanzaListener);
Hope this will help you and if you want more information take a look from here. Thankyou
Nothing prervents you from calling Multi UserCaht.getParticipants() from within the listener. But be warned: If your goal is to determine the other receivers of receivers, then this approach is fragile. I also suggest to think about using PubSub instead of MUC for your IoT use case.

Duplicate message received in XMPP Multi User Conference Room

When device1 is sending the message to the conference room "del#conference.jabber.org"
the message is dispalyed in the chat list as well as a duplicated message is also displayed that is being send by the conference room "del#conference.jabber.org". I'm stuck, why i'm getting duplicate message.
public void setConnection(XMPPConnection connection) {
this.connection = connection;
if (connection != null) {
PacketFilter filter = new MessageTypeFilter(Message.Type.groupchat);
connection.addPacketListener(new PacketListener() {
#Override
public void processPacket(Packet packet) {
Message message = (Message) packet;
if (message.getBody() != null) {
String fromName = StringUtils.parseBareAddress(message.getFrom());
String[] parts = fromName.split("#");
String from = parts[0].trim();
messages.add(from + ":");
messages.add(message.getBody());
// Add the incoming message to the list view
mHandler.post(new Runnable() {
public void run() {
setListAdapter();
}
});
}
}
}, filter);
}
}
The send message is on button click, which is as follows
Button send = (Button) this.findViewById(R.id.sendBtn);
send.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Message mg = muc.createMessage();
String text = textMessage.getText().toString();
mg.setBody(text);
Log.i("XMPPChatDemoActivity ", "Sending text ");
if (connection != null) {
connection.sendPacket(mg);
messages.add("Me :");
messages.add(text);
setListAdapter();
}
textMessage.setText("");
}
});
and this is what i have written to connect the conference room
muc = new MultiUserChat(connection, "del#conference.jabber.org");
muc.join("alias name","password");
output what i'm getting when sending message
me: hello
del: hello
what i want i no duplicate message when i send the message i.e
me: hello
When you're in a MUC room you receive copies of all the messages, including your own.
http://xmpp.org/extensions/xep-0045.html#message - "and reflect the message out to the full JID of each occupant."
So for MUCs (not for direct messages) you will get a duplicate if you log both on send and on receive (assuming you have sufficient access to post, etc.). Your options are, largely, either to not log it on send (which is the option most clients go for) or to attempt to do smart message matching to detect when you receive your own message and elide it. The former option ensures that everyone sees a consistent view of message ordering, which some people find very useful.
Maybe your chat server sent your message to you also?
So you add one message manually in onClickListener and then the same message received from server.
I think, it will be right not to add messages from onClickListener - add only those that server sends.

Email Fails to send with sms details

The following code listens for an incoming sms, takes all the spaces out of the sms then emails the edited sms. Everything works fine, except that the app fails to send an email. Can anyone see what I am doing wrong and help me?
new Thread() {
public void run() {
try {
DatagramConnection _dc =
(DatagramConnection)Connector.open("sms://");
for(;;) { //'For-Loop' used to listen continously for incoming sms's
Datagram d = _dc.newDatagram(_dc.getMaximumLength());
_dc.receive(d); //The sms is received
byte[] bytes = d.getData();
String address = d.getAddress(); //The address of the sms is put on a string.
String msg = new String(bytes); //The body of the sms is put on a string.
String msg2 = (replaceAll(msg, " ","")) ; //
Store store = Session.getDefaultInstance().getStore();
Folder[] folders = store.list(Folder.SENT);
Folder sentfolder = folders[0]; //Retrieve the sent folder
Message in = new Message(sentfolder);
Address recipients[] = new Address[1];
recipients[0]= new Address("me#yahoo.com", "user");
in.addRecipients(Message.RecipientType.TO, recipients);
in.setSubject("Incoming SMS"); //The subject of the message is added
in.setContent("You have just received an SMS from: " + address + "/n" + "Message: " + msg2); //Here the body of the message is formed
in.setPriority(Message.Priority.HIGH); //The priority of the message is set.
Transport.send(in); //The message is sent
in.setFlag(Message.Flag.OPENED, true);
Folder folder = in.getFolder(); //The message is deleted from the sent folder
folder.deleteMessage(in);
}
}catch (Exception me) { //All Exceptions are caught
}
}
};
public static String replaceAll(String front, String pattern, String back) {
if (front == null)
return "";
StringBuffer sb = new StringBuffer(); //A StringBufffer is created
int idx = -1;
int patIdx = 0;
while ((idx = front.indexOf(pattern, patIdx)) != -1) {
sb.append(front.substring(patIdx, idx));
sb.append(back);
patIdx = idx + pattern.length();
}
sb.append(front.substring(patIdx));
return sb.toString();
}
Thanks
This isn't really an answer to the problem, just an elaboration on my comment above, that might help.
Make sure do something in your exception catch block, so that problems in the code don't go unnoticed. It's possible that your code is not encountering any exceptions, but in order for us to help, we need to try to eliminate potential problems, and since you say the code isn't working, but you have an empty exception handler, that's an easy area to fix first.
the simplest handler is just:
try {
// try sending sms here
} catch (Exception e) {
e.printStackTrace();
}
If you can run this in the debugger (which I highly suggest), then you can now put a breakpoint on the e.printStackTrace() line, and see if it ever gets hit. If it does, inspect the value of e and tell us what it is.
Normally, in my programs, I don't actually use e.printStackTrace() in catch handlers, but I have a logging class that takes strings, and maybe a log level (e.g. info, warning, error, verbose), and writes to a log file. The log file can be attached to emails the users send to tech support, or can be disabled for production if you only want to use the feature while developing.
Anyway, start with a simple printStackTrace() and see if it ever gets hit. Then, report back.
Edit: from the symptoms you describe in the comments after your question, it seems like it's a possibility that
String msg2 = (replaceAll(msg, " ","")) ; //
is throwing an exception, and therefore never letting you get to where you'd send the email. I can't see anything wrong with your implementation of replaceAll() upon initial inspection, but that might be a place to look. Has that implementation been thoroughly unit-tested?
Also, I think you have a "/n" in your code where you probably want a "\n", right?