Newsletter emails

Topics: ASP.NET 2.0, Controls
Jan 5, 2009 at 5:20 PM
Hey all,
Have my blog working. No matter what I try I can't get it to send emails out whan I add new entries.

I have a user list in the newsletter widget.

I can send email test in the settings part. And comment emails work.

What's wrong? I get no error messages. They just never get sent

kevin

http://www.onbrokenground.com/blog

Coordinator
Jan 5, 2009 at 5:51 PM
I took a quick look at your blog.  I don't see the newsletter entry signup field.  Do you not have the newsletter widget added to your blog, but have a list of email addresses in the newsletter.xml file under App_Data?  From what I can tell, if the newsletter widget isn't added to your blog, then the emails won't be sent out ... even if you have a list of email addresses in the newsletter.xml file.
Jan 5, 2009 at 6:07 PM
I took it down since it wasn't working. just forgot to put it back up.
It's there now.
Coordinator
Jan 5, 2009 at 9:42 PM
The code that sends the test email looks pretty much the same as the code that sends the newsletter emails.  So it seems like if you can send a test email, then the newsletter emails should also go out.  The problem is most likely that either the code that sends the emails isn't running or the emails are failing to be sent when sending them through your mail server.  You might want to double check to see if there are email addresses in that newsletter.xml file.

One thing to note is that the newsletter emails will only be sent when you are saving a new blog post and if it is marked as published.  If you're modifying an old post, emails won't be sent, and if the Published box isn't checked when saving the new blog post, the newsletter emails won't be sent.

If you want to look into this further, I put together a few modifications to the Newsletter widget you can try out.  The modifications add some logging to a new file called newsletter_widget.log in your App_Data folder.  Under widgets\Newsletters, there's a file called widget.ascx.cs.  In that file, you should see the following piece of code:

static widgets_Newsletter_widget()
{
    Post.Saved += new EventHandler<SavedEventArgs>(Post_Saved);
}

The modification I came up with replaces that code above and adds some other code for the logging.  After replacing/adding the modifications below, you can try creating a blog post and see if the new file, newsletter_widget.log, gets created in the App_Data folder and see what's in that file after saving a new blog post.  You might have to wait a little bit (10 seconds or so) after saving the blog post before checking that file since the newsletter emails are sent asynchronously (so you don't have to wait around while emails are being sent out).

// REPLACEMENT
static widgets_Newsletter_widget()
{
    Post.Saved += new EventHandler<SavedEventArgs>(Post_Saved);

    AddToNewsletterWidgetLog("Newsletter Widget Loaded");
    Utils.EmailFailed += new EventHandler<EventArgs>(Email_Failed);
    Utils.EmailSent += new EventHandler<EventArgs>(Email_Sent);
}

// NEW STUFF BELOW
private static void AddToNewsletterWidgetLog(string Log)
{
    string file = Path.Combine(BlogSettings.Instance.StorageLocation, "newsletter_widget.log");
    file = System.Web.Hosting.HostingEnvironment.MapPath(file);
    System.IO.File.AppendAllText(file, DateTime.Now.ToString() + " - " + Log + "\r\n");
}

public static void Email_Sent(object sender, EventArgs e)
{
    string Details = string.Empty;
    if (sender != null)
    {
        Details = ((MailMessage)sender).To.ToString();
    }
    AddToNewsletterWidgetLog("Newsletter Widget Email Sent - " + Details);
}
public static void Email_Failed(object sender, EventArgs e)
{
    string Details = string.Empty;
    if (sender != null)
    {
        Details = ((MailMessage)sender).To.ToString();
    }
    AddToNewsletterWidgetLog("Newsletter Widget Email Failed - " + Details);
}
Jan 6, 2009 at 7:19 PM
Okay I've added the code. I get the log.

It goes through each email.

Message back is Newsletter email failed with the address.

So we know the list is okay and the code is executing.
Any idea why it's failing?

Thanks
Coordinator
Jan 6, 2009 at 7:50 PM
That helps narrows things down.  Unfortunately, the exact error isn't directly accessible.  But, what we can do is copy the email sending code out of the BE core, and put it into the newsletter widget.  Then, we can call the code in the newsletter widget instead.  We should be able to get actual error message this way.  The error message will be put into the same newsletter_widget.log file.

