I have a sendgrid account which includes 7 days of email history.
I try to get these with the api command:
var sendgridtask = sendgridclient.RequestAsync(method: SendGrid.SendGridClient.Method.GET, urlPath: "messages?limit=10");
but this gives the response:
{"errors":[{"message":"authorization required"}]}
I guess the api key isn't correct, but when I try to execute the command:
var sendgridtask = sendgridclient.RequestAsync(method: SendGrid.SendGridClient.Method.GET, urlPath: "suppression/bounces/" + email);
it gives no error and responses the right info.
I checked the api key and it has full access.
I've also tried:
sendgridclient.AddAuthorization(new KeyValuePair<string, string>("Authorization", $"Bearer {apiKey}"));
but this gives the same response
Do you know what I am doing wrong?
Already got an answer from SendGrid:
Unfortunately in order to gain access to the Email Activity Feed API, you must purchase additional email activity history.
Or you can use our event webhook for your activity. https://sendgrid.com/docs/for-developers/tracking-events/getting-started-event-webhook/
So it seems that our license included history is only accessible from the SendGrid website, not from the API without an additional license.
Related
I am trying to use Amazon's new Selling Partner API to access a direct fulfillment / vendor central account. I have followed the documentation to the best of my ability but I can't get a simple po request call to work. Here is all of the elements from my request. I am at a loss what if any part is actually wrong. I don't know of any way of testing all the elements for validity like you can with the Amazon MWS scratchpad.
canonical request
GET
/vendor/directFulfillment/orders/v1/purchaseOrders
createdAfter=2020-10-05T23%3A00%3A00-08%3A00&createdBefore=2020-10-09T23%3A00%3A00-08%3A00
host:sellingpartnerapi-na.amazon.com
user-agent:My, Selling, Tool/1.0, (Language=C#.NET; Platform=Windows/10)
x-amz-access-token:Atza|IwEBIG0G7EXAMPLE
x-amz-date:20201014T193028Z
host;user-agent;x-amz-access-token;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
string to sign
AWS4-HMAC-SHA256
20201014T193352Z
20201014/us-east-1/execute-api/aws4_request
d8efa99344ee27ae5505888ac5069f78734af9a95637485396274f8e773e2784
credential scope
20201014/us-east-1/execute-api/aws4_request
authorization header
AWS4-HMAC-SHA256 Credential=AKIAUEXAMPLE/20201014/us-east-1/execute-api/aws4_request, SignedHeaders=host;user-agent;x-amz-access-token;x-amz-date, Signature=cab976c4d1d2546328e19ff2314f888d0c4b25da4d36f66e53a6614c37b92dff
Here is the error response we are getting.
{Connection: keep-alivex-amzn-RequestId: 728bd01f-32ec-49d3-b845-558f4970014ax-amzn-ErrorType: InvalidSignatureExceptionx-amz-apigw-id: Uaxq-G6MoAMF6Cg=Date: Wed, 14 Oct 2020 20:44:02 GMT}
The error response showing your signature is not right. Also, you can test easier API to test the connection with your AWS.
Try this one, product-pricing-api, https://github.com/amzn/selling-partner-api-docs/blob/main/references/product-pricing-api/productPricingV0.md
First, using refresh_token and grant_type(refresh_token) send post to https://api.amazon.com/auth/o2/token and get the access_token;
Second, create a request, and addHeader.
Request request = new Request.Builder()
.url("https://sellingpartnerapi-na.amazon.com/products/pricing/v0/price?MarketplaceId=A2EUQ1WTGCTBG2&Skus="+sku+"&ItemType=Sku")
.method("GET", null)
.addHeader("x-amz-access-token","your token")
.build();
Third, using this utils AWSSigV4Signer.java to sign your request. Reference with "Step 1. Configure your AWS credentials" and "Step 2. Configure your AWS credentials provider" https://github.com/amzn/selling-partner-api-docs/blob/main/guides/en-US/developer-guide/SellingPartnerApiDeveloperGuide.md
AWSSigV4Signer awsSigV4Signer = new AWSSigV4Signer(awsAuthenticationCredentials,awsAuthenticationCredentialsProvider);
request = awsSigV4Signer.sign(request);
Your header should be add those information SignedHeaders=host;x-amz-access-token;x-amz-date;x-amz-security-token
x-amz-access-token: Atza|...
X-Amz-Security-Token: FwoGZX...
Host:sellingpartnerapi-na.amazon.com
X-Amz-Date:20201014T193352Z
Authorization: AWS4-HMAC-SHA256 Credential=AKIAUEXAMPLE/20201014/us-east-1/execute-api/aws4_request, SignedHeaders=host;x-amz-access-token;x-amz-date;x-amz-security-token, Signature= {your signature}
I want to be able to create an envelope and then email the link to the signer. The code segment I came up with is:
EnvelopesApi envelopesApi = new EnvelopesApi();
envDef.Status = "sent";
EnvelopeSummary envelopeSummary = envelopesApi.CreateEnvelope(accountId, envDef);
RecipientViewRequest viewOptions = new RecipientViewRequest()
{
ReturnUrl = "https://www.docusign.com/devcenter",
ClientUserId = signer.ClientUserId,
AuthenticationMethod = "email",
UserName = signer.Name,
Email = signer.Email // does NOT send an email
};
ViewUrl recipientView = envelopesApi.CreateRecipientView(accountId, envelopeSummary.EnvelopeId, viewOptions);
The code before this segment gets the account, signer an envelope definition, etc.
This code works fine if I set envDef.Status = "sent". If I do not set that status, I get an exception from the last line of code in this segment.
I want to just have the envelope go into created status, then get the URL and send the email in my own code that does relay email.
Or, can I supply an email address and have Docusign send the email? But, in that case, what if their email fails for some reason?
The bottom line is that I want a way to deal with the problem of how to re-send the link if the email fails to get sent.
Re your stated objective:
I want to just have the envelope go into created status, then get the URL and send the email in my own code that does relay email.
This approach is not recommended, since the URL that you obtain via CreateRecipientView will timeout in a short amount of time (I believe it's 5 minutes). In other words, if the recipient does not open the email that you send them and click the link to launch their signing session within that period of time, the link becomes invalid and they'll be unable to use it to access their signing session.
Instead of using CreateRecipientView, I'd recommend that you simply specify the recipient's info (name, email, etc.) as part of the envelope definition and then DocuSign will send the recipient an email that contains a link that they can use to access their Envelope. This link will be valid for days (not minutes, like the link that you generate yourself via CreateRecipientView), so there's no requirement that the signer act on it immediately. If for some reason the recipient misplaces or does not receive the email that DocuSign sends them, you can easily have DocuSign re-send that email notification by either using the DocuSign web UI or by using the UpdateRecipient API operation with resendEnvelope=true specified (as Frederic described in his answer).
Update #1
There's no way to retrieve a long-lived link that a recipient can use to initiate their signing session. A common way to address your scenario would be the following:
Send the signer an email that contains a link that leads them to a web page that you build -- and instructions for them to click that link to launch their Envelope whenever they are ready to review/sign the document(s). (The link URL would need to contain some sort of querystring parameters that your web page could use to identify the Envelope and Recipient.)
Design your web page such that when it receives an inbound request (as it would when the recipient clicks the link in the email you send them), it uses the information in the querystring parameters to identify the Envelope and Recipient, then issues a CreateRecipientView request to retrieve the URL that will launch that recipient's signing session, and finally, automatically redirects the user to the URL that the CreateRecipientView response returns, thereby opening the Envelope for the recipient to review/sign/submit.
By following a process like this, you're able to craft/send the email that the recipient receives (instead of relying upon DocuSign to do so), and can ensure that you're only retrieving the envelope URL whenever the user has indicated that they're ready to sign (thereby avoiding the potential of the short-lived link expiring before it's used).
Update #2
For an example of how to add recipient(s) to the EnvelopeDefinition object using the DocuSign C# SDK, see this "recipe" -- specifically, see the code within the requestSignatureOnDocumentTest method. It's basically a two-step process:
1) Define each recipient. For example:
// Add a recipient to sign the documeent
Signer signer = new Signer();
signer.Email = recipientEmail;
signer.Name = recipientName;
signer.RecipientId = "1";
2) Populate the Recipients property of the EnvelopeDefinition object with the recipient(s) that you create. For example:
envDef.Recipients = new Recipients();
envDef.Recipients.Signers = new List<Signer>();
envDef.Recipients.Signers.Add(signer);
I'm going to try to answer both of your inquiries :
1) The bottom line is that I want a way to deal with the problem of how to re-send the link if the email fails to get sent.
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 :
RecipientsUpdateSummary recipientsUpdateSummary =
envelopeApi.UpdateRecipients(
accountId,
envelope.EnvelopeId,
envelope.Recipients,
new EnvelopesApi.UpdateRecipientsOptions { resendEnvelope = "true" });
Here is what the official documentation states :
2) Is there a way to create an envelope in the 'created' state and then put it into 'sent' later?
Yes, it is possible.
When you create your envelope, make sure to specify the "Created" status as below :
Status = "created"
Create your envelope :
envelopeApi.CreateEnvelope(accountId, envelope);
Then, when you're ready, change the envelope status to "sent". This will trigger the emails to the recipients. Voila !
Envelope updatedEnvelope = new Envelope
{
Status = "sent"
};
envelopeApi.Update(
accountId,
envelopeId,
updatedEnvelope);
I am in the process of learning the Autodesk Forge API. With a simple C# application, I am able to authenticate using the Forge API.
var responseString = await
"https://developer.api.autodesk.com/authentication/v1/authenticate"
.PostUrlEncodedAsync(new
{
client_id = Client_ID.Text,
client_secret = Client_Secret.Text,
grant_type = "client_credentials",
scope = "data:read data:write bucket:create bucket:read"
})
.ReceiveJson();
Though I have explicitly specified the bucket:read scope bucket:read, further call to check a bucket exists fails with error:-
Http code 403 (Forbidden) with the message "Only the bucket creator is allowed to access this API"
When I try to create another bucket with the same name it fails with the:-
Http Code 409 (Conflict) with the message "Bucket already exists"
Can someone please help me on what is missing here?
Yes, the issue is that your bucket key should be globally unique across all application and regions. You can check the doc at https://developer.autodesk.com/en/docs/data/v2/reference/http/buckets-POST/ for the detail, especially for the description of Bucket Key.
I wonder if it is possible to get a permanent access token for personal use on Reddit?
It will only be me using the App.
For users, the access token expires after 1 hour.
My using the below information that I have about my client-id and secret, I put up a start attempt of trying to get an access token. (MessageBox show "Error 401")
If a user will get a token, one have to click "Allow" in the browser. Very well described here. https://github.com/reddit/reddit/wiki/OAuth2
This it NOT what I am after. I am after for, personal use, an access token only through code. Is this possible?
String requestUrl = "https://ssl.reddit.com/api/v1/access_token";
RestSharp.RestClient rc = new RestSharp.RestClient();
RestSharp.RestRequest request = new RestSharp.RestRequest(requestUrl, RestSharp.Method.POST);
request.AddHeader("Content-Type", "application/json");
//request.AddHeader("Authorization", ""); //???
request.AddHeader("x-li-format", "json");
request.AddParameter("client_id", "abcdefg");
request.AddParameter("client_secret", "abc123-456");
request.AddParameter("grant_type", "abc123-456");
request.AddParameter("scope", "identity");
request.AddParameter("state", "adhasegw"); //whatever value
request.AddParameter("duration", "permanent");
request.AddParameter("redirect_uri", "http://mywebsite.co");
request.RequestFormat = RestSharp.DataFormat.Json;
RestSharp.RestResponse restResponse = (RestSharp.RestResponse)rc.Execute(request);
RestSharp.ResponseStatus responseStatus = restResponse.ResponseStatus;
MessageBox.Show(restResponse.Content.ToString() + "," + responseStatus.ToString());
As of right now, you cannot retrieve a permanent access token. You have 2 options that come close.
The first is to request a "refresh" token when using the standard OAuth flow. That's what you're doing by sending "duration" as "permanent" in your code. The refresh token can be used to automatically retrieve new 1 hour access tokens without user intervention; the only manual steps are on the initial retrieval of the refresh token.
The second alternative, which applies only when writing a script for personal use, is to use the password grant type. The steps are described in more detail on reddit's "OAuth Quick Start" wiki page, but I'll summarize here:
Create an OAuth client (under https://www.reddit.com/prefs/apps) with type = "script"
Make a request to https://www.reddit.com/api/v1/access_token with POST parameters grant_type=password&username=<USERNAME>&password=<PASSWORD>. Send your client ID and secret as HTTP basic authentication. <USERNAME> must be registered as a developer of the OAuth 2 client ID you send.
A client_id and client_secret can be generated for a reddit account by going to https://www.reddit.com/prefs/apps and creating an app:
The part I have hidden is my client_id.
Then you can use a client like praw to access reddit e.g. with Python:
import praw
r = praw.Reddit(client_id='insert id here',
client_secret='insert secret here',
user_agent='insert user agent')
page = r.subreddit('aww')
top_posts = page.hot(limit=None)
for post in top_posts:
print(post.title, post.ups)
You could use your current browser's user agent, which can be easily found by google searching "what is my user agent" (among other ways).
I'm developing a feature for our product that will allow users to send SMS messages via Twilio and we handle all of the account issues. We have our Master Account and all of our customers will be sub accounts under us.
In an effort to not have to keep track of 1000+ auth tokens, we decided to use our Master Account credentials to send the SMS message however we still want it to roll up under the sub account. According to Twilio, this shouldn't be an issue.
My problem is that there is very little (that I've found) documentation for the c# library they provide. I'm not sure if what I've done is the correct way to accomplish what I described above and since I'm on a trial account until the project is finished and can be rolled out to production I have no way of testing.
var twilio = new TwilioRestClient("Master SID", "Master Auth Token");
var response = twilio.SendSmsMessage(sender, recipient.ConvertToE164Format(), message, null, "Subaccount SID");
The comment on this overload isn't really clear on if passing the subaccounts SID here will send the message as if I had logged into their account and sent it.
// applicationSid:
// Twilio will POST SmsSid as well as SmsStatus=sent or SmsStatus=failed to
// the URL in the SmsStatusCallback property of this Application. If the StatusCallback
// parameter above is also passed, the Application's SmsStatusCallback parameter
// will take precedence.
The callback url will be the same across all accounts so I don't need/care about that value.
Short Version:
If I log in with my Master Account details but pass the subaccount SID in the SendSmsMessage() method, which account does the message come from?
Twilio support finally got back to me and confirmed my fears that this wouldn't work. I do have to pull the subaccount information down and reinstantiate the twilioRestClient with the new credentials which I was hoping I could get away with not doing. Just a few extra lines.
var twilio = new TwilioRestClient("Master SID", "Master Auth Token");
var subAccount = twilio.GetAccount("SubAccount SID");
var subAccountClient = new TwilioRestClient(subAccount.Sid, subAccount.AuthToken);
var response = subAccountClient.SendSmsMessage(sender, recipient.ConvertToE164Format(), message);
return response.Sid;