Invalid recipient from docusign API - c#

I'm trying to embed a docusign signature page into a website. but I get this error
Message=Error calling CreateRecipientView: {
"errorCode": "UNKNOWN_ENVELOPE_RECIPIENT",
"message": "The recipient you have identified is not a valid recipient of
the specified envelope."
}
I'm using the .Net nuget client and here's the code I'm using (note I've changed guids and emails)
Authenticate
string userId = "0570b3da-652e-4040-842e-65a0e6fc8133"; // use your userId (guid), not email address
string integratorKey = "cf73e7bb-e05d-4ce9-9cea-ac065dc894ac";
string host = "https://demo.docusign.net/restapi";
ApiClient apiClient = new ApiClient(host);
string username = "my#email.com";
string password = "[password]";
// initialize client for desired environment (for production change to www)
Configuration.Default.ApiClient = apiClient;
// configure 'X-DocuSign-Authentication' header
string authHeader = "{\"Username\":\"" + username + "\", \"Password\":\"" + password + "\", \"IntegratorKey\":\"" + integratorKey + "\"}";
Configuration.Default.AddDefaultHeader("X-DocuSign-Authentication", authHeader);
Find account id
this was part of the example code
// we will retrieve this from the login API call
string accountId = null;
AuthenticationApi authApi = new AuthenticationApi(apiClient.Configuration);
LoginInformation loginInfo = authApi.Login();
//find the default account for this user
foreach (LoginAccount loginAcct in loginInfo.LoginAccounts)
{
if (loginAcct.IsDefault == "true")
{
accountId = loginAcct.AccountId;
string[] separatingStrings = { "/v2" };
// Update ApiClient with the new base url from login call
apiClient = new ApiClient(loginAcct.BaseUrl.Split(separatingStrings, StringSplitOptions.RemoveEmptyEntries)[0]);
break;
}
}
Create Envelope from a template
EnvelopeDefinition envDef = new EnvelopeDefinition();
TemplateRole tRole = new TemplateRole();
tRole.Email = "recipient#email.com";
tRole.RoleName = "Leaseholder";
tRole.ClientUserId = tRole.Email;
List<TemplateRole> rolesList = new List<TemplateRole> { tRole };
envDef.TemplateRoles = rolesList;
envDef.TemplateId = "2504e3f0-f4d9-4eca-9fd3-3b26cfd6c086";
RecipientViewRequest viewOptions = new RecipientViewRequest()
{
ReturnUrl = "http://localhost:64202/home/winning",
ClientUserId = tRole.Email, // must match clientUserId of the embedded recipient
AuthenticationMethod = "email",
UserName = tRole.Email,
Email = tRole.Email
};
EnvelopesApi envelopesApi = new EnvelopesApi();
var summary = envelopesApi.CreateEnvelope(accountId, envDef);
var receipients = envelopesApi.ListRecipients(accountId, summary.EnvelopeId);
ViewUrl viewUrl = envelopesApi.CreateRecipientView(accountId, summary.EnvelopeId, viewOptions);
return Content($"<h2>hmm</h2><iframe width=\"100%\" height=\"100%\" src=\"{viewUrl.Url}\"/>");
Recipients on the template
Recipients
{
"agents": [],
"carbonCopies": [],
"certifiedDeliveries": [],
"editors": [],
"inPersonSigners": [],
"intermediaries": [],
"recipientCount": "1",
"seals": [],
"signers": [
{
"clientUserId": "recipient#email.com",
"creationReason": "sender",
"deliveryMethod": "email",
"email": "recipient#email.com",
"isBulkRecipient": "false",
"name": "",
"note": "",
"recipientId": "1",
"recipientIdGuid": "52abdeea-2bd6-4108-97b9-170ca27d573a",
"requireIdLookup": "false",
"roleName": "Leaseholder",
"routingOrder": "1",
"status": "created",
"userId": "0570b3da-652e-4040-842e-65a0e6fc8133"
}
]
}

