Emails with event invite generated by MVC application not synced with calendar in outlook.com - asp.net-mvc-5

I am creating ASP.NET MVC5 application. One functionality is to send emails with event invitations. In Gmail client such generated email works fine. But in outlook.com even if the email has correct buttons - accept/tentative/decline - clicking on them won't sync that into the calendar itself.
I took some inspiration here:
StackOverflow Q1
StackOverflow Q2
StackOverflow Q3
Here is my current implementation:
I am using DDay.ical library for creating the event:
IICalendar iCal = new iCalendar();
iCal.Version = "2.0";
iCal.Method = "REQUEST";
iCal.ProductID = "my#product.com";
Event evt = iCal.Create<Event>();
evt.UID = Guid.NewGuid().ToString();
evt.Class = "PUBLIC";
evt.Created = new iCalDateTime(DateTime.Now);
evt.DTStamp = new iCalDateTime(DateTime.Now);
evt.Start = new iCalDateTime(DateTime.Now.AddHours(2));
evt.End = new iCalDateTime(DateTime.Now.AddHours(4));
evt.Location = "Party room";
evt.Description = "Awesome party";
evt.Summary = "Lets get wasted";
evt.Priority = 5;
evt.Transparency = TransparencyType.Transparent;
string res = new iCalendarSerializer().SerializeToString(iCal);
return res;
I am packing this event into email as an alternative view:
MailMessage email = new MailMessage();
email.To.Add(addressesToJoined);
email.Subject = Party;
email.Body = "";
if (!String.IsNullOrEmpty(calendarEvent))
{
System.Net.Mime.ContentType calendarType = new System.Net.Mime.ContentType("text/calendar");
calendarType.Parameters.Add("method", "REQUEST");
AlternateView ICSview = AlternateView.CreateAlternateViewFromString(calendarEvent, calendarType);
email.AlternateViews.Add(ICSview);
}
And here is the .ics itself:
BEGIN:VCALENDAR
VERSION:2.0
METHOD:REQUEST
PRODID:my#product.com
BEGIN:VEVENT
CLASS:PUBLIC
CREATED:20151115T152442
DESCRIPTION:Awesome party
DTEND:20151115T192442
DTSTAMP:20151115T142442Z
DTSTART:20151115T172442
LOCATION:Party room
PRIORITY:5
SEQUENCE:0
SUMMARY:Lets get wasted
TRANSP:Transparent
UID:1735cdca-cb36-4e6b-a1ec-4fb4149f798a
END:VEVENT
END:VCALENDAR
When this email comes to Gmail client, I can correctly see the invitation with option to add event into calendar, which works fine.
But in outlook.com even when the email itself is correctly recognized as invitation and I can see accept/tentative/decline buttons it does not work as expected. When I click for example accept option, new response email is created and when I send it out, I would expect, the event will be set in my calendar, however there is no event synced.
Can someone please see why events are not synced in calendar in outlook.com?
Also, is there possibility in outlook.com to just set event in calendar, without sending response email? - invitations are auto-generated from system no need for response.
Thanks

Finally I've found a solution - there was missing ORGANIZER parameter of the VEVENT part in .ics. Gmail is able to handle that, Outlook.com not. So the trick was to add following line when setting DDay.iCal.Event object:
evt.Organizer = new Organizer("organizer#mail.com");
Everything else remained untouched so the final look of the .ics which works in both - Gmail and Outlook.com is this:
BEGIN:VCALENDAR
VERSION:2.0
METHOD:REQUEST
PRODID:my#product.com
BEGIN:VEVENT
CLASS:PUBLIC
CREATED:20151115T152442
DESCRIPTION:Awesome party
DTEND:20151115T192442
DTSTAMP:20151115T142442Z
DTSTART:20151115T172442
LOCATION:Party room
ORGANIZER:mailto:organizer#email.com
PRIORITY:5
SEQUENCE:0
SUMMARY:Lets get wasted
TRANSP:Transparent
UID:1735cdca-cb36-4e6b-a1ec-4fb4149f798a
END:VEVENT
END:VCALENDAR
Now it works fine.

Related

Unable to obtain embedded recipient view from DocuSign

