i am trying to detect new emails in inbox using subscribeToPullNotifications as follows:
PullSubscription subscription = service.subscribeToPullNotifications(
folder, 1, null, EventType.NewMail);
GetEventsResults events = subscription.getEvents();
System.out.println("####### EVENTS: "
+ events.getItemEvents().toString());
for (ItemEvent itemEvent : events.getItemEvents()) {
if (itemEvent.getEventType() == EventType.NewMail) {
EmailMessage message = EmailMessage.bind(service,
itemEvent.getItemId());
System.out.println("######## NEW EMAIL MESSAGE IS: "
+ message.getSubject());
}
}
but the events.getItemEvents() is always empty, even i can see new emails in the inbox.
also how to make the above code is always repeated while the application is running, so that each minute it check for new emails.
Here it depends on when you are calling this, if suppose you are calling this as particular interval then you need to pass "WaterMark" of previous response in new request, else all events which occurred in between would be lost.
method : subscription.getWaterMark()
need to pass this as thrid argument to method subscribeToPullNotifications()
else you can continously pull on the same service by placing that in loop :
while (true) {
GetEventsResults events = null;
try {
events = subscription.getEvents();
} catch (Exception e1) {
e1.printStackTrace();
}
for (ItemEvent itemEvent : events.getItemEvents()) {
// do something...
}
}
But this would continuously pull from server increasing load, so rather use first approach by subscribing at regular interval, and passing previous water-mark in request.
Related
so I have made a comments option on my app which lets the users comment something on posts. It is directly referenced and sends info from the string to the api endpoint. That works, now I was wondering if there was a way to limit the number of essentially requests to the API so users can send comments once every minute per say
TextField("Comment...", text: $comment) { editingChanged in
} onCommit: {
validate()
showsAlert = !isValid
if isValid{
viewModel.sendComment(nickname: nickname, body: comment) {
self.comment = ""
}
}
}
}
.padding()
.frame(width: UIScreen.main.bounds.width, height: 80)
.ignoresSafeArea(.keyboard, edges: .bottom)
It would help me reduce spam on the comments and would be a life saver
You can create a simple Swift class to control the time.
public class Time_Control:Thread{
var wait_time:Int //In seconds
public var can_send:Bool = true
init(_ wait_time:Int) {
self.wait_time = wait_time
}
public override func start() {
super.start()
self.can_send = false
Thread.self.sleep(forTimeInterval: TimeInterval(self.wait_time))
self.can_send = true
}
}
Then you can use this object in any part of your code to control time between events. For this, first have a variable to store the object of the class Time_Control, for example, var control:Time_Control = Time_Control(0). After that, each time you want to control the time of something just do the following:
func send_message(){
if control.can_send{
//Start the time controller with 60 seconds
control = Time_Control(60)
control.start()
//Let the user send message
//... your code
}else{
//Don't let the user send message
//...
}
}
When the user interacts with your UI, you can call the function send_message(). It will allow the user to send a message every 60 seconds.
In Swift you can get the Unix timestamp of the current moment using:
let currentUnixTimestamp = Date().timeIntervalSince1970
Unix time simply counts the seconds that have elapsed since 1 Jan, 1970 00:00:00 UTC. See Wikipedia to learn more.
Using this, you could create a field in which you save the current timestamp every time a comment is sent and then check the current time against the saved timestamp. If your viewModel is of a class type, which I assume it is, it is the perfect place to put this code. It might look like this:
class ViewModel {
// How many seconds to wait before the user can comment again
private static let cooldownInSeconds = 60
private var lastSendTimestamp: Int? = nil
func sendComment(nickname: String, body: String) {
let currentTime = Date().timeIntervalSince1970
if currentTime >= (lastSendTimestamp ?? Int.min) + ViewModel.cooldownInSeconds {
lastSendTimestamp = currentTime
// Send comment here
} else {
// Cannot send comment because cooldown has not run out
}
}
}
Note that putting the variable in structs (like your View) will not work well, due to their immutable nature.
So I am trying to make a reminder chatbot and the code I made is not working as well as I expected.
What I did was, for example, if I were to send a reminder after a day, response conditions would be like the following:
"conditions": now().reformatDateTime().toInt()+1
then followed by output-text-value as usual.
Is this valid? Any kinds of suggestion will be more than welcome. Thanks!
You user need to call the day for you get before you did something.
Active your sys entitie: #sys-date for get days.
And, for example, user will ask:
What I need to do today?
Save the day with one context variable, like:
{
"context": {
"verifiedDate": <? #sys-date ?>;
},
"output": {
"text": {
"values": [
"Please wait and I'll verified your request."
],
"selection_policy": "sequential"
}
}
}
And, only if user asks, you will do something within your application for remember the user.
Like:
Example (app.js):
function updateMessage(input, data, req, res) {
if (data.context.verifiedDate){
searchRequest(data, req, res);
} else if (data.output && data.output.text) {
return res.json(data);
}
return data;
}
You can use the data for sending something within conversation flow.
function searchRequest(data, req, res){
// something to do and return value
var sendRequest = "Thanks for wait, the request is" + valueRequest;
data.output.text[0] = sendRequest;
return data;
}
This example is with Nodejs, data have all return from Watson Conversation, like entities, intents, context variables, node flows, etc. The logic is the same, you need to access the data returned from your conversation, and after, access the context variables to do something within your app.
Add days:
Date.prototype.addDays = function(days) {
var dat = new Date(this.valueOf());
dat.setDate(dat.getDate() + days);
return dat;
}
var dat = new Date();
alert(dat.addDays(5))
You can add days with the days parameter or with one number, like my example.
I'm sending push notification using azure notification hub by node js script. I can send and receive push notification. I don't know how to retrieve data. I'm sending push as follows:-
function sendNotifications(pushMessage) {
console.log('inside sendNotifications');
var hub = azure.createNotificationHubService('hubname','connection string');
hub.mpns.sendToast(
null,
{
text1: pushMessage,
text2: 'some data'
},
function (error)
{
if (!error)
{
//message send successfully
console.log("mpns.sendToast push success: "+error);
RESPONSE.send(statusCodes.OK, { ResponseMessage : 'mpns.sendToast message success' });
}
else
{
// msg failed to send
console.log("errro error.shouldDeleteChannel: "+error);
RESPONSE.send(statusCodes.OK, { ResponseMessage :'mpns.sendToast message error '+error });
}
});
}
I would like to receive the text1 and text2 in my receiving application. Could you inform me how to do it? Or do I need to send push notification differently if I want to push some data? How to push data together with push nitrification? Also how large data I can push?
If your app is already open when the toast notification is received, the following event handler can get the parameters of the notification (for example e.Collection[wp:Text1] will return the title of the toast) :
void PushChannel_ShellToastNotificationReceived(object sender, NotificationEventArgs e)
{
StringBuilder message = new StringBuilder();
string relativeUri = string.Empty;
message.AppendFormat("Received Toast {0}:\n", DateTime.Now.ToShortTimeString());
// Parse out the information that was part of the message.
foreach (string key in e.Collection.Keys)
{
message.AppendFormat("{0}: {1}\n", key, e.Collection[key]);
if (string.Compare(
key,
"wp:Param",
System.Globalization.CultureInfo.InvariantCulture,
System.Globalization.CompareOptions.IgnoreCase) == 0)
{
relativeUri = e.Collection[key];
}
}
// Display a dialog of all the fields in the toast.
Dispatcher.BeginInvoke(() => MessageBox.Show(message.ToString()));
}
If your app is opened by clicking the toast notification, you can implement the following method in the page where your app is opened. You can access the parameters passed in the query string of the wp:Param parameter of the toast notification. I'm not sure how to get Text1 and Text2 in this method.
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// If we navigated to this page
// from the MainPage, the DefaultTitle parameter will be "FromMain". If we navigated here
// when the secondary Tile was tapped, the parameter will be "FromTile".
textBlockFrom.Text = "Navigated here from " + this.NavigationContext.QueryString["NavigatedFrom"];
}
Code samples were taken from here.
I am implementing of server-sent event(HTML5) in my project without using node.js, It is just simple webpage(another JSP page) call and i get response from it. But when i get response from it but none of method/function(onopen,onmessage or onerror) is execute...
Client Code:
if (!!window.EventSource) {
var source=new EventSource("kitAvailCall.jsp");
source.onopen = function(){
alert("Kit is not available");
source.close();
};
source.onmessage=function(event){
console.log(event.data);
alert("Kit is not available");
}
source.onerror =function(){
console.log("EventSOurce: Getting error call");
alert("Kit is not available");
}
}
Server-side code:
try{
while(true) {
Thread.sleep(15000);
String IpAddress = (String) session.getAttribute("IPName");
boolean bool;
if(IpAddress != null && ((new Date()).getTime() - session.getLastAccessedTime())/1000 > 28){
bool = sample.pingToKit((String) session.getAttribute("IPName"));
System.out.println("Long polling request: "+bool);
//if bool is false then i want to quit loop and back to browser
if(bool == false){
response.setHeader("Content-Type","text/event-stream");
response.setHeader("Cache-Control", "no-cache");
out.print("data: " + bool);
out.flush();
break;
}
}
}
}catch(Exception e){
System.out.println("Going bad CONN:"+ e);
}
I don't know much of java, but i could conjecture that you might be listening to the same controller/jsp servlet(whatever routes data in java) which you made to send as streaming.
Listen on a page other than kitavailcall.jsp. This script is meant only for streaming, use another view/html page other than kitavailcall.jsp
The thing you have to understand is, SSE is a concurrent process, you create another page and run on that page with the javascript(client code) included in that page. And your server should support multi-threading as well.
In web app development I would like a consistent way to catch and report error conditions. For example, a database update routine may detect a variety of error conditions and ideally I would like the application to capture them and report gracefully. The code below din't work because retdiag is undefined when error is thrown...
function saveData(app,e) {
var db ;
var retdiag = "";
var lock = LockService.getPublicLock();
lock.waitLock(30000);
try {
// e.parameters has all the data fields from form
// re obtain the data to be updated
db = databaseLib.getDb();
var result = db.query({table: 'serviceUser',"idx":e.parameter.id});
if (result.getSize() !== 1) {
throw ("DB error - service user " + e.parameter.id);
}
//should be one & only one
retdiag = 'Save Data Finished Ok';
}
catch (ex) {
retdiag= ex.message // undefined!
}
finally {
lock.releaseLock();
return retdiag;
}
}
Is there a good or best practice for this is GAS?
To have a full error object, with message and stacktrace you have to build one, and not just throw a string. e.g. throw new Error("DB error ...");
Now, a more "consistent" way I usually implement is to wrap all my client-side calls into a function that will treat any errors for me. e.g.
function wrapper_(f,args) {
try {
return f.apply(this,args);
} catch(err) {
;//log error here or send an email to yourself, etc
throw err.message || err; //re-throw the message, so the client-side knows an error happend
}
}
//real client side called functions get wrapped like this (just examples)
function fileSelected(file,type) { return wrapper_(fileSelected_,[file,type]); }
function loadSettings(id) { return wrapper_(loadSettings_,[id]); }
function fileSelected_(file,type) {
; //do your thing
}
function loadSettings_(id) {
; //just examples
throw new Error("DB error ...");
}