The UNKNOWN_ENVELOPE_RECIPIENT error usually means that one of the following three property values specified for the Recipient within the Envelope doesn't exactly match the corresponding value that's been specified in the Get Recipient View request:
Name
Email
ClientUserId
In your case (based upon the code you posted), I suspect that the UNKNOWN_ENVELOPE_RECIPIENT error is being caused by the fact that the info you've specified for the recipient does not include a value for the Name property -- where as the info you've specified when creating the RecipientViewRequest object does include a value for the UserName property (as it must).
To fix this error, I'd suggest that you try adding this line to the portion of your code when you're specifying information for the TemplateRole object (where "RECIPIENT_NAME" is the first and last name of the recipient).
tRole.Name = "RECIPIENT_NAME;
And then specify the same value for the UserName property of the RecipientViewRequest object:
UserName = "RECIPIENT_NAME",
(The value you specify as RECIPIENT_NAME will be the name that the recipient signs in the doc(s), so you should specify first name / last name of the person, not an email address.)
UPDATE
Re the subsequent RECIPIENT_NOT_IN_SEQUENCE error that you've mentioned in your comment, this error occurs when you call Get Recipient View for a recipient either before the Envelope has been sent or before it's "their turn" in the routing order to receive the Envelope. In your case, I suspect this is occurring because you're not setting the status of the Envelope to sent -- the recipient can't receive/access the Envelope until it's been sent. To resolve this error, set the status of of the Envelope when you're composing the EnvelopeDefinition object:
envDef.Status = "sent";

Related

AD B2C Keep Password from Expiring on New User

We're trying to create a user in Azure AD B2C (cloud tenant, not local) via the C# library. I cannot log in with the new user; it's saying the password has expired. From the AD B2C Sign-in log:
However, I'm creating them with password expiration disabled like so:
PasswordProfile passwordProfile = GetPasswordProfile(password);
var newB2cUser = new User
{
Id = id,
MailNickname = id,
UserPrincipalName = $"{id}#{tenant}",
GivenName = claims.FirstName,
Surname = claims.LastName,
DisplayName = displayName,
AccountEnabled = true,
PasswordProfile = passwordProfile,
PasswordPolicies = "DisablePasswordExpiration,DisableStrongPassword",
Identities = new List<ObjectIdentity>
{
new ObjectIdentity
{
SignInType = "emailAddress",
IssuerAssignedId = claims.Email,
Issuer = tenant
}
}
};
User createdB2cUser = await this.GraphServiceClient.Users.Request().AddAsync(newB2cUser);
...and with the password profile created like this:
private static PasswordProfile GetPasswordProfile(string password)
{
var passwordProfile = new PasswordProfile
{
Password = password,
ForceChangePasswordNextSignIn = false,
ForceChangePasswordNextSignInWithMfa = false
};
return passwordProfile;
}
We've used code like the above to create users all the time that need to reset their password on login. Now we need to create a user with a preset password that won't immediately expire (e.g., seeding a test environment). I added what I thought were the correct password policies and password profile above. What's going on?
I can see nothing wrong with the code sample you provided. But did you try achieving the same goal using Graph API directly? Just to understand what is going on and where the fault may be. You can use GraphExplorer: https://developer.microsoft.com/en-us/graph/graph-explorer
Invoke a POST request to the https://graph.microsoft.com/v1.0/users endpoint with the similar JSON to see whether you face the same issue.
{
"id": "fcaba916-17b0-4d88-84ea-03371d55067a",
"mailNickname": "MelissaD",
"userPrincipalName": "MelissaD#contoso.onmicrosoft.com",
"givenName": "Melissa",
"surname": "Darrow",
"displayName": "Melissa Darrow",
"accountEnabled": true,
"passwordPolicies": "DisablePasswordExpiration,DisableStrongPassword",
"passwordProfile": {
"password": "da413e48-180d-1945-6025-d7e5947711ed",
"forceChangePasswordNextSignIn": false,
"forceChangePasswordNextSignInWithMfa": false
},
"identities": [
{
"signInType": "emailAddress",
"issuer": "yourissuer",
"issuerAssignedId": "email"
}
]
}
Try to simulate the request body exactly as Graph Client does to know what is going on behind the scenes.

Microsoft Graph API inaccurate error message

