{"id":13463420,"url":"https://github.com/amro/gibbon","last_synced_at":"2025-05-14T08:08:15.290Z","repository":{"id":1178064,"uuid":"1075959","full_name":"amro/gibbon","owner":"amro","description":"Gibbon is an API wrapper for MailChimp's API","archived":false,"fork":false,"pushed_at":"2023-06-07T13:41:21.000Z","size":393,"stargazers_count":1066,"open_issues_count":4,"forks_count":165,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-04-11T02:51:58.310Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://github.com/amro/gibbon","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/amro.png","metadata":{"files":{"readme":"README.markdown","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null},"funding":{"github":["amro"]}},"created_at":"2010-11-12T22:13:10.000Z","updated_at":"2025-01-21T16:36:05.000Z","dependencies_parsed_at":"2023-07-06T07:29:14.598Z","dependency_job_id":null,"html_url":"https://github.com/amro/gibbon","commit_stats":{"total_commits":437,"total_committers":84,"mean_commits":"5.2023809523809526","dds":0.3890160183066361,"last_synced_commit":"36c3bdca7352b246cb1b82e6053a6a724487212a"},"previous_names":[],"tags_count":68,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amro%2Fgibbon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amro%2Fgibbon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amro%2Fgibbon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amro%2Fgibbon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/amro","download_url":"https://codeload.github.com/amro/gibbon/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254101558,"owners_count":22014908,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T13:00:53.163Z","updated_at":"2025-05-14T08:08:10.280Z","avatar_url":"https://github.com/amro.png","language":"Ruby","funding_links":["https://github.com/sponsors/amro"],"categories":["Web Apps, Services \u0026 Interaction","Ruby","Email"],"sub_categories":["API Clients"],"readme":"# gibbon\n\nGibbon is an API wrapper for MailChimp's [API](http://kb.mailchimp.com/api/).\n\n[![Build Status](https://travis-ci.com/amro/gibbon.svg?branch=master)](https://app.travis-ci.com/github/amro/gibbon)\n\n## Important Notes\n\nPlease read MailChimp's [Getting Started Guide](http://kb.mailchimp.com/api/article/api-3-overview).\n\nGibbon 3.0.0+ returns a `Gibbon::Response` instead of the response body directly. `Gibbon::Response` exposes the parsed response `body` and `headers`.\n\n## Installation\n\n    $ gem install gibbon\n\n## Requirements\n\nA MailChimp account and API key. You can see your API keys [here](http://admin.mailchimp.com/account/api).\n\n## Usage\n\nFirst, create a *one-time use instance* of `Gibbon::Request`:\n\n```ruby\ngibbon = Gibbon::Request.new(api_key: \"your_api_key\")\n```\n\n***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.\n\nYou can set an individual request's `timeout` and `open_timeout` like this:\n\n```ruby\ngibbon.timeout = 30\ngibbon.open_timeout = 30\n```\n\nYou can read about `timeout` and `open_timeout` in the [Net::HTTP](https://ruby-doc.org/stdlib-2.3.3/libdoc/net/http/rdoc/Net/HTTP.html) doc.\n\nNow you can make requests using the resources defined in [MailChimp's docs](http://kb.mailchimp.com/api/resources). Resource IDs\nare 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.\n\n***Note*** `upsert` requires Gibbon version 2.1.0 or newer!\n\nYou can specify `headers`, `params`, and `body` when calling a `CRUD` method. For example:\n\n```ruby\ngibbon.lists.retrieve(headers: {\"SomeHeader\": \"SomeHeaderValue\"}, params: {\"query_param\": \"query_param_value\"})\n```\n\n***Note*** `get` can be substituted for `retrieve` as of Gibbon version 3.4.1 or newer!\n\nOf course, `body` is only supported on `create`, `update`, and `upsert` calls. Those map to HTTP `POST`, `PATCH`, and `PUT` verbs respectively.\n\nYou can set `api_key`, `timeout`, `open_timeout`, `faraday_adapter`, `proxy`, `symbolize_keys`, `logger`, and `debug` globally:\n\n```ruby\nGibbon::Request.api_key = \"your_api_key\"\nGibbon::Request.timeout = 15\nGibbon::Request.open_timeout = 15\nGibbon::Request.symbolize_keys = true\nGibbon::Request.debug = false\n```\n\nFor example, you could set the values above in an `initializer` file in your `Rails` app (e.g. your\\_app/config/initializers/gibbon.rb).\n\nAssuming you've set an `api_key` on Gibbon, you can conveniently make API calls on the class itself:\n\n```ruby\nGibbon::Request.lists.retrieve\n```\n\nYou can also set the environment variable `MAILCHIMP_API_KEY` and Gibbon will use it when you create an instance:\n\n```ruby\ngibbon = Gibbon::Request.new\n```\n\n***Note*** Substitute an underscore if a resource name contains a hyphen.\n\nPass `symbolize_keys: true` to use symbols (instead of strings) as hash keys in API responses.\n\n```ruby\ngibbon = Gibbon::Request.new(api_key: \"your_api_key\", symbolize_keys: true)\n```\n\nMailChimp's [resource documentation](http://kb.mailchimp.com/api/resources) is a list of available resources.\n\n## Debug Logging\n\nPass `debug: true` to enable debug logging to STDOUT.\n\n```ruby\ngibbon = Gibbon::Request.new(api_key: \"your_api_key\", debug: true)\n```\n\n### Custom logger\n\nRuby `Logger.new` is used by default, but it can be overrided using:\n\n```ruby\ngibbon = Gibbon::Request.new(api_key: \"your_api_key\", debug: true, logger: MyLogger.new)\n```\n\nLogger can be also set by globally:\n\n```ruby\nGibbon::Request.logger = MyLogger.new\n```\n\n## Examples\n\n### Lists\n\nFetch first page of lists:\n\n```ruby\ngibbon.lists.retrieve\n```\n\nRetrieving a specific list looks like:\n\n```ruby\ngibbon.lists(list_id).retrieve\n```\n\nRetrieving a specific list's members looks like:\n\n```ruby\ngibbon.lists(list_id).members.retrieve\n```\n\n### Subscribers\n\nGet first page of subscribers for a list:\n\n```ruby\ngibbon.lists(list_id).members.retrieve\n```\n\nBy default the Mailchimp API returns 10 results. To set the count to 50:\n\n```ruby\ngibbon.lists(list_id).members.retrieve(params: {\"count\": \"50\"})\n```\n\nAnd to retrieve the next 50 members:\n\n```ruby\ngibbon.lists(list_id).members.retrieve(params: {\"count\": \"50\", \"offset\": \"50\"})\n```\n\nAnd to retrieve only subscribed members\n\n```ruby\ngibbon.lists(list_id).members.retrieve(params: {\"count\": \"50\", \"offset\": \"50\", \"status\": \"subscribed\"})\n```\n\nSubscribe a member to a list:\n\n```ruby\ngibbon.lists(list_id).members.create(body: {email_address: \"foo@bar.com\", status: \"subscribed\", merge_fields: {FNAME: \"First Name\", LNAME: \"Last Name\"}})\n```\n\nIf you want to `upsert` instead, you would do the following:\n\n```ruby\ngibbon.lists(list_id).members(lower_case_md5_hashed_email_address).upsert(body: {email_address: \"foo@bar.com\", status: \"subscribed\", merge_fields: {FNAME: \"First Name\", LNAME: \"Last Name\"}})\n```\n\nYou can also unsubscribe a member from a list:\n\n```ruby\ngibbon.lists(list_id).members(lower_case_md5_hashed_email_address).update(body: { status: \"unsubscribed\" })\n```\n\nGet a specific member's information (open/click rates etc.) from MailChimp:\n\n```ruby\ngibbon.lists(list_id).members(lower_case_md5_hashed_email_address).retrieve\n```\n\nPermanently delete a specific member from a list:\n\n```ruby\ngibbon.lists(list_id).members(lower_case_md5_hashed_email_address).actions.delete_permanent.create\n```\n\n### Tags\n\n[Tags](https://mailchimp.com/help/getting-started-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.\n\nAdd tags to a subscriber:\n\n```ruby\ngibbon.lists(list_id).members(Digest::MD5.hexdigest(lower_case_email_address)).tags.create(\n  body: {\n    tags: [{name:\"referred-from-xyz\", status:\"active\"},{name:\"pro-plan\",status:\"active\"}]\n  }\n)\n```\n\n\n### Batch Operations\n\nAny 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.\n\n```ruby\n# Create a new batch job that will create new list members\ngibbon.batches.create(body: {\n  operations: [\n    {\n      method: \"POST\",\n      path: \"lists/#{ list_id }/members\",\n      body: \"{...}\" # The JSON payload for PUT, POST, or PATCH\n    },\n    ...\n  ]\n})\n```\n\nThis 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.\n\n##### Checking on a Batch Job\n```ruby\ngibbon.batches(batch_id).retrieve\n```\n\n###### Response Body (i.e. `response.body`)\n```ruby\n{\n  \"id\"=\u003e\"0ca62e43cc\",\n  \"status\"=\u003e\"started\",\n  \"total_operations\"=\u003e1,\n  \"finished_operations\"=\u003e1,\n  \"errored_operations\"=\u003e0,\n  \"submitted_at\"=\u003e\"2016-04-19T01:16:58+00:00\",\n  \"completed_at\"=\u003e\"\",\n  \"response_body_url\"=\u003e\"\"\n}\n```\n\n***Note*** This response truncated for brevity. Reference the MailChimp\n[API documentation for Batch Operations](http://developer.mailchimp.com/documentation/mailchimp/reference/batches/) for more details.\n\n### Fields\n\nOnly retrieve ids and names for fetched lists:\n\n```ruby\ngibbon.lists.retrieve(params: {\"fields\": \"lists.id,lists.name\"})\n```\n\nOnly retrieve emails for fetched lists:\n\n```ruby\ngibbon.lists(list_id).members.retrieve(params: {\"fields\": \"members.email_address\"})\n```\n\n### Campaigns\n\nGet first page of campaigns:\n\n```ruby\ncampaigns = gibbon.campaigns.retrieve\n```\n\nFetch the number of opens for a campaign\n\n```ruby\nemail_stats = gibbon.reports(campaign_id).retrieve[\"opens\"]\n```\n\nCreate a new campaign:\n\n```ruby\nrecipients = {\n  list_id: list_id,\n  segment_opts: {\n    saved_segment_id: segment_id\n  }\n}\nsettings = {\n  subject_line: \"Subject Line\",\n  title: \"Name of Campaign\",\n  from_name: \"From Name\",\n  reply_to: \"my@email.com\"\n}\n\nbody = {\n  type: \"regular\",\n  recipients: recipients,\n  settings: settings\n}\n\nbegin\n  gibbon.campaigns.create(body: body)\nrescue Gibbon::MailChimpError =\u003e e\n  puts \"Houston, we have a problem: #{e.message} - #{e.raw_body}\"\nend\n```\n\nAdd content to a campaign:\n\n*(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](http://stackoverflow.com/questions/29366766/mailchimp-api-not-replacing-mcedit-content-sections-using-ruby-library) instead.)*\n\n```ruby\nbody = {\n  template: {\n    id: template_id,\n    sections: {\n      \"name-of-mc-edit-area\": \"Content here\"\n    }\n  }\n}\n\ngibbon.campaigns(campaign_id).content.upsert(body: body)\n```\n\nSend a campaign:\n\n```ruby\ngibbon.campaigns(campaign_id).actions.send.create\n```\n\nSchedule a campaign:\n\n```ruby\nbody = {\n  schedule_time: \"2016-06-27 20:00:00\"\n}\n```\n\n```ruby\ngibbon.campaigns(campaign_id).actions.schedule.create(body: body)\n```\n\n### Interests\n\nInterests are a little more complicated than other parts of the API, so here's an example of how you would set interests during at subscription time or update them later. The ID of the interests you want to opt in or out of must be known ahead of time so an example of how to find interest IDs is also included.\n\nSubscribing a member to a list with specific interests up front:\n\n```ruby\ngibbon.lists(list_id).members.create(body: {email_address: user_email_address, status: \"subscribed\", interests: {some_interest_id: true, another_interest_id: true}})\n```\n\nUpdating a list member's interests:\n\n```ruby\ngibbon.lists(list_id).members(member_id).update(body: {interests: {some_interest_id: true, another_interest_id: false}})\n```\n\nSo how do we get the interest IDs? When you query the API for a specific list member's information:\n\n```ruby\ngibbon.lists(list_id).members(member_id).retrieve\n```\n\nThe response body (i.e. `response.body`) looks someting like this (unrelated things removed):\n\n```ruby\n{\"id\"=\u003e\"...\", \"email_address\"=\u003e\"...\", ..., \"interests\"=\u003e{\"3def637141\"=\u003etrue, \"f7cc4ee841\"=\u003efalse, \"fcdc951b9f\"=\u003efalse, \"3daf3cf27d\"=\u003etrue, \"293a3703ed\"=\u003efalse, \"72370e0d1f\"=\u003efalse, \"d434d21a1c\"=\u003efalse, \"bdb1ff199f\"=\u003efalse, \"a54e78f203\"=\u003efalse, \"c4527fd018\"=\u003efalse} ...}\n```\n\nThe API returns a map of interest ID to boolean value. Now we to get interest details so we know what these interest IDs map to. Looking at [this doc page](http://kb.mailchimp.com/api/resources/lists/interest-categories/interests/lists-interests-collection), we need to do this:\n\n```ruby\ngibbon.lists(list_id).interest_categories.retrieve\n```\n\nTo get a list of interest categories. That gives us something like (again, this is the `response.body`):\n\n```ruby\n{\"list_id\"=\u003e\"...\", \"categories\"=\u003e[{\"list_id\"=\u003e\"...\", \"id\"=\u003e\"0ace7aa498\", \"title\"=\u003e\"Food Preferences\", ...}] ...}\n```\n\nIn this case, we're interested in the ID of the \"Food Preferences\" interest, which is `0ace7aa498`. Now we can fetch the details for this interest group:\n\n```ruby\ngibbon.lists(list_id).interest_categories(\"0ace7aa498\").interests.retrieve\n```\n\nThat response gives the interest data, including the ID for the interests themselves, which we can use to update a list member's interests or set them when we call the API to subscribe her or him to a list.\n\n### Error handling\n\nGibbon raises an error when the API returns an error.\n\n`Gibbon::MailChimpError` has the following attributes: `title`, `detail`, `body`, `raw_body`, `status_code`. Some or all of these may not be\navailable depending on the nature of the error. For example:\n\n```ruby\nbegin\n  gibbon.lists(list_id).members.create(body: body)\nrescue Gibbon::MailChimpError =\u003e e\n  puts \"Houston, we have a problem: #{e.message} - #{e.raw_body}\"\nend\n```\n\n### Other\n\nOverriding Gibbon's API endpoint (i.e. if using an access token from OAuth and have the `api_endpoint` from the [metadata](http://apidocs.mailchimp.com/oauth2/)):\n\n```ruby\nGibbon::Request.api_endpoint = \"https://us1.api.mailchimp.com\"\nGibbon::Request.api_key = your_access_token_or_api_key\n```\n\nYou can set an optional proxy url like this (or with an environment variable MAILCHIMP_PROXY):\n\n```ruby\ngibbon.proxy = 'http://your_proxy.com:80'\n```\n\nYou can set a different [Faraday adapter](https://github.com/lostisland/faraday) during initialization:\n\n```ruby\ngibbon = Gibbon::Request.new(api_key: \"your_api_key\", faraday_adapter: :net_http)\n```\n\n### Migrating from Gibbon 1.x\n\nGibbon 2.x+ exposes a different API from version 1.x. This is because Gibbon maps to MailChimp's API and because version 3 of the API is quite different from version 2. First, the name of the primary class has changed from `API` to `Request`. And the way you pass an API key during initialization is different. A few examples below.\n\n#### Initialization\n\nGibbon 1.x:\n\n```ruby\ngibbon = Gibbon::API.new(\"your_api_key\")\n```\n\nGibbon 2.x+:\n\n```ruby\ngibbon = Gibbon::Request.new(api_key: \"your_api_key\")\n```\n\nMailChimp API 3 is a RESTful API, so Gibbon's syntax now requires a trailing call to a verb, as described above.\n\n#### Fetching Lists\n\nGibbon 1.x:\n\n```ruby\ngibbon.lists.list\n```\n\nGibbon 2.x+:\n\n```ruby\ngibbon.lists.retrieve\n```\n\n#### Fetching List Members\n\nGibbon 1.x:\n\n```ruby\ngibbon.lists.members({:id =\u003e list_id})\n```\n\nGibbon 2.x+:\n\n```ruby\ngibbon.lists(list_id).members.retrieve\n```\n\n#### Subscribing a Member to a List\n\nGibbon 1.x:\n\n```ruby\ngibbon.lists.subscribe({:id =\u003e list_id, :email =\u003e {:email =\u003e \"foo@bar.com\"}, :merge_vars =\u003e {:FNAME =\u003e \"Bob\", :LNAME =\u003e \"Smith\"}})\n```\n\nGibbon 2.x+:\n\n```ruby\ngibbon.lists(list_id).members.create(body: {email_address: \"foo@bar.com\", status: \"subscribed\", merge_fields: {FNAME: \"Bob\", LNAME: \"Smith\"}})\n```\n\n## Thanks\n\nThanks to everyone who has [contributed](https://github.com/amro/gibbon/contributors) to Gibbon's development.\n\n## Copyright\n\n* Copyright (c) 2010-2022 Amro Mousa. See LICENSE.txt for details.\n* MailChimp (c) 2001-2022 The Rocket Science Group.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famro%2Fgibbon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Famro%2Fgibbon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famro%2Fgibbon/lists"}