Are there any gems or libraries that can be used to show a message once to a user? I'm looking in particular for something that allows me to:
Display a "welcome aboard" full overlay when the user logs in for the first time. (And only on the first time)
A smaller drop down overlay that informs users that there may be maintenance in the next 24 hours, or they need to do something (fill in their profile, etc). This would display until dismissed.
I'm a bit stuck with this, because I don't know what these kind of messages are commonly called. Do these kind of one-time messages have a name?
there are many ways to implement such a notification system, your requirements are pretty basic so I'll stick with a basic approach using flash
Show Message on the first login:
You should keep track of ther user's last login and maybe count the logins, so what you could do:
Add a field "last_login_at" to your User Model which gets updated every time the user logs in, set it to NULL after registration. When the user logs in you check if the last_login_at is NULL if yes you set a message to the flash like flash[:first_login] = true then you can render a special welcome message in your template if this flag is set.
A better approach is to add a field like login_counter which gets incremented every time the user logs in, so if it is zero the user is logging in for the first time. A login counter can also help you to identify "active" users who log in often etc.
There is a popular authentication system called devise which has these (and many more!) features built in: https://github.com/plataformatec/devise
Show maintenance warnings etc.
I'd create a new model called SystemMessage which has fields like:
id | message_type | title | body | valid_from | valid_until
The message_type attribute describes what kind of message it is like "maintenace notice", "new features" etc. dependent on the type of the message you could render different templates and adjust the look of the message.
The valid_from and valid_until attributes lets you control in which time frame the message should appear.
On every request you fetch these messages and show them to the user, you can also cache the messages on a regular basis to reduce the amount of queries. Have a look at the rails guide about caching: http://guides.rubyonrails.org/caching_with_rails.html
To inform users that are idle on a page you can implement an AJAX request which fires every five minutes or so and fetches the messages and checks if there are any messages newer than the ones already displayed.
If you need to show user-specific messages (like you got 5 new mails, someone commented on your post etc.) in real-time you could use a pub-sub messaging system like 'Faye' (tutorial: http://railscasts.com/episodes/260-messaging-with-faye or just google for "rails 3 faye")
I hope this is a starting point for you :)
Related
We are having a lot of transactions on the site, so for this reason we are re-cycling our booking confirmation numbers/ order id numbers on the confirmation screen which is set into our purchaseID . Since we are re-using our booking confirmation number, in order to make our purchaseID unique we are adding timestamp to our purchaseID variable using pipe delimeter. So formula looks like:
purchaseID = order_id + '|' + timestamp (current date).
My concern here is, let's say I make a booking today and my purchase id looks like -
purchaseID = 5747118 | 6-7-2019
Now I access my confirmation screen again tomorrow and after 2 days, 3 days and so on and I see adobe calls firing. Because I accessed my confirmation page on different dates my timestamp changed and thus my purchaseID is not unique anymore. Even though I am seeing my same booking confirmation page my purchaseID is not unique now. Does this mean, every time i view my confirmation screen on a different day my booking/revenue would be counted multiple times ? If yes, what's the best way to tackle this issue ?
So it sounds like someone can go to your site, make a purchase and see the confirmation page, and then later on, go back to the same confirmation page without actually making another purchase. Maybe they bookmarked the page and come back to it later for reference. Or maybe they refreshed the page, because reasons.
Does your site charge their credit card for accessing the page again? I sure hope not. Your site/coding should be structured in a way that does not keep charging the customer more money every time they view the page again.
And your code logic for outputting Adobe Analytics should be structured in the same way: your coding logic should be that you only output purchase event and variables (e.g. purchaseID) when a purchase actually occurs.
In practice, this sometimes isn't easy to do because of how the site is structured. So part of why purchaseIDexists is to de-duplicate purchases, so that if purchase event and data is re-popped, it will be de-duped. But it only works if you output the same purchaseID when the visitor refreshes the page or otherwise comes back to it later on (where they aren't actually making another purchase).
Which it sounds like you were doing with the original booking confirmation number you pushed to purchaseID. But things went south when you decided to throw a current datestamp into the mix because you started recycling booking confirmation numbers. Well you can't do that. You can use a dynamic value such as the current date/timestamp as part of the value, but you must remember it, and output it in the future.
Maybe this involves adding an extra column to your database with the date/timestamp of purchase (which I have to assume you surely already have), and then pull that value when you pull the booking confirmation number.
Or maybe the solution involves stepping back and rethinking the fact you are recycling booking confirmation numbers. This seems like a bad idea to me. It's definitely a bad idea for your Adobe Analytics implementation, as you have seen for yourself. But is this not a bad idea in general? What happens if a customer buys something today and has # 12345 as proof of transaction to reference, and then tomorrow, a week, a year or whatever from now, some other customer gets the same number?
It stands to reason that you will end up with a mess on your hands, trying to sort out which customer bought what. Transaction ids by their nature are supposed to be forever unique to the transaction. So my very first recommended solution to you would be to stop recycling your booking confirmation numbers. Move to a different format if you need to (e.g. UUID).
Failing that, my next recommendation would be what I said a couple paragraphs up, about storing the date/timestamp in a column at the actual time of purchase (which surely you already have), and then grab and use that value along with the booking confirmation # to use as delimited value, instead of generating the current date on the fly (which absolutely does not work).
I'd like to display a message to each user the first time they log in after a deployment, which describes the changes. I have some ideas about rolling my own. For example, I could maintain a table of messages and another which tracks which users have seen which. But it seems like a common-enough use case that I'm surprise I can't find a gem which does this.
Thanks!
You could create a table of messages that have a publish_date column. If you maintain a last_logged_in column on a record for a user, you can get all the messages created since that person logged in last and display them.
I have Users that can create DinnerEvent that contain Food. User specify preferred Food using a join table. Would like to create an internal message system that automatically sends out a notice to other Users who "prefer" the Food in the DinnerEvent that was created. Can anyone provide some guidance as to how I can go about approaching this or if there are any good reference resources out there (haven't had much luck searching)? Thought about ActiveMailer but decided I wouldn't want people to get spammed all the time in their email inbox. Would prefer to only use Rails to achieve this.
There's a lot of options here and many use cases to think through. Maybe you can start with something very simple that:
Tracks the last date/time of login for each user
On some page (specific to the logged in user), display all DinnerEvents created since last login that match their Food preferences. Should be simple Active Record to pull this.
Continue to show this list until they dismiss it (record this date/time) or login again
A full blown messaging system will probably require more complex stuff like queues for each user that are subscribed to a master queue. And, possibly an additional backend data store like Redis. I'm purposefully leaving out the details of something like this for now; it's a much bigger topic.
I am currently using wepay with rails. Don't worry this post is nothing about wepay.
So when a customer wants to buy something from my site, he/she will be redirected to wepay.
Then after paying on wepay, wepay will redirect the user to /purchases/received
After X amount of time, Wepay will also do a post call to /purchases/callback to tell me that the payment has been captured (credit card processing is slow)
So my original plan is as follows:
For the Purchase model, have a field, wepay_id and wepay_confirmed.
When the user place an order on wepay, the redirection to /puchases/received will create a purchase instance and save in my db
When the callback is called look up by wepay_id and then set wepay_confirmed to true.
However, as I discovered that the X amount of time could be so fast that /purchases/callback is called before /purchases/received could create the object.
So now I have two options:
Allow /purchases/callback to create an empty Purchase instance with just the id and confirmed = true. As I was doing this, I realized that I no longer can validate my model in the traditional manner. This really bugs me.
Create a separate table called Wepay_Confirmed. Whenever callback is called, create an entry in wepay_confirmed. Map the presence of an (checkout_id) in this table to Purchase.confirmed attribute.
I am thinking of doing 2. How can I do this? Do I have to generate a scaffold for a specific model to map to Wepay_Confirmed?
If you have any other suggestions, please reply
I would try to keep your application the way it is because it does make sense however you should look into returning an error code to wepay and have them submit the request later after the record is created.
Just emailed the developers over at WePay and got this response:
Hi Devin,
We do have automatic IPN retries. Retries happen 5 minutes after the
initial try, if the retry doesn't work, we try 15 minutes later, and
then an hour later. However, right now they are only on empty 404
responses.
The best solution is to actually just ignore the IPN if he does not
have the record in his database. Our IPNs only tell an application to
look up the checkout details with the /checkout call. They do not have
any details of the checkout. Since he should be looking up the
/checkout status anyway when he creates the checkout object on his
end, he doesn't need the IPN to tell him to look up the status in this
case.
If that doesn't work for him he can also email me at api#wepay.com and
we may be able to work out a solution.
Andrew
So it looks like you can modify the flow of you application to ignore the IPN's without a record and check manually or you can respond with a 404 and they will retry at the above intervals.
As I mentioned in my comment, I would personally prefer to create the purchase record upon purchase, then send the user to the WePay site, then handle the return trip and callback as actions to be completed against that original purchase site.
For one, that matches the reality of the transaction more accurately. When a user makes a purchase from your site, it makes sense to me that it's something you should persist at that point.
The two elements of the WePay transaction (the return trip to your site and the charge confirmation callback) would all act on that original purchase record. This will also allow you to see how many people abandon the purchase process when they hit WePay, which could reveal issues in your user experience that might help to maximize conversions.
I created a gem called wepay-rails which handles all of this for you. Under the hood it creates the entry (WepayCheckoutRecord) before sending the payer off to wepay. It has an IPN listener built in that handles the updating of that record. In my personal rails app, I am using state machine on the WepayCheckoutRecord model to track the changes to the state and doing 'things' as the state changes on that record.
I hope that helps.
Adam -
If you take the 2nd approach, you dont need to scaffold it. You can just create a migration and use it inside one of your other 'scaffolds'. Scaffolds are really just a way to get started with a resource. I dont think your intent here is to have a fully-fledged resource. Unless it is then you can use it as a scaffold.
What I would like to do is have my admin user be able to see - in real time (via some AJAX/jQuery niceness) - what my user's are doing.
How do I go about doing that ?
I assume it has something to do with session activity - and I have started saving the session to the db, rather than the cookie.
But generally speaking, how do I take that info and parse it in real time ?
I looked at my session table and aside from the ids (id and session_id), I see a 'data' field. That data field stores a hash - which I can't make any sense of (looks like an md5 hash).
How would I use that to see that User A just clicked on Link B, and right after that User B clicked on link A, etc. ?
Is there a gem - aside from rackamole - that might be able to help me?
You might want to check out Mixpanel. They are easy to setup and have some of what you are asking for.
The session data only contains the values stored in the session[]-hash from the user. It doesn't store which action/controller was called, so you don't know which "link was clicked".
Get the activity of your users:
Besides rackamole you have two options IMHO.
Use a before_filter in your ApplicationController to store the relevant info you are interested in. (Name of controller, action or URI, additional parameters and id of the logged in user for example).
Use an AJAX-call at the bottom of each page which posts back the info you are interested in (URI, id of logged in user, etc.) to your server. This allows faster response times from the server, as the info is stored after the page has already been delivered. Plus, you don't have to use a Rails-request to store it. The AJAX-request could also be calling a simple PHP-script writing the data to disk. This is much faster.
Storing this activity:
Store this data/info either in the database or in a logfile. The database will give your more flexibility like showing all actions from one user, or all visitors for one page, etc. The logfile solution will give you better performance.
Realtime vs. Oldschool:
As for pulling out your collected data in realtime, you have to build your own solution. To do this elegantly (without querying your server once a second to look if new data has arrived) you'll need another server process. Search for AJAX Push for more info.
Depending on your application I'd ask myself if realtime notifications for this are really necessary (because of all the hassles of setting this up).
To monitor the activity on your site, it should be enough to have a page listing the latest actions and manually refresh it (or refresh it automatically every ten seconds).
Maybe you can test https://github.com/raid5/acts_as_scribe#readme
It works with Rails 3 too.