Sendgrid email not sent + no "recent activity" + no exceptions - c#

I am configuring Sendgird for the first time and I want to send emails using c#.
This is the code I am using, and I know for a fact that it is working because I can use it with another sendgird account that was configured by the IT department:
public static async void SendEmailsToUser(string[] mailAddresses, string subject, string fullHtmlEmail)
{
var sendgridMessage = new SendGrid.SendGridMessage();
foreach (var emailAddress in mailAddresses)
sendgridMessage.AddTo(emailAddress);
sendgridMessage.From = new MailAddress("blah#blah.com", "blah");
sendgridMessage.Subject = subject;
sendgridMessage.Html = fullHtmlEmail;
var transportWeb = new SendGrid.Web("sendgrid_key");
await transportWeb.DeliverAsync(sendgridMessage);
}
The code generates no exceptions, but I don't receive the test email and the sendgrid webpage shows no trace of recent activity.
The only idea that comes to mind is that maybe I have not generated the API key correctly? (Settings -> API keys -> Generate new -> full permissions)

Related

Using C# REST API to send TriggeredSend email - created in Content Builder in SFMC in C# code

I am totally new to SalesForce Marketing cloud.
We have a “Triggered Send” created using “Content Builder” with an email body with HTML attribuites. For eg. %%=v(#EVENT)=%% Invitation
There is a Customer_key for this TriggerSendDefinition
I am using FuelSDK – to TriggerSend this email.
I have NUget Package manager install Fuel SDK in my Visual studio 2019 project.
The App.config has the “clientId” and “clientSecret” values in the FuelSDK config section.
Here is my code below.
public void TestInvitationSend(string CustomerKey)
{
string myName = "John Adams";
string myEvent = "13989";
string fullurl = baseAPIAuthURL + AuthTokenUrl; // Values passed in
NameValueCollection parameters = new NameValueCollection();
parameters.Add("clientId", clientId);
parameters.Add("clientSecret",clientSecret);
parameters.Add("accountId", "account123");
**ETClient myclient = new ETClient(parameters);**
TriggeredSendDefinition definition = new TriggeredSendDefinition();
definition.CustomerKey = customerKey;
//subscriber to whom email is sent
Subscriber subscriber = new Subscriber();
subscriber.EmailAddress = myTest#test.com;
subscriber.SubscriberKey = myTest#test.com;
TriggeredSend triggeredsend = new TriggeredSend();
triggeredsend.TriggeredSendDefinition = definition;
triggeredsend.AuthStub = myclient;
triggeredsend.CustomerKey = customerKey;
triggeredsend.Subscribers = new Subscriber[] { subscriber };
SendReturn results = triggeredsend.Send();
Console.WriteLine("Send Status: " + results.Status.ToString());
}
I am getting a 404 error at the line in “bold” when initializing myClient and unable to pass-in values dynamically. Could not find much documentation for email send through code.
Can you point me to some examples of TriggerSend emails using REST API ?
Thanks

Validating spam, temporary emails and emails with invalid domains

recently I have noticed a lot of users being registered to my site and they all use disposable emails, temporary email addresses or fake emails to register on the site...
What I have done to partially prevent that is I added mailgun email verification which tells me whether an email is valid or not , disposable one or not...
This filtered out like 95% of the fake emails and users, however there is still a small portion of them which go "unnoticed". What I have figured out to do are following things via code:
public static bool IsValidEmail(string email)
{
RestClient client = new RestClient();
client.BaseUrl = new Uri("https://api.mailgun.net/v3");
client.Authenticator = new HttpBasicAuthenticator("api", "");
RestRequest request = new RestRequest();
request.Resource = "/address/validate";
request.AddParameter("address", email);
var res = new JavaScriptSerializer().Deserialize<RootObject>(client.Execute(request).Content);
if (res.is_disposable_address || res.is_valid==false)
return false;
return true;
}
This is one step via mailgun that I described previously... And second method to prevent spam/fake users is that I have set up manually a table in my DB with blacklisted domains to which registration won't be allowed... And the logic for that is:
public static bool IsValid(string email)
{
using (var ctx = new myEntities())
{
var blacklistedProviders = ctx.BlacklistedDomains.ToList();
foreach (var item in blacklistedProviders)
{
if (email.ToLower().Contains(item.DomainName.ToLower()))
return false;
}
}
return true;
}
However I don't think this will prevent them from doing more malicious stuff on the website...
I have also added google recaptcha to harden the process of registration for spammers, that does the job well too....
So my questions here are:
Are there any other ways that I can validate the email to see whether it is disposable or invalid email
What other way could I implement to prevent users from creating fake accounts?
Can someone help me out with this?

Sparkpost C# API add attachments to templates

I've been going thumbing through the documentation and searching the internet to find documenation on how to add attachments to created templates. I'm using darrencauthon's CSharp-Sparkpost to handle the API calls. So far what I have is not working. Does anyone have a working solution (possible?) or a better solution for C#? I'm not opposed to using a different library. This is the link to CSharp-Sparkpost
Here's what I've got so far:
var t = new Transmission();
t.Content.From.Email = "from#thisperson.com";
t.Content.TemplateId = "my-template-email";
new Recipient
{
Address = new Address { Email = recipient }
}
.Apply(t.Recipients.Add);
new Attachment
{
Data = //CSVDATA,
Name = "Table.csv",
Type = "text/csv"
}.Apply(t.Content.Attachments.Add);
var client = new SparkPost.Client(Util.GetPassword("sparkpostapikey"));
client.Transmissions.Send(t).Wait();
I've verified that I can send this attachment without a template and also verified that I can send this template without the attachment. So... the Email is getting sent; however, the content received is only the template and substitution data. No attachment with the template email.
Using Darren's library, and combining the requirements for my project, this is the solution I've come up with. I'm just making an additional API call to grab the template Html so I can build the transmission without having to send the template_id. Still using the CSharp-Sparkpost library to make all of the calls. I modified Darren's example SendInline program as such:
static async Task ExecuteEmailer()
{
var settings = ConfigurationManager.AppSettings;
var fromAddr = settings["fromaddr"];
var toAddr = settings["toaddr"];
var trans = new Transmission();
var to = new Recipient
{
Address = new Address
{
Email = toAddr
},
SubstitutionData = new Dictionary<string, object>
{
{"firstName", "Stranger"}
}
};
trans.Recipients.Add(to);
trans.SubstitutionData["firstName"] = "Sir or Madam";
trans.Content.From.Email = fromAddr;
trans.Content.Subject = "SparkPost sending attachment using template";
trans.Content.Text = "Greetings {{firstName or 'recipient'}}\nHello from C# land.";
//Add attachments to transmission object
trans.Content.Attachments.Add(new Attachment()
{
Data = Convert.ToBase64String(System.IO.File.ReadAllBytes(#"C:\PathToFile\ExcelFile.xlsx")),
Name = "ExcelFile.xlsx",
Type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
});
Console.Write("Sending mail...");
var client = new Client(settings["apikey"]);
client.CustomSettings.SendingMode = SendingModes.Sync;
//retrieve template html and set Content.Html
var templateResponse = await client.Templates.Retrieve("template-email-test");
trans.Content.Html = templateResponse.TemplateContent.Html;
//Send transmission
var response = client.Transmissions.Send(trans);
Console.WriteLine("done");
}
Oh actually, I see now -- you are talking about adding attachments to templates, not attachments.
My answer to that is that back when I developed this library, attachment on templates was not supported by SparkPost itself.
My library allows you to try it, but that's because every template and non-template emails are considered "transmissions." So if you create a transmission, it has the option of adding attachments... but if you send the transmission with a template id, the attachment is ignored.
I could throw an error, or somehow design the API around this limitation, but what if they stopped ignoring the attachment but my library threw an error? I designed the library for flexibility as the SparkPost web API grew, and I didn't want my library to get in the way.
If you want to test if you're sending the attachment right, send your transmission without a transmission id, and instead with a subject and email body. If the email goes through and you get an attachment, then you know it's because of this template/attachment restriction from SparkPost.
NOTE: I'm putting this answer on Stack Overflow, and it's possible that this dated message will no longer be valid in the future.
I'm Darren Cauthon, the primary author of this library.
I have attachment support in my acceptance tests, which are run before each release. The link is below, but the code should be as simple as:
// C#
var attachment = File.Create<Attachment>("testtextfile.txt");
transmission.Content.Attachments.Add(attachment);
https://github.com/darrencauthon/csharp-sparkpost/blob/3a8cb1efbb8c9a0448c71c126ce7f88759867fb0/src/SparkPost.Acceptance/TransmissionSteps.cs#L56

C# Console Application - Parsing Office 365 Inbox

I was able to succeed via a package I found called EAGetMail. Unfortunately, I realized soon after that they have a token system and this is not a free approach.
There are a couple other choices available, like using Outlook Mail REST API, and MimeKit, but I'm lost on how to achieve my end result because no "start to finish" code is available on either of these references that demonstrates how to parse an Inbox for an account.
I've started to write this with the help of Mimekit, but am not sure if this is the proper way at all.
I must imagine it looks something like:
using (var client = new SmtpClient ())
{
client.Connect("outlook.office365.com", 587);
client.Authenticate("myemail#office365account.com", "mypassword");
var message = MimeMessage.Load(stream);
}
I don't know how to setup the stream mentioned above, and I don't know if it's possible to do this with Mimekit and Office 365.
I'm open to seeing a solution for this in any other approach that's not through EAGetMail. If anyone has a lightweight solution ranging from actual establishing a connection, to pulling messages from the inbox, would be great to see!
I've got it using EWS (Exchange Web Services). Here's my code:
private static bool RedirectionUrlValidationCallback(string redirectionUrl)
{
// The default for the validation callback is to reject the URL.
bool result = false;
Uri redirectionUri = new Uri(redirectionUrl);
// Validate the contents of the redirection URL. In this simple validation
// callback, the redirection URL is considered valid if it is using HTTPS
// to encrypt the authentication credentials.
if (redirectionUri.Scheme == "https")
{
result = true;
}
return result;
}
static void Main(string[] args)
{
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
service.Credentials = new WebCredentials("email#myemail.com", "myPassword");
service.AutodiscoverUrl("email#myemail.com", RedirectionUrlValidationCallback);
//creates an object that will represent the desired mailbox
Mailbox mb = new Mailbox(#"email#myemail.com");
//creates a folder object that will point to inbox folder
FolderId fid = new FolderId(WellKnownFolderName.Inbox, mb);
//this will bind the mailbox you're looking for using your service instance
Folder inbox = Folder.Bind(service, fid);
//load items from mailbox inbox folder
if (inbox != null)
{
FindItemsResults<Item> items = inbox.FindItems(new ItemView(100));
foreach (var item in items)
{
item.Load();
Console.WriteLine("Subject: " + item.Subject);
}
}
}

MS Bot Builder: how to set session data to proactive message?

I first send a proactive message to the user via sms channel inside OAuthCallback method
var connector = new ConnectorClient();
Message message = new Message();
message.From = new ChannelAccount { Id = Constants.botId, Address = "+12312311", ChannelId = "sms", IsBot = true };
message.To = new ChannelAccount { Id = newUserId, Address = "+18768763", ChannelId = "sms", IsBot = false };
message.Text = $"How are you doing? ";
message.Language = "en";
connector.Messages.SendMessage(message);
IBotData myDataBag = new JObjectBotData(message);
myDataBag.UserData.SetValue("Username", "Bob");
myDataBag.PerUserInConversationData.SetValue("Newuser", "yes");
Then in my main Dialog.cs I try to access it
public static readonly IDialog<string> dialog = Chain
.PostToChain()
.Switch(new Case<Message, IDialog<string>>((msg) =>
{
var regex = new Regex("hello$", RegexOptions.IgnoreCase);
return regex.IsMatch(msg.Text);
},
(ctx, msg) =>
{
// Clearing user related data upon logout
string isnewuser = ctx.PerUserInConversationData.TryGetValue("Newuser");
string username = ctx.UserData.TryGetValue("Username");
return Chain.Return($"Welcome {username}");
}))
.Unwrap()
.PostToUser();
I receive the message on my phone. However, I am not able to get back the username and newuser session data saved inside OAuthCallback.
I suspect that this is happening because the proactive message does not have conversationId set. And the conversationId must differ somehow.
so how can I get it to set session data to my proactive message in the future conversation?
In proactive's scenarios, the conversation Id for channels change when the user answers your message, it's like a new session, we do this type of features using the channel data, but this solution is only for small data, you also have the option of creating a persistent session using the same table storage that the bot framework is using to save the dialog context, in this solution you can create another table to store your data serialized, and the final one is a persistent session using a distributed cache like Redis, but this type of services are expensive, so you have to analyze which type of solution is the right one for your solution, but as a start, you should try with the Channel Data property and if it works, you can analyze another approach
I hope I have been helpful
Not sure if this is still relevant after four years, but I think I figured this out in Access UserProfile from NotifyBot. Check it out.

Categories

Resources