I have integrated DocuSign embedded signing into my web app, which is still in development so using DocuSign developer sandbox.
When an envelope is created programmatically, I am including Name, Email and ClientUserId for the signer like this:
var signers = new List<TemplateRole>();
foreach (var r in req.Recipients)
{
var signer = new TemplateRole();
signer.ClientUserId = r.SSOUserId;
signer.Email = r.Email;
signer.Name = r.Name;
signer.RoleName = r.RoleName;
signer.RoutingOrder = r.RoutingOrder.ToString();
signer.Tabs = r.MergeFields
signers.Add(signer);
}
var env = new EnvelopeDefinition()
{
TemplateId = ...,
TemplateRoles = new List<TemplateRole>(signers),
EventNotification = ...,
Status = "Sent"
};
When an embedded recipient view is requested, I include the same exact Name, Email and ClientUserId in the request like this:
var envelopeApi = new EnvelopesApi(ApiClient);
var viewOptions = new RecipientViewRequest
{
ReturnUrl = ...,
AuthenticationMethod = "Password",
ClientUserId = recipient.SSOUserId,
UserName = recipient.Name,
Email = recipient.Email
};
var viewUrl = envelopeApi.CreateRecipientView(AccountId, DocuSignEnvelopeId, viewOptions);
Even though the user may change their Name and/or Email in my app, I have the original values saved in a table and I use those original values when requesting the view from DocuSign. This setup has worked 100% of the time for many months until now when an envelope is having trouble obtaining a recipient view. The envelope was created + viewed last week (April 27, 2022), and when the user tried to sign it today (May 4, 2022), they keep getting this error:
DocuSign.eSign.Client.ApiException: Error calling CreateRecipientView: {
"errorCode":"UNKNOWN_ENVELOPE_RECIPIENT",
"message":"The recipient you have identified is not a valid recipient of the specified envelope."
}
Note that hundreds of envelopes created before and after the above envelope are still able to obtain a recipient view with the exact same code + configuration. The problematic envelope has not expired, I can still see it in the Waiting for Others section of the DocuSign admin site. I have compared its recipient info at DocuSign (by invoking ListRecipients) with the info I have in my database, and the Name, Email, ClientUserId, RoleName, RoutingOrder all match completely. My account is set up to expire envelopes after 120 days, and I am not doing anything during envelope creation to set an expiration date. I have seen many others having this issue but typically their problem is the ClientUserId. My code has that handled, and it works for every other envelope.
The only difference I have seen between this envelope and the others is that ListRecipients results show the affected envelope as having a property
"signatureInfo": {
"fontStyle": "docusign7",
"signatureInitials": "RW",
"signatureName": "Test"
}
that is null for all other envelopes. The documentation states that this property can be set by the sender to pre-fill signature fields. However, I didn't even know about this property before today, so my app has never set it. It would be weird for this property to cause the envelope to be in a state where it cannot be signed anymore but I am struggling to find a reason why this particular envelope cannot be signed. Btw, the signatureName of Test actually matches the Name property of the recipient so its even more confusing why DocuSign is refusing to recognize the signer.
If the envelope is still active, I suggest doing a Recipients:list operation. Also check that the recipient is a "current" recipient. (If there's only one recipient, then this doesn't apply.)
If the Recipients:list doesn't give you any clues then I suggest you contact developer support. They can check our backend logs to see if there's additional information on why the RecipientsView call didn't work.
See page https://support.docusign.com/s/contactSupport?language=en_US First login to that page if you have a production account. You can get support if you only have a developer account.

IBM Domino - meeting document reschedule (in db) chair receives email but doesn't update

I'm running a java XPage rest api that operates on the rooms & resource reservation database. It's executed by a single designated user which has full access to the database.
What I want to do, is to re-schedule someone's else meeting directly via the database. It works when I view it in the database, the meeting is updated successfully, however in the chair's notes client calendar, the meeting still appears as it was, despite receiving an "Accepted: " e-mail with new meeting date (I think it should be "Rescheduled:" though..)
Here's my code that creates a response document & sends it:
DateTime dt_startDateUTC = session.createDateTime(dtStart);
DateTime dt_endDateUTC = session.createDateTime(dtEnd);
Document docNew = reDatabase.createDocument(); // response doc
docAppointment.copyAllItems(docNew, true); // copy items from origianl doc
docNew.replaceItemValue("NoticeType", "U"); // update notice
docNew.replaceItemValue("CalendarDateTime", dt_startDateUTC);
docNew.replaceItemValue("SequenceNum", docAppointment.getItemValueInteger("SequenceNum") + 1); // bump SequenceNum
docNew.replaceItemValue("RmNameUpdated", "");
docNew.replaceItemValue("ResNameUpdated", "");
docNew.replaceItemValue("$RnRVersion", "2");
docNew.replaceItemValue("$CSVersion", "2");
docNew.replaceItemValue("Form", "Notice");
docNew.replaceItemValue("$NoPurge", dt_endDateUTC.getLocalTime());
docNew.replaceItemValue("StartDateTime", dt_startDateUTC);
docNew.replaceItemValue("StartDate", dt_startDateUTC);
docNew.replaceItemValue("StartTime", dt_startDateUTC);
docNew.replaceItemValue("RepeatInstanceDates", dt_startDateUTC);
docNew.replaceItemValue("EndDateTime", dt_endDateUTC);
docNew.replaceItemValue("EndDate", dt_endDateUTC);
docNew.replaceItemValue("EndTime", dt_endDateUTC);
docNew.removeItem("ReserveDate");
docNew.removeItem("step");
docNew.removeItem("$BusyPriority");
docNew.removeItem("$BusyName");
docNew.replaceItemValue("wgcIGNORE", "1");
docNew.replaceItemValue("$CSFlags", "w"); // taken from c&s workflow schema
docNew.replaceItemValue("Form", "Notice");
docNew.replaceItemValue("_ViewIcon", "33");
docNew.makeResponse(docAppointment);
docNew.send();
docNew.save();
docNew.recycle();
In my server log I see:
Router: Message 00325BD6, 0027FEE7 delivered to Room 1/Organization
Router: Message 00325C92 delivered to testuser/Organization
In my user's notes client I can see a new received mail from Room 1 titled "Accepted: Meeting subject" and when I enter it, the dates are correct (rescheduled), but when I click "Open meeting" the meeting still has old dates.
Am I doing something wrong? How can I enforce an update of that meeting? I already tried many different ways but without luck. I cannot modify user's calendar directly because I'd need to assign access to every user's mail database and that wouldn't be secure.