I'm trying to add users in an Azure AD B2C using the Microsoft Graph API. My code works just fine when I add a User, but I tried to add it a second time with the same info given to the API (mail, names, etc...) and expected an error like
User already exists
or something similar.
My API call is done like this :
var result = await graphClient.Users.Request().AddAsync(new User()
{
AccountEnabled = true,
Mail = "example#example.onmicrosoft.com",
MailNickname = "example",
UserPrincipalName = "example#example.onmicrosoft.com",
Surname = "TEST",
DisplayName = "test",
GivenName = "TEST test",
PasswordProfile = new PasswordProfile
{
ForceChangePasswordNextSignIn = true,
Password = "tmpPwd"
}
});
Keeping in mind that my first call correctly add the user to the AD, why the API would return me this message :
Microsoft.Graph.ServiceException : 'Code: Request_BadRequest
Message: One or more properties contains invalid values.
Thank you in advance.
According to the document Create the user using the below property without mail .so that when a user has already existed then you will get the error as below
Code: Request_BadRequest
Message: Another object with the same value for property userPrincipalName already exists.
code:
var result = await graphClient.Users.Request().AddAsync(new User()
{
AccountEnabled = true,
MailNickname = "example",
UserPrincipalName = "example665#XX.live",
Surname = "TEST",
DisplayName = "test",
GivenName = "TEST test",
PasswordProfile = new PasswordProfile
{
ForceChangePasswordNextSignIn = true,
Password = "password#1234"
}
});
Console.WriteLine(JsonConvert.SerializeObject(result));
}
Using additional property may change the error context as you are receiving currently

Add MS Teams website tab using graph API error

