My requirement is to send an email with a button that return the user to the application at the right place.
The email is sent by a background job.
The background job check if an object exist in a table and if there is any object, it will send email for each of them.
My main problem is to retrieve the 'http://my-app-domaine.com' part, because the other part is static to all the environment.
I would like to retrieve that part of the url without being in a controller.
Is it possible ?
Everything i find is about the HttpContext and UrlHelper which i doesn't have acccess.
Related
Context of what I'm trying to accomplish:
User shares a file with the bot
Other users interact with the bot via a dialog
The bot shares the original file to the other users
For example, we want to share a file to the bot that contains this week's cafeteria menu. Each time users would interact with the bot in a certain way, it would share the cafeteria menu with them so that they can consult it.
I've tried calling files.share method but bots can't perform this action (get invalid token type error).
As far as I can tell, there is no way to do this currently. I've tried link unfurling in the message body but that only works if the file itself was already shared to the user. If not, the link simply won't unfurl and clicking it will fail.
The bot can perform a files.upload call and re-upload the contents of the file to each user individually. This seems incredibly wasteful but appears to be the only way to work currently.
Is there something I'm missing?
The reason your bot can not use file.share is that this is an undocumented API method and you need a legacy token to use it. No other token (user token, bot token) will work, because it requires the post scope, which only exists for legacy token.
Approach A: Legacy Token
So one approach would be to use a legacy token with your bot, which you can create here for your current workspace. That should work nicely if your Slack app is only used on your "own" Slack workspace where you can create and use a legacy token.
Approach B: File Mention
Another approach is to use the mention feature in messages to share a file. This works by sending the private link (url_private property) of an already shared file in a message to a new channel. This will automatically re-share the file in that channel. I believe this only works with files that how been previously shares in a public channel and can therefore be re-shared. Be aware though that the file mention feature is currently being reworked, so this behavior might change.
Example:
https://slack.com/api/chat.postMessage?token=TOKEN&channel=CHANNEL&as_user=true&text=URL_PRIVATE
For more details see the Slack tutorial Storing, retrieving, and modifying file uploads.
Approach C: External File / image file
If you host your file externally or create a public URL for a file uploaded to Slack you can share it in every channel by just adding the URL to a message. Slack will automatically unfurl it and therefore share it to the user in any channel. This is different to Approach B, because its not a file mention and requires a public URL. You get the public URL of an uploaded file by calling files.sharedPublicURL.
If i'm not wrong, you can do like this :
you share a file with your bot
you retrieve the file shared ID, so his url_private property (cf https://api.slack.com/types/file#authentication)
you then donwload the file
you can then re-share it several times later (without re-uploading to each user)...
I'm building an application using Grails 2.5.1 , i want to implement a user's notification service ,similar as Stack overflow for instance when the user has unread messages it notifies the user as soon as he login . is there a plugin or a handy way to achieve this ?
thanks
If you want some data (ex: unread messages) on demand (login), then you could include this in the action's returned map or fetch the data from a separate Ajax call when the document.event fires and manipulate the DOM (easily done through jquery, angular, etc.)
If you are looking to update the DOM asynchronously based on events that happen server-side (another user sends a message and you would like to 'instantly' alert the current user), then things become more complicated.
Spring Websocket
There is a grails plugin that we have experimented with and have had success with: grails-spring-websocket. Check out the link for examples and more info.
There is a bean brokerMessagingTemplate that is injected within your service class that has methods to publish a message. On the client, you subscribe to the corresponding message url using javascript. When the callback function is executed, a message has been published - manipulate the DOM as needed.
There are also some controller annotations provided by the plugin, but I don't have experience with them.
When the client calls a Controller, a new Thread is created, which takes a long time. The View is intimidatingly returned to the user. The user should stay informed over the progress of the work, so SignalR is used.
How can send updates only to the user which called the Controller.
If I create a new Thread the HTTP Context get's lost, so I don't know how I can tell SignalR to which client it should send the information.
When you spawn your thread you should pass to it a user identifier, and then from the thread get a hub context and call something like:
var context = GlobalHost.ConnectionManager.GetHubContext<YourHub>();
context.Clients.User(userId).whatever();
on it. By default the user id would match the user name you get from your principal before calling the thread (so your HTTP context is still valid), but you can also check the IUserIdProvider interface for alternate ways of handling it.
If nature of long running operation allows it (ie you don't need to render any view or something specific to MVC), you can just implement your "long running work" inside the hub method (always use Task<T> and await to do that) and report progress back to client as shown here. Sample code is missing client side part. For that, take a look at this SO question.
This approach has another benefit. If your controller\action performing long running operation is using ASP.NET Session (which is default behavior), no other MVC actions\requests can run on server until the long running request finishes because of the Session lock - take a look here for more details. SignalR on the other side do not use Session by default so there is one less problem to worry about...
Oh BTW: Do not create your own Threads - its very inefficient. Use ThreadPool.QueueUserWorkItem or better Task<T> API...
I've been having this design-pattern problem for weeks. Where do I put the logic for sending emails? Behaviors can be accessed through the asp.net mvc web interface or through a wcf endpoint hosted inside the asp.net app.
Here are the features of the app:
Email notifications.
Template rendering - This means I have to know the url structure (actions, base address, etc).
Currently, I am storing base url and paths inside the web.config file and having this email service inside the service layer.
One particular feature is sending confirmation emails to the user and sending the generated confirm url to them. (no idea how to generate this url from the service layer)
Emails should never ever ever ever be served from the web layer. You never want a user to wait while an email is sending.
The best thing to do is create a persistent email queue ( sql is fine ) which another job accesses to send the email. This gives you the ability to re-send failed emails and run them completely outside your web request thread.
What jfar say is true; that said, you could use Postal to generate your emails and then store those emails in a database, again, as jfar suggests.
From the postal website:
Postal lets you create emails using
regular MVC views.
That means you'll have an Email folder under your Views folder; those views are actually your email templates and have full access to all Html and URL helpers any other view has which will probably make it easy for you to generate a confirm URL or whatever it is that you may need.
Postal includes and IEmailService interface with a concrete EmailService implementation. This service allows you to directly send an email message or, even better, generate a regular MailMessage object. You could then just store the ready-to-go email in a table on your db and send it later on with a background job.
You can also run an SMTP server on your web server machine, and simply have your business logic layer send mails to that SMTP server.
As long as the SMTP server is up and running, there will be no performance hit on your web application, and the SMTP server itself queues incoming requests and handles them in the background.
Trying to figure out a way where I can pass some data/fields from a web page back into my application. This needs to works on Windows/Linux/Mac so I can't use a DLL or ActiveX. Any ideas?
Here's the flow:
1. Application gathers some data and then sends it to a web page using POST that is either imbedded in the app or pops up a new IE window.
2. The web page does some services and then needs to relay the results back to the application.
The only way to do this that I can think of is writing the results locally from the page in a cookie or something like that and have the application monitor for a specific file in that folder.
Alternatively, make a web service that the application hits after passing control to the page and when the page is done the web service will return the data. This sounds like it might have some performance drawbacks.
Can anyone suggest any better solutions for this?
Thanks
My suggestion:
Break the processing logic out of the Web Page into a seperate assembly. You can then create a Web Service that handles all of the processing without needing to pass control over to a page.
Your application can then call the Web Service directly and then serialize the results and work with the data quite easily.
Update
Since the page is supplied by a third party, you obviously can't break anything out. The next best thing would be to handle the entire web request internal to your application (rather than popping a new Window).
With this method, you can get the raw HTTP response (and page markup) and work with it directly. You can then parse the Response stream and gather the required data from it.
During performing an HTTP request you should be able to retrieve the text returned by the page. For instance, if your HTTP POST was to hit a Java servlet, the doPost() method would be fired and you would then perform your actions, you could then use the PrintWriter object from the Response object (PrintWriter out = response.getWriter();) and write text back to the calling application. I'm not sure this helps?
The fact that
web page is hosted by a third party
and they need to be doing the
processing on their servers.
is important to this question.
I like your idea of having the app call a webservice after it passes the data to the third-paty web page. You can always call the webservice asynchronously if you're worried about blocking your application while waiting for results from this webservice.
Another option is that your application implements an XML-RPC server that can be called from the web page using PHP, Python or whatever you use to build the website
A REST server will do the job also...