danesparza / MailChimp.NET

:envelope: .NET Wrapper for the MailChimp v2.0 API
MIT License
179 stars 119 forks source link

MailChimp API v3.0 integration #183

Closed rakib32 closed 8 years ago

rakib32 commented 8 years ago

Hi,

Any a plan to migrate it to v3.0 api?

fireole commented 8 years ago

I would be interested in knowing this as well. I think you have a great api and love it. Thanks.

mdissel commented 8 years ago

Pull requests are welcome! At the end of 2016 the old API can't be used anymore..

balexandre commented 8 years ago

I think we should branch it from master and start doing some tests on the new api from MC... I'll give it a try and will post some results on how to move forward.

danesparza commented 8 years ago

Thanks @balexandre! I'd really like to move away from ServiceStack (if possible) as well. It has given us quite a few headaches.

balexandre commented 8 years ago

@danesparza I love SS, I use it every day in several fronts (REST, Message Queue, etc) let me know if I can help. The ServiceStack.Text is the fastest around to decode json into objects... version 3.x is still free and you can apply for a version 4.x license for free.

But I can easily use only RestSharp/Json.NET for the job, though I would think it's a bad revert :(

olivercross commented 8 years ago

@danesparza @balexandre I would be really interested in helping to migrate to v3. I will be doing an MC integration projection this year and would love to have a stable v3 wrapper to use

balexandre commented 8 years ago

@danesparza I'm starting to look on how to accomplish this, and I think we would be better to start from scratch though, maintaining the same flow idea as current (then again, I use NUnit for my unit tests and never VS testing)... but will find something common :)

MC API 3.0 has a nice json schema that we can easily create and update our POCO library, without the need to write anything for this, maybe we could use this feature.

I've forked and updated a Gist (https://gist.github.com/balexandre/e8cd6a965cdc532cb6ae) and you can see it runs fine even on LinqPad ...

using the ApiRoot schema I end up with this:

public class MailChimp_Account_Contact {

/// <summary>
/// Company
/// The company name assocated with the account.
/// </summary>
/// <readonly>True</readonly>
/// <example>MailChimp</example>
public string company { get; set; }

/// <summary>
/// Address Line 1
/// The street address for the account contact.
/// </summary>
/// <readonly>True</readonly>
/// <example>675 Ponce de Leon Ave NE</example>
public string addr1 { get; set; }

/// <summary>
/// Address Line 2
/// The street address for the account contact.
/// </summary>
/// <readonly>True</readonly>
/// <example>Suite 5000</example>
public string addr2 { get; set; }

/// <summary>
/// City
/// The city for the account contact.
/// </summary>
/// <readonly>True</readonly>
/// <example>30308</example>
public string city { get; set; }

/// <summary>
/// State
/// The state (if available) for the account contact.
/// </summary>
/// <readonly>True</readonly>
/// <example>GA</example>
public string state { get; set; }

/// <summary>
/// Zip Code
/// The zip code (if available) for the account contact.
/// </summary>
/// <readonly>True</readonly>
/// <example>30308</example>
public string zip { get; set; }

/// <summary>
/// Country
/// The country for the account contact.
/// </summary>
/// <readonly>True</readonly>
/// <example>US</example>
public string country { get; set; }
}
public class MailChimp_API_Root {

/// <summary>
/// User ID
/// The id associated with this account. Used for things like subscribe forms.
/// </summary>
/// <readonly>True</readonly>
/// <example>8d3a3db4d97663a9074xxxx16</example>
public string account_id { get; set; }

/// <summary>
/// Login Name
/// The name of the login for this account.
/// </summary>
/// <readonly>True</readonly>
/// <example>freddiesjokes</example>
public string account_name { get; set; }

/// <summary>
/// Email
/// The email address tied to the account
/// </summary>
/// <readonly>true</readonly>
/// <example>freddie@mailchimp.com</example>
public string email { get; set; }

/// <summary>
/// Role
/// the role assigned to the account
/// </summary>
/// <readonly>true</readonly>
/// <example>owner</example>
public string role { get; set; }

/// <summary>
/// Account Contact
/// </summary>
public MailChimp_Account_Contact contact { get; set; }

/// <summary>
/// </summary>
/// <readonly>True</readonly>
/// <example>True</example>
public bool pro_enabled { get; set; }

/// <summary>
/// Last Login Date
/// The date and time of the last login for this account.
/// </summary>
/// <readonly>True</readonly>
/// <example>2015-07-10 15:05:24</example>
public string last_login { get; set; }

/// <summary>
/// Total Subscribers
/// The total number of subscribers across all lists in the account.
/// </summary>
/// <readonly>True</readonly>
/// <example>42</example>
public int total_subscribers { get; set; }
}