Context:
I am trying to add a new website tab to an existing channel in MS Teams and then get the id of newly-created tab.
Problem:
I am able to create new tab but I am getting a "BadRequest" exception from the Graph:
Message: Value cannot be null. Parameter name: entity
The interesting part is that the tab is created and visible in MS Teams in the correct team and channel but I cannot get it's id in any way.
My code:
var tab = await _graphClient.Teams[teamId].Channels[channelId].Tabs.Request().WithMaxRetry(3).AddAsync(
new TeamsTab
{
DisplayName = "New Tab",
AdditionalData = new Dictionary<string, object>
{
["teamsApp#odata.bind"] =
$"{_teamsFactory.GraphV1Endpoint}/appCatalogs/teamsApps/com.microsoft.teamspace.tab.web"
},
Configuration = new TeamsTabConfiguration
{
EntityId = null,
WebsiteUrl = $"{_appUrl}/1",
ContentUrl = $"{_appUrl}/1",
RemoveUrl = null,
}
}
);
Like I wrote above, this code works and the tab is created but GraphServiceClient throws an exception before the tab variable is assigned.
And when I tried to get the tab list in Graph Explorer
https://graph.microsoft.com/v1.0/teams/{teamid}/channels/{channelid}/tabs
I received an error response:
{
"error": {
"code": "InternalServerError",
"message": "Failed to execute request.",
"innerError": {
"request-id": "a03654e8-37a7-4fbb-8052-6a1b11721234",
"date": "2020-02-24T15:11:54"
}
}
}
I think you might need to set a value for "EntityId" - basically just a string value to uniquely "name" your tab. It's not the "DisplayName", more a string "id" for the tab.
POST https://graph.microsoft.com/v1.0/teams/{id}/channels/{id}/tabs
{
"displayName": "My Contoso Tab",
"teamsApp#odata.bind" : "https://graph.microsoft.com/v1.0/appCatalogs/teamsApps/06805b9e-77e3-4b93-ac81-525eb87513b8",
"configuration": {
"entityId": "2DCA2E6C7A10415CAF6B8AB6661B3154",
"contentUrl": "https://www.contoso.com/Orders/2DCA2E6C7A10415CAF6B8AB6661B3154/tabView",
"websiteUrl": "https://www.contoso.com/Orders/2DCA2E6C7A10415CAF6B8AB6661B3154",
"removeUrl": "https://www.contoso.com/Orders/2DCA2E6C7A10415CAF6B8AB6661B3154/uninstallTab"
}
}
Please take a look at Add Tab to a channel using Graph API
Edit 1: Could you please check you have appropriate permissions to add the Tab?
Edit2: Could you please try below piece of code?
GraphServiceClient graphClient = new GraphServiceClient( authProvider );
var teamsTab = new TeamsTab
{
DisplayName = "WebsiteTab",
AdditionalData = new Dictionary<string, object>()
{
{"teamsApp#odata.bind","https://graph.microsoft.com/v1.0/appCatalogs/teamsApps/com.microsoft.teamspace.tab.web"}
},
Configuration = new TeamsTabConfiguration
{
EntityId = null,
ContentUrl = "https://learn.microsoft.com/en-us/microsoftteams/platform/resources/bot-v3/bots-context",
RemoveUrl = null,
WebsiteUrl = "https://learn.microsoft.com/en-us/microsoftteams/platform/resources/bot-v3/bots-context"
}
};
await graphClient.Teams["TeamId"].Channels["ChannelId"].Tabs
.Request()
.AddAsync(teamsTab);
Finally I found the "solution" though a better name is a workaround for my issue. To make it work I had to set ODataType to null in TeamsTabConfiguration. That's all. The code should look like this:
var tab = await _graphClient.Teams[teamId].Channels[channelId].Tabs.Request().WithMaxRetry(3).AddAsync(
new TeamsTab
{
DisplayName = TabTitle,
ODataBind = $"{_teamsFactory.GraphV1Endpoint}/appCatalogs/teamsApps/com.microsoft.teamspace.tab.web",
Configuration = new TeamsTabConfiguration
{
ODataType = null,
EntityId = null,
WebsiteUrl = $"{_appUrl}/1",
ContentUrl = $"{_appUrl}/1",
RemoveUrl = null
}
});
Like I mentioned it is only a workaround. It is labeled as "service bug" on GitHub (issue#598)

Resend Docusign envelope using C#

I'm trying to use code I found here to resend an envelope, but no luck. My code is in two parts. Here's the code on my ASPX page to call a method to resend the envelope:
protected void btnResend_Click(object sender, EventArgs e)
{
Signer signer = new Signer();
signer.Email = txtRecipeintEmail.Text;
signer.Name = txtRecipientName.Text;
Manager mgr = new Manager();
mgr.ResendEnvelope(txtEnvelopeID.Text, signer);
}
Here's the code in the Manager class:
public void ResendEnvelope (string envelopeID, Signer signer)
{
// instantiation of recipients as per https://stackoverflow.com/questions/21565765/resend-docusign-emails
Recipients recipients = new Recipients
{
Signers = new List<Signer>()
{
new Signer
{
RecipientId = "1",
RoleName = "Prospect",
Email = signer.Email,
Name = signer.Name,
},
}
};
string accountID = GetAccountID();
EnvelopesApi api = new EnvelopesApi();
EnvelopesApi.UpdateRecipientsOptions options = new EnvelopesApi.UpdateRecipientsOptions();
options.resendEnvelope = "true";
RecipientsUpdateSummary summary = api.UpdateRecipients(accountID, envelopeID, recipients, options);
var responses = summary.RecipientUpdateResults.ToList<RecipientUpdateResponse>();
var errors = responses.Select(rs => rs.ErrorDetails).ToList();
}
My GetAccountID function works fine - I use it to send the envelope. The value in txtEnvelopeID.Text is set from the code used to send the initial email. I get the initial email.
Here's what I see in errors:
?errors[0].Message
"The specified envelope corrections have duplicate recipients."
?errors[0].ErrorCode
"CORRECTION_HAS_DUPLICATE_RECIPIENTS"
When I tried to set the third argument of UpdateRecipients to null, I got a different error. When I left recipients blank (api.UpdateRecipients(accountID, envelopeID, options: = options)), I got an error.
So, I'm out of new ideas to try. Can anyone help?
The issue you are encountering is that you are creating again a signer that already exists, except that you don't assign the same RecipientId, hence the duplicate error.
Instead of
RecipientId = "1"
You need to make sure you assign the original signer ID, see below :
Signers = new List<Signer>()
{
new Signer
{
RecipientId = signer.RecipientId
},
}
In order to re-send the DocuSign email to your recipients, you can use the UpdateRecipient() method as such (see my C# example below). This will re-trigger the signing email to be sent one more time to the transaction recipients you specify in the recipients parameter :
RecipientsUpdateSummary recipientsUpdateSummary =
envelopeApi.UpdateRecipients(
accountId,
EnvelopeId,
RecipientsToNotifyAgain,
new EnvelopesApi.UpdateRecipientsOptions { resendEnvelope = "true" });
Here is what the official documentation states :

Gmail api with .Net CLient library: Missing draft message [400]

I'm trying to create drafts in Gmail using the .Net Client Library. I can successfully login and retrieve a list of drafts so the authentication and api are working. Now I need to create an instance of the Draft class and send it to the API. But what does the draft message need to look like? It doesn't matter what I fill in the API explorer on https://developers.google.com/gmail/api/v1/reference/users/drafts/create, my draft is always empty.
Also when doing it from my C# code I need to set the draft.Message.Raw field to something else I get an error:
Missing draft message [400]
Using the client library you can set the base64 encoded email to the raw property of a Message then use that Message as the message property of the Draft.
More generally:
The Draft Message consists of an id and a Message Resource
https://developers.google.com/gmail/api/v1/reference/users/drafts
{
"id": string,
"message": users.messages Resource
}
The Message Resource should have its "raw" field set to a base64 encoded RCF 2822 formatted string.
Eg:
from: me#email.com
to: you#email.com
subject: test email
email body
As a base64 encoded string is:
ZnJvbTogbWVAZW1haWwuY29tDQp0bzogeW91QGVtYWlsLmNvbQ0Kc3ViamVjdDogdGVzdCBlbWFpbA0KDQplbWFpbCBib2R5
So the request body of a draft.create should look something like:
{
"message": {
"raw": "ZnJvbTogbWVAZW1haWwuY29tDQp0bzogeW91QGVtYWlsLmNvbQ0Kc3ViamVjdDogdGVzdCBlbWFpbA0KDQplbWFpbCBib2R5"
}
}
I was struggling with this until today.
What I did was adapting the solution on this link for drafts.
http://jason.pettys.name/2014/10/27/sending-email-with-the-gmail-api-in-net-c/
Jason uses a nuget called AE.Net.Mail to serialize an mail object to RFC 2822.
what I did was I installed both nugets
Install-Package Google.Apis.Gmail.v1
Install-Package AE.Net.Mail
And after that I created two methods
static GmailService Service;
public static void CriaService(string emailaConectar)
{
var certificate = new X509Certificate2(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ClientCredentials.CertificatePath), ClientCredentials.ClientSecret, X509KeyStorageFlags.Exportable);
var credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(ClientCredentials.ServiceAccountEmail)
{
Scopes = new[] { GmailService.Scope.GmailCompose },
User = emailaConectar
}.FromCertificate(certificate)) { };
Service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ClientCredentials.ApplicationName,
});
}
private static string Base64UrlEncode(string input)
{
var inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
// Special "url-safe" base64 encode.
return Convert.ToBase64String(inputBytes)
.Replace('+', '-')
.Replace('/', '_')
.Replace("=", "");
}
And on my Main method I designed like this
CriaService("xpto#gmail.com");
var msg = new AE.Net.Mail.MailMessage
{
Subject = "Your Subject",
Body = "Hello, World, from Gmail API!",
From = new MailAddress("xpto#gmail.com")
};
msg.To.Add(new MailAddress("someone#gmail.com"));
msg.ReplyTo.Add(msg.From);
var msgStr = new StringWriter();
msg.Save(msgStr);
Message m = new Message();
m.Raw = Base64UrlEncode(msgStr.ToString());
var draft = new Draft();
draft.Message = m;
try
{
Service.Users.Drafts.Create(draft, "xpto#opportunity.com.br").Execute();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
message > raw is expected to be the full SMTP message.
{
"message": {
"raw": "From: me#example.com\nTo:you#example.com\nSubject:Ignore\n\nTest message\n"
}
Alternatively, you can also set the appropriate fields in message > payload:
{
"message": {
"payload": {
"headers": {
{"name": "From", "value": "me#example.com},
{"name": "To", "value": "you#example.com"},
{"name": "Subject", "value":"Ignore"}
},
"body": {
"data": "Test message"
}
}
}
}

Categories

Resources