### Install Chats Gem Source: https://github.com/rameerez/chats/blob/main/README.md Install the gem, generate migrations, and update the database. ```bash bundle install rails generate chats:install rails db:migrate ``` -------------------------------- ### Example Notifier Configuration in Host Application Source: https://github.com/rameerez/chats/blob/main/docs/PRD.md This is an example of how the 'chats' gem's Notifier can be configured within the host application. The default proc is a no-op, allowing 'chats' to run standalone if Noticed is not yet integrated. ```ruby ->(event, **p) { NewMessageNotifier.with(message: p[:message]).deliver } ``` -------------------------------- ### Initiate Chat Conversations Source: https://github.com/rameerez/chats/blob/main/README.md Ruby API examples for starting direct messages or group chats with specific participants or related to a particular object. ```ruby # Messagers alice.chat_with(bob) # find-or-create the DM alice.chat_with(bob, about: ride) # the DM about that ride alice.chat_with(bob, carol, title: "Trip") # a group (alice is owner) ``` -------------------------------- ### Rails Generator for Chats Installation Source: https://github.com/rameerez/chats/blob/main/docs/PRD.md Installs the Chats gem by configuring initializers, copying migrations, mounting the engine, and providing guidance for host model integration. ```ruby rails g chats:install ``` -------------------------------- ### Testing Across Rails Versions with Appraisal Source: https://github.com/rameerez/chats/blob/main/README.md Install appraisals and run tests against different Rails versions. ```bash bundle exec appraisal install # then test across Rails versions: bundle exec appraisal rails-7.1 rake test bundle exec appraisal rails-8.1 rake test ``` -------------------------------- ### Post System Message to Conversations Source: https://github.com/rameerez/chats/blob/main/README.md Example of posting a system-generated message into all conversations associated with a ride. ```ruby ride.chat_conversations.find_each { |c| c.post_system_message!("Your ride was cancelled") } ``` -------------------------------- ### Configure Chats Gem Settings Source: https://github.com/rameerez/chats/blob/main/README.md Full configuration example for the Chats gem, covering messager class, controller integration, features, limits, policies, and display options. ```ruby Chats.configure do |config| config.messager_class = "User" # Controller integration (Devise-compatible defaults) config.parent_controller = "::ApplicationController" config.current_messager_method = :current_user config.authenticate_method = :authenticate_user! config.layout = nil # nil inherits the parent controller's # Features — all on by default config.groups = true config.reactions = true config.read_receipts = true config.typing_indicators = true config.editing = true config.deletion = :soft # :soft (tombstone) | :hard | false config.attachments = :images # false | :images | :any config.search = true # Limits config.messages_per_page = 30 config.max_message_length = 5_000 config.max_group_size = 32 config.max_attachment_size = 10.megabytes config.max_attachments_per_message = 4 config.send_rate_limit = { to: 60, within: 1.minute } # Rails 8 rate_limit; nil disables config.encrypt_messages = false # ActiveRecord Encryption on bodies # Policies (on top of — never instead of — block enforcement) config.can_message = ->(sender, recipient) { true } config.can_create_group = ->(creator) { true } # Ecosystem seams (no-op defaults; chats runs standalone) config.blocked_messager_ids = ->(messager) { [] } config.notifier = ->(event, **payload) {} # Display (used by the bundled views) config.messager_display_name = ->(messager) { messager.display_name } config.messager_avatar = ->(messager) { messager.avatar } # URL/attachment/variant or nil end ``` -------------------------------- ### Send Messages and Query Chats Source: https://github.com/rameerez/chats/blob/main/README.md Ruby API examples for sending messages into conversations, querying unread counts, and accessing the inbox. ```ruby alice.message!(bob, "hi", about: ride) # send (resolves the thread) alice.message!(conversation, "hi", files: []) # send into a conversation alice.chats # inbox relation, newest first alice.unread_chats_count # conversations with unread messages ``` -------------------------------- ### Manually Flag a Message Source: https://github.com/rameerez/chats/blob/main/README.md Create a manual flag for a chat message from the admin interface. This example shows how to populate the `Moderate::Flag` object with relevant details like the message excerpt and context. ```ruby Moderate::Flag.flag!( flaggable: message, field: "body", owner: message.reported_owner, source: "manual", mode: "flag", excerpt: message.body.to_s.truncate(500), categories: ["manual_review"], scores: {}, context: { flagged_by_admin_id: admin.id } ) ``` -------------------------------- ### Conversation Membership and Details Source: https://github.com/rameerez/chats/blob/main/README.md Check active membership, retrieve other participants, get conversation titles, and access subject labels. ```ruby conversation.participant?(user) # active membership conversation.other_participants(user) conversation.title_for(viewer) # counterpart name / group title conversation.subject_label # "Madrid → Barcelona" ``` -------------------------------- ### Enable Reportable Content for Messages Source: https://github.com/rameerez/chats/blob/main/README.md Configure Chats::Message to support reporting for specific attributes like body and files. This setup integrates with the Moderate gem for content filtering and moderation. ```ruby Rails.application.config.to_prepare do Chats::Message.has_reportable_content :body, :files Chats::Message.moderates :body, mode: :flag # text → built-in wordlist Chats::Message.moderates :files, mode: :flag, with: :your_image_adapter end ``` -------------------------------- ### Conversation Unread Count and State Management Source: https://github.com/rameerez/chats/blob/main/README.md Get the unread message count for a user and mark conversations as read. Also includes posting system messages and adding participants. ```ruby conversation.unread_count_for(user) conversation.mark_read_by!(user) conversation.post_system_message!("Ride cancelled") conversation.add_participant!(user) # idempotent, race-safe ``` -------------------------------- ### Get Unread Chat Count Source: https://github.com/rameerez/chats/blob/main/README.md Retrieve the count of unread chats for a user, useful for navigation badges. ```ruby alice.unread_chats_count ``` -------------------------------- ### Action Push Native Configuration Gotchas Source: https://github.com/rameerez/chats/blob/main/docs/PRD.md Highlights specific configuration requirements for the `:action_push_native` delivery method in Noticed v3. All three of `with_apple`, `with_google`, and `with_data` must be set, and `before_enqueue` callbacks should be used cautiously. ```ruby -> { {} } ``` -------------------------------- ### Running the Full Test Suite Source: https://github.com/rameerez/chats/blob/main/README.md Execute the complete test suite for the gem using Rake. ```bash bundle exec rake test # full suite ``` -------------------------------- ### Configure User Model and Routes Source: https://github.com/rameerez/chats/blob/main/README.md Configure your User model to be a messager and mount the chats engine in your routes. ```ruby # app/models/user.rb class User < ApplicationRecord acts_as_messager end # config/routes.rb mount Chats::Engine => "/messages" ``` -------------------------------- ### Generate Chat Views Source: https://github.com/rameerez/chats/blob/main/README.md Command to generate the bundled UI views, allowing for customization within your application's view layer. ```bash rails generate chats:views ``` -------------------------------- ### Configure Content Filtering Policies Source: https://github.com/rameerez/chats/blob/main/docs/PRD.md Sets the filtering mode and optional adapter for specific classes and fields. Use `:flag` mode for out-of-band review and `:block` mode to reject at write time. Ensure the adapter is correctly specified for custom review processes. ```ruby Moderation.configure do |c| c.filter_policy "Chats::Message", :body, mode: :flag c.filter_policy "Chats::Message", :files, mode: :flag, adapter: Chats::AttachmentReviewAdapter end ``` -------------------------------- ### Open a Conversation Source: https://github.com/rameerez/chats/blob/main/README.md Initiate or open a direct conversation between two users. ```ruby alice.chat_with(bob) ``` -------------------------------- ### Create a Group Chat Source: https://github.com/rameerez/chats/blob/main/README.md Create a group chat with a specified title involving multiple users. ```ruby alice.chat_with(bob, carol, title: "Trip") ``` -------------------------------- ### Configure Default Notifier Hook Source: https://github.com/rameerez/chats/blob/main/README.md Set a lambda to handle domain events like new messages. This hook allows for custom notification logic, such as sending emails or push notifications. ```ruby config.notifier = ->(event, **payload) { case event when :message_created # payload: message: NewMessageNotifier.with(record: payload[:message]).deliver # Noticed, email, push… when :conversation_read # payload: conversation:, participant: — fired when a read actually # consumed unread content. Use it to keep EXTERNAL notification # surfaces truthful: e.g. mark this chat's rows read in your # notification center the moment the thread is read, so a bell badge # doesn't keep advertising messages the user has already seen. end } ``` -------------------------------- ### Participant State Management Source: https://github.com/rameerez/chats/blob/main/README.md Advance the read horizon, mute/unmute participants, and handle leaving conversations. ```ruby participant.read! # advance the read horizon participant.mute! / participant.unmute! participant.leave! # groups ``` -------------------------------- ### Host Integration with acts_as_messager Source: https://github.com/rameerez/chats/blob/main/docs/PRD.md Integrates a host model with the Chats gem, injecting necessary associations and helper methods for chat functionality. This is the primary contract for host models acting as chat participants. ```ruby class User < ApplicationRecord acts_as_messager # injects has_many :chat_participations, :chat_messages, helpers end ``` -------------------------------- ### Define Messager Model Source: https://github.com/rameerez/chats/blob/main/README.md Include `acts_as_messager` in your User model to enable messaging capabilities. ```ruby class User < ApplicationRecord acts_as_messager end ``` -------------------------------- ### Participant Notification Logic Source: https://github.com/rameerez/chats/blob/main/README.md Determine notification etiquette for participants and mark messages as notified. ```ruby participant.notifiable_for?(message) # notification etiquette participant.should_notify? / participant.mark_notified! ``` -------------------------------- ### Define CSS Variables for Chat UI Source: https://github.com/rameerez/chats/blob/main/README.md Customize the appearance of the bundled UI by defining CSS variables for accent colors and contrast. ```css :root { --chats-accent: #facc15; /* own bubbles, send button, badges */ --chats-accent-contrast: #111827; } ``` -------------------------------- ### Message Read Status and Reactions Source: https://github.com/rameerez/chats/blob/main/README.md Check if a user has read a message and toggle reactions on messages. ```ruby message.read_by?(user) Chats::Reaction.toggle!(message:, reactor:, emoji: "👍") ``` -------------------------------- ### Rails Generator for Chats Migrations Source: https://github.com/rameerez/chats/blob/main/docs/PRD.md Idempotently copies the Chats gem's migrations to the host application. ```ruby rails chats:install:migrations ``` -------------------------------- ### Add Gem to Gemfile Source: https://github.com/rameerez/chats/blob/main/README.md Add the chats gem to your application's Gemfile. ```ruby gem "chats" ``` -------------------------------- ### Adapter Classification Interface Source: https://github.com/rameerez/chats/blob/main/docs/PRD.md Defines the interface for content classification adapters. The `classify` method should return a hash containing `allowed`, `categories`, `scores`, `source`, and `metadata`. This allows for interchangeable use of different classification methods like wordlists or AI classifiers. ```ruby adapter.classify(value) # => { allowed:, categories:, scores:, source:, metadata: } ``` -------------------------------- ### Posting a System Message to a Conversation Source: https://github.com/rameerez/chats/blob/main/docs/PRD.md Illustrates the `chats` API for posting system messages directly into a conversation. This is used when other notifiers need to inject messages into the chat interface, such as ride status updates. ```ruby Chats::Conversation#post_system_message!(body:) ``` -------------------------------- ### Implement Unread Email Notification Job Source: https://github.com/rameerez/chats/blob/main/README.md A background job to send unread message notifications to participants. It checks participant eligibility and notification status before sending emails. ```ruby class ChatsUnreadEmailJob < ApplicationJob def perform(message) message.conversation.participants.active.each do |participant| next unless participant.notifiable_for?(message) # not the sender, not muted, not departed next unless participant.should_notify? # unread + not already notified this burst ChatsMailer.with(participant: participant).unread_messages.deliver_now participant.mark_notified! end end end config.notifier = ->(event, message:, **) { ChatsUnreadEmailJob.set(wait: 10.minutes).perform_later(message) if event == :message_created } ``` -------------------------------- ### Define Chat Subject Model Source: https://github.com/rameerez/chats/blob/main/README.md Associate conversations with specific domain objects using `acts_as_chat_subject`. ```ruby class Ride < ApplicationRecord acts_as_chat_subject end ``` -------------------------------- ### Report Link for Chat Messages Source: https://github.com/rameerez/chats/blob/main/README.md Implement a report link for chat messages in the message partial. This uses a signed-target URL to ensure the link is broadcast-safe and works correctly with Moderate's `report_visible_to?` check on the server-side. ```erb <%# in your ejected chats/messages/_message.html.erb, inside the actions row %> <% if message.sender %> <%= link_to "Report", main_app.new_abuse_report_path( target: message.to_sgid_param(for: Moderate::Report::SIGNED_GLOBAL_ID_PURPOSE), field: "body" ), class: "chats-message__action in-own-hidden" %> <%# hide on .chats-message--own via your CSS; moderate's controller re-checks report_visible_to? server-side, so hiding is cosmetic %> <% end %> ``` -------------------------------- ### Debounced Email Configuration Source: https://github.com/rameerez/chats/blob/main/docs/PRD.md Configures debounced email notifications using Noticed. Emails are sent only if the notification remains unread after a specified delay. ```ruby config.wait = 10.minutes config.unless = -> { read? } ``` -------------------------------- ### Rails Generator for Ejecting Stimulus Controllers Source: https://github.com/rameerez/chats/blob/main/docs/PRD.md Copies the Stimulus controller files from the Chats gem into the host application for deep customization. ```ruby rails g chats:stimulus ``` -------------------------------- ### Render Chat Button Source: https://github.com/rameerez/chats/blob/main/README.md Render a 'Message' button that conditionally appears when a user is allowed to message another. ```erb <%= chat_button_to @driver, about: @ride %> ``` -------------------------------- ### Configure Message Filtering Source: https://github.com/rameerez/chats/blob/main/README.md Register Chats::Message with Moderate to filter its body and files. Use `:flag` mode for chat messages, which sends the message and creates a pending moderation flag. ```ruby config.filter "Chats::Message", :body, mode: :flag config.filter "Chats::Message", :files, mode: :flag, with: :your_image_adapter ``` -------------------------------- ### Recipient Calculation in Host Notifier Source: https://github.com/rameerez/chats/blob/main/docs/PRD.md Demonstrates how the host Notifier calculates recipients based on the message and conversation participants, excluding the sender. This logic resides in the host application, not within the 'chats' gem. ```ruby recipients -> { params[:message].conversation.participants.excluding(params[:message].sender) } ``` -------------------------------- ### Rails Generator for Ejecting Chats Views Source: https://github.com/rameerez/chats/blob/main/docs/PRD.md Copies the overridable view files from the Chats gem into the host application for customization. ```ruby rails g chats:views [scope] ``` -------------------------------- ### Chats Gem Configuration Block Source: https://github.com/rameerez/chats/blob/main/docs/PRD.md Configures various features and settings for the Chats gem, such as the messager class, feature flags, message limits, and authorization policies. ```ruby Chats.configure do |c| # ... configuration options ... end ``` -------------------------------- ### Send a Direct Message Source: https://github.com/rameerez/chats/blob/main/README.md Send a direct message between two users in a single line of code. ```ruby alice.message!(bob, "hola!") ``` -------------------------------- ### Message About a Subject Source: https://github.com/rameerez/chats/blob/main/README.md Send a message related to a specific subject, creating context-specific threads. ```ruby passenger.message!(driver, "Can I bring a suitcase?", about: ride) ``` -------------------------------- ### Configure Blocked Messager IDs Source: https://github.com/rameerez/chats/blob/main/README.md Configure the Chats gem to use the Moderate gem's blocked IDs for enforcing blocking rules. This hook ensures that blocked users cannot open or send messages to each other. ```ruby Chats.configure do |config| config.blocked_messager_ids = ->(user) { Moderate.blocked_ids_for(user) } end ``` -------------------------------- ### Display Unread Badge Source: https://github.com/rameerez/chats/blob/main/README.md Display a live unread message badge in your application's navigation. ```erb <%= chats_unread_badge %> ``` -------------------------------- ### Include Content Filterable Concern Source: https://github.com/rameerez/chats/blob/main/docs/PRD.md Include this concern in your model to enable content filtering. It drives the validation for `:block` mode and the `after_commit` hook for `:flag` mode. This is essential for applying moderation policies to model fields. ```ruby include Moderation::ContentFilterable moderates_content :body ``` -------------------------------- ### Implement Reportable Concern for Chats::Message Source: https://github.com/rameerez/chats/blob/main/docs/PRD.md This snippet shows how to include the Moderation::Reportable concern in a Chats::Message model. It defines necessary methods to support reporting messages, including fields to report, owner identification, snapshot text, field removal, and visibility checks. Ensure the host application registers 'Chats::Message' in Moderation.config.reportable_class_names. ```ruby class Chats::Message < ApplicationRecord include Moderation::Reportable reportable_fields :body def reported_owner = sender def moderation_label = "Message #{id}" def moderation_snapshot_text(field) = body if field.to_s == "body" def remove_reported_field!(field) = (update!(body: nil, deleted_at: Time.current); true) if field.to_s == "body" def report_visible_to?(viewer, field:) = participant?(viewer) # only people in the convo can report it # moderation_subject_url / return_path / admin_path take a routes object (already the concern's shape) end ``` -------------------------------- ### Message Editing and Deletion Source: https://github.com/rameerez/chats/blob/main/README.md Edit existing messages and perform soft deletions (tombstoning). ```ruby message.edit!("fixed") # stamps edited_at message.soft_delete! # tombstone (or destroy, per config) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.