nlapiSendEmail returns SSS_AUTHOR_MUST_BE_EMPLOYEE from correct employee id (on Sandbox)

in a Sandbox environment nlapiSendEmail (defined inside a suitelet) returns SSS_AUTHOR_MUST_BE_EMPLOYEE even when the sender id is correct
My distribution is Kilimanjaro, with SuiteScript 1.0. I have an administrator role, when calling nlapiSenEmail() directly from the backend model with my employee id, the email was sent to my employee profile, but not to the specified email, which is really a company distribution list. Even when I did not specify the logged customer email, a copy was sent to the logged customer email, a gmail account. The backend model operates only for the MyAccount application. It's worth noting that in this scenario nlapiSendEmail() return value was undefined. In my experience, Netsuite is really ambiguous in its behavior returning values or just functioning in an expected way, due to the "execution context". So, with the same data I put my call inside a suitelet, and now I am having the return SSS_AUTHOR_MUST_BE_EMPLOYEE.
function sendEmailWithAPI(request, response)
{
var senderId = request.getParameter('senderId');
var to = request.getParameter('emailTo');
var subject = request.getParameter('subject');
var body = request.getParameter('body');
var cc = request.getParameter('emailCC');
var result = {success:false, errorInfo:''};
try
{
var sendingResult = nlapiSendEmail(senderId, to, subject, body, cc);
result.success = true;
}
catch (errorOnMailSending)
{
result.returnValue = sendingResult;
result.errorInfo = errorOnMailSending.details;
}
response.write(JSON.stringify(result));
}
What is the record type of the senderId? NetSuite only accepts Employee records as sender of script generated emails. Also in Sandbox accounts, the emails are re-routed to the logged in user, specific list, or not at all. This is actually based on the Company preference in your Sandbox account. The reason for this is Sandbox is usually used for testing and you don't want to send test emails to actual customers.
In the end the "problem" was that I was just working in the Sandbox, as I prepared a snippet to test email sending in production everything went right. In the sandbox you can still send emails specifying a list at the subtab "Email options"
with the option "SEND EMAIL TO (SEPARATE ADDRESSES WITH COMMAS)"
this is located at Setup > Company > Email Preferences.

How to send document to client's more than one personal email ids to sign it using DocuSignAPI .NET Client?

I've setup a developer sandbox environment of DocuSign. Using its C#.NET API Client, I want to send a document for signing to client's more than one personal email ids. Once the client opens any email to see and sign it, the corresponding DocuSign envelope state should get updated to Completed.
Also, I tried to achieve the above behavior through multiple signer recipients, but the envelope state gets marked completed, when all the signer recipients sign the document. Here I want any signer recipient sign should be enough to complete the document signing workflow.
Please suggest how to get it done
Regards,
A
In order to deliver an envelope to several emails in a single role, you'll need to create a Signing Group. Signing Groups can be created and managed through the API, so you'll be able to do that programatically.
While you'll need to implement your own business logic and error checking, a sample of creating a Signing Group in c# looks like:
SigningGroup signingGroup = new SigningGroup();
signingGroup.GroupName = "SigningGroup_" + DateTime.UtcNow.Ticks.ToString();
signingGroup.GroupType = "sharedSigningGroup";
signingGroup.Users = new List<SigningGroupUser>();
SigningGroupUser signingGroupUser1 = new SigningGroupUser();
signingGroupUser1.UserName = "Example Signer";
signingGroupUser1.Email = "signer#example.com";
signingGroup.Users.Add(signingGroupUser1);
SigningGroupUser signingGroupUser2 = new SigningGroupUser();
signingGroupUser2.UserName = "Example Signer";
signingGroupUser2.Email = "personal.email#example.com";
signingGroup.Users.Add(signingGroupUser2);
SigningGroupInformation signingGroupInformation = new SigningGroupInformation();
signingGroupInformation.Groups = new List<SigningGroup> { signingGroup };
SigningGroupsApi signingGroupsApi = new SigningGroupsApi(apiClient.Configuration);
SigningGroupInformation newGroupInfo = signingGroupsApi.CreateList(accountId, signingGroupInformation);
string newGroupId = newGroupInfo.Groups[0].SigningGroupId;
To use the Signing Group in an envelope, define a signer with that group ID:
Signer signer = new Signer
{
SigningGroupId = newGroupId,
RecipientId = "1",
RoutingOrder = "1"
};
Once the envelope is created as a draft, you can then clean up the signing group:
signingGroupsApi.DeleteList(accountId, newGroupInfo);

