Why Send Email Plugin is not working? - dynamics-crm-2011

I have created a plugin (using Developer's tool kit) which will send a mail to Participants, which is converted Contacts, whenever a Participants is created.
But this plugin is not Working. When I was trying to debug it this following message came in plugin registration tool(SDK)
Profiler> Plug-in AppDomain Created
Profiler> Parsed Profiler File Successfully.
Profiler> Constructor Execution Started: XXXXXXXX
Profiler> Constructor Execution Completed Successfully (Duration = 8ms).
Profiler> Profiler Execution Started: XXXXXXXXXXX
Plug-in> Entered CRMEmailToParticipantsPackage.EmailPlugins.PostParticipantCreate.Execute(),
Plug-in> Exiting CRMEmailToParticipantsPackage.EmailPlugins.PostParticipantCreate.Execute(),
Profiler> Profiler Execution Completed Successfully (Duration = 57ms).
Profiler> Profiler AppDomain Unloaded
. Pipeline Stage is Pre-Validation on Create Message.
And this is my Code:
protected void ExecutePostParticipantCreate(LocalPluginContext localContext)
{
if (localContext == null)
{
throw new ArgumentNullException("localContext");
}
// TODO: Implement your custom Plug-in business logic.
IPluginExecutionContext context = localContext.PluginExecutionContext;
IOrganizationService service = localContext.OrganizationService;
if (context.InputParameters.Contains("Target") &&
context.InputParameters["Target"] is Entity)
{
try
{
Entity entity = (Entity)context.InputParameters["Target"];
if (entity.LogicalName == "new_participant")
{
Guid Contact_id = ((EntityReference)entity.Attributes["new_participantscontact"]).Id;
Guid trip_Id = ((EntityReference)entity.Attributes["new_tripparticipants"]).Id;
ColumnSet col1 = new ColumnSet("new_name", "new_date", "new_destination");
Entity trip = service.Retrieve("new_trip", trip_Id, col1);
var Trip_name = trip.Attributes["new_name"];
var Trip_date = trip.Attributes["new_date"];
var Trip_destination = trip.Attributes["new_destination"];
string emailBody = "Hi, your " + Trip_name.ToString() + "is booked on : " + Trip_date.ToString() + "; Destination : " + Trip_destination.ToString();
Guid _userId = context.UserId;
ActivityParty fromParty = new ActivityParty
{
PartyId = new EntityReference(SystemUser.EntityLogicalName, _userId)
};
ActivityParty toParty = new ActivityParty
{
PartyId = new EntityReference("new_participantscontact", Contact_id)
};
Email email = new Email
{
To = new ActivityParty[] { toParty },
From = new ActivityParty[] { fromParty },
Subject =Trip_name.ToString()+ " :Trip Details",
Description = emailBody,
DirectionCode = true
};
Guid emailID = service.Create(email);
SendEmailRequest req = new SendEmailRequest();
req.EmailId = emailID;
req.TrackingToken = "";
req.IssueSend = true;
SendEmailResponse res = (SendEmailResponse)service.Execute(req);
}
}
catch (FaultException ex)
{
throw new InvalidPluginExecutionException("An error occurred in the plug-in.", ex);
}
}
}
Have I done any thing wrong here?
Thank you.

i think the first thing is discover if your plugin is fired or not. Try debug or use ITracingService to know that. If you discover that is your plugin isn't fired the code is unnecessary. Be careful that the deploy of a plugin in CRM Online has a limitation of running just in sandbox mode. Try see this step-by-step deploy of a plugin in CRM Online.

Are you able to debug using the steps listed here: http://microsoftcrmworld.blogspot.com/2013/01/debug-plugins-on-your-local-pc-without.html ?
If not, you can add some localContext.trace() calls and then throw an exception at the very end of your execute method. Download and view the log file to see the outputs from localContext.trace(). This will give you an idea of what's going on.

Your code seems to be fine...
I observed that you are sending mail to a custom entity...
Have you enabled "Sending Email" option during customization?
Check this link for enabling it

Related

Recording Bot using Skype.bot.media

We are creating a bot that can join the team meeting and it can start the recording as it joins the team meeting. But we are getting this error(Expected not null
Parameter name: client). I am attaching the code below:
when debugger goes to CreateLocalMediaSession() session method then at that method it gives the error.(Expected not null
Parameter name: client)
public async Task<ICall> JoinCallAsync()
{
// A tracking id for logging purposes. Helps identify this call in logs.
var scenarioId = Guid.NewGuid();
var (chatInfo, meetingInfo) = JoinInfo.ParseJoinURL("https://teams.microsoft.com/l/meetup-join/19:meeting_YTI5NDQ2ODQtMmNlNy00YTBhLTg2NTMtYmZmOGIyMzdhMTgw#thread.v2/0?context=%7B%22Tid%22:%22204d6395-ea6c-4e64-abea-e04cd30845e2%22,%22Oid%22:%225a95f69b-70e2-40d3-8b9a-5810ffcc6ec9%22%7D");
var tenantId = (meetingInfo as OrganizerMeetingInfo).Organizer.GetPrimaryIdentity().GetTenantId();
var mediaSession = this.CreateLocalMediaSession(scenarioId);
var joinParams = new JoinMeetingParameters(chatInfo, meetingInfo, mediaSession)
{
TenantId = tenantId,
};
if (!string.IsNullOrWhiteSpace("bot"))
{
// Teams client does not allow changing of one's display name.
// If the display name is specified, we join as an anonymous (guest) user
// with the specified display name. This will put the bot in lobby
// unless lobby bypass is disabled.
joinParams.GuestIdentity = new Identity
{
Id = Guid.NewGuid().ToString(),
DisplayName = "bot",
};
}
var statefulCall = await this.Client.Calls().AddAsync(joinParams, scenarioId).ConfigureAwait(false);
statefulCall.GraphLogger.Info($"Call creation complete: {statefulCall.Id}");
return statefulCall;
}
Code for creating local media session:
private ILocalMediaSession CreateLocalMediaSession(Guid mediaSessionId = default)
{
try
{
// create media session object, this is needed to establish call connections
return this.Client.CreateMediaSession(
new AudioSocketSettings
{
StreamDirections = StreamDirection.Recvonly,
// Note! Currently, the only audio format supported when receiving unmixed audio is Pcm16K
SupportedAudioFormat = AudioFormat.Pcm16K,
ReceiveUnmixedMeetingAudio = true //get the extra buffers for the speakers
},
new VideoSocketSettings
{
StreamDirections = StreamDirection.Inactive
},
mediaSessionId: mediaSessionId);
}
catch (Exception e)
{
_logger.Log(System.Diagnostics.TraceLevel.Error, e.Message);
throw;
}
}
We are creating a bot that can join the team meeting and it can start the recording as it joins the team meeting. But we are getting this error(Expected not null
Parameter name: client). I am attaching the code below:
error facing:
enter image description here

Unable to get a Stripe Checkout session object

Stripe.Net v34.16.0 bounces my code on the creation of the checkout session object responding with:
StripeException: No such plan: plan_myPlanId; a similar object exists in live mode, but a test mode key was used to make this request.
I do not see a means in the Stripe Dashboard to designate a given plan as a test plan .I also do not see
anything resembling a mode property.. my code
public async Task<IActionResult> Index()
{
//var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
//user = await _userManager.FindByIdAsync(userId);
StripeConfiguration.ApiKey = "sk_test_mytestkey";
var options = new Stripe.Checkout.SessionCreateOptions
{
PaymentMethodTypes = new List<string> {
"card",
},
SubscriptionData = new Stripe.Checkout.SessionSubscriptionDataOptions
{
Items = new List<SessionSubscriptionDataItemOptions> {
new SessionSubscriptionDataItemOptions {
Plan = "plan_myplanid",
},
},
},
//to do
SuccessUrl = "localhost://home",
CancelUrl = "localhost://home",
//CancelUrl = "https://example.com/cancel",
};
var service = new Stripe.Checkout.SessionService();
Stripe.Checkout.Session session = service.Create(options); //error out here
StripeCheckoutSessionId stripeCheckoutSessionId = new StripeCheckoutSessionId();
stripeCheckoutSessionId.StripeSessionID = session.Id;
return View(stripeCheckoutSessionId);
}
I am referring to Stripe sample code in the .Net tab here: https://stripe.com/docs/payments/checkout/subscriptions/starting
I appreciate your guidance in correcting my errors.

Sendgrid not sending email in an on demand azure webjob running as console application

I have an on-demand azure webjob running as a console application.
Objective is send emails to customers.
Issue is it does not send emails.
My code is heavily lifted from msdn section How to: Send an Email. Following is my code snippet.
class Program
{
static void Main(string[] args)
{
Execute(Environment.GetEnvironmentVariable("WEBJOBS_COMMAND_ARGUMENTS")).Wait();
}
static async Task Execute(string email)
{
DeserializedCustomer customer = JsonConvert.DeserializeObject<DeserializedCustomer>(email);
var apiKey = Environment.GetEnvironmentVariable("SENDGRID_APIKEY");
var client = new SendGridClient(apiKey);
SendGridMessage msg = new SendGridMessage()
{
From = new EmailAddress(customer.Email, "From Email"),
Subject = $"Inquiry by - {customer.FirstName} {customer.LastName}",
PlainTextContent = customer.Comments + Environment.NewLine + $"Phone : {customer.Phone}",
};
msg.AddTo(new EmailAddress(ToMail, ToMailName));
if (!String.IsNullOrWhiteSpace(customer.Attachment))
{
List<Attachment> attachments = new List<Attachment>()
{
new Attachment()
{
Content = customer.Attachment,
Type = customer.AttachmentType,
Filename = customer.AttachmentFileName,
Disposition = "inline",
ContentId = customer.AttachmentFileName + Guid.NewGuid()
}
};
msg.Attachments = attachments;
}
await client.SendEmailAsync(msg);
}
}
Searching I found an SO post where giving time to sendgrid to send email in a console application
Adding time did not help either.
If there are some quirkiness about sending emails from azure webjobs running as console applications then I'm unaware.
Searching further I found this SO post where they successfully tested sending emails in console application so I thought it might help but it did not send emails.
All the above examples are more than a year old and none of them work currently.
I tried using an earlier version of SendGrid library but I am stuck on
var transportWeb = new Web(credentials);
transportWeb.DeliverAsync(myMessage);
as SendGrid library has been updated.
On github I found this which clearly states that console apps only work with transportWeb.DeliverAsync(myMessage).Wait
therefore I am trying with transportWeb.
Is there an amalgamation of azure with on demand webjob running as console application?
Can anyone help?
Update
After Randy Minder's help I updated the code to the following
static async Task Execute(string email)
{
try
{
DeserializedCustomer customer = new DeserializedCustomer();
customer = JsonConvert.DeserializeObject<DeserializedCustomer>(email);
Console.WriteLine(customer);
SendGridMessage msg = new SendGridMessage();
msg.From = new MailAddress(customer.EmailAddress, "From Email");
msg.Subject = $"Inquiry by - {customer.FirstName} {customer.LastName}";
msg.Text = customer.Comments + Environment.NewLine + $"Phone : {customer.Phone}";
msg.AddTo(ToMail);
// Create a network credentials object
var credentials = new NetworkCredential(Environment.GetEnvironmentVariable("UserName"), Environment.GetEnvironmentVariable("Password"));
var transportWeb = new SendGrid.Web(credentials);
transportWeb.DeliverAsync(msg).Wait();
}
catch (Exception ex)
{
DateTime now = DateTime.Now;
Trace.TraceError($"{now.ToLongDateString()} {now.ToLongTimeString()}" + Environment.NewLine + new ExceptionSerializer(ex));
}
}
I'm using SendGrid 6.1.0
<package id="Sendgrid" version="6.1.0" targetFramework="net47" />
I do not get any exception and my webjob runs to success
[09/06/2017 17:48:42 > 1a8d37: SYS INFO] Run script 'SaSRizqTechCloudWhizEngineering.Backgr.exe' with script host - 'WindowsScriptHost'
[09/06/2017 17:48:42 > 1a8d37: SYS INFO] Status changed to Running
[09/06/2017 17:48:42 > 1a8d37: INFO] SerializedEmail - {"FirstName":"adsfkh","LastName":"adfkjladf","EmailAddress":"jamilakhtar#gmail.com","Phone":"","Comments":"lkjadf ","AttachmentType":"","AttachmentFileName":"","Attachment":null}
[09/06/2017 17:48:42 > 1a8d37: INFO] FirstName adsfkh - LastName adfkjladf - EmailAddress jamilakhtar#gmail.com - Phone - Comments lkjadf - Attachment - AttachmentType - - AttachmentFileName
[09/06/2017 17:48:44 > 1a8d37: SYS INFO] Status changed to Success
However I do not get any email
When attempting to send an email via SendGrid in a console app, you have to do it a bit differently. Here is a method I have that works in a console app:
/// <summary>
/// Send the email async in a console app.
/// </summary>
public async Task SendAsync()
{
// Create a network credentials object
var credentials = new NetworkCredential(azureUserName, azurePassword);
// Create an Web transport for sending the email
var transportWeb = new Web(credentials);
transportWeb.DeliverAsync(this._email).Wait();
}
This is what I use in a non-console app:
/// <summary>
/// Send the email async in backend or MVC code.
/// </summary>
public async Task SendAsync()
{
// Create a network credentials object
var credentials = new NetworkCredential(azureUserName, azurePassword);
// Create an Web transport for sending the email
var transportWeb = new Web(credentials);
await transportWeb.DeliverAsync(this._email).ConfigureAwait(false);
}
The actual email object is contained in this._email.
According to your description, I have also create a test demo on my side, it works well. I used the sendgird SDK is 9.90.
The details codes is like as below:
class Program
{
static void Main(string[] args)
{
string serializedEmail = args[0];
Console.WriteLine($"SerializedEmail - {serializedEmail}");
Customer customer = JsonConvert.DeserializeObject<Customer>(args[0]);
//Customer customer = new Customer() { Name = "aaaa" };
Execute(customer).Wait();
Console.WriteLine(customer.Name);
Console.ReadLine();
}
static async Task Execute(Customer customer)
{
var client = new SendGridClient("apikey");
var from = new EmailAddress("sendgird#xxxxxx.com", "Example User");
var subject = "Sending with SendGrid is Fun";
var to = new EmailAddress("sendgird#xxxxxxx.com", "Example User");
var plainTextContent = $"Name : {customer.Name}";
var htmlContent = "<strong>and easy to do anywhere, even with C#</strong>";
var msg = MailHelper.CreateSingleEmail(from, to, subject, plainTextContent, htmlContent);
var response = await client.SendEmailAsync(msg);
}
}
public class Customer
{
public string Name { get; set; }
}
However I do not get any email
I suggest you could firstly access this url to check the sendgird has already send the email to right email address.
The result is like this:

How to get back to app after google login

I'm trying to implement google login in my app using xamarin.auth like below
var auth = new OAuth2Authenticator("284202576320-7kgdhaa5sgvkoe03jmmcv0p8lfdma306.apps.googleusercontent.com","cAZW7uegD-h2-
tNMMf5q1UGQ","https://www.googleapis.com/auth/userinfo.email",new
Uri("https://accounts.google.com/o/oauth2/auth"),new
Uri("http://dev.myfav.restaurant/Account/LoginComplete"),new
Uri("https://accounts.google.com/o/oauth2/token"),null,true)
{
AllowCancel = true,
};
but Completed event not firing and its going to web page after login :(
I'm getting below error
i need to get back user to my app how can i achieve this ???? Can anyone help me on this please.
Thanks in advance
Hey follow these two examples one is using web view and one is using google sign in sdk for google auth.
https://timothelariviere.com/2017/09/01/authenticate-users-through-google-with-xamarin-auth/
and
https://developer.xamarin.com/samples/xamarin-forms/WebServices/OAuthNativeFlow/
So according to this issue reported by Mounika.Kola .I think u should refer that authenticator.Completed -= OnAuthCompleted is there in ur code. For reference just see these codes which i used for google authorization in Xamarin Forms.
void OnLoginClicked(object sender, EventArgs e)
{
string clientId = null;
string redirectUri = null;
switch (Device.RuntimePlatform)
{
case Device.iOS:
clientId = Constants.iOSClientId;
redirectUri = Constants.iOSRedirectUrl;
break;
case Device.Android:
clientId = Constants.AndroidClientId;
redirectUri = Constants.AndroidRedirectUrl;
break;
}
var authenticator = new OAuth2Authenticator(
clientId,
null,
Constants.Scope,
new Uri(Constants.AuthorizeUrl),
new Uri(redirectUri),
new Uri(Constants.AccessTokenUrl),
null,
true);
authenticator.Completed += OnAuthCompleted;
authenticator.Error += OnAuthError;
AuthenticationState.Authenticator = authenticator;
var presenter = new Xamarin.Auth.Presenters.OAuthLoginPresenter();
presenter.Login(authenticator);
}
async void OnAuthCompleted(object sender, AuthenticatorCompletedEventArgs e)
{
var authenticator = sender as OAuth2Authenticator;
if (authenticator != null)
{
authenticator.Completed -= OnAuthCompleted;
authenticator.Error -= OnAuthError;
}
User user = null;
if (e.IsAuthenticated)
{
// If the user is authenticated, request their basic user data from Google
// UserInfoUrl = https://www.googleapis.com/oauth2/v2/userinfo
var request = new OAuth2Request("GET", new Uri(Constants.UserInfoUrl), null, e.Account);
var response = await request.GetResponseAsync();
if (response != null)
{
// Deserialize the data and store it in the account store
// The users email address will be used to identify data in SimpleDB
string userJson = await response.GetResponseTextAsync();
user = JsonConvert.DeserializeObject<User>(userJson);
}
if (account != null)
{
store.Delete(account, Constants.AppName);
}
await store.SaveAsync(account = e.Account, Constants.AppName);
await DisplayAlert("Email address", user.Email, "OK");
}
}
I hope it helps you.
In iOS once you have completed the authentication with Xamarin.Auth you just need to dismiss the viewController and you will be put back in your app.
You do this subscribing to the Completed event of the OAuth2Authenticator
auth.Completed += (sender, e) =>
{
DismissViewController(true, null);
};
If the "Native UI" is used (the last parameter in the constructor is set to true), which means that external/system browser is used for login not WebView. So, on Android instead of WebView [Chrome] CustomTabs is used and on iOS instead of UIWebView (or WKWebView) SFSafariViewController is used.
With native UI user is leaving your app and the only way to return to your app is app-linking (or deep-linking) and this requires completely different approach.
1st you cannot use http[s] scheme for redirect_url (OK on Android it is possible, but on iOS not). Use custom scheme for that.
See the sample[s] (Xamarin.Forms ComicBook):
https://github.com/moljac/Xamarin.Auth.Samples.NugetReferences
And the docs in the repo:
https://github.com/xamarin/Xamarin.Auth/tree/master/docs

Azure log showing: "The supplied notification payload is invalid" for official Xamarin.Android sample

So I tried running this Push notification sample for Xamarin.Android http://azure.microsoft.com/en-us/documentation/articles/partner-xamarin-mobile-services-android-get-started-push/ and after following instructions from the docs - I got it up and running. The insertion of items work absolutely fine however push notification refuses to work.
This is the error I get on Azure for push: Error: 400 - The supplied notification payload is invalid.
Anyone else tried running this sample on their device and tried push notifications? The error isn't doing much to help my case.
The sample is using PushSharp.
I'd appreciate any help. Thanks a bunch!
This is how I send push notification to Google Cloud Messaging from the back-end server.
public async Task<bool> SendNotification(int id, int index, string from, string text, string tag)
{
try
{
var payload = new
{
data = new
{
message = new
{
// this part can be anything you want
id,
index,
from,
text,
when = DateTime.UtcNow.ToString("s") + "Z"
}
}
};
var json = JsonConvert.SerializeObject(payload);
await _hubClient.SendGcmNativeNotificationAsync(json, tag);
return true;
}
catch (ArgumentException ex)
{
// This is expected when an APNS registration doesn't exist.
return false;
}
Then in your app Intent Service, you can parse the JSON "message":
protected override void OnMessage(Context context, Intent intent)
{
var message = intent.Extras.GetString("message");
// message is JSON payload
// { "id":"someid", "index":"1", "text":"some text","from"... }
var json = JObject.Parse(message);
var id = json["id"].ToString();
var index = json["index"].ToString();
var text = json["text"].ToString();
var from = json["from"].ToString();
var when = DateTime.Parse(json["when"].ToString());
// do whatever you want with your values here
}

Resources