使用MailChimp WebHooks功能

时间:2013-02-22 09:29:15

标签: asp.net mailchimp webhooks

有人可以提供在ASP.NET中执行此操作的示例。我们想做一些MailCHimp - 内部数据库同步并计划使用webhooks功能执行此操作,但我们无法让它工作。当有人取消订阅邮件黑猩猩时,我们希望使用网络钩子来同步数据。

要解决的另一件事是安全性。我们如何保护此页面不被恶意用户访问?

4 个答案:

答案 0 :(得分:6)

这是一段适合我们的代码。这很简单,但它确实需要我们进行一些实验才能让它发挥作用。

        if (Request.Form["type"] != null && Request.Form["type"] == "unsubscribe")
        {

            string email = Request.Form["data[merges][EMAIL]"];
           //now you can do insert/update data in your local database
     }

查看API文档以获取更多详细信息http://apidocs.mailchimp.com/webhooks/

关于安全性,你可以做很多事情,但这取决于你想要的深度。我建议的一件事是检查您的IIS日志,找到邮件黑猩猩使用哪个IP地址/用户代理来触发Web挂钩,然后阻止此页面除此之外的所有其他IP地址。你可以采取其他措施来额外保护这一点,例如使用不容易猜到的页面名称(f3jijselife.aspx远远优于webhooks.aspx)

答案 1 :(得分:4)

我最近基于他们在这里提供的PHP代码实现了这个骨架...我拿出了实际的实现,但希望有用

public class MailChimpWebHook : IHttpHandler
{
    private static readonly ILog Logger = LogManager.GetLogger(typeof(MailChimpWebHook));

    private const string Key = "xxxx";
    private const string ParamKey = "key";
    private const string ParamType = "type";
    private const string ParamListId = "data[list_id]";
    private const string ParamListIdNew = "data[new_id]";
    private const string ParamEmail = "data[email]";
    private const string ParamOldEmail = "data[new_email]";
    private const string ParamNewEmail = "data[old_email]";
    private const string ParamProfileEmail = "data[merges][EMAIL]";
    private const string ParamProfileFirstName = "data[merges][FNAME]";
    private const string ParamProfileLastName = "data[merges][LNAME]";
    private const string ParamProfileGroups = "data[merges][INTERESTS]";

    private const string TypeSubscribe = "subscribe";
    private const string TypeUnsubscribe = "unsubscribe";
    private const string TypeCleaned = "cleaned";
    private const string TypeUpdateEmail = "upemail";
    private const string TypeProfileUpdate = "profile";

    public void ProcessRequest(HttpContext context)
    {
        Logger.Info("==================[ Incoming Request ]==================");

        if (string.IsNullOrEmpty(context.Request[ParamKey]))
        {
            Logger.Warn("No security key specified, ignoring request"); 
        }
        else if (context.Request[ParamKey] != Key)
        {
            Logger.WarnFormat("Security key specified, but not correct. Wanted: '{0}' | , but received '{1}'", Key, context.Request[ParamKey]);
        }
        else
        {
             //process the request
            Logger.InfoFormat("Processing a '{0}' request...", context.Request[ParamType]);

            try
            {
                switch (context.Request[ParamType])
                {
                    case TypeSubscribe:
                        Subscribe(context.Request);
                        break;
                    case TypeUnsubscribe:
                        Unsubscribe(context.Request);
                        break;
                    case TypeCleaned:
                        Cleaned(context.Request);
                        break;
                    case TypeUpdateEmail:
                        UpdateEmail(context.Request);
                        break;
                    case TypeProfileUpdate:
                        UpdateProfile(context.Request);
                        break;
                    default:
                        Logger.WarnFormat("Request type '{0}' unknown, ignoring.", context.Request[ParamType]);
                        break;
                }
            }
            catch (Exception e)
            {
                Logger.Error("There was an error processing the callback", e);
            }
        }

        Logger.Info("Finished processing request.");
    }

    private void UpdateProfile(HttpRequest httpRequest)
    {
        Logger.Info("Processing update profile request!");

        #region [ sample data structure ]
        //  "type": "profile", 
        //  "fired_at": "2009-03-26 21:31:21", 
        //  "data[id]": "8a25ff1d98", 
        //  "data[list_id]": "a6b5da1054",
        //  "data[email]": "api@mailchimp.com", 
        //  "data[email_type]": "html", 
        //  "data[merges][EMAIL]": "api@mailchimp.com", 
        //  "data[merges][FNAME]": "MailChimp", 
        //  "data[merges][LNAME]": "API", 
        //  "data[merges][INTERESTS]": "Group1,Group2", 
        //  "data[ip_opt]": "10.20.10.30"
        #endregion
    }

