User Master Account to send SMS on behalf of a Sub Account - c#

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;

Related

SendGrid api email activity response authorization required

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.

Docusign: Is there a way to create an envelope in the 'created' state and then put it into 'sent' later?

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);

"Cannot create payouts with an OAuth key" exception when creating payout for Stripe custom account

We have our master Stripe account, and custom / connected accounts which we eventually want to transfer funds to, and then payout to their external bank accounts.
I have some code that works without issue in test mode, but on production we get an exception when doing the payout step. The error details are:
Stripe.StripeException: Cannot create payouts with an OAuth key.
at Stripe.Infrastructure.Requestor.ExecuteRequest(HttpRequestMessage requestMessage)
at Stripe.Infrastructure.Requestor.PostString(String url, StripeRequestOptions requestOptions)
As far as I know, we are not using an OAuth key for this request, as I set up the StripeAPI with the secret key in Startup.cs of our MVC web application:
StripeConfiguration.SetApiKey("sk_live_**************");
And the actual code to attempt the payout:
StripePayoutService sps = new StripePayoutService();
StripeRequestOptions connectRequest = new StripeRequestOptions();
connectRequest.StripeConnectAccountId = stripeConnectID; //"acct_*********"
StripePayoutCreateOptions spco = new StripePayoutCreateOptions();
spco.Amount = (int)(amount * 100);
spco.Currency = "GBP";
spco.StatementDescriptor = reference;
StripePayout result = sps.Create(spco, connectRequest);
I've specified the connected account id on the stripe request options and the Api Key in initialization, so what is causing the request to complain about OAuth credentials, or what am I missing / doing wrong in this scenario?
It turns out due to an edge case, as the wrong Stripe key was being used, so the OAuth key error message was a red herring. I would recommend anyone investigating an issue similar to this to check:
the request details (via the request id) in the api/logs section on the stripe dashboard, and that a request exists against the appropriate Stripe account
there are enough funds / the transfer succeeded, prior to the payout being requested
You are not doing anything wrong here. Its completely correct just available amount for payout is not available in test data of connect account. Do a test transaction and add amount to stripe test account. It should work fine.

Saving Tweetinvi credentials without re-authenticating every time

Basically what I'm trying to do is to get recent tweets from a user and do stuff with them. I'm using Tweetinvi with PIN-based authentication, as described on the website, like this:
// Create a new set of credentials for the application
var appCredentials = new TwitterCredentials("CONSUMER_KEY", "CONSUMER_SECRET");
// Go to the URL so that Twitter authenticates the user and gives him a PIN code
var url = CredentialsCreator.GetAuthorizationURL(appCredentials);
// This line is an example, on how to make the user go on the URL
Process.Start(url);
// Ask the user to enter the pin code given by Twitter
var pinCode = Console.ReadLine();
// With this pin code it is now possible to get the credentials back from Twitter
var userCredentials = CredentialsCreator.GetCredentialsFromVerifierCode(pinCode, appCredentials);
// Use the user credentials in your application
Auth.SetCredentials(userCredentials);
Now the problem is that I have to sign in and connect to Twitter every time I launch my application via browser, which is mildly annoying. I've tried to save my authentication details in a text file (Consumer Key, Consumer Secret, Access Token, Access Token Secret), and then just insert the info into appCredentials and userCredentials, but with no results, as I keep getting TwitterNullCredentialsException. So how do I save my credentials so that I don't have to reconnect on every launch?
I am the main developer of Tweetinvi.
If you store the 4 credentials information you can then reuse them with 2 different solutions :
Auth.SetUserCredentials("CONSUMER_KEY", "CONSUMER_SECRET", "ACCESS_TOKEN", "ACCESS_TOKEN_SECRET");
// OR
var creds = new TwitterCredentials("CONSUMER_KEY", "CONSUMER_SECRET", "ACCESS_TOKEN", "ACCESS_TOKEN_SECRET");
Auth.SetCredentials(creds);
The documentation might help you set up your application : https://github.com/linvi/tweetinvi/wiki/Introduction

Posting to a friends wall with exception

The exception I am getting is "The user hasn't authorized the application to perform this action". I know this is a well published exception but there are no rules which I can follow to get this code to work. I am trying to post to a friends wall via the API.
AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
String accessToken = result.ExtraData["accesstoken"];
FacebookClient client = new FacebookClient(accessToken);
dynamic parameters = new ExpandoObject();
arameters.message = "Testing";
I have managed to get my friends facebook ids and this is facebookFriendID
object resTest = client.Post("/" + facebookFriendID + "/feed", parameters);
This is throwing the exception. Do I need to set any special options in my app to allow this to post to friends walls and/or do the users receving the post need to accept the app first? Is there any other params I need to send?
Thanks in advance
Posting to a friend's wall has been disabled
Post to friends wall via the API generate a high levels of negative user feedback, including “Hides” and “Mark as Spam" and so we are removing it from the API. If you want to allow people to post to their friend’s timeline from your app, you can invoke the feed dialog. Stories that include friends via user mentions tagging or action tagging will show up on the friend’s timeline (assuming the friend approves the tag).
https://developers.facebook.com/blog/post/2012/10/10/growing-quality-apps-with-open-graph/
ensure which authorization check the user has access to only his/her pages or whole application.
For basic authorization you can do like this
[BasicAuthorize]
public ActionResult Index()
{
// code will go here
}
For Anonymous
[AllowAnonymous]
public ActionResult Index()
{
// code will go here
}
[BasicAuthorize] requires at least user should login
[AllowAnonymous] Allow Every one to application
I think the exception is pretty explicit: your app must ask the target user for an authorization to post on its wall, and the user has to approve it. Imagine how would Facebook it be if any app could just post whatever it wanted on anyone's behalf in anyone's wall.
Depending on your implementation, you will need to ask for the publish_stream, status_update, or even other permission.
Do I pass this as a param? – CR41G14
I think it's more complicated than that, as you have to ask for the permission before acting. Check out this question for some information that may help you (here in SO there are several other questions about the topic, too).

Categories

Resources