code to subscribe a user to a list in mailchimp - c#

When I execute the below code, the mail id is not added to the list, but the "result" parameter contains the value of Email,EUIdl, LEId. Anyone can give the exact code. The code taken from
https://github.com/danesparza/MailChimp.NET
MailChimpManager mc = new MailChimpManager("5323a23b12022d250c23c48253641dd5-us8");
// Create the email parameter
EmailParameter email = new EmailParameter()
{
Email = "riyas.k13#gmail.com"
};
EmailParameter results = mc.Subscribe("33cacee7d8", email);

With the MCAPI this is the call to subscribe to a list, you might want to check all the options in the subscribeOptions, and determine your required Merge values
MCApi mc = new MCApi(ConfigurationManager.AppSettings["MCAPIKey"], false);
var subscribeOptions = new Opt<List.SubscribeOptions>(new List.SubscribeOptions { SendWelcome = true, UpdateExisting = true });
var merges = new Opt<List.Merges>(new List.Merges { { "FNAME", [Subscriber FirstName here] }, { "LNAME", [Subscriber lastName here] } });
if (mc.ListSubscribe(ConfigurationManager.AppSettings["MCListId"], [Subscriber email ], merges, subscribeOptions))
// The user is subscribed Do Something

I had the same issue where the code seemed to work but no email was added to the list. The code does work by the way.
When a new email address is added to the mail list MailChimp sends out a confirmation email to that address, which you need need to confirm naturally.
If you don't do this the new email address won't be added to the list. If you didn't receive any email at the target address check the spam folder or see if any filters have accidentally caught it without you realising.
Sad to say I spent a good few hours going around in circles because of this.

This depends on maichimp list setting when you created the list. There is something called "ask users to confirm the subscription". By default, if admin checked this option, after importing, the users will receive confirmation emails. New added user names will be added only if they confirmed.
If you don't want to sent confirmation emails but directly added new users. Set "DoubleOptIn" to false.
/*
Set subscribe options
*/
MailChimp.Types.List.SubscribeOptions option = new MailChimp.Types.List.SubscribeOptions();
option.UpdateExisting = true;
option.DoubleOptIn = false;
List<MailChimp.Types.List.Merges> lstMerges = new List<MailChimp.Types.List.Merges>();
/*
Merge new users here.
*/
returnStatus = api.ListBatchSubscribe("your MailChimp List ID", lstMerges, option);

Related

How do you create a PDF after submitting a form and attach it to an automated email in ASP.NET MVC C#?