requires only a small update on some types, like DateTime instead of string, we can also tweak the generator to even append the json.net attributes for better handling as well... what's your input?

balexandre commented 8 years ago

further more...

this is what I'm doing to move into MC API 3.0

in the MailChimpManager I use the amazing and free to use RestSharp, like:

private RestClient _restClient;

//  Default constructor
public MailChimpManager()
{
    ...
    _restClient = new RestClient(string.Format(_httpsUrl, GetDatacenterPrefix(this.APIKey)));
}

then, and for example only, the GetCampaignContent call would be like:

public CampaignListResult GetCampaigns(
    CampaignFilter filterParam = null, int start = 0, int limit = 25, 
    string sort_field = "create_time", string sort_dir = "DESC")
{
    //  Our api action:
    var apiAction = $"campaigns/{cId}";
    var apiMethod = Method.GET;

    //  Create our arguments object:
    var args = new List<Parameter>()
    {
        Param("filters", filterParam),
        Param("start", start),
        Param("limit", limit),
        Param("sort_field", sort_field),
        Param("sort_dir", sort_dir)
    };

    //  Make the call:
    return MakeAPICall<CampaignListResult>(apiAction, apiMethod, args).Result;
}

and we can always add a signature that actually returns the task as

public async Task<CampaignListResult> GetCampaignsAsync(
    CampaignFilter filterParam = null, int start = 0, int limit = 25, 
    string sort_field = "create_time", string sort_dir = "DESC")
{
   ...
    return await MakeAPICallAsync<CampaignListResult>(apiAction, apiMethod, args);
}

and the new generic api call as:

private Task<T> MakeAPICallAsync<T>(string apiAction, Method method, List<Parameter> args) 
    where T : new()
{
    // inistializes request
    var request = new RestRequest(apiAction, method)
    {
        JsonSerializer = new Utilities.JsonSerializer()
    };

    // headers
    request.AddHeader("cache-control", "no-cache");
    request.AddHeader("content-type", "application/json");

    // add common API KEY
    request.AddParameter("apikey", APIKey);

    // add arguments
    foreach (var p in args)
        request.AddParameter(p);

    // async task holder
    var taskCompletionSource = new TaskCompletionSource<T>();

    // executes request
    _restClient.ExecuteAsync<T>(request, (response) =>
    {
        if (response.StatusCode == HttpStatusCode.OK)
        {
            var r = JsonConvert.DeserializeObject<T>(response.Content);
            taskCompletionSource.SetResult(r);
        }
    });
    return taskCompletionSource.Task;
}

This way, we can maintain the same call names, and move to async calls in just one go...

any other thoughts?

danesparza commented 8 years ago

To be honest, I'm not sure I'm interested in maintaining the codebase for the Mailchimp 3.x API at this point. If I were, I'd like it to use as much native .NET functionality as possible, including any built-in serialization.

Trying to troubleshoot ServiceStack.Text versioning issues has been a real pain -- I'm not sure that RestSharp would be a panacea. @balexandre: I encourage you to begin your own effort. I may be completely off-base and you might be right. Why not start your own repo? :smile:

To anybody else interested in supporting the 3.x API, I suggest you start on the Mailchimp site, here.