Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
G

gibbon

> 编程语言
Open source

Gibbon is an API wrapper for MailChimp's API

1.1K stars0 likes0 views
WebsiteGitHub

About

Gibbon is an API wrapper for MailChimp's API

gibbon

Gibbon is an API wrapper for MailChimp's API.

Important Notes

Please read MailChimp's Getting Started Guide.

Gibbon returns a Gibbon::Response, which exposes the parsed response body and the response headers. See Responses below.

See the CHANGELOG for release history and Upgrading for breaking changes.

Installation

$ gem install gibbon

Or add it to your Gemfile:

ruby
gem "gibbon"

Requirements

  • Ruby 3.1 or newer. Gibbon 4.0 dropped support for Ruby 2.4 through 3.0.
  • A MailChimp account and API key. You can see your API keys here.

Gibbon depends on Faraday (both 1.x and 2.x are supported) and MultiJson. Connections to MailChimp negotiate TLS 1.2 or newer.

Usage

First, create a one-time use instance of Gibbon::Request:

ruby
gibbon = Gibbon::Request.new(api_key: "your_api_key")

Note Only reuse instances of Gibbon after terminating a call with a verb, which makes a request. Requests are light weight objects that update an internal path based on your call chain. When you terminate a call chain with a verb, a request instance makes a request and resets the path. See How call chains build paths.

You can set an individual request's timeout and open_timeout like this:

ruby
gibbon.timeout = 30
gibbon.open_timeout = 30

You can read about timeout and open_timeout in the Net::HTTP doc.

Now you can make requests using the resources defined in MailChimp's docs. Resource IDs are specified inline and a CRUD (create, retrieve (or get), update, upsert, or delete) verb initiates the request. upsert lets you update a record, if it exists, or insert it otherwise where supported by MailChimp's API.

Each verb maps to an HTTP method:

Gibbon verb HTTP method Accepts body
create POST yes
retrieve (or get) GET no
update PATCH yes
upsert PUT yes
delete DELETE no

You can specify headers, params, and body when calling a CRUD method. For example:

ruby
gibbon.lists.retrieve(headers: {"SomeHeader": "SomeHeaderValue"}, params: {"query_param": "query_param_value"})

Of course, body is only supported on create, update, and upsert calls. Those map to HTTP POST, PATCH, and PUT verbs respectively.

You can set api_key, timeout, open_timeout, faraday_adapter, proxy, symbolize_keys, logger, and debug globally:

ruby
Gibbon::Request.api_key = "your_api_key"
Gibbon::Request.timeout = 15
Gibbon::Request.open_timeout = 15
Gibbon::Request.symbolize_keys = true
Gibbon::Request.debug = false

For example, you could set the values above in an initializer file in your Rails app (e.g. your_app/config/initializers/gibbon.rb).

Assuming you've set an api_key on Gibbon, you can conveniently make API calls on the class itself:

ruby
Gibbon::Request.lists.retrieve

You can also set the environment variable MAILCHIMP_API_KEY and Gibbon will use it when you create an instance:

ruby
gibbon = Gibbon::Request.new

Pass symbolize_keys: true to use symbols (instead of strings) as hash keys in API responses.

ruby
gibbon = Gibbon::Request.new(api_key: "your_api_key", symbolize_keys: true)

MailChimp's resource documentation is a list of available resources.

How call chains build paths

Gibbon::Request defines no methods for MailChimp's resources. Any unknown method appends a segment to an internal path and returns the same object; a CRUD verb turns the accumulated path into a request. So gibbon.lists(list_id).members.retrieve builds lists//members and issues a GET.

Three consequences are worth knowing.

Underscores become hyphens. Segments containing a hyphen aren't valid Ruby method names, so write them with underscores and Gibbon converts:

ruby
gibbon.lists(list_id).members(subscriber_hash).actions.delete_permanent.create
# POST lists//members//actions/delete-permanent

send is special cased. Object#send would otherwise shadow the path segment, so Gibbon::Request#send falls through to path building when called with no arguments. That's what makes sending a campaign work:

ruby
gibbon.campaigns(campaign_id).actions.send.create
# POST campaigns//actions/send

Called with arguments, send keeps its usual Ruby meaning and invokes the named method.

An instance is reusable only after a verb. The path resets when a verb runs, not when a chain goes out of scope. Abandoning a chain leaves its segments in place and corrupts the next call:

ruby
gibbon = Gibbon::Request.new(api_key: "your_api_key")

gibbon.lists               # no verb, so nothing is sent and nothing is reset
gibbon.campaigns.retrieve  # GET lists/campaigns -- not what you wanted

Use a fresh instance per chain unless you know the previous one ended in a verb.

Responses

Every CRUD verb returns a Gibbon::Response with two attributes:

  • body — the parsed JSON response, as a Hash (or Array, depending on the endpoint)
  • headers — the response headers, keyed by lower case string
ruby
response = gibbon.lists.retrieve

response.body["lists"]           # => [{"id" => "...", "name" => "...", ...}, ...]
response.headers["content-type"] # => "application/json; charset=utf-8"

body respects symbolize_keys; headers keys are always strings.

A response with an empty body — as with a successful delete, which MailChimp answers with 204 No Content — returns nil rather than a Gibbon::Response.

Debug Logging

Pass debug: true to enable debug logging to STDOUT.

ruby
gibbon = Gibbon::Request.new(api_key: "your_api_key", debug: true)

