Using X-SMTPAPI in sendgrid not working - c#

Please help! I'm new to SendGrid and I need to send a mass email, so I found this X-SMTPAPI on SendGrid. The problem is that email was only sent to "TO" only. You can give another approach if you like. Here's my code.
Email from = new Email(retsendemail.From);
Email to = new Email(retsendemail.To);
String subject = retsendemail.Subject;
Content content = new Content("text/html", retsendemail.Body);
Mail mail = new Mail(from, subject, to, content);
var header = new Header();
var recipients = new List<String> { "test1#xxx.com", "test2#xxx.com", "test3#xxx.com" };
header.SetTo(recipients);
var subs1 = new List<String> { "t1", "t2", "t3" };
header.AddSubstitution("%name%", subs1);
string jsonvalue = header.JsonString();
Dictionary<String, String> headers = new Dictionary<String, String>();
headers.Clear();
headers.Add("X-SMTPAPI", jsonvalue);
dynamic response = sg.client.mail.send.post(requestBody: mail.Get(), requestHeaders: headers).GetAwaiter().GetResult();
string statusCode = ((object)response.StatusCode).ToString();
string headerString = response.Headers.ToString() as string;
Here's the Jsonvalue:
{
"to": [
"test1#xxx.com",
"test2#xxx.com",
"test3#xxx.com"
],
"sub": {
"%name%": [
"t1",
"t2",
"t3"
]
}
}

Related

SendGrid API Substitutions not working in C#

I created a simple email dynamic transactional email template in SendGrid with only tag "First_Name".
When I DO NOT use a substitution everything works fine i.e. I get an email. But when I do use a substitution the email fails. Here is the code that uses substitution.
var client = new SendGridClient(apiKey);
Personalization personalization = new Personalization();
personalization.Substitutions = new Dictionary<string, string>() { {"First_Name","Don" } };
var msgs = new SendGridMessage()
{
TemplateId = "d-123",
From = new EmailAddress("info#domain.us", "Name"),
Subject = "Account is ready",
ReplyTo = new EmailAddress("info#domain.us", "Name"),
Personalizations = new List<Personalization>() { personalization },
};
msgs.AddTo(new EmailAddress("user#email.com"));
msgs.AddBcc(new EmailAddress("admin#domain.us));
msgs.SetClickTracking(true, true);
var responses = await client.SendEmailAsync(msgs);
Any help will be most appreciated.

Casting JArray to Dynamic[] so NEST's IndexMany works

Problem description
I need to receive JSON array of objects (with almost any shape) and store them to ES database using function IndexMany (or some similar bulk indexing function). I found some clumsy solution with one drawback - it doesn't set _id property in ES correctly (according to the id property in JSON object).
And also I would like to know if there is any more elegant way how to achieve my goal without casting every JArray item to string and back to ExpandoObject.
Additional info
Elasticsearch DB 7.5.1
NEST (7.6.1)
Newtonsoft.Json (12.0.3)
TLDR
Is there any elegant solution of following code:
var settings = new ConnectionSettings(new Uri("http://localhost:9200")).DefaultIndex("people");
var client = new ElasticClient(settings);
// this string represents incoming JSON message
string json = #"[
{
""id"": ""1"",
""name"": ""Andrej"",
""surname"": ""Burak"",
""dob"": ""1921-11-10T00:00:00+00:00""
},
{
""id"": ""2"",
""name"": ""Franta"",
""surname"": ""Dobrota"",
""dob"": ""1933-10-05T00:00:00+00:00""
},
{
""id"": ""3"",
""name"": ""Milos"",
""surname"": ""Ovcacek"",
""dob"": ""1988-05-05T00:00:00+00:00""
}
]";
JArray jArray = JArray.Parse(json);
foreach (var jtoken in jArray)
{
var jobj = (JObject)jtoken;
jobj.Add("DbCreated", JToken.FromObject(DateTime.UtcNow));
jobj.Add("DbCreatedBy", JToken.FromObject("authors name"));
}
//working, but seems to me a bit too clumsy to convert every item to string and then back to dynamic object
var converter = new ExpandoObjectConverter();
dynamic[] dlst = jArray.Select(t => (dynamic)JsonConvert.DeserializeObject<ExpandoObject>(t.ToString(), converter)).ToArray();
//not working cast
dynamic[] dlstNW = jArray.ToObject<dynamic[]>();
var indexManyResponse = client.IndexMany(dlst); //working partially (but not using ID as index)
var indexManyResponseNotWorking = client.IndexMany(jArray); //not working
var indexManyResponseNotWorking2 = client.IndexMany(dlstNW); //not working
// expected behavior
dynamic[] jsondyn = new dynamic[]
{
new { Id = "1", Name = "foo" },
new { Id = "2", Name = "bar" },
new { Id = "3", Name = "baz" },
};
var indexManyResponseWithIndex = client.IndexMany(jsondyn); //working perfectly, but don't know how to acieve this
After #gnud pointed me to low-level client I think I have found my answer. Important thing is to build request manually like it was explained here.
var settings = new ConnectionSettings(new Uri("http://localhost:9200")).DefaultIndex("people").DisableDirectStreaming();
var client = new ElasticClient(settings);
// this string represents incoming JSON message
string json = #"[
{
""id"": ""1"",
""name"": ""Andrej"",
""surname"": ""Burak"",
""dob"": ""1921-11-10T00:00:00+00:00""
},
{
""Id"": ""2"",
""name"": ""Franta"",
""surname"": ""Dobrota"",
""dob"": ""1933-10-05T00:00:00+00:00""
},
{
""Id"": ""3"",
""name"": ""Milos"",
""surname"": ""Ovcacek"",
""dob"": ""1988-05-05T00:00:00+00:00""
}
]";
JArray jArray = JArray.Parse(json);
// I have to build my request manually
List<string> esRequest = new List<string>();
foreach (var jtoken in jArray)
{
var jobj = (JObject)jtoken;
jobj.Add("DbCreated", JToken.FromObject(DateTime.UtcNow));
jobj.Add("DbCreatedBy", JToken.FromObject("authors name"));
string id;
// Ensure that Id is set even if we receive it in lowercase
if( jobj["Id"] == null)
{
if( jobj["id"] == null)
{
throw new Exception("missing Id");
}
id = jobj["id"].Value<string>();
}
else
{
id = jobj["Id"].Value<string>();
}
string indexName = "people";
esRequest.Add($"{{\"index\":{{\"_index\":\"{indexName}\",\"_id\":\"{id}\"}}}}");
esRequest.Add(jobj.ToString(Formatting.None));
}
PostData pd = PostData.MultiJson(esRequest);
var llres = client.LowLevel.Bulk<BulkResponse>(pd);
Hope it helps someone.