Docusign Embedded Signing "User_Lacks_Permissions"

I am using the code from the Code Recipes for Embedded signing but converted from C# to VB.NET, the code uses the Docusign API Nuget.
The CreateEnvelope returns a USER_LACKS_PERMISSIONS.
I have gone through my permissions and checked everything. The user I am logging in with is an Account Administrator and seems to have all permissions checked.
I am setting the Recipient Email to the actual recipient email (different from my administrator account) even though it's embedded signing, I don't know if that is the problem. I do want the actual signer to get a copy of the signed document which is why I am using the recipient email as the RecipientEmail.
Below is the code that causes the error:
Dim accountId As String
accountId = loginApi()
Dim envDef As New DocuSign.eSign.Model.EnvelopeDefinition()
envDef.EmailSubject = "TEST - Please sign this doc"
' Add a document to the envelope
Dim doc As New DocuSign.eSign.Model.Document()
doc.DocumentBase64 = System.Convert.ToBase64String(DocumentBytes)
doc.Name = "TestFile.pdf"
doc.DocumentId = "1"
envDef.Documents = New List(Of DocuSign.eSign.Model.Document)()
envDef.Documents.Add(doc)
' Add a recipient to sign the documeent
Dim signer As New DocuSign.eSign.Model.Signer()
signer.Email = recipientEmail
signer.Name = recipientName
signer.RecipientId = "1"
signer.ClientUserId = "1234"
' must set |clientUserId| to embed the recipient!
' Create a |SignHere| tab somewhere on the document for the recipient to sign
signer.Tabs = New DocuSign.eSign.Model.Tabs()
signer.Tabs.SignHereTabs = New List(Of DocuSign.eSign.Model.SignHere)()
Dim signHere As New DocuSign.eSign.Model.SignHere()
signHere.DocumentId = "1"
signHere.PageNumber = "1"
signHere.RecipientId = "1"
signHere.XPosition = "100"
signHere.YPosition = "100"
signer.Tabs.SignHereTabs.Add(signHere)
envDef.Recipients = New DocuSign.eSign.Model.Recipients()
envDef.Recipients.Signers = New List(Of DocuSign.eSign.Model.Signer)()
envDef.Recipients.Signers.Add(signer)
' set envelope status to "sent" to immediately send the signature request
envDef.Status = "sent"
' |EnvelopesApi| contains methods related to creating and sending Envelopes (aka signature requests)
Dim envelopesApi As New DocuSign.eSign.Api.EnvelopesApi()
Dim envelopeSummary As DocuSign.eSign.Model.EnvelopeSummary = envelopesApi.CreateEnvelope(accountId, envDef)
These are the permissions:
The first issue when diagnosing a problem like this is to figure out if it is a credentials (permissions) problem or something else.
There's an easy test for to see if the user name is set up right:
Run the Recipe tester. You can quickly run it for free on Heroku. See the "Deploy on Heroku" button. Choose the Embedded Signing recipe. If it works with your user demo sandbox email/password then you know that the problem lies somewhere in your code.
You can use the tool to authenticate using either OAuth or DocuSign Legacy authentication (Service Integration authentication.)
Next, use the tester's API log feature to see the API calls of your VB program. Compare the DocuSign API requests that your program is making vs the requests from the Recipe tester.
The heroku app used a post that goes to:
https://demo.docusign.net:7802/restapi/v2/accounts/13193/envelopes
Whereas my visual studio app uses the production url:
https://www.docusign.net/restapi
All this time I was checking the permissions of the user in demo.docusign.net
But it turns out ANOTHER USER WITH THE SAME EMAIL and password existed in production (www.docusign.net)
The production account did not have the correct permissions.
The fact that the DocuSign app showed me the "Select User" page first, showing two identical entries was the clue that TWO ACCOUNTS EXIST: one in production and one in demo.
It would be nice if in the "Select User" page, DocuSign listed the BASE URL as well, or a column showing Production or Demo.

Resources