updating/dismissing message after dialog submitted - slack-api

Is there a way to do any of the following:
a. Update a chat message that initiated a dialog.
b. Store "hidden" fields in a dialog.
Basically, I have a bot message that opens from a button on a message attachment. I know when the user clicks the button, I get the ts of the message and at that time I could alter it. However, the workflow is not complete until the user has submitted the dialog, but the submit on the dialog loses all the original_message stuff and the ts of the dialog being submitted no longer corresponds with the original, calling message.
If there was a mechanism to store hiddens, I could stash the original ts or the response url on the form itself.
Thanks! This is my first slack workflow, so any advise is appreciated as usual!
.....
The suggested duplicate answer refers to an interactive message, which I'm using to call the dialog already.
However, that isn't where my problem is, it is the dialog submission.
You don't have any access to the button elements on a dialog and the dialog element can only have 5 elements of type: text, select, text area. Plus it's a bit overkill considering that a action invocation from an interactive message actually includes the original message in the post back to your server.

So slack dev support got back to me:
Thanks for writing in, this is a great question!
You can use the callback_id parameter when calling dialog.open to store a string that will help your app locate the message. This callback_id will be returned to you in the dialog submission.
In your case, you could store the original message's ts and channel_id so that > you can locate the message to update.
I hope this helps! Let me know if you have any further questions!
So, it's a bit hacky (imo), but i did get it to work so I thought I'd close this question in case anyone else ran into this.
I'm just parsing the original ts value inside the callback w/ some other data i can use when the form submits. The only limitation to this is that it only stores 200 characters but that should be sufficient considering that is in addition to the 5 fields you have on the dialog and the other stuff slack gives you in the post (user, channel, etc).

Related

Modal creating a log without changing the page

My page display a list of question. Near each question, a button switch a hidden statement to display a model over the page asking for some information. The goal would be, after the user complete the information and click submit, to access the backend and send the information to the database WITHOUT loading another page. I would like this popup to close and the user to resume what he was doing as if he did not do anything.
How would I go about doing something like this ?
You can use ajax and send a Post HttpRequest to an action which would then be tasked to save those information.
Please refer to this thread and this for more info.
Hope this helps you.

Reset Struts2 Token?

I have a token interceptor to block double submitting a form which works great, but I'm looking to reset the token under circumstances.
Essentially what I've got in the page is a list of criteria and a submit button. When the user clicks the submit button, the criteria is stored as a new row in a specific table in the database. An ajax call updates the div underneath the form with a succeeded or failed message. The token works in that I don't want the user attempting to add duplicate rows. However, if you user changes the criteria (either by choosing a different option in a drop-down menu or editing the text in s:textfield) I want it to reset the token to allow form submission again. Currently the user has to go back and fill out a new form which is somewhat inconvenient.
I'm using the standard s:token in the .jsp and interceptor lines in struts.xml. I've been searching for something to reset the token but I haven't found anything. Thanks.
The token is a value in session under "struts.token" and in the form as "struts.token.name".
Since you're making an Ajax request underneath the easiest would likely be to set the session token to whatever is already in the form, or to create your own token interceptor (it's quite short, although it uses a static TokenHelper class, which is unfortunate–noted and logged as something to do) that changes the definition of "multiple" submit. (Hash of form vals? Not sure, never given this much thought.)
I couldn't find any answers on google and I don't appear to be getting any answers here so what I did is created a new button called "Clear Form" which calls some javascript to refresh the page and therefore resetting the token and the forms. Not the most elegant but it works.

Passing message to another window