I am having the hardest time figuring out how to create a pdf and attach it to an automated email. I thought it wouldn't be that hard but have quickly found out that it is much more complex than I imagined. Anyways, what I am doing is I have an order form, and when the customer fills out an order and submits it, I want it to generate a PDF for that order and attach it to an automated confirmation email. I am currently using Rotativa to generate the pdf and if I just ran the action result for generating it, it works perfectly fine which looks something like this:
public ActionResult ProcessOrder(int? id)
{
string orderNum = "FulfillmentOrder" + orderDetail.OrderID + ".pdf";
var pdf = new ActionAsPdf("OrderReportPDF", new { id = orderDetail.OrderID }) { FileName = orderNum };
return pdf;
}
When I added the function to send an automated email after the order form was submitted, that works perfectly fine with just the email by itself. But I can't seem to figure out how to generate the pdf and attach it to the email. The report view that gets the data from the order form is called "OrderReportPDF". My order form is called "Checkout", but the action result I use for this is called "Process Order". I've taken out the code in this function that is for the order form as it is not applicable. The section of my code for sending the email after the form is submitted is:
public ActionResult ProcessOrder(int? id)
{
//Send a confirmation email
var msgTitle = "Order Confirmation #" + orderDetail.OrderID;
var recipient = JohnDoe;
var fileAttach = //This is where I can't figure out how to attach//
var fileList = new string[] { fileAttach };
var errorMessage = "";
var OrderConfirmation = "Your order has been placed and is pending review." +
" Attached is a copy of your order.";
try
{
// Initialize WebMail helper
WebMail.SmtpServer = "abc.net";
WebMail.SmtpPort = 555;
WebMail.UserName = recipient;
WebMail.Password = "12345";
WebMail.From = "orders#samplecode.com";
// Send email
WebMail.Send(to: "orders#samplecode.com",
subject: msgTitle,
body: OrderConfirmation,
filesToAttach: fileList
);
}
catch (Exception ex)
{
errorMessage = ex.Message;
}
//5. Remove item cart session
Session.Remove(strCart);
return View("OrderSuccess");
}
I have been able to find very few articles on this issue using Rotativa and the ones I have found don't work for what I'm doing. Maybe Rotativa won't work for this, I'm hoping it does because I've designed my pdf report it generates from it, and not sure if doing it another way will screw up my formatting of it or not. As you can see at the bottom of the code, I return the view to an "OrderSuccess" page. When I try to implement the first code into the second code, it won't let me "return pdf" to execute the ActionAsPdf that generates the pdf when I do the "return View("OrderSuccess")". It only lets me do one or the other. If anybody knows how I can accomplish this, I need some help. I appreciate any suggestions or feedback. I'm pretty new to this so please be patient with me if I don't understand something.
Here is the updated code that fixed my problem and created the pdf, then attached it to an automated email once the order form was submitted:
public ActionResult ProcessOrder(int? id)
{
//1. Generate pdf file of order placed
string orderNum = "FulfillmentOrder" + orderDetail.OrderID + ".pdf";
var actionResult = new Rotativa.ActionAsPdf("OrderReportPDF", new { id = orderDetail.OrderID }) { FileName = orderNum };
var PdfAsBytes = actionResult.BuildFile(this.ControllerContext);
//2. Send confirmation email
var msgTitle = "Order Confirmation #" + orderDetail.OrderID;
var OrderConfirmation = "Your order has been placed and is pending review.<br />" +
" Attached is a copy of your order." +
using (MailMessage mail = new MailMessage())
{
mail.From = new MailAddress("orders#samplecode.com");
mail.To.Add("orders#samplecode.com");
mail.Subject = msgTitle;
mail.Body = OrderConfirmation;
mail.IsBodyHtml = true;
//STREAM THE CONVERTED BYTES AS ATTACHMENT HERE
mail.Attachments.Add(new Attachment(new MemoryStream(PdfAsBytes), orderNum));
using (SmtpClient smtp = new SmtpClient("abc.net", 555))
{
smtp.Credentials = new NetworkCredential("orders#samplecode.com", "password!");
smtp.EnableSsl = true;
smtp.Send(mail);
}
}
//3. Remove item cart session
Session.Remove(strCart);
return View("OrderSuccess");
}
Thank you again to the people that helped and got me pointed in the right direction! Also, a quick shout out to #Drewskis who posted this answer in convert Rotativa.ViewAsPdf to System.Mail.Attachment where I was able to use it to solve my issue!

Check if an input form is filled in a Adaptive Card bot framework c#

