mailboxer gem - find message sender - ruby-on-rails

I am having the hardest time with the mailboxes gem. I have gotten it working in that I can send and receive messages, but for the life of me I cannot figure out how to display them. i want to display the inbox in table organized like this:
message sender | message subject | message sent date
I have been working for hours to try and figure out how to access the sender of the message in the receivers inbox, but I can't figure it out. I've tried looping through conversations, receipts, notifications, etc and I still cannot figure out what to do. I can't use:
#user wants to retrieve all his conversations
user.mailbox.conversations
#user wants to retrieve his inbox
user.mailbox.inbox
#user wants to retrieve his sent conversations
user.mailbox.sentbox
because there is no way to organize how the messages are displayed using those methods (at least as far as I know). How can I loop through the messages and find the message sender for each message?

A Mailboxer::Message is a Mailboxer::Notification
And you can have the notification's sender: message.sender
A Mailboxer::Conversation is a collection of messages.
You can get the participants, even the originator (plus many other) from it.
Is it clearer?

Related

Rails—how to see whether an email was sent in the past week

I'm sending an email to inactive users, saying "please sign in within 7 days or your account will be deactivated".
I have a service that will fetch all inactive users and send the email, but I run this daily, and I only want to email each user once, not every day.
class DeactivateOldEmailsService
def run
to_deactivate = User.havent_signed_in_for_n_days(97)
to_deactivate.each { |user| user.update(active: false) }
to_warn = User.havent_signed_in_for_n_days(90)
to_warn.each do |user|
messages_for_user_per_employer = InactiveEmailsMailer.account_will_expire(user).deliver_later
end
end
end
How can I check whether a user has been sent an email already?
It is very hard to check whether an user has been sent a notice email, if you did not save the time the email was sent in the database. There might be still some data in log file, but any sending job are quickly deleted from queue as soon as that email was sent successfully.
From your piece of source code, I guess you might have something like "last_signed_in" in your users table. You can just do it simple and send emails to users if they haven't signed in for exactly 90 days, something like:
to_warn.each do |user|
if user.last_signed_in === 90.days.from_now
messages_for_user_per_employer = InactiveEmailsMailer.account_will_expire(user).deliver_later
end
end
Or you can create a new column notice_deactivation_email_sent_at in users table to check whether an user has received the notice email or not.
I'm actually facing something very similar:
Send weekly emails to user (who subscribed to changes that occurred since last sent), this Job is run every day and I don't want user to receive more than one email a day.
My plan is to store this information on a dedicated column last_sent_at on table users, and send email only if condition DateTime.current - last_sent_at > 7.days is true.
EDIT: I should have read last sentence of previous answer... Exactly what I just described... Sorry!

Sending mail 'to' OpenStruct through mailer

I have an app where users can sign up for workshops and admin has a possibility to write an e-mail to all the participants through the app. The fragment of code to send mail message to the group looks like this
workshop.students_all.each do |user|
WorkshopNotifyGroupMailer.notify_user(user, workshop, subject, body).deliver_later
end
so it's nothing extraordinary (User and Workshops are instances of models).
Now, I wanted to add one additional e-mail address to be sent each time a group is notified (just to have a copy how does the sent mail look like). I thought of doing it something like that (to keep the code short):
admin = OpenStruct.new(email: 'admin#email.com', first_name: 'Nameless') #These are fields taken from User instance by mailer
WorkshopNotifyGroupMailer.notify_user(admin, workshop, subject, body).deliver_later
Unfortunately, I receive "Unsupported argument type: OpenStruct" error. Is there a way to send an e-mail which uses an instance of a model using some kind of artificial structure? (In this case just assume admin is not on the user list and won't be)

Best route for adding conversations to messages

I have a inbox system but I am not sure how to implement a reply to feature. All messages should belong to some other entity, e.g. a "conversation". When the first message is created, the conversation is also created. All subsequent messages are then part of that conversation. Conversations can only occur between two users, there are no options to allow people to forward messages, or add more people to the conversation. If the users exchange several messages back and forth using the 'reply' action..the users should be able to view their past messages from that conversation in the view. What would be the requirements for doing this? Should I create a conversation model or can I add a new column to the Messages table conversation_id. If a user replies to message id 27, then it would create a new message id 28 and the conversation_id value would be 27. Then I can just do a desc from conversation_id 27. That will show the history of all messages that belong to id 27.
You want to populate a recipient_id on the new Message in your new action? Is that right?
If a conversation is guaranteed to only have two users, you could do something like
current_conversation.users.select { |u| u.id != current_user.id }
or
User.joins(:conversations).where("conversations.id = ? AND users.id != ?", current_conversation.id, current_user.id).first
You're using the phrase "reply to", so I'm assuming the conversation already exists. If it doesn't, the author has to specify the other user in the conversation anyway.
You may want to take a look at the Mailboxer Gem's sourcecode, you might find some of your answers in there.

How do I pass additional information to into ActionMailer to handle incoming messages?

I have an application that checks multiple email accounts (think Webmail). Because I'm retrieving multiple accounts, I need to associate the inbound email with a user's account. However, I can't seem to find a way to do this.
If i pass into Fetcher a user_id in the options hash, from what I understand it creates it as an attribute. But, I'm unclear how to get the fetched message modified in such a way as to make it happy for ActionMailer. If I add an argument to the "receive" method, that fails with a message "wrong number of arguments."
If I try to modify the message retrieved, I get an error with "wrong number of arguments". And, because ActionMailer is not really a full class, I can't simply initialize it with the right data.
Any thoughts on how to pass this information?
I'll answer this because I hate not finding answers.
I wrapped ActionMailer in another class. This new class took the additional attributes and handled them. This is how I got around this problem.

rails 3.1: Where to filter out email addresses that have opted out

Trying to figure out the cleanest way prevent sending email to users who have opted out from receiving them in rails 3.1.
I was thinking about overriding Mail.deliver to check the db and determine if the recipients are unsubscribed or not, then conditionally delivering the email.
That seems like the least intrusive way to go about it, but requires creating the Mail objects that are never going to be sent.
Seems like the most resource conscious way would be to do the check in the controller, thus preventing the Mail objects that are never going to be sent from the burden of existence.
This though seems more intrusive and prone to developers forgetting to make the check when creating new mailers.
Is there a standard practice for this situation?
** edit **
This is for managing a collection of users who have opted out of receiving notifications, rather than something like managing subscriptions to a news letter.
If the attribute that determines whether or not to get email notifications is just a field on a model in the DB, you could create a named scope called something like 'want_email_notifications' to get all the users that have subscribed.
So, if you have a User class, and that class has an attribute called opt_out, then you could do something like:
class User < ActiveRecord::Base
named_scope :want_email_notifications, :conditions => ['opt_out = ?', false]
...
end
Then, to call it, you do User.want_email_notifications, which gives you an array of all User objects that want email notifications.
Then, when you're checking whether or not a given user should receive an email notification, write a condition similar to:
send_email_notification(user_in_question) if User.want_email_notifications.include?(user_in_question)
In this example, send_email_notification is the method where you would call the associated delivery method, which actually sends the email.

Resources