I would like to write an application which passes every message it receives to another window. For example, I have an application where user can press some keys, move mouse over it, etc. and I want all these messages passed to, for example, MS Paint.
How do I do this? Any ideas? As far as I know, there may be a problem with sending key strokes to another window, so please advice as well.
EDIT
Okay, maybe I will give you more description of what I'm looking for.
My applications displays a window of another application on the form. Now I would like to control the other window using messages sent to my application's form (like key downs, mouse moves, etc.).
I have been thinking of passing all the messages my form receives to the window of the application I'm kind of 'embedding' into my own. By 'embedding' I mean making the application window display on my form.
Maybe there's another solution to my problem. Please advice.
Thank you for your time.
Some messages (i.e. input messages) arrive through the message queue and the rest are delivered straight to the recipient windows. What you are asking to do therefore requires you to do all of the following:
Implement a top level message loop that retrieves messages from the queue and sends them to the other app.
Reimplement all modal window loops to pass all messages on.
Replace the window procedure for all windows in your process with one that passes all messages on to the other app.
Look for other opportunities for messages to arrive that I have not covered.
I can't imagine that this is really going to be the solution to your problem, whatever that problem is.
Forwarding the messages is definitely possible and easy, but it likely won't do what you are expecting. Take a look here.
Override the form's DefaultHandler() and post every message it gets to the other form. If there are any explicit message handlers in the form or even some controls then you may not see those messages in DefaultHandler().

Ruby/RoR and many subprocesses

I am trying to build a free web application using ruby/rails It should be able to send sms through online forms of various mobile operators. (like this one (in russian)).
So, I need to
wait for the user, who wants to send an sms through my website.
establish connection to operator website. Probably, using Mechanize.
retrieve captcha
show captcha to the user
allow user to enter a message and captcha
submit form on operators website (with message, captcha, phone number)
The connection to the operator website should be alive during all this process (otherwise captcha will change). As far as I understand, I need to create a (sub)process each time sms is sent.
Could you please advise what is the best way of handling this in rails\ruby?
I am still rather new to web-development...
Should I use threads? forks? popen? using PTY? some external gem? How should I communicate with my process?
Assuming there's nothing special about the operator's web site, no, you don't need to keep a connection alive during the whole process. Generally speaking, forms on web pages work like this: You visit the URL, your web browser downloads the page with the form on it. In your case, it will also have an <img> tag or similar to show the CAPTCHA. Once your browser has downloaded the page, the connection is severed. After you fill out the form and click on Submit, your web browser opens a new connection to the server and sends the data, and the server sends its response (whatever page is shown after you click Submit).
All your program has to do is emulate this experience. So: 1) Download the page with the form on it. Scrape the form fields (make sure you don't miss any hidden fields--with a CAPTCHA there will probably be some) and the CAPTCHA. 2) Build a page to show your user that includes the CAPTCHA and a form with all the fields they need to fill out. If there were hidden fields in the original form, make sure you include their values (as hidden fields in your form) as well, because when the user submits your form you'll need them. 3) Then, when the user submits your form, send the data, including the hidden values and what the user entered for the CAPTCHA, to the operator. 4) Finally, check if the operator indicated success, and build a page to tell your user.
If you're doing this in Rails, you'll probably have two methods in your controller: One called e.g. 'show' (steps 1 and 2 above) that will scrape the CAPTCHA and other info from the operator's site and show the user your form view, and one called e.g. 'send' (step 3 and 4 above) that the form will submit to, and which will take their data and send it to the operator's web site, collect the response and tell your user if it was successful or not.
Note: You'll want to read the operators' terms of service before you bother with any of this. I'm fairly certain that this kind of thing will be against their TOSes and if they notice your server sending a lot of requests their way they're going to block you pretty quick.
To answer another question of yours, you can use DRb or background_job (aka BJ) to actually accomplish the sending in the background so that after your user submits the captcha they don't have to wait for the response. Or you could wrap this in ajax and have the DRb/BJ process notify you when the sms sending has happened so you can notify the user of success or any problems.
Typically opening threads in Ruby is something to avoid as there are so many great gems that do what we need. Not to say that you shouldn't use threads, just that for the most part it's probably already been done really well.

Preventing double HTTP POST