Can we check whether the input form in an adaptive card is filled or not with a warning message.
I am currently using an adaptive card to gather user input in bot application,I have already added isRequired for input validation but it doesnot give any warning message instead when I click on submit it doesnot go to the next method.
As soon as the user presses submit I want to make sure that the form is not empty
If you have an Adaptive Card like this (notice the ID given to the input):
var card = new AdaptiveCard
{
Body =
{
new AdaptiveTextBlock("Adaptive Card"),
new AdaptiveTextInput { Id = "text" },
},
Actions = {
new AdaptiveSubmitAction { Title = "Submit" } },
},
};
You can validate the value sent through the submit action like this:
if (string.IsNullOrEmpty(turnContext.Activity.Text))
{
dynamic value = turnContext.Activity.Value;
string text = value["text"]; // The property will be named after your input's ID
var emailRegex = new Regex(#"^\S+#\S+$"); // This is VERY basic email Regex. You might want something different.
if (emailRegex.IsMatch(text))
{
await turnContext.SendActivityAsync($"I think {text} is a valid email address");
}
else
{
await turnContext.SendActivityAsync($"I don't think {text} is a valid email address");
}
}
Validating email with regex can get very complicated and I've taken a simple approach. You can read more about email Regex here: How to validate an email address using a regular expression?
I took totally different approach than the accepted answer here. If you are going to use adaptive cards a lot in your bot than it makes sense to create card models and have validation attributes applied to each field that needs validation. Create custom card prompt inheriting from Prompt<object> class. Override OnPromptAsync and OnRecognizeAsync and check the validation of each field there.

DocuSign SOAP API Title Tab does not keep value

I am using DocuSign SOAP API in an ASP.NET app in C# to send some docs for e-signature.
One of the field is the title tab. I have the following code for that.
When testing, the tab correctly shows the title, which is picked up from the back-end DB. But when I see the completed document, the title is changed to something else. Does anyone know how can I resolve this?
When signing, if I modify the value - add and remove space - it works OK.
tab5 = new DocuSignAPI.Tab();
tab5.RecipientID = rcpt1.ID;
tab5.DocumentID = docId;
tab5.Type = DocuSignAPI.TabTypeCode.Custom;
tab5.CustomTabType = DocuSignAPI.CustomTabType.Text;
tab5.Name = "clientTitle";
tab5.CustomTabTypeSpecified = true;
tab5.Value = (dr["Rcpt_1_Role"]).ToString();
tab5.Type = DocuSignAPI.TabTypeCode.Title;
tab5.AnchorTabItem = new DocuSignAPI.AnchorTab();
tab5.AnchorTabItem.AnchorTabString = "CLIENT TITLE:";
tab5.AnchorTabItem.Unit = DocuSignAPI.UnitTypeCode.Pixels;
tab5.AnchorTabItem.UnitSpecified = false;
tab5.AnchorTabItem.IgnoreIfNotPresent = true;
tab5.AnchorTabItem.UnitSpecified = true;
tab5.AnchorTabItem.YOffset = -10;
tab5.AnchorTabItem.XOffset = 100;
When using certain DocuSign tab types (such as titleTabs or emailTabs for instance) the DocuSign platform will populate some of that information from the user's account if they have one.
For example, if the user has a DocuSign account where they have entered the title "CEO", then whenever you send an envelope to that exact recipient (name and email combo) and you use a titleTab the system will populate from their account.
I do not believe there is a way to override this, probably your best option is to just use a textTab instead and with that you can populate with any data from a database or wherever else you want to supply it from.

EWS error when retrieving complex property

We have an Exchange Web Services application that is throwing errors when an email is referenced that doesn't have a subject.
Our automated process needs to use the subject of the email, so the code is trying to reference it. However, when the subject is missing for an email in the inbox, instead of throwing an error, I want to change the behaviour.
Here is my code:
//creates an object that will represent the desired mailbox
Mailbox mb = new Mailbox(common.strInboxURL);
//creates a folder object that will point to inbox fold
FolderId fid = new FolderId(WellKnownFolderName.Inbox, mb);
... code removed fro brevity ...
// Find the first email message in the Inbox that has attachments. This results in a FindItem operation call to EWS.
FindItemsResults<Item> results = service.FindItems(fid, searchFilterCollection, view);
if (results.Count() > 0)
{
do
{
// set the prioperties we need for the entire result set
view.PropertySet = new PropertySet(
BasePropertySet.IdOnly,
ItemSchema.Subject,
ItemSchema.DateTimeReceived,
ItemSchema.DisplayTo, EmailMessageSchema.ToRecipients,
EmailMessageSchema.From, EmailMessageSchema.IsRead,
EmailMessageSchema.HasAttachments, ItemSchema.MimeContent,
EmailMessageSchema.Body, EmailMessageSchema.Sender,
ItemSchema.Body) { RequestedBodyType = BodyType.Text };
// load the properties for the entire batch
service.LoadPropertiesForItems(results, view.PropertySet);
so in that code, the error is being thrown on the complex property get on the line service.LoadPropertiesForItems(results, view.PropertySet); at the end.
So, I know I am going to have to do something like a Try..Catch here, however, I would need to check that the Subject property of the mail item exists before I can reference it to see what it is - some kind of chicken and egg problem.
If there is no subject, I need to mark the email as read, send a warning email off to a team, and then gon onwith the next unread email in the mailbox.
Any suggestions about the best way to approach this would be appreciated.
Thanks
Is the Subject not set or is it blank ?
You should be able to isolate any of these type of Emails with a SearchFitler eg use an Exists Search filter for the Subject property and then negate it so it will return any items where the Subject is not set
SearchFilter sfSearchFilteri = new SearchFilter.Exists(ItemSchema.Subject);
SearchFilter Negatesf = new SearchFilter.Not(sfSearchFilteri);
service.FindItems(WellKnownFolderName.Inbox, Negatesf, new ItemView(1000));
Then just exclude those items from your LoadPropertiesForItems
Cheers
Glen

Sitecore workflow approval/rejection emails

We are working on implementing some custom code on a workflow in a Sitecore 6.2 site. Our workflow currently looks something like the following:
Our goal is simple: email the submitter whether their content revision was approved or rejected in the "Awaiting Approval" step along with the comments that the reviewer made. To accomplish this we are adding an action under the "Approve" and "Reject" steps like so:
We are having two big issues in trying to write this code
There doesn't seem to be any easy way to determine which Command was chosen (the workaround would be to pass an argument in the action step but I'd much rather detect which was chosen)
I can't seem to get the comments within this workflow state (I can get them is the next state though)
For further context, here is the code that I have so far:
var contentItem = args.DataItem;
var contentDatabase = contentItem.Database;
var contentWorkflow = contentDatabase.WorkflowProvider.GetWorkflow(contentItem);
var contentHistory = contentWorkflow.GetHistory(contentItem);
//Get the workflow history so that we can email the last person in that chain.
if (contentHistory.Length > 0)
{
//contentWorkflow.GetCommands
var status = contentWorkflow.GetState(contentHistory[contentHistory.Length - 1].NewState);
//submitting user (string)
string lastUser = contentHistory[contentHistory.Length - 1].User;
//approve/reject comments
var message = contentHistory[contentHistory.Length - 1].Text;
//sitecore user (so we can get email address)
var submittingUser = sc.Security.Accounts.User.FromName(lastUser, false);
}
I ended up with the following code. I still see no good way to differentiate between commands but have instead implemented two separate classes (one for approve, one for reject):
public void Process(WorkflowPipelineArgs args)
{
//all variables get initialized
string contentPath = args.DataItem.Paths.ContentPath;
var contentItem = args.DataItem;
var contentWorkflow = contentItem.Database.WorkflowProvider.GetWorkflow(contentItem);
var contentHistory = contentWorkflow.GetHistory(contentItem);
var status = "Approved";
var subject = "Item approved in workflow: ";
var message = "The above item was approved in workflow.";
var comments = args.Comments;
//Get the workflow history so that we can email the last person in that chain.
if (contentHistory.Length > 0)
{
//submitting user (string)
string lastUser = contentHistory[contentHistory.Length - 1].User;
var submittingUser = Sitecore.Security.Accounts.User.FromName(lastUser, false);
//send email however you like (we use postmark, for example)
//submittingUser.Profile.Email
}
}
I have answered a very similar question.
Basically you need to get the Mail Workflow Action and then you need to further extend it to use the original's submitter's email.
Easiest way to get the command item itself is ProcessorItem.InnerItem.Parent
This will give you the GUID for commands like submit, reject etc.
args.CommandItem.ID
This will give you the GUID for states like Draft, approved etc.
args.CommandItem.ParentID

Categories