Please excuse me for asking what is probably an easy question. I am trying to use a Template that I created in my DocuSign account. I am using C# and using the Nuget package api. I am needing to get the template so that I can fill it out and send the envelope. I can send out an envelope just fine, I am now trying to just make it look better by using the template option.
As I stated above, I have the complete process working, I am just trying to use the Templates now rather than a document that I am building through HTML. I have looked all through the Nuget API and everything I see for getting Templates looks like it has to be from an existing document. All I am trying to do is get a list of templates, select the one that I want and then fill in the fields appropriately then send the document. Any help would be awesome!
See our example code here - https://github.com/docusign/eg-03-csharp-auth-code-grant-core/blob/master/eg-03-csharp-auth-code-grant-core/Controllers/Eg009UseTemplateController.cs
Let me copy/paste the relevant code into here:
string DoWork (string signerEmail, string signerName, string ccEmail,
string ccName, string accessToken, string basePath,
string accountId, string templateId)
{
// Data for this method
// signerEmail
// signerName
// ccEmail
// ccName
// accessToken
// basePath
// accountId
// templateId
var config = new Configuration(new ApiClient(basePath));
config.AddDefaultHeader("Authorization", "Bearer " + accessToken);
EnvelopesApi envelopesApi = new EnvelopesApi(config);
EnvelopeDefinition envelope = MakeEnvelope(signerEmail, signerName, ccEmail, ccName, templateId);
EnvelopeSummary result = envelopesApi.CreateEnvelope(accountId, envelope);
return result.EnvelopeId;
}
private EnvelopeDefinition MakeEnvelope(string signerEmail, string signerName,
string ccEmail, string ccName, string templateId)
{
// Data for this method
// signerEmail
// signerName
// ccEmail
// ccName
// templateId
EnvelopeDefinition env = new EnvelopeDefinition();
env.TemplateId = templateId;
TemplateRole signer1 = new TemplateRole();
signer1.Email = signerEmail;
signer1.Name = signerName;
signer1.RoleName = "signer";
TemplateRole cc1 = new TemplateRole();
cc1.Email = ccEmail;
cc1.Name = ccName;
cc1.RoleName = "cc";
env.TemplateRoles = new List<TemplateRole> { signer1, cc1 };
env.Status = "sent";
return env;
}
// ***DS.snippet.0.end
Related
Need to store the image from a private git repository to a blob using C#. Tried with below code but getting 404 errors.
I am using the below code from
C# example of downloading GitHub private repo programmatically
var githubToken = "[token]";
var url =
"https://github.com/[username]/[repository]/archive/[sha1|tag].zip";
var path = #"[local path]";
using (var client = new System.Net.Http.HttpClient())
{
var credentials = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}:", githubToken);
credentials = Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(credentials));
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", credentials);
var contents = client.GetByteArrayAsync(url).Result;
System.IO.File.WriteAllBytes(path, contents);
}
Note: Able to fetch from the public repository
How to fix :
The URL is changed to GET /repos/:owner/:repo/:archive_format/:ref. See https://developer.github.com/v3/repos/contents/#get-archive-link
For private repositories, these links are temporary and expire after five minutes.
GET /repos/:owner/:repo/:archive_format/:ref
You should not pass the credentials using basic authentication. Instead, you should create a token by following the official docs. see https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line
Finally, you need pass an extra User-Agent header. It is required by GitHub API. See https://developer.github.com/v3/#user-agent-required :
All API requests MUST include a valid User-Agent header.
Demo
public class GitHubRepoApi{
public string EndPoint {get;} = "https://api.github.com/repos";
public async Task DownloadArchieveAsync(string saveAs, string owner, string token, string repo,string #ref="master",string format="zipball")
{
var url = this.GetArchieveUrl(owner, repo, #ref, format);
var req = this.BuildRequestMessage(url,token);
using( var httpClient = new HttpClient()){
var resp = await httpClient.SendAsync(req);
if(resp.StatusCode != System.Net.HttpStatusCode.OK){
throw new Exception($"error happens when downloading the {req.RequestUri}, statusCode={resp.StatusCode}");
}
using(var fs = File.OpenWrite(saveAs) ){
await resp.Content.CopyToAsync(fs);
}
}
}
private string GetArchieveUrl(string owner, string repo, string #ref = "master", string format="zipball")
{
return $"{this.EndPoint}/{owner}/{repo}/{format}/{#ref}"; // See https://developer.github.com/v3/repos/contents/#get-archive-link
}
private HttpRequestMessage BuildRequestMessage(string url, string token)
{
var uriBuilder = new UriBuilder(url);
uriBuilder.Query = $"access_token={token}"; // See https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line
var req = new HttpRequestMessage();
req.RequestUri = uriBuilder.Uri;
req.Headers.Add("User-Agent","My C# Client"); // required, See https://developer.github.com/v3/#user-agent-required
return req;
}
}
Test :
var api = new GitHubRepoApi();
var saveAs= Path.Combine(Directory.GetCurrentDirectory(),"abc.zip");
var owner = "newbienewbie";
var token = "------your-----token--------";
var repo = "your-repo";
var #ref = "6883a92222759d574a724b5b8952bc475f580fe0"; // will be "master" by default
api.DownloadArchieveAsync(saveAs, owner,token,repo,#ref).Wait();
According to the message you provide, you use the wrong url to download. Regarding how to get the download url, please refer to the following steps:
Use the following url to get the download url
Method: GET
URL: https://api.github.com/repos/:owner/:repo/contents/:path?ref:<The name of the commit/branch/tag>
Header:
Authorization: token <personal access token>
The repose body will tell you the download url
For example :
Download file
For more details, please refer to https://developer.github.com/v3/repos/contents/#get-contents.
I'm working on an application that needs to send email notifications and reminders to users when they have actions to complete. A user submits data, then the app notifies other users to perform actions in a specific order (i.e. User 1: Task 1, after Task 1 is complete, User 2: Task 2, etc.) - if a user is taking too long to perform their action, the system will remind them then defer to their manager (via a Windows service or similar). Due to this, I can't send messages on behalf of the current signed in user - it needs to be able to send messages on its own. It is preferred to send on behalf of the user that submitted the data, so subsequent users can reply directly to them.
I'm using the Microsoft Graph Client Library v1.10.0. Running my code yields an aggregate exception ultimately boiling down to a code 400, code "generalException", message "Unexpected exception returned from the service." I've used LinqPad to look into the Graph objects, and attempted to reproduce the call in Postman, which yields a 400 with a message of "Open navigation properties are not supported on OpenTypes. Property name: 'microsoft.graph.sendmail'."
More thorough details:
Application has Microsoft Graph -> Send mail as any user, Read all groups, Read all users' full profiles permissions.
Calling GraphServiceClient.Client.Users["MyUPN"].SendMail(email, true).Request().PostAsync() yields a 400 general exception with Unexpected exception returned from the service. (Full code below)
Looking at the request, I found it's calling https://graph.windows.net:443/{{tenantId}}/users/{{MyUPN}}/microsoft.graph.sendMail?api-version=1.6 and attempted to make the same call via Postman (with a valid token), which yielded a 400 bad request with message Open navigation properties are not supported on OpenTypes. Property name: 'microsoft.graph.sendMail'.
Full Code:
String MyEmailAddress = "";
String MyUpn = "";
String TenantId = "";
String AppGuid = "";
String AppKey = "";
var sender = new Microsoft.Graph.Recipient()
{
EmailAddress = new Microsoft.Graph.EmailAddress() { Address = MyEmailAddress }
};
var email = new Microsoft.Graph.Message
{
Sender = sender,
From = sender,
Subject = "Test",
Body = new Microsoft.Graph.ItemBody()
{
Content = "Test Body",
ContentType = Microsoft.Graph.BodyType.Text
}
};
email.ToRecipients = new List<Microsoft.Graph.Recipient>(){ sender };
email.BodyPreview = "Test Summary";
GraphSdk _Sdk = new GraphSdk(TenantId, AppGuid, AppKey);
// Where the error throws
await _Sdk.Client.Users[MyUpn].SendMail(email, true).Request().PostAsync();
As a test, I also tried await _Sdk.Client.Users[MyUpn].Messages.Request().Top(20).GetAsync(); which yielded the same error. Other Graph calls, like getting a user's groups or manager, work fine - this error only appears on email-related calls.
Update 9/19/2018 AM
It looks like I can get emails working if I use a certificate to generate the token instead of the Key -> Password; and call the Outlook API instead. Unfortunately, that doesn't work through the GraphServiceClient and Graph API - it can use the certificate, and use the Outlook API base URL, but the microsoft.graph.sendMail action is just sendMail in the Outlook API.
For maintainability, I'd still like to get it all working under the Graph API so I'm still looking for an answer to the original question.
At some point I had set the BaseUrl for the client to https://graph.windows.net:443/{{tenantId}}, possibly due to the varying branding over the past few years (Microsoft Graph vs Azure Graph). Under current recommendations for the Microsoft.Graph it should be https://graph.microsoft.com/v1.0/ - which also appears to be the default value.
Additionally, I had to switch to using a certificate instead of the Azure-generated Key -> Password for the app.
Total working code is:
String AADTenantId = "";
String AppGuid = "";
String SenderAddress = "";
String SenderId = "";
String ToAddress = "";
String SubjectText = "";
String BodyText = "";
Byte[] Certificate = ...GetCertBytes...
String CertPassword = "";
var client = new GraphServiceClient(new DelegateAuthenticationProvider(
async requestMessage =>
{
var authContext = new AuthenticationContext($"https://login.microsoftonline.com/{AADTenantId}");
var cert = new X509Certificate2(Certificate, CertPassword);
var clientAssertion = new ClientAssertionCertificate(AppGuid, cert);
AuthenticationResult authresult = await authContext.AcquireTokenAsync("https://graph.microsoft.com", clientAssertion);
// Append the access token to the request
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authresult.AccessToken);
}));
var sender = new Recipient()
{
EmailAddress = new EmailAddress() { Address = SenderAddress }
};
var email = new Message
{
Sender = sender,
From = sender,
Subject = SubjectText,
Body = new ItemBody()
{
Content = BodyText,
ContentType = BodyType.Text
},
ToRecipients = new List<Recipient>() {
new Recipient() { EmailAddress = new EmailAddress { Address = ToAddress }}
}
};
await client.Users[SenderId].SendMail(email, true).Request().PostAsync();
According to your description, you want send an email but get an 400 error.
Based on my test, we can use the following steps to send an email.
step1, we should get a graphClient which is a authenticated HttpClient.
The code like this:
GraphServiceClient graphServiceClient = new GraphServiceClient(
new DelegateAuthenticationProvider(
async (requestMessage) =>
{
string accessToken = await MsalAuthProvider.Instance.GetUserAccesstokenAsync();
requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", accessToken);
}));
return graphServiceClient;
We can refer to the simple code in the official document.
step2, we can use the following code to send a mail:
public async Task<bool> SendAsync(EmailAddress toaddress)
{
var email = new Message
{
Body = new ItemBody
{
Content = "Test for sending eamil ",
ContentType = BodyType.Text,
},
Subject = "Test for sending eamil",
ToRecipients = new List<Recipient>
{
new Recipient
{
EmailAddress = toaddress
}
},
};
try
{
await _serviceClient.Me.SendMail(email).Request().PostAsync(); // the _serviceClient is the result in the step1.
return true;
}
catch (Exception ex)
{
return false;
}
I have an account ID and also a template ID, but I am getting null in text custom and list fields. I am using DocuSign's REST api for getting custom fields and listed fields.
configureApiClient("https://demo.docusign.net/restapi");
// Step 1: Login()
// call the Login() API which sets the user's baseUrl and returns their accountId
AccountId = loginApi(username, password);
TemplatesApi envelopesApi2 = new TemplatesApi();
CustomFields cfe = envelopesApi2.ListCustomFields(AccountId, templateId);
Console.WriteLine("Get Custom Fields Information:\n{0}",
JsonConvert.SerializeObject(cfe));
Could you please help me to solve my problem?
Thanks in advance
I see that you are adding the custom fields to an envelope and not template. You should use the EnvelopesApi to retrieve the CustomFields. You are incorrectly using the TemplateId.
Use the following code and pass the envelopeId that is returned from the envelopesApi.CreateEnvelope() call
var envelopesApi2 = new EnvelopesApi();
CustomFields cfe = envelopesApi2.ListCustomFields(AccountId, envelopeId);
Console.WriteLine("Get Custom Fields Information:\n{0}",
JsonConvert.SerializeObject(cfe));
Please see my below code to create custom field in templates.
public EnvelopeSummary requestSignatureFromTemplateTest(DocuSignData data)
{
// instantiate api client with appropriate environment (for production change to www.docusign.net/restapi)
configureApiClient("https://demo.docusign.net/restapi");
//===========================================================
// Step 1: Login()
//===========================================================
// call the Login() API which sets the user's baseUrl and returns their accountId
AccountId = loginApi(username, password);
//===========================================================
// Step 2: Signature Request from Template
//===========================================================
EnvelopeDefinition envDef = new EnvelopeDefinition();
envDef.EmailSubject = "Please sign this sample template document11111111111";
// assign recipient to template role by setting name, email, and role name. Note that the
// template role name must match the placeholder role name saved in your account template.
TemplateRole tRole = new TemplateRole();
tRole.Email = recipientEmail;
tRole.Name = recipientName;
tRole.RoleName = templateRoleName;
List<TemplateRole> rolesList = new List<TemplateRole>() { tRole };
// add the role to the envelope and assign valid templateId from your account
envDef.TemplateRoles = rolesList;
envDef.TemplateId = templateId;
// set envelope status to "sent" to immediately send the signature request
envDef.Status = "sent";
List<TextCustomField> customFieldsTextList = new List<TextCustomField>();
if (data.CustomFieldsText != null)
{
//custom text fields
foreach (DocuSignCustomField customField in data.CustomFieldsText)
{
TextCustomField newField = new TextCustomField();
newField.Name = customField.Name;
newField.Value = customField.Value;
newField.Show = customField.Show;
newField.Required = customField.Required;
customFieldsTextList.Add(newField);
}
}
CustomFields customFields = new CustomFields();
customFields.TextCustomFields = customFieldsTextList;
envDef.CustomFields = customFields;
// |EnvelopesApi| contains methods related to creating and sending Envelopes (aka signature requests)
EnvelopesApi envelopesApi = new EnvelopesApi();
EnvelopeSummary envelopeSummary = envelopesApi.CreateEnvelope(AccountId, envDef);
// print the JSON response
//Console.WriteLine("Envelope Template Summary:\n{0}", JsonConvert.SerializeObject(envelopeSummary));
return envelopeSummary;
} // end requestSignatureFromTemplateTest()
this code for getting custom fields from template
configureApiClient("https://demo.docusign.net/restapi");
// Step 1: Login()
// call the Login() API which sets the user's baseUrl and returns their accountId
AccountId = loginApi(username, password);
TemplatesApi envelopesApi2 = new TemplatesApi();
CustomFields cfe = envelopesApi2.ListCustomFields(AccountId, templateId);
Console.WriteLine("Get Custom Fields Information:\n{0}",
JsonConvert.SerializeObject(cfe));
I am trying to find a way to add the submission of someone's name to the search function. I need to send the name as a tag, but the issue is on the display end.
You can see the site here - http://southu.tumblr.com/ You will need a password - test123
The tag is displayed above the video. The current tags are "Commitment" and "Sacrifice". The name is separate so it can be displayed in a different spot. Tumblr doesn't inherently allow for defining between different tags on the display side.
Basically, I need to support both fields as tags, but not display the name in the tag display (above the video)
Here is the C# from the VideoSubmissionController.cs file.
// Posts the video submission using the TumblrApi.
private void SendToTumblr(VideoSubmission videoSubmission)
{
string consumerKey = ConfigurationManager.AppSettings.Get("TumblrConsumerKey");
string consumerSecret = ConfigurationManager.AppSettings.Get("TumblrConsmerSecret");
string oauthToken = ConfigurationManager.AppSettings.Get("TumblrOauthTokenKey");
string oauthVerifier = ConfigurationManager.AppSettings.Get("TumblrOauthTokenSecret");
Token token = new Token(oauthToken, oauthVerifier);
var client_factory = new TumblrClientFactory();
using (var client = client_factory.Create<TumblrClient>(consumerKey, consumerSecret, token))
{
//string body = "This post was created through the api";
//string title = "Testing API Push";
string[] tags = new string[] { videoSubmission.Question.QuestionText };
//create the data for a text post: use PostData.CreateText
var postData = PostData.CreateVideo(videoSubmission.VideoUrl, videoSubmission.Name, tags);
//create the post: pass the name of the blog where to post to
var postTask = client.CreatePostAsync(ConfigurationManager.AppSettings.Get("TumblrUrl"), postData);
postTask.Wait();
var postResult = postTask.Result;
videoSubmission.TumblrId = postResult.PostId.ToString();
db.Entry(videoSubmission).State = EntityState.Modified;
db.SaveChanges();
}
}
First, I open Facebook Developers page, and I create new App. ( I get AppID, AppSecret values)
I want create Unit Test method for do Post to the wall, and later delete the post.
publish_stream, publish_actions
Manually, I do this 3 steps
Open url
https://graph.facebook.com/oauth/authorize?client_id=xxxxx&redirect_uri=http://www.kiquenet.com/&scope=publish_stream,publish_actions
Then, this url opened, and I get the code value:
http://www.kiquenet.com/?code=A....3qhOw#=
And then, open this url and I get the access token value:
https://graph.facebook.com/oauth/access_token?client_id=xxxxx&redirect_uri=http://www.kiquenet.com/&scope=publish_stream,publish_actions&client_secret=zzzzz&code=A...3qhOw#=
Finally, I get the access token:
const string token = "C...SNo";
My code now is for my unit test is working. Only I need do the delete.
using Facebook;
[TestMethod]
public void Post_to_the_wall()
{
var client = new FacebookClient(token);
dynamic parameters = new ExpandoObject();
parameters.message = "Check out this funny article";
parameters.link = "http://www.example.com/article.html";
parameters.picture = "http://www.example.com/article-thumbnail.jpg";
parameters.name = "Article Title";
parameters.caption = "Caption for the link";
parameters.description = "Longer description of the link";
parameters.actions = new
{
name = "View on Zombo",
link = "http://www.zombo.com",
};
parameters.privacy = new
{
value = "ALL_FRIENDS",
};
dynamic result = client.Post("me/feed", parameters);
// TODO: NOW, delete the post ???
}
How can I do programmatically the 3 Manually steps ?