You'll want to continue using the same modified widget.ascx.cs file.  In that file, you should see this line of code:

Utils.SendMailMessageAsync(mail);

Change that line of code to:

// REPLACE line above with this line
SendMailMessageAsync(mail);

Then add the code below into widget.ascx.cs.

// NEW CODE for widget.ascx.cs
public static void SendMailMessage(MailMessage message)
{
    if (message == null)
        throw new ArgumentNullException("message");

    try
    {
        message.IsBodyHtml = true;
        message.BodyEncoding = System.Text.Encoding.UTF8;
        SmtpClient smtp = new SmtpClient(BlogSettings.Instance.SmtpServer);
        smtp.Credentials = new System.Net.NetworkCredential(BlogSettings.Instance.SmtpUserName, BlogSettings.Instance.SmtpPassword);
        smtp.Port = BlogSettings.Instance.SmtpServerPort;
        smtp.EnableSsl = BlogSettings.Instance.EnableSsl;
        smtp.Send(message);
        Email_Sent(message, new EventArgs());
    }
    catch (SmtpException exception)
    {
        string Details = "Message = " + exception.Message;
        if (exception.InnerException != null)
        {
            Details += " ... InnerException = " + exception.InnerException.ToString();
        }
        AddToNewsletterWidgetLog(Details);
        Email_Failed(message, new EventArgs());
    }
    finally
    {
        // Remove the pointer to the message object so the GC can close the thread.
        message.Dispose();
        message = null;
    }
}

public static void SendMailMessageAsync(MailMessage message)
{
    System.Threading.ThreadPool.QueueUserWorkItem(delegate { SendMailMessage(message); });
}
Jan 6, 2009 at 8:25 PM

Message = Mailbox unavailable. The server response was: "email address" No such user here

Huh?

There's no user registration.
The email is valid.

Thanks

Coordinator
Jan 6, 2009 at 9:08 PM
That sounds like it could be a problem with either the "E-mail address" or the Username/Password settings in the control panel.  Your mail server may be trying to authenticate who you are and that you are sending email through a valid email account.

Is your "E-mail address" a real email account on the mail server you're sending thru, or just an alias account?  Do you have values for all 3 of these settings (Email address, username, password)?  Depending on your mail server, sometimes the "Username" needs to be the full email address.  So if your email account is you@domain.com, then the Username should be "you@domain.com" (not just "you").  You might want to verify your email settings in the control panel are correct.  Also, do you have values for all the other email settings ... Port number, SMTP Server, etc?
Jan 7, 2009 at 6:14 AM
as I suspected all along, it was a config problem.

instead of taking smtp.mydomain.com
as the smtp server it took "localhost".

I using discount.aspnet as hosting service
I guess the smtp server is on the same machine as the webserver.


Thanks, Ben for all your help.
I'm using your newsletter fix for published posts.

This sends email  when a post is published.
It does not send email when post is unpublished.
It does not send email when a published post is edited.

Correct?
Coordinator
Jan 7, 2009 at 4:25 PM
Glad you got that figured out.  The two or three webhosts I've dealt with all have their mail services on separate servers.  I have BE also installed at DiscountAsp.Net, and so yes, can't use localhost there.

Now that you have your email settings configured correctly, you don't really need these changes we made here (although they don't hurt to leave).

The newsletter widget only sends emails when creating a new post and that post is marked as published.  If it's originally marked as unpublished, and you later go back in and mark it as published, then emails won't be sent out.  When editing an already published post, emails are not sent out.

I did submit a modified newsletter widget.ascx.cs file in this work issue.  It's listed as a File Attachment that can be downloaded.  This modified version will send emails whenever a post is going from unpublished to published.  So if you first create a post and mark it as unpublished so you can first see what it looks like (for example), then you could later mark it as published when you're done, and emails would be sent out at that time.

Taylex mentioned in this thread that there is an Enhanced Newsletter widget.  I haven't looked into it myself.