3

I'm trying to subscribe users to Mailchimp with Gibbon 2.2.4 with a generic subscribe method I've been using, and then shortly after I want to add in some extra fields to track the results of a quiz they took.

I want to store this data on Mailchimp because I'd like to manage the emails I send off directly from Mailchimp's dashboard.

The service I created to handle my subscriptions:

class MailchimpService

  def subscribe(list_id,email,first_name)
    GIBBON.lists(list_id).members.create({
      body: {
        email_address: email,
        status: 'subscribed',
        merge_fields: {
          FNAME: first_name,
        },
        double_optin: false,
        update_existing: true
      }
    })
  end

  def subscribe_to_quiz(first_name, email, user_id, quiz_id)
    list_id = ENV['QUIZ_MAILCHIMP_LIST_ID']
    if subscribe(list_id,email,first_name)
      attempt = QuizAttempt.where("user_id = ? AND quiz_id = ?", user_id, quiz_id).last
      correct = attempt.correct_answer_count
      total = attempt.questions_answered
      successful = attempt.successful?
      send_quiz_results(list_id, email, correct, total, successful)
    end
  end

  def send_quiz_results(list_id, email, correct, total, successful)
    GIBBON.lists(list_id).members(email).upsert(
      body: {
        email_address: email,
        status: 'subscribed',
        merge_fields: {
          correct_answers: correct,
          total_answers: total,
          successful: successful
        },
        update_existing: true
    })
  end
end

In subscribe_to_quiz, I'm subscribing the user to my quiz_list in Mailchimp. The values of the fields I'm updating here are irrelevant, but I think they're quite explanatory. When I try to run my upsert statement in send_quiz_results, I get the following error:

the server responded with status 400 
@title="Member Exists", 
@detail="foo@bar.baz is already a list member. Use PUT to insert or update list members.", 
@body={"type"=>"http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary/", "title"=>"Member Exists", "status"=>400, "detail"=>"foo@bar.baz is already a list member. Use PUT to insert or update list members.", "instance"=>""}, 
@raw_body="{\"type\":\"http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary/\",\"title\":\"Member Exists\",\"status\":400,\"detail\":\"foo@bar.baz is already a list member. Use PUT to insert or update list members.\",\"instance\":\"\"}", 
@status_code=400

I have no clue why it won't let me do this... It seems like it's referencing a create statement, but the extracted source for the error references my upsert statement.

I know I'm using the corresponding PUT verb for Gibbon, since the following is taken straight from the documentation:

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

I have no clue why this isn't working... I've tried taking out the other fields and just simply throwing in the ones I'm updating. I've also tried running it straight from the terminal to make sure nothing's overlapping.

Doug
  • 1,517
  • 3
  • 18
  • 40
  • Can you tell me how you know this? `but the extracted source for the error references my upsert statement.` what do you mean by "the extracted source for the error" ? – Taryn East Sep 09 '16 at 04:10
  • 1
    Because that's the line that the error shows. I guess I should have been more clear and just said the upsert call is at the top of the trace. – Doug Sep 09 '16 at 17:10
  • I've also explicitly called upsert directly from the terminal to confirm it wasn't trying to do a member *creation*. Although it still seems to be doing a POST or something... – Doug Sep 09 '16 at 17:12
  • @Doug i have the exact same issue, was you able to find the source of the problem? – Mikhail Nikalyukin Sep 29 '16 at 11:10
  • 1
    No solutions yet. I just decided to not use MailChimp. – Doug Sep 30 '16 at 17:31

1 Answers1

6

The MailChimp API docs show that when updating a member you must provide the member's subscriber_hash, which the MD5 hash of the lowercase version of the members email address.

Use Digest::MD5.hexdigest to hash the email address with MD5:

GIBBON.lists(list_id).members(Digest::MD5.hexdigest(email.downcase)).upsert
infused
  • 24,000
  • 13
  • 68
  • 78