### Setup Mailkick Development Environment
Source: https://github.com/ankane/mailkick/blob/master/README.md
Clone the repository, install dependencies with Bundler, and run tests using Rake. This is the standard procedure for setting up the Mailkick development environment.
```sh
git clone https://github.com/ankane/mailkick.git
cd mailkick
bundle install
bundle exec rake test
```
--------------------------------
### Install Mailkick Gem and Run Migrations
Source: https://context7.com/ankane/mailkick/llms.txt
Add the Mailkick gem to your Gemfile, install it, and then generate and run the migration to create the necessary database table.
```ruby
gem "mailkick"
```
```sh
bundle install
rails generate mailkick:install
rails db:migrate
```
--------------------------------
### Generate and Migrate Mailkick Install
Source: https://github.com/ankane/mailkick/blob/master/README.md
Run the Mailkick generator and migrate your database to set up the necessary tables for subscription management.
```sh
bundle install
rails generate mailkick:install
rails db:migrate
```
--------------------------------
### Install Mailkick Gem
Source: https://github.com/ankane/mailkick/blob/master/README.md
Add the Mailkick gem to your Gemfile to begin using its features.
```ruby
gem "mailkick"
```
--------------------------------
### Using `has_subscriptions` Model Mixin (Default)
Source: https://context7.com/ankane/mailkick/llms.txt
Integrate subscription management into an ActiveRecord model. This default setup provides `subscribe`, `unsubscribe`, `subscribed?` instance methods and a `subscribed` class scope without any prefix.
```ruby
# Default (no prefix) — methods: subscribe, unsubscribe, subscribed?, User.subscribed(list)
class User < ApplicationRecord
has_subscriptions
end
```
--------------------------------
### Configure Mailkick Opt-Out Processing
Source: https://github.com/ankane/mailkick/blob/master/README.md
Define a lambda method for `Mailkick.process_opt_outs_method` to handle opt-out data fetched from email services. This example shows how to process bounces and spam reports by destroying relevant subscriptions.
```ruby
Mailkick.process_opt_outs_method = lambda do |opt_outs|
emails = opt_outs.map { |v| v[:email] }
subscribers = User.includes(:mailkick_subscriptions).where(email: emails).index_by(&:email)
opt_outs.each do |opt_out|
subscriber = subscribers[opt_out[:email]]
next unless subscriber
subscriber.mailkick_subscriptions.each do |subscription|
subscription.destroy if subscription.created_at < opt_out[:time]
end
end
end
```
--------------------------------
### Customize Mailkick Subscription Status View
Source: https://context7.com/ankane/mailkick/llms.txt
Example of a customized `show.html.erb` view for the Mailkick subscription status page, allowing users to unsubscribe or resubscribe.
```erb
<%# app/views/mailkick/subscriptions/show.html.erb (after running views generator) %>
<% if !subscribed? %>
You are unsubscribed.
<%= link_to "Resubscribe", subscribe_url %>
<% else %>
You are subscribed.
<%= link_to "Unsubscribe", unsubscribe_url %>
<% end %>
```
--------------------------------
### Get Users Subscribed to a List
Source: https://github.com/ankane/mailkick/blob/master/README.md
Retrieve all users subscribed to a specific list using the `subscribed` class method. This is useful for sending emails.
```ruby
User.subscribed("sales")
```
--------------------------------
### Using `has_subscriptions` Model Mixin (Prefixed)
Source: https://context7.com/ankane/mailkick/llms.txt
Integrate subscription management into an ActiveRecord model with prefixed methods to avoid name collisions. This setup provides `mailkick_subscribe`, `mailkick_unsubscribe`, `mailkick_subscribed?` instance methods and a `mailkick_subscribed` class scope.
```ruby
# Prefixed — methods: mailkick_subscribe, mailkick_unsubscribe,
# mailkick_subscribed?, Admin.mailkick_subscribed(list)
class Admin < ApplicationRecord
has_subscriptions prefix: true
end
```
--------------------------------
### Prefixed Instance and Class Methods
Source: https://context7.com/ankane/mailkick/llms.txt
Demonstrates the usage of prefixed subscription methods for models configured with `prefix: true`. This ensures method names do not collide with other parts of your application.
```ruby
# ---- Prefixed variant ----
admin = Admin.find(1)
admin.mailkick_subscribe("alerts")
admin.mailkick_subscribed?("alerts") # => true
Admin.mailkick_subscribed("alerts") # => ActiveRecord::Relation
admin.mailkick_unsubscribe("alerts")
```
--------------------------------
### Instance Methods for Subscription Management
Source: https://context7.com/ankane/mailkick/llms.txt
Manage individual user subscriptions using `subscribe`, `subscribed?`, and `unsubscribe` methods. These methods are idempotent and handle record creation or deletion accordingly.
```ruby
# ---- Instance methods ----
user = User.find(42)
user.subscribe("newsletter") # => nil (idempotent, uses first_or_create!)
user.subscribed?("newsletter") # => true
user.subscribe("newsletter") # no-op, no duplicate record created
user.unsubscribe("newsletter") # => nil (deletes the record, no error if absent)
user.subscribed?("newsletter") # => false
```
--------------------------------
### Mailkick.discover_services
Source: https://context7.com/ankane/mailkick/llms.txt
Called automatically by the Rails engine on boot. Iterates over all `Mailkick::Service` subclasses and instantiates any whose `discoverable?` class method returns `true`. You rarely need to call this manually.
```APIDOC
## `Mailkick.discover_services` — Automatic ESP Discovery
Called automatically by the Rails engine on boot. Iterates over all `Mailkick::Service` subclasses and instantiates any whose `discoverable?` class method returns `true` (i.e., the matching gem is loaded and the environment variable is set). You rarely need to call this manually.
```ruby
# Triggered automatically in config/initializers via the Engine:
# Mailkick.discover_services unless Mailkick.services.any?
# Manually force re-discovery (e.g., in tests or after credential change):
Mailkick.services = []
Mailkick.discover_services
# => nil
# Mailkick.services now contains auto-detected service instances
# Check which services were discovered:
puts Mailkick.services.map(&:class)
# => [Mailkick::Service::SendGrid] (if SENDGRID_API_KEY is set and gem is present)
```
```
--------------------------------
### Manual Mailkick Service Configuration
Source: https://context7.com/ankane/mailkick/llms.txt
Explicitly configure Mailkick's ESP clients using `Mailkick.services`. This allows for custom credentials, API keys, and specific options like `stream_id` or `domain` for each service.
```ruby
# config/initializers/mailkick.rb
# SendGrid — requires gem "sendgrid-ruby" and SENDGRID_API_KEY env var
Mailkick.services = [
Mailkick::Service::SendGrid.new(api_key: ENV["SENDGRID_API_KEY"])
]
```
```ruby
# Multiple services at once
Mailkick.services = [
Mailkick::Service::SendGrid.new(api_key: ENV["SENDGRID_API_KEY"]),
Mailkick::Service::Mailchimp.new(
api_key: ENV["MAILCHIMP_API_KEY"],
list_id: ENV["MAILCHIMP_LIST_ID"]
)
]
```
```ruby
# Postmark with non-default stream
Mailkick.services = [
Mailkick::Service::Postmark.new(
api_key: ENV["POSTMARK_API_KEY"],
stream_id: "outbound" # default is "broadcast"
)
]
```
```ruby
# Mailgun with explicit domain
Mailkick.services = [
Mailkick::Service::Mailgun.new(
api_key: ENV["MAILGUN_API_KEY"],
domain: "mg.example.com"
)
]
```
```ruby
# AWS SES — uses aws-sdk-sesv2 and standard AWS credential chain (no explicit key)
Mailkick.services = [
Mailkick::Service::AwsSes.new
]
```
```ruby
# Mandrill
Mailkick.services = [
Mailkick::Service::Mandrill.new(api_key: ENV["MANDRILL_API_KEY"])
]
```
--------------------------------
### Configure Postmark Service Stream
Source: https://github.com/ankane/mailkick/blob/master/README.md
If fetching suppressions from Postmark, use this initializer to change the default stream from 'broadcast' to 'outbound' by specifying the stream_id. Requires an API key.
```ruby
Mailkick.services = [Mailkick::Service::Postmark.new(api_key: api_key, stream_id: "outbound")]
```
--------------------------------
### Subscribe User to a List
Source: https://github.com/ankane/mailkick/blob/master/README.md
Use the `subscribe` method on a user instance to add them to a specific mailing list.
```ruby
user.subscribe("sales")
```
--------------------------------
### Restore Unsubscribe Link Support
Source: https://github.com/ankane/mailkick/blob/master/README.md
Use this initializer to restore support for unsubscribe links created before version 1.1.1 by rotating the previous secret token. Ensure the previous secret token is correctly determined.
```ruby
Mailkick.message_verifier.rotate(previous_secret_token, serializer: Marshal)
```
--------------------------------
### Manually Configure Mailkick Services
Source: https://github.com/ankane/mailkick/blob/master/README.md
For advanced control, manually configure the Mailkick services by providing instances with their respective API keys and list IDs.
```ruby
Mailkick.services = [
Mailkick::Service::SendGrid.new(api_key: "API_KEY"),
Mailkick::Service::Mailchimp.new(api_key: "API_KEY", list_id: "LIST_ID")
]
```
--------------------------------
### Mailkick.services
Source: https://context7.com/ankane/mailkick/llms.txt
Override automatic service discovery and configure ESP clients explicitly with specific credentials or options.
```APIDOC
## `Mailkick.services` — Manual Service Configuration
Override automatic service discovery and configure ESP clients explicitly with specific credentials or options.
```ruby
# config/initializers/mailkick.rb
# SendGrid — requires gem "sendgrid-ruby" and SENDGRID_API_KEY env var
Mailkick.services = [
Mailkick::Service::SendGrid.new(api_key: ENV["SENDGRID_API_KEY"])
]
# Multiple services at once
Mailkick.services = [
Mailkick::Service::SendGrid.new(api_key: ENV["SENDGRID_API_KEY"]),
Mailkick::Service::Mailchimp.new(
api_key: ENV["MAILCHIMP_API_KEY"],
list_id: ENV["MAILCHIMP_LIST_ID"]
)
]
# Postmark with non-default stream
Mailkick.services = [
Mailkick::Service::Postmark.new(
api_key: ENV["POSTMARK_API_KEY"],
stream_id: "outbound" # default is "broadcast"
)
]
# Mailgun with explicit domain
Mailkick.services = [
Mailkick::Service::Mailgun.new(
api_key: ENV["MAILGUN_API_KEY"],
domain: "mg.example.com"
)
]
# AWS SES — uses aws-sdk-sesv2 and standard AWS credential chain (no explicit key)
Mailkick.services = [
Mailkick::Service::AwsSes.new
]
# Mandrill
Mailkick.services = [
Mailkick::Service::Mandrill.new(api_key: ENV["MANDRILL_API_KEY"])
]
```
```
--------------------------------
### Add SendGrid Gem for Mailkick
Source: https://github.com/ankane/mailkick/blob/master/README.md
Include the `sendgrid-ruby` gem in your Gemfile if you are using SendGrid for fetching opt-outs.
```ruby
gem "sendgrid-ruby"
```
--------------------------------
### Mailkick.fetch_opt_outs
Source: https://context7.com/ankane/mailkick/llms.txt
Iterates over every configured service and calls `process_opt_outs_method` with the combined opt-out records. Typically invoked from a scheduled job.
```APIDOC
## `Mailkick.fetch_opt_outs` — Fetch Suppressions from ESPs
Iterates over every configured service and calls `process_opt_outs_method` with the combined opt-out records. Typically invoked from a scheduled job.
```ruby
# app/jobs/sync_opt_outs_job.rb
class SyncOptOutsJob < ApplicationJob
queue_as :default
def perform
Mailkick.fetch_opt_outs
# => nil on success; raises on HTTP/API errors
end
end
# Schedule with e.g. Sidekiq-Cron or Whenever:
# SyncOptOutsJob.perform_later
# every 1.hour, "Sync email opt-outs" (Whenever)
```
```
--------------------------------
### Prefix Mailkick Methods with `mailkick_`
Source: https://github.com/ankane/mailkick/blob/master/README.md
Configure Mailkick to prefix its generated methods with `mailkick_` by setting `prefix: true` in the `has_subscriptions` macro.
```ruby
class User < ApplicationRecord
has_subscriptions prefix: true
end
```
--------------------------------
### Add AWS SES Gem for Mailkick
Source: https://github.com/ankane/mailkick/blob/master/README.md
Include the `aws-sdk-sesv2` gem in your Gemfile if you are using AWS SES for fetching opt-outs.
```ruby
gem "aws-sdk-sesv2"
```
--------------------------------
### Add Postmark Gem for Mailkick
Source: https://github.com/ankane/mailkick/blob/master/README.md
Include the `postmark` gem in your Gemfile if you are using Postmark for fetching opt-outs.
```ruby
gem "postmark"
```
--------------------------------
### Generate Mailkick Web UI Views
Source: https://context7.com/ankane/mailkick/llms.txt
Run this generator to copy the Mailkick unsubscribe/resubscribe UI views into your application for customization.
```sh
# Mount path is /mailkick by default (set Mailkick.mount = false to disable)
# Routes provided by the engine:
# GET /mailkick/subscriptions/:id → show subscription status page
# GET /mailkick/subscriptions/:id/unsubscribe → unsubscribe (browser flow)
# POST /mailkick/subscriptions/:id/unsubscribe → one-click unsubscribe (RFC 8058)
# GET /mailkick/subscriptions/:id/subscribe → resubscribe
# Customize the view:
rails generate mailkick:views
# Creates: app/views/mailkick/subscriptions/show.html.erb
```
--------------------------------
### Enable Unsubscribe Headers
Source: https://github.com/ankane/mailkick/blob/master/README.md
Configure Mailkick to automatically add one-click unsubscribe headers to emails by setting `Mailkick.headers = true` in an initializer.
```ruby
Mailkick.headers = true
```
--------------------------------
### Access Mailkick Subscription Model
Source: https://github.com/ankane/mailkick/blob/master/README.md
You can directly access and query the `Mailkick::Subscription` model to manage subscriptions.
```ruby
Mailkick::Subscription.all
```
--------------------------------
### Fetch Opt-Outs from Email Services
Source: https://github.com/ankane/mailkick/blob/master/README.md
Call `Mailkick.fetch_opt_outs` to retrieve bounces, spam reports, and unsubscribes from configured email services.
```ruby
Mailkick.fetch_opt_outs
```
--------------------------------
### Enable RFC 8058 One-Click Unsubscribe Headers
Source: https://context7.com/ankane/mailkick/llms.txt
Configure Mailkick to automatically include `List-Unsubscribe` and `List-Unsubscribe-Post` headers in outgoing emails by setting `Mailkick.headers = true` in an initializer.
```ruby
# config/initializers/mailkick.rb
Mailkick.headers = true
```
--------------------------------
### Processing Opt-Outs with Mailkick
Source: https://context7.com/ankane/mailkick/llms.txt
Configure `Mailkick.process_opt_outs_method` to handle opt-out records fetched from your ESP. This lambda should update your subscription records based on the provided email, time, and reason.
```ruby
# config/initializers/mailkick.rb
Mailkick.process_opt_outs_method = lambda do |opt_outs|
# opt_outs is an Array of:
# { email: "alice@example.com", time: Time, reason: "bounce"|"spam"|"unsubscribe" }
emails = opt_outs.map { |v| v[:email] }
subscribers = User
.includes(:mailkick_subscriptions)
.where(email: emails)
.index_by(&:email)
opt_outs.each do |opt_out|
subscriber = subscribers[opt_out[:email]]
next unless subscriber
# Only remove subscriptions that were created BEFORE the opt-out event
subscriber.mailkick_subscriptions.each do |subscription|
subscription.destroy if subscription.created_at < opt_out[:time]
end
end
end
```
--------------------------------
### Generate Mailkick Views
Source: https://github.com/ankane/mailkick/blob/master/README.md
Run this command to copy Mailkick's default unsubscribe view into your application for customization.
```sh
rails generate mailkick:views
```
--------------------------------
### Add has_subscriptions to User Model
Source: https://github.com/ankane/mailkick/blob/master/README.md
Include the `has_subscriptions` macro in your User model to enable subscription functionality.
```ruby
class User < ApplicationRecord
has_subscriptions
end
```
--------------------------------
### Mailkick Subscription Table Migration Schema
Source: https://context7.com/ankane/mailkick/llms.txt
This is the schema for the `mailkick_subscriptions` table generated by the Mailkick migration. It includes polymorphic references for subscribers and a unique index for subscriber and list combinations.
```ruby
# db/migrate/YYYYMMDDHHMMSS_mailkick_install.rb
class MailkickInstall < ActiveRecord::Migration[8.0]
def change
create_table :mailkick_subscriptions do |t|
t.references :subscriber, polymorphic: true, index: false
t.string :list
t.timestamps
end
add_index :mailkick_subscriptions,
[:subscriber_type, :subscriber_id, :list],
unique: true,
name: "index_mailkick_subscriptions_on_subscriber_and_list"
end
end
```
--------------------------------
### Automatic Mailkick Service Discovery
Source: https://context7.com/ankane/mailkick/llms.txt
Mailkick automatically discovers and instantiates services based on loaded gems and environment variables. You can manually trigger re-discovery or inspect the discovered services.
```ruby
# Triggered automatically in config/initializers via the Engine:
# Mailkick.discover_services unless Mailkick.services.any?
# Manually force re-discovery (e.g., in tests or after credential change):
Mailkick.services = []
Mailkick.discover_services
# => nil
# Mailkick.services now contains auto-detected service instances
# Check which services were discovered:
puts Mailkick.services.map(&:class)
# => [Mailkick::Service::SendGrid] (if SENDGRID_API_KEY is set and gem is present)
```
--------------------------------
### Mailkick.process_opt_outs_method
Source: https://context7.com/ankane/mailkick/llms.txt
A lambda that Mailkick calls with an array of opt-out hashes. This method is used to wire opt-outs into your subscription records.
```APIDOC
## `Mailkick.process_opt_outs_method` — Opt-Out Callback
A required lambda that Mailkick calls with an array of opt-out hashes (`{ email:, time:, reason: }`) after fetching suppressions from your ESP. Define it in an initializer to wire opt-outs into your subscription records.
```ruby
# config/initializers/mailkick.rb
Mailkick.process_opt_outs_method = lambda do |opt_outs|
# opt_outs is an Array of:
# { email: "alice@example.com", time: Time, reason: "bounce"|"spam"|"unsubscribe" }
emails = opt_outs.map { |v| v[:email] }
subscribers = User
.includes(:mailkick_subscriptions)
.where(email: emails)
.index_by(&:email)
opt_outs.each do |opt_out|
subscriber = subscribers[opt_out[:email]]
next unless subscriber
# Only remove subscriptions that were created BEFORE the opt-out event
subscriber.mailkick_subscriptions.each do |subscription|
subscription.destroy if subscription.created_at < opt_out[:time]
end
end
end
```
```
--------------------------------
### Add Mailgun Gem for Mailkick
Source: https://github.com/ankane/mailkick/blob/master/README.md
Include the `mailgun-ruby` gem in your Gemfile if you are using Mailgun for fetching opt-outs.
```ruby
gem "mailgun-ruby"
```
--------------------------------
### Generating Mailkick Subscription Tokens
Source: https://context7.com/ankane/mailkick/llms.txt
Use `Mailkick.generate_token` to create signed tokens for unsubscribe URLs. This method is used internally by `mailkick_unsubscribe_url` but can be used for custom URL construction. It requires a subscriber object and a list name.
```ruby
user = User.find(99)
token = Mailkick.generate_token(user, "newsletter")
# => "eyJfcmFpbHMiOnsibWVzc..." (a JSON MessageVerifier-signed string)
# Build a raw URL without ActionMailer context:
url = Rails.application.routes.url_helpers.url_for(
controller: "mailkick/subscriptions",
action: "unsubscribe",
id: token,
host: "example.com"
)
# => "https://example.com/mailkick/subscriptions/TOKEN/unsubscribe"
# Error handling:
Mailkick.generate_token(nil, "newsletter") # raises ArgumentError: Missing subscriber
Mailkick.generate_token(user, "") # raises ArgumentError: Missing list
```
--------------------------------
### Add Mandrill Gem for Mailkick
Source: https://github.com/ankane/mailkick/blob/master/README.md
Include the `mandrill-api` gem in your Gemfile if you are using Mandrill for fetching opt-outs.
```ruby
gem "mandrill-api"
```
--------------------------------
### Add Gibbon Gem for Mailchimp
Source: https://github.com/ankane/mailkick/blob/master/README.md
Include the `gibbon` gem if you are using Mailchimp for fetching opt-outs.
```ruby
gem "gibbon", ">= 2"
```
--------------------------------
### Access Mailkick Subscription Model Directly
Source: https://context7.com/ankane/mailkick/llms.txt
Interact with the underlying ActiveRecord model for subscription records. Supports polymorphic associations and direct creation/deletion.
```ruby
# Query all active subscriptions
Mailkick::Subscription.all
# => ActiveRecord::Relation
# Find subscriptions for a specific user
user = User.find(42)
user.mailkick_subscriptions
# => [#]
# Find all subscribers to a list across all types
Mailkick::Subscription.where(list: "newsletter")
# Directly create / destroy (prefer model methods for business logic)
Mailkick::Subscription.create!(
subscriber: user,
list: "newsletter"
)
Mailkick::Subscription.where(subscriber: user, list: "newsletter").delete_all
# Validations enforced by the model:
Mailkick::Subscription.new(subscriber: user, list: "").valid? # => false
# errors.full_messages => ["List can't be blank"]
```
--------------------------------
### Rotate Message Verifier Secret for Legacy Tokens
Source: https://context7.com/ankane/mailkick/llms.txt
Use this to restore support for unsubscribe links generated before Mailkick 1.1.1, which used Marshal serialization and a legacy secret.
```ruby
# config/initializers/mailkick.rb
# Restore support for unsubscribe links generated before Mailkick 1.1.1
# (links signed with Marshal instead of JSON, using a legacy secret)
previous_secret = "your-old-secret-token-here"
Mailkick.message_verifier.rotate(previous_secret, serializer: Marshal)
```
--------------------------------
### Unsubscribe User from a List
Source: https://github.com/ankane/mailkick/blob/master/README.md
Use the `unsubscribe` method on a user instance to remove them from a specific mailing list.
```ruby
user.unsubscribe("sales")
```
--------------------------------
### Injecting Unsubscribe Headers with Mailkick
Source: https://context7.com/ankane/mailkick/llms.txt
Use `mailkick_unsubscribe_url` within your mailer to automatically inject List-Unsubscribe headers. This ensures compliance and provides a one-click unsubscribe option for users.
```ruby
class TransactionalMailer < ApplicationMailer
def receipt(user, order)
@user = user
@order = order
mailkick_unsubscribe_url(@user, "transactional") # triggers header injection
mail(to: @user.email, subject: "Your receipt ##{order.id}")
end
end
```
--------------------------------
### Add Unsubscribe Link to Text Emails
Source: https://github.com/ankane/mailkick/blob/master/README.md
Include an unsubscribe link in your plain text emails using the `mailkick_unsubscribe_url` helper.
```erb
Unsubscribe: <%= mailkick_unsubscribe_url(@user, "sales") %>
```
--------------------------------
### Check if User is Subscribed
Source: https://github.com/ankane/mailkick/blob/master/README.md
Use the `subscribed?` method to check if a user is currently subscribed to a given list.
```ruby
user.subscribed?("sales")
```
--------------------------------
### Generating Unsubscribe URL in ActionMailer
Source: https://context7.com/ankane/mailkick/llms.txt
Use the `mailkick_unsubscribe_url` helper within your ActionMailer mailers to generate a secure unsubscribe link for users. This helper can also automatically set RFC 8058 headers if `Mailkick.headers` is enabled.
```ruby
# app/mailers/newsletter_mailer.rb
class NewsletterMailer < ApplicationMailer
def weekly(user)
@user = user
@unsubscribe_url = mailkick_unsubscribe_url(@user, "newsletter")
mail(to: @user.email, subject: "This week in Rails")
end
end
```
--------------------------------
### Mailkick.generate_token
Source: https://context7.com/ankane/mailkick/llms.txt
Generates the signed token embedded in unsubscribe URLs. Used internally by `mailkick_unsubscribe_url` but available for custom URL construction.
```APIDOC
## `Mailkick.generate_token` — Signed Subscription Token
Generates the signed token embedded in unsubscribe URLs. Used internally by `mailkick_unsubscribe_url` but available for custom URL construction.
```ruby
user = User.find(99)
token = Mailkick.generate_token(user, "newsletter")
# => "eyJfcmFpbHMiOnsibWVzc..." (a JSON MessageVerifier-signed string)
# Build a raw URL without ActionMailer context:
url = Rails.application.routes.url_helpers.url_for(
controller: "mailkick/subscriptions",
action: "unsubscribe",
id: token,
host: "example.com"
)
# => "https://example.com/mailkick/subscriptions/TOKEN/unsubscribe"
# Error handling:
Mailkick.generate_token(nil, "newsletter") # raises ArgumentError: Missing subscriber
Mailkick.generate_token(user, "") # raises ArgumentError: Missing list
```
```
--------------------------------
### Disable Mailkick Automatic Mounting
Source: https://context7.com/ankane/mailkick/llms.txt
Configure Mailkick to disable automatic mounting of its engine at `/mailkick`. This allows for manual mounting or complete disabling.
```ruby
# Disable automatic mounting (if you want to mount manually or not at all):
# config/initializers/mailkick.rb
Mailkick.mount = false
# Manual mount in config/routes.rb:
Rails.application.routes.draw do
mount Mailkick::Engine => "/email-preferences"
end
```
--------------------------------
### Unsubscribe Link in Plain-Text Email View
Source: https://context7.com/ankane/mailkick/llms.txt
Include the unsubscribe URL in the plain-text version of your emails for users who prefer or only receive plain text. This ensures the unsubscribe option is available across all email formats.
```erb
<%# Plain-text variant — app/views/newsletter_mailer/weekly.text.erb %>
Hello <%= @user.first_name %>,
Here is your weekly digest…
Unsubscribe: <%= mailkick_unsubscribe_url(@user, "newsletter") %>
```
--------------------------------
### Add Unsubscribe Link to HTML Emails
Source: https://github.com/ankane/mailkick/blob/master/README.md
Embed an unsubscribe link in your HTML emails using the `mailkick_unsubscribe_url` helper.
```erb
<%= link_to "Unsubscribe", mailkick_unsubscribe_url(@user, "sales") %>
```
--------------------------------
### Class Scope for Subscribed Users
Source: https://context7.com/ankane/mailkick/llms.txt
Query for subscribed users using the `subscribed` class scope. This scope returns an ActiveRecord::Relation, allowing further querying or iteration.
```ruby
# ---- Class scope ----
User.subscribed("newsletter") # => ActiveRecord::Relation of subscribed users
User.subscribed("newsletter").count # => integer
User.subscribed("newsletter").each do |u|
NewsletterMailer.weekly(u).deliver_later
end
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.