Can you have a returnUrlRequest for a sender view generated from a bulk send?

I'm trying to create a workflow where a user can do a bulk send through docusign within my application. They would select the clients they want to send forms to for a signature, be presented with a sender view to specify what fields they require, send it off, then have it post back to my application in order to generate emails for embedded signing. However, currently, it doesn't return back to my application after the user has sent off the bulk request despite the return url request being set. Is this currently not possible with a bulk send request?
The following is just some code to generate the sender view url:
// Create envelope definition
var envelopeDefinition = new EnvelopeDefinition
{
EmailSubject = documentDesc,
Documents = new List<Document>(),
Recipients = new Recipients { Signers = new List<Signer> {
new Signer
{
Name = "Multi Bulk Recipient::signer",
Email = "multiBulkRecipients-signer#docusign.com",
RoleName = "signer",
RoutingOrder = "1",
Status = "sent",
DeliveryMethod = "Email",
RecipientId = "1",
RecipientType = "signer"
}
} },
CustomFields = new CustomFields()
{
TextCustomFields = new List<TextCustomField>()
{
new TextCustomField() {Name = "Client", Value = _config.DatabaseName},
new TextCustomField() {Name = "Server", Value = _config.DatabaseServer},
new TextCustomField() {Name = "DocId", Value = documentId.ToString()}
}
},
EnvelopeIdStamping = "true",
};
// Read a file from disk to use as a document.
byte[] fileBytes = File.ReadAllBytes("test.pdf");
// Add a document to the envelope
Document doc = new Document();
doc.DocumentBase64 = System.Convert.ToBase64String(fileBytes);
doc.Name = "TestFile.pdf";
doc.DocumentId = "1";
envDef.Documents = new List<Document>();
envDef.Documents.Add(doc);
// Add each recipient and add them to the envelope definition
var recipients = new List<BulkSendingCopyRecipient>();
var recipients = new List<BulkSendingCopyRecipient> {
new BulkSendingCopyRecipient
{
Name = "Bob Ross",
Email = "bobross#happymistakes.com",
ClientUserId = "1234",
CustomFields = new List<string>()
{
"A custom field for internal use"
},
RoleName = "signer"
},
new BulkSendingCopyRecipient
{
Name = "Fred Rogers",
Email = "mrrogers#neighborhood.com",
ClientUserId = "5678",
CustomFields = new List<string>()
{
"Another custom field for internal use"
},
RoleName = "signer"
}
};
var bulkSendingCopy = new BulkSendingCopy
{
Recipients = recipients
};
var bulkCopies = new List<BulkSendingCopy>
{
bulkSendingCopy
};
var bulkSendingList = new BulkSendingList
{
BulkCopies = bulkCopies
};
bulkSendingList.Name = "A document name";
envelopeDefinition.Status = "created";
var envelopesApi = new EnvelopesApi(config);
var bulkEnvelopesApi = new BulkEnvelopesApi();
var createBulkListResult = bulkEnvelopesApi.CreateBulkSendList(AccountId, bulkSendingList);
envelopeDefinition.CustomFields.TextCustomFields.Add(
new TextCustomField
{
Name = "mailingListId",
Required = "false",
Show = "false",
Value = createBulkListResult.ListId //Adding the BULK_LIST_ID as an Envelope Custom Field
}
);
var envelopeSummary = envelopesApi.CreateEnvelope(AccountId, envelopeDefinition);
var options = new ReturnUrlRequest
{
ReturnUrl = HttpContext.Current.Request.Url.Scheme + "://" +
HttpContext.Current.Request.Url.Authority +
HttpContext.Current.Request.ApplicationPath +
"/SIP/ConfirmTagSendAndPublish.aspx?idockey=" + documentId
};
var senderView = envelopesApi.CreateSenderView(AccountId, envelopeSummary.EnvelopeId, options);
var senderViewInfo = new string[2];
senderViewInfo[0] = senderView.Url;
senderViewInfo[1] = envelopeSummary.EnvelopeId;
return senderViewInfo;
When the sender view comes up and you hit send it just takes me to the Sent tab in docusign
What I see after send
So in order for you to do the scenario you're asking to do, you will have to take a slightly different approach:
Generate a regular envelope in draft mode with the things you need.
Have user interact with it in embedded sending experience.
Generate a bulk using the CreateBulkList() method based on the envelope from #2 and the users you add like in your code.
(to do #3 you may need to copy custom fields etc. from the initial envelope to the one used for custom fields)

How to implement Signer Attachment in Docusign?

The requirement which I have regarding docusign is I need to implement Signer Attachment and that same scenario is mentioned at [https://github.com/docusign/docusign-soap-sdk/wiki/Code-Walkthrough-_-Signer-Attachments]
But I am not sure how do I achieve with code in C#. As not sure how do I attach it to Envelope?
I want to send someone a contract letter to sign and also request them attach few docs and when all of that is completed , those docs should be sent to my email.
Anyone knows if I can achieve it with docusign?
The previous entry is not bad... I got it working eventually. But this code below is solid, in production, and works great! It also uses anchor strings.
EnvelopeDefinition env = new EnvelopeDefinition();
env.EmailSubject = "Please sign this document set";
Document doc4 = new Document
{
DocumentBase64 = doc4PdfBytes,
Name = "Voided Check Attachment", // can be different from actual file name
FileExtension = "pdf",
DocumentId = "4"
};
env.Documents = new List<Document> { doc4 };
SignerAttachment signAttachDoc = new SignerAttachment
{
TabLabel = "Attach your voided check",
DocumentId = "1",
TabId = "1",
PageNumber = "1",
AnchorString = "/at1/",
AnchorUnits = "pixels",
AnchorXOffset = "0",
AnchorYOffset = "0",
AnchorIgnoreIfNotPresent = "false",
};
Tabs signer1Tabs = new Tabs
{
SignerAttachmentTabs = new List<SignerAttachment> { signAttachDoc }
};
signer1.Tabs = signer1Tabs;
Recipients recipients1 = new Recipients
{
Signers = new List<Signer> { signer1 }
};
env.Recipients = recipients1;
Here is how we can do it while using C# SDK
create a signer object
Signer signer = new Signer();
signer.Name = recipientName;
signer.Email = recipientEmail;
signer.RecipientId = "1";
then create attachment tabs
signer.Tabs.SignerAttachmentTabs = new List<SignerAttachment>();
after which we need an attachment to add to it
SignerAttachment signDoc = new SignerAttachment();
signDoc.TabLabel = "Attach your Other Doc";
signDoc.DocumentId = "1";
signDoc.TabId = "1";
signDoc.PageNumber = "1";
And finally we add it to the tabs
signer.Tabs.SignerAttachmentTabs.Add(signDoc);

sending mailchimp campaign in asp.net

I'm trying to send a mail chimp campaign using asp.net, actually i created successfully the campaign and i can see it through my profile but also i want to send it through my code here is my code so if any one can help!!
private static void CreateCampaignAndSend(string apiKey, string listID)
{
Int32 TemplateID = 0;
string campaignID = string.Empty;
// compaign Create Options
var campaignCreateOpt = new campaignCreateOptions
{
list_id = listID,
subject = "subject",
from_email = "cbx#abc.com",
from_name = "abc",
template_id = TemplateID
};
// Content
var content = new Dictionary<string, string>
{
{"html", "Lots of cool stuff here."}
};
// Conditions
var csCondition = new List<campaignSegmentCondition>();
var csC = new campaignSegmentCondition {field = "interests-" + 123, op = "all", value = ""};
csCondition.Add(csC);
// Options
var csOptions = new campaignSegmentOptions {match = "all"};
// Type Options
var typeOptions = new Dictionary<string, string>
{
{"offset-units", "days"},
{"offset-time", "0"},
{"offset-dir", "after"}
};
// Create Campaigns
var campaignCreate = new campaignCreate(new campaignCreateInput(apiKey, EnumValues.campaign_type.plaintext, campaignCreateOpt, content, csOptions, typeOptions));
campaignCreateOutput ccOutput = campaignCreate.Execute();
campaignSendNow c=new campaignSendNow();
List<Api_Error> error = ccOutput.api_ErrorMessages; // Catching API Errors
if (error.Count <= 0)
{
campaignID = ccOutput.result;
}
else
{
foreach (Api_Error ae in error)
{
Console.WriteLine("\n ERROR Creating Campaign : ERRORCODE\t:" + ae.code + "\t ERROR\t:" + ae.error);
}
}
}

Categories