    private void UpdateEmail(HttpRequest httpRequest)
    {
        Logger.Info("Processing update email request!");

        #region [ sample data structure ]
        //  "type": "upemail", 
        //  "fired_at": "2009-03-26\ 22:15:09", 
        //  "data[list_id]": "a6b5da1054",
        //  "data[new_id]": "51da8c3259", 
        //  "data[new_email]": "api+new@mailchimp.com", 
        //  "data[old_email]": "api+old@mailchimp.com"
        #endregion

    }

    private void Cleaned(HttpRequest httpRequest)
    {
        Logger.Info("Processing cleaned email request!");

        #region [ sample data structure ]
        //  "type": "cleaned", 
        //  "fired_at": "2009-03-26 22:01:00", 
        //  "data[list_id]": "a6b5da1054",
        //  "data[campaign_id]": "4fjk2ma9xd",
        //  "data[reason]": "hard",
        //  "data[email]": "api+cleaned@mailchimp.com"
        #endregion
    }

    private void Unsubscribe(HttpRequest httpRequest)
    {
        Logger.Info("Processing unsubscribe...");

        #region [ sample data structure ]
        //  "type": "unsubscribe", 
        //  "fired_at": "2009-03-26 21:40:57",  
        //  "data[action]": "unsub",
        //  "data[reason]": "manual", 
        //  "data[id]": "8a25ff1d98", 
        //  "data[list_id]": "a6b5da1054",
        //  "data[email]": "api+unsub@mailchimp.com", 
        //  "data[email_type]": "html", 
        //  "data[merges][EMAIL]": "api+unsub@mailchimp.com", 
        //  "data[merges][FNAME]": "MailChimp", 
        //  "data[merges][LNAME]": "API", 
        //  "data[merges][INTERESTS]": "Group1,Group2", 
        //  "data[ip_opt]": "10.20.10.30",
        //  "data[campaign_id]": "cb398d21d2",
        //  "data[reason]": "hard"
        #endregion

    }

    private void Subscribe(HttpRequest httpRequest)
    {
        Logger.Info("Processing subscribe...");

        #region [ sample data structure ]
        //  "type": "subscribe", 
        //  "fired_at": "2009-03-26 21:35:57", 
        //  "data[id]": "8a25ff1d98", 
        //  "data[list_id]": "a6b5da1054",
        //  "data[email]": "api@mailchimp.com", 
        //  "data[email_type]": "html", 
        //  "data[merges][EMAIL]": "api@mailchimp.com", 
        //  "data[merges][FNAME]": "MailChimp", 
        //  "data[merges][LNAME]": "API", 
        //  "data[merges][INTERESTS]": "Group1,Group2", 
        //  "data[ip_opt]": "10.20.10.30", 
        //  "data[ip_signup]": "10.20.10.30"
        #endregion

    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

答案 2 :(得分:3)

我正在使用C#WebAPI,我的解决方案是使用POST MailChimp的主体发送的FormDataCollection对象和webhook。

    using System.Net.Http.Formatting;

    [HttpPost]
    [Route("mailchimp/subscriber")]
    public IHttpActionResult Post([FromBody] FormDataCollection data)
    {
        if (data != null)
        {
            string type = data.Get("type");

            if (!string.IsNullOrWhiteSpace(type))
            {
                string listId = data.Get("data[list_id]");
                string id = data.Get("data[id]");
                string firstName = data.Get("data[merges][FNAME]");
                string lastName = data.Get("data[merges][LNAME]");
                string email = data.Get("data[email]");

                if (!string.IsNullOrWhiteSpace(email))
                {
                    // Do something with the subscriber
                }
            }
        }
    }

答案 3 :(得分:1)

我完全支持詹姆斯的答案。

然而,当我自己尝试实现webhook时,我发现你还需要实现一个GET方法,以便甚至能够在MailChimp中创建webhook。

这对我有用:

[HttpGet]
[HttpOptions]
public HttpResponseMessage Get()
{
    return Request.CreateResponse(HttpStatusCode.OK);
}

MailChimp文档: https://developer.mailchimp.com/documentation/mailchimp/guides/about-webhooks/