I have made a little app for signing up for an event. User input their data and click "sign me in".
Now sometimes people are double in the database, the exact same data that got inserted 2 times very quickly after each other. This can only mean someone clicked the button twice, which caused two posts to happen.
This is common web problem, as credit card apps and forum apps often say: "Clicking once is enough!".
I guess you could solve it by checking for the exact same data to see if the post is unique, but I wonder if there are other methods.
This ofcourse does not count for ASP.NET webforms, because POST doesn't matter as much.
While JavaScript solutions can disable the submit button after it has been clicked, this will have no effect on those people who have JavaScript disabled. You should always make things work correctly without JavaScript before adding it in, otherwise there's no point as users will still be able to bypass the checks by just disabling JavaScript.
If the page where the form appears is dynamically generated, you can add a hidden field which contains some sort of sequence number, a hash, or anything unique. Then you have some server-side validation that will check if a request with that unique value has already come in. When the user submits the form, the unique value is checked against a list of "used" values. If it exists in the list, it's a dupe request and can be discarded. If it doesn't exist, then add it to the list and process as normal. As long as you make sure the value is unique, this guarantees the same form cannot be submitted twice.
Of course, if the page the form is on is not dynamically generated, then you'll need to do it the hard way on the server-side to check that the same information has not already been submitted.
Most of the answers so far have been client-side. On the server-side, you can generate a hidden field with a GUID when you first produce the form, and then record that GUID as a submitted form when the post is received. Check it before doing any more processing.
Whenever a page is requested from the server , generate a unique requestToken , save it in server side,mark status as NOT Processed and pass it along with the current requested page. Now whenever a page submit happens , get the requestToken from the "POST"ed data and check the status and save the data or take alternate action.
Most of the banking applications use this technique to prevent double "POST"ing.So this is a time proven & reliable way of preventing double submissions.
A user-side solution is to disable the submission button via Javascript after the first click.
It has drawbacks, but I see it often used on e-commerce websites.
But, it won't never replace a real server-side validation.
Client side techniques are useful, but you may want to couple it with some server side techniques.
One way to do this is to include a unique token in the form (e.g. a GUID or similar), so that when you come to process the form you can check to see whether the token has already been used, preventing a double submission.
In your case, if you have a table with event visitors, you might include this token as a column.
A client-only solution won't be enough, as stated in many of the answers here. You need to go with a server-side fail-safe.
An often overlooked reason that disabling the submit button doesn't work is, the user can simply refresh the submit target (and click OK on the "are you sure you want to resubmit the POST data?" dialog). Or even, some browsers may implicitly reload the submitted page when you try to save the page to disk (for example, you're trying to save a hard-copy of an order confirmation).
Almost no one has js disabled.
Think about coding your e-commerce website for the 70 year old woman who double clicks every link and button.
All you want to do is add a javascript to prevent her clicking "Order Now" twice.
Yes - check this at the server side too "be defensive" - but don't code for that case. But for the sake of a better UI do it on the client side too.
Here are some scripts that I found:
//
// prevent double-click on submit
//
jQuery('input[type=submit]').click(function(){
if(jQuery.data(this, 'clicked')){
return false;
}
else{
jQuery.data(this, 'clicked', true);
return true;
}
});
and
// Find ALL <form> tags on your page
$('form').submit(function(){
// On submit disable its submit button
$('input[type=submit]', this).attr('disabled', 'disabled');
});
None of the solutions address a load-balance server.
If you have some load balancer, send a UUID (or any type of unique number) to the server to store and read again will not work well if the server is not aware of other servers, because each request could be processed by a different server in a stateless environment. These servers need to read/write to the same place.
If you have multiple servers you will need to have some shared cache (like a Redis) among the servers to read/write the unique value in the same place (what could be an over-engineering solution, but works).
Client side alteration is a common technique:
Disable submit button
Change the screen to a "please wait" screen
If the form was modal, changing the screen back to their usual process (this has the benefit of making things look really slick)
But it's not perfect. It all relies on JS being available and if that's not the case, without back-end duplication detection, you'll get duplicates still.
So my advice is to develop some sort of detection behind the scenes and then improve your form to stop people with JS being able to double-submit.
You can track the number of times the form's been submitted and compare it to the number of unique visits to the page with the form on it in the session.
Beside the many good techniques already mentioned, another simple server-side method, that has the drawback of requiring a session, is to have a session variable that is switched off on the first submit.

Resources