Custom logger

Ruby Logger.new is used by default, but it can be overridden using:

ruby
gibbon = Gibbon::Request.new(api_key: "your_api_key", debug: true, logger: MyLogger.new)

Logger can be also set by globally:

ruby
Gibbon::Request.logger = MyLogger.new

Examples

Lists

Fetch first page of lists:

ruby
gibbon.lists.retrieve

Retrieving a specific list looks like:

ruby
gibbon.lists(list_id).retrieve

Retrieving a specific list's members looks like:

ruby
gibbon.lists(list_id).members.retrieve

Subscribers

Get first page of subscribers for a list:

ruby
gibbon.lists(list_id).members.retrieve

By default the Mailchimp API returns 10 results. To set the count to 50:

ruby
gibbon.lists(list_id).members.retrieve(params: {"count": "50"})

And to retrieve the next 50 members:

ruby
gibbon.lists(list_id).members.retrieve(params: {"count": "50", "offset": "50"})

And to retrieve only subscribed members

ruby
gibbon.lists(list_id).members.retrieve(params: {"count": "50", "offset": "50", "status": "subscribed"})

Subscribe a member to a list:

ruby
gibbon.lists(list_id).members.create(body: {email_address: "[email protected]", status: "subscribed", merge_fields: {FNAME: "First Name", LNAME: "Last Name"}})

If you want to upsert instead, you would do the following:

ruby
gibbon.lists(list_id).members(lower_case_md5_hashed_email_address).upsert(body: {email_address: "[email protected]", status: "subscribed", merge_fields: {FNAME: "First Name", LNAME: "Last Name"}})

You can also unsubscribe a member from a list:

ruby
gibbon.lists(list_id).members(lower_case_md5_hashed_email_address).update(body: { status: "unsubscribed" })

Get a specific member's information (open/click rates etc.) from MailChimp:

ruby
gibbon.lists(list_id).members(lower_case_md5_hashed_email_address).retrieve

Permanently delete a specific member from a list:

ruby
gibbon.lists(list_id).members(lower_case_md5_hashed_email_address).actions.delete_permanent.create

Tags

Tags are a flexible way to organize (slice and dice) your list: for example, you can send a campaign directly to one or more tags.

Add tags to a subscriber:

ruby
gibbon.lists(list_id).members(Digest::MD5.hexdigest(lower_case_email_address)).tags.create(
  body: {
    tags: [{name:"referred-from-xyz", status:"active"},{name:"pro-plan",status:"active"}]
  }
)

Batch Operations

Any API call that can be made directly can also be organized into batch operations. Performing batch operations requires you to generate a hash for each individual API call and pass them as an Array to the Batch endpoint.

ruby
# Create a new batch job that will create new list members
gibbon.batches.create(body: {
  operations: [
    {
      method: "POST",
      path: "lists/#{ list_id }/members",
      body: "{...}" # The JSON payload for PUT, POST, or PATCH
    },
    ...
  ]
})

This will create a new batch job and return a Batch response. The response will include an id attribute which can be used to check the status of a particular batch job.

Checking on a Batch Job
ruby
gibbon.batches(batch_id).retrieve
Response Body (i.e. response.body)
ruby
{
  "id"=>"0ca62e43cc",
  "status"=>"started",
  "total_operations"=>1,
  "finished_operations"=>1,
  "errored_operations"=>0,
  "submitted_at"=>"2016-04-19T01:16:58+00:00",
  "completed_at"=>"",
  "response_body_url"=>""
}

Note This response truncated for brevity. Reference the MailChimp API documentation for Batch Operations for more details.

Fields

Only retrieve ids and names for fetched lists:

ruby
gibbon.lists.retrieve(params: {"fields": "lists.id,lists.name"})

Only retrieve emails for fetched lists:

ruby
gibbon.lists(list_id).members.retrieve(params: {"fields": "members.email_address"})

Campaigns

Get first page of campaigns:

ruby
campaigns = gibbon.campaigns.retrieve

Fetch the number of opens for a campaign

ruby
email_stats = gibbon.reports(campaign_id).retrieve.body["opens"]

Create a new campaign:

ruby
recipients = {
  list_id: list_id,
  segment_opts: {
    saved_segment_id: segment_id
  }
}
settings = {
  subject_line: "Subject Line",
  title: "Name of Campaign",
  from_name: "From Name",
  reply_to: "[email protected]"
}

body = {
  type: "regular",
  recipients: recipients,
  settings: settings
}

begin
  gibbon.campaigns.create(body: body)
rescue Gibbon::MailChimpError => e
  puts "Houston, we have a problem: #{e.message} - #{e.raw_body}"
end

Add content to a campaign:

(Please note that Mailchimp does not currently support dynamic replacement of mc:edit areas in their drag-and-drop templates using their API. Custom templates can be used instead.)

ruby
body = {
  template: {
    id: template_id,
    sections: {
      "name-of-mc-edit-area": "Content here"
    }
  }
}

gibbon.campaigns(campaign_id).content.upsert(body: body)

Send a campaign:

ruby
gibbon.campaigns(campaign_id).actions.send.create

Schedule a campaign:

ruby
body = {
  schedule_time: "2016-06-27 20:00:00"
}
ruby
gibbon.campaigns(campaign_id).actions.schedule.create(body: body)

Interests

Interests are a little more complicated than other parts of the API, so here's an example of how you would set interests at subscription time or u

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

Ruby

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言