I have the following code(facebook C# SDK) to post to facebook wall :
public long? UploadPost(string intLinkTitle, string inMessage, string inLinkCaption, string inLinkUrl, string inLinkDescription, string inLinkUrlPicture)
{
object obj;
Facebook.JsonObject jsonObj;
FacebookClient client;
string access_token = ConfigurationManager.AppSettings["FacebookPageAccessToken"].ToString();
client = new FacebookClient(access_token);
var args = new Dictionary<string, object>();
args["message"] = inMessage;
args["caption"] = inLinkCaption;
args["description"] = inLinkDescription;
args["name"] = intLinkTitle;
args["picture"] = inLinkUrlPicture;
args["link"] = inLinkUrl;
if ((obj = client.Post("/" + ConfigurationManager.AppSettings["FacebookPageId"].ToString() + "/feed", args)) != null)
{
if ((jsonObj = obj as Facebook.JsonObject) != null)
{
if (jsonObj.Count > 0)
return long.Parse(jsonObj[0].ToString().Split('_').Last().ToString());
}
}
return null;
}
}
This works great as long as I post to my public facebook website page but when changing the FacebookPageId to a group id instead I get (FacebookApiException - #200) Permissions error.
My user are admin of both the group and the page.
I have tried to post the message from the Graph API Explorer with the following line : 294632750660619/feed/?message=test but there is a syntax problem here, have also tried 294632750660619/feed?message=test but with no success.
How do I post to the closed facebook group?
Okay, I found the correct way. This is what I hade to do :
Go to the https://developers.facebook.com/ and create a new application
Settings > Add platform(Website and set the site URL(for example localhost..)
Set the app to go live(status & review > Yes), to do this a email adress needs to be set under settings > Contact Email
Go to the Graph API Explorer
Choose the new app from the dropdown
Click Get Access Token
Choose correct permissions(user_groups, user_status, user_photos, manage_pages, publish_actions, read_insights and read_stream) and click Get Access Token. Now we bot a short lived tooken
Generate a extended user token (valid for 60 days) by using this URL(change parameters(3)) : https://graph.facebook.com/oauth/access_token?grant_type=fb_exchange_token&client_id=[app-id]&client_secret=[app-secret]&fb_exchange_token=[short-lived-token]
Use the generated none expiring access token in the application
Validate the Access token here : https://developers.facebook.com/tools/debug/access_token/
Use this code to upload post :
public long? UploadPost(string intLinkTitle, string inMessage, string inLinkCaption, string inLinkUrl, string inLinkDescription, string inLinkUrlPicture)
{
object obj;
Facebook.JsonObject jsonObj;
FacebookClient client;
string access_token = ConfigurationManager.AppSettings["FacebookPageAccessToken"].ToString();
client = new FacebookClient(access_token);
var args = new Dictionary<string, object>();
args["message"] = inMessage;
args["caption"] = inLinkCaption;
args["description"] = inLinkDescription;
args["name"] = intLinkTitle;
args["picture"] = inLinkUrlPicture;
args["link"] = inLinkUrl;
if ((obj = client.Post("/" + ConfigurationManager.AppSettings["FacebookPageId"].ToString() + "/feed", args)) != null)
{
if ((jsonObj = obj as Facebook.JsonObject) != null)
{
if (jsonObj.Count > 0)
return long.Parse(jsonObj[0].ToString().Split('_').Last().ToString());
}
}
return null;
}
And to get feed, use this :
private void GetFeed()
{
object obj;
Facebook.JsonObject jsonObj;
Facebook.JsonObject jsonPaging;
FacebookClient client;
int pageCount = 0;
string access_token;
string URL;
DateTime fetchFaceBookFeedFromDate;
DateTime? oldestPostFetched = null;
fetchFaceBookFeedFromDate = DateTime.Now.AddDays(-30);
access_token = ConfigurationManager.AppSettings["FacebookPageAccessToken"].ToString();
URL = "/" + ConfigurationManager.AppSettings["FacebookPageId"].ToString() + "/feed";
client = new FacebookClient(access_token);
while (URL.Length > 0 && pageCount < 1000)
{
if ((obj = client.Get(URL)) != null)
{
if ((jsonObj = obj as Facebook.JsonObject) != null && jsonObj.Count > 0)
{
if (jsonObj[0] is Facebook.JsonArray)
oldestPostFetched = SaveFacebookForumThread(jsonObj[0] as Facebook.JsonArray, fetchFaceBookFeedFromDate);
if (jsonObj.Keys.Contains("paging") && (jsonPaging = jsonObj["paging"] as Facebook.JsonObject) != null && jsonPaging.Keys.Contains("next"))
URL = jsonPaging["next"].ToString();
else
break;
}
}
pageCount++;
if (oldestPostFetched.HasValue && fetchFaceBookFeedFromDate > oldestPostFetched)
break;
}
}
Related
I am currently working on an dotnet maui app and I need to integrate Sign in With Apple. But when I click the sign in button, It shows "invalid_request invalid web redirect url"
Tried solutions
I tried the solutions available here, but it is not working.
Other than that I have also read the documentation, also got help from tutorials such as this, this and this
Code
Initializing request:
//Initiating apple sign in request
WebAuthenticatorResult result = null;
if (scheme.Equals(Constants.apple, StringComparison.Ordinal)
&& DeviceInfo.Platform == DevicePlatform.iOS
&& DeviceInfo.Version.Major >= 13)
{
// Make sure to enable Apple Sign In in both the
// entitlements and the provisioning profile.
var options = new AppleSignInAuthenticator.Options
{
IncludeEmailScope = true,
IncludeFullNameScope = true,
};
result = await AppleSignInAuthenticator.AuthenticateAsync(options);
}
else
{
var authUrl = new Uri(Constants.authenticationUrl + scheme);
var callbackUrl = new Uri(Constants.callbackUrl);
result = await WebAuthenticator.AuthenticateAsync(authUrl, callbackUrl);
}
AuthToken = string.Empty;
// Get Name and Email from callback url
//if (result.Properties.TryGetValue("name", out var name) && !string.IsNullOrEmpty(name))
// AuthToken += $"Name: {name}{Environment.NewLine}";
//if (result.Properties.TryGetValue("email", out var email) && !string.IsNullOrEmpty(email))
// AuthToken += $"Email: {email}{Environment.NewLine}";
AuthToken += result?.AccessToken ?? result?.IdToken;
AuthCredential credential = null;
Handling results:
// WebAuthenticator Endpoint - use for social login e.g. Google, Facebook, Apple etc.
const string callbackScheme = "socialloginauthenticator";
[HttpGet("{scheme}")]
public async Task Get([FromRoute] string scheme)
{
var auth = await Request.HttpContext.AuthenticateAsync(scheme);
if (!auth.Succeeded
|| auth?.Principal == null
|| !auth.Principal.Identities.Any(id => id.IsAuthenticated)
|| string.IsNullOrEmpty(auth.Properties.GetTokenValue("access_token")))
{
// Not authenticated, challenge
await Request.HttpContext.ChallengeAsync(scheme);
}
else
{
var claims = auth.Principal.Identities.FirstOrDefault()?.Claims;
var email = string.Empty;
email = claims?.FirstOrDefault(c => c.Type == System.Security.Claims.ClaimTypes.Email)?.Value;
// Get parameters to send back to the callback
var qs = new Dictionary<string, string>
{
{ "access_token", auth.Properties.GetTokenValue("access_token") },
{ "refresh_token", auth.Properties.GetTokenValue("refresh_token") ?? string.Empty },
{ "expires_in", (auth.Properties.ExpiresUtc?.ToUnixTimeSeconds() ?? -1).ToString() },
{ "email", email }
};
// Build the result url
var url = callbackScheme + "://#" + string.Join(
"&",
qs.Where(kvp => !string.IsNullOrEmpty(kvp.Value) && kvp.Value != "-1")
.Select(kvp => $"{WebUtility.UrlEncode(kvp.Key)}={WebUtility.UrlEncode(kvp.Value)}"));
// Redirect to final url
Request.HttpContext.Response.Redirect(url);
}
}
I have resolved the issue. The issue was with redirect uri in apple service I made.
The required uri was of format "www.example.com/signin-apple" while I was following "www.example.com/path/to/endpoints"
I've built a DocuSign integration that works fine with a sandbox account, but I'm having trouble with a live account. I'm using the C# SDK. I'm using an authorization code grant with impersonation. Debugging shows that a LoginInformation object is created, but it's LoginAccounts property is null, which, of course, breaks the code attempting to get the appropriate base URL for subsequent API calls. Any suggestions?
public static ApiClient GetDocuSignClient()
{
string accountType = SettingsKeyInfoProvider.GetValue(SiteContext.CurrentSiteName + ".DocuSignAccountType");
string integratorKey = SettingsKeyInfoProvider.GetValue(SiteContext.CurrentSiteName + ".DocuSignIntegratorKey");
string userID = SettingsKeyInfoProvider.GetValue(SiteContext.CurrentSiteName + ".DocuSignUserID");
string rsaPrivate = SettingsKeyInfoProvider.GetValue(SiteContext.CurrentSiteName + ".DocuSignRSAKey");
string basePath = accountType == "sandbox" ? "account-d.docusign.com" : "account.docusign.com";
// this gets replaced when we communicate with the api
string clientBasePath = accountType == "sandbox" ? "https://demo.docusign.net/restapi" : "https://www.docusign.net/restapi";
int expirationHours = 1;
if (accountType == "" || integratorKey == "" || userID == "" || rsaPrivate == "")
throw new System.Configuration.ConfigurationErrorsException("All DocuSign settings must be set in Settings->Integration->DocuSign");
ApiClient dsClient = new ApiClient(clientBasePath);
dsClient.ConfigureJwtAuthorizationFlow(integratorKey, userID, basePath, HttpContext.Current.Server.MapPath(rsaPrivate), expirationHours);
AuthenticationApi authClient = new AuthenticationApi(dsClient.Configuration);
LoginInformation loginInfo = authClient.Login();
// find the default account for this user
foreach (LoginAccount loginAcct in loginInfo.LoginAccounts)
{
...
Per our DS Docs also, With OAUTH (and JWT), you should not use Login_information API, instead you need to use User Info API Call to get the base URI. Once you get the Base URI then you all other non-authentication related APIs using this Base URI. Demo environment is only at one data center, so with your current code it is working fine in Sandbox, but PROD has multiple data centers like NA1, NA2, NA3, EU1, and your account can be in any one of them, so to know the exact URI to use to hit data center for creating envelopes, you need to use User Info API call to know the Base URI.
Currently in your code, you have hard coded the BaseUri (or client Base Path) clientBasePath = https://www.docusign.net/restapi, in this hard coding you are assuming that your PROD account is in NA1, but as I mentioned earlier it can be in any other datacenters also, so please change the code to call userinfo/ API call. Our SDK has this code (of incorrectly calling LoginInformation instead of userinfo/) incorrectly written and I have already reported it to DS Dev center team to fix this flow.
I've found what are either errors or very misleading statements in the DocuSign API documentation. It seems the oauth/userinfo call returns the base URL for an account in different formats for sandbox and live accounts. The following code is a bit messy, but it's working for both.
public static ApiClient GetDocuSignClient()
{
string accountType = SettingsKeyInfoProvider.GetValue(SiteContext.CurrentSiteName + ".DocuSignAccountType");
string integratorKey = SettingsKeyInfoProvider.GetValue(SiteContext.CurrentSiteName + ".DocuSignIntegratorKey");
string userID = SettingsKeyInfoProvider.GetValue(SiteContext.CurrentSiteName + ".DocuSignUserID");
string rsaPrivate = SettingsKeyInfoProvider.GetValue(SiteContext.CurrentSiteName + ".DocuSignRSAKey");
string basePath = accountType == "sandbox" ? "account-d.docusign.com" : "account.docusign.com";
// this gets replaced when we communicate with the api
string clientBasePath = accountType == "sandbox" ? "https://demo.docusign.net/restapi" : "https://www.docusign.net/restapi";
int expirationHours = 1;
if (accountType == "" || integratorKey == "" || userID == "" || rsaPrivate == "")
throw new System.Configuration.ConfigurationErrorsException("All DocuSign settings must be set in Settings->Integration->DocuSign");
ApiClient dsClient = new ApiClient(clientBasePath);
dsClient.ConfigureJwtAuthorizationFlow(integratorKey, userID, basePath, HttpContext.Current.Server.MapPath(rsaPrivate), expirationHours);
var rsUserClient = new RestSharp.RestClient("https://" + basePath); ;
RestSharp.RestRequest acctReq = new RestSharp.RestRequest();
acctReq.Method = RestSharp.Method.GET;
acctReq.RequestFormat = RestSharp.DataFormat.Json;
acctReq.Resource = "oauth/userinfo";
// even though we're not using the SDK to get accounts, we can use the token it generates
AuthenticationApi authClient = new AuthenticationApi(dsClient.Configuration);
acctReq.AddHeader("Authorization", authClient.Configuration.DefaultHeader["Authorization"]);
RestSharp.IRestResponse rsResponse = rsUserClient.Execute(acctReq);
if (rsResponse.ResponseStatus != RestSharp.ResponseStatus.Completed || rsResponse.StatusCode != HttpStatusCode.OK)
{
if (rsResponse.ErrorException != null)
throw new WebException("DocuSign login failed: " + rsResponse.ErrorException.Message, rsResponse.ErrorException);
else if (rsResponse.StatusCode == HttpStatusCode.BadRequest)
throw new WebException(String.Format("DocuSign login failed. StatusCode: {0} <br/>ErrorDescription: {1}", rsResponse.StatusCode, rsResponse.Content));
else
throw new WebException(String.Format("DocuSign login failed. StatusCode: {0} ResponseStatus: {1}", rsResponse.StatusCode, rsResponse.ResponseStatus));
}
DocuSignLoginInfo loginInfo = JsonConvert.DeserializeObject<DocuSignLoginInfo>(rsResponse.Content);
DocuSignLoginAccount toUse = null;
foreach (var loginAcct in loginInfo.Accounts)
{
if (toUse == null)
{
toUse = loginAcct; // use first account
}
else if (loginAcct.IsDefault &&
((accountType == "sandbox" && loginAcct.Base_Uri.Contains("demo.")) ||
(accountType != "sandbox" && !loginAcct.Base_Uri.Contains("demo."))))
{
toUse = loginAcct; // use default account if appropriate
}
}
if (toUse == null)
{
throw new WebException("DocuSign login failed: " + loginInfo.Email + " doesn't have a login account we can use.");
}
else
{
SettingsKeyInfoProvider.SetValue("DocuSignAccountID", SiteContext.CurrentSiteName, toUse.Account_Id);
string[] separatingStrings = { "/v2" };
string restUrl = toUse.Base_Uri.Split(separatingStrings, StringSplitOptions.RemoveEmptyEntries)[0];
if (!restUrl.Contains("/restapi"))
restUrl += "/restapi";
// Update ApiClient with the new base url from login call
dsClient = new ApiClient(restUrl);
}
return dsClient;
}
public class DocuSignLoginAccount
{
public string Account_Id;
public string Account_Name;
public bool IsDefault;
public string Base_Uri;
}
public class EnvelopeBrief
{
public string EnvID;
public Signer CurrentSigner;
public string ClientUserID;
}
I`m using PayPal.AdaptivePayments sdk for chained payment and refund process of chained payment.
Using following methods:
for payment : pay() method
for refund : refund() method as per sdk.
When try to refund with payKey then getting response with status: "NO_API_ACCESS_TO_RECEIVER"
Currently I`m sandbox account on development.
I have also followed paypal developer api/sdk docs but still getting same problem.
So please help me to refund process with status of "Refunded".
I have already review post related to this on stack-overflow but I didn`t proper solution in any post.
https://devtools-paypal.com/guide/ap_chained_payment?interactive=ON&env=sandbox
private void Refund(HttpContext contextHttp)
{
NameValueCollection parameters = contextHttp.Request.Params;
RefundRequest request = new RefundRequest(new RequestEnvelope("en_US"));
// Set optional parameters
if(parameters["receiverEmail"].Length > 0)
{
//(Required) Amount to be paid to the receiver
string[] amt = contextHttp.Request.Form.GetValues("receiverAmount");
// Maximum length: 127 characters
string[] receiverEmail = contextHttp.Request.Form.GetValues("receiverEmail");
//Telephone country code
string[] phoneCountry = contextHttp.Request.Form.GetValues("phoneCountry");
string[] phoneNumber = contextHttp.Request.Form.GetValues("phoneNumber");
//Telephone extension
string[] phoneExtn = contextHttp.Request.Form.GetValues("phoneExtn");
string[] primaryReceiver = contextHttp.Request.Form.GetValues("primaryReceiver");
string[] invoiceId = contextHttp.Request.Form.GetValues("invoiceId");
string[] paymentType = contextHttp.Request.Form.GetValues("paymentType");
//(Optional) The transaction subtype for the payment.
string[] paymentSubType = contextHttp.Request.Form.GetValues("paymentSubType");
List<Receiver> receivers = new List<Receiver>();
for(int i=0; i<amt.Length; i++) {
Receiver r = new Receiver(Convert.ToDecimal(amt[i]));
r.email = receiverEmail[i];
r.primary = Convert.ToBoolean(primaryReceiver[i]);
if(invoiceId[i] != string.Empty) {
r.invoiceId = invoiceId[i];
}
if(paymentType[i] != string.Empty) {
r.paymentType = paymentType[i];
}
if(paymentSubType[i] != string.Empty) {
r.paymentSubType = paymentSubType[i];
}
if(phoneCountry[i] != string.Empty && phoneNumber[i] != string.Empty) {
r.phone = new PhoneNumberType(phoneCountry[i], phoneNumber[i]);
if(phoneExtn[i] != string.Empty) {
r.phone.extension = phoneExtn[i];
}
}
receivers.Add(r);
}
request.receiverList = new ReceiverList(receivers);
}
if(parameters["currencyCode"] != string.Empty) {
request.currencyCode = parameters["currencyCode"];
}
if(parameters["payKey"] != string.Empty) {
request.payKey = parameters["payKey"];
}
if(parameters["transactionId"] != string.Empty) {
request.transactionId = parameters["transactionId"];
}
if(parameters["trackingId"] != string.Empty) {
request.trackingId = parameters["trackingId"];
}
AdaptivePaymentsService service = null;
RefundResponse response = null;
try
{
Dictionary<string, string> configurationMap = Configuration.GetAcctAndConfig();
service = new AdaptivePaymentsService(configurationMap);
response = service.Refund(request);
}
catch (System.Exception e)
{
contextHttp.Response.Write(e.Message);
return;
}
Dictionary<string, string> responseValues = new Dictionary<string, string>();
// string redirectUrl = null;
string redirectUrl = null;
if (!(response.responseEnvelope.ack == AckCode.FAILURE) &&
!(response.responseEnvelope.ack == AckCode.FAILUREWITHWARNING))
{
responseValues.Add("Currency code", response.currencyCode);
int idx = 1;
foreach (RefundInfo refund in response.refundInfoList.refundInfo)
{
//Receiver's email address.Maximum length: 127 characters
responseValues.Add("Refund receiver " + idx, refund.receiver.email);
// Amount to be refunded to the receiver.
responseValues.Add("Refund amount " + idx, refund.receiver.amount.ToString());
responseValues.Add("Refund status " + idx, refund.refundStatus);
responseValues.Add("Acknowledgement", response.responseEnvelope.ack.ToString());
}
}
Display(contextHttp, "Refund", responseValues, service.getLastRequest(), service.getLastResponse(), response.error, redirectUrl);
}
I need some help.Firstly I wrote one soap web service with basic authentication.But I have to change with wssecurity in soap.How can I consume coming ws security header I have to read username and password and I have to compare my username and password in my webconfig file inside service. I write this code but I m not sure : I done this way.But how can I configure in webconfig.file
public class QuantityService : Microsoft.Web.Services3.WebServicesClientProtocol, IQuantityService
{
private OperationResult AuthCheck()
{
OperationResult retVal = new OperationResult()
{
ReturnCode = 0,
ReturnMessage = "OK"
};
string userName = ConfigurationManager.AppSettings["username"].ToString();
string password = ConfigurationManager.AppSettings["password"].ToString();
//UsernameToken token = new UsernameToken(userName,password,PasswordOption.SendPlainText);
QuantityService serviceProxy = new QuantityService();
SoapContext requestContext = serviceProxy.RequestSoapContext;
//requestContext.Security.Tokens.Add(token);
if (requestContext == null)
{
throw new ApplicationException("Non-SOAP request.");
}
foreach (SecurityToken tok in requestContext.Security.Tokens)
{
if (tok is UsernameToken)
{
if (userName == ((UsernameToken)tok).Username && password == ((UsernameToken)tok).Password)
{
retVal.ReturnCode = 0;
retVal.ReturnMessage = "OK";
}
else
{
retVal.ReturnCode = -2;
retVal.ReturnMessage = "Unauthorized.";
}
}
}
return retVal;
}
I am getting the following error:
(OAuthException) client_secret should not be passed to
/oauth/access_token/
While I am calling the Facebook API to get me a "User Access Token" for further inquiries. My code is very simple:
string appId = "99999999"; // Long number - Given by FB in my application page
string appSecret = "98907kjlhkh908098"; // // Long string- Given by FB in my application page
string code = "089789uokjj"; // Access Code in response to my first FB call - It is in query string of response
var fb = new FacebookClient ( appId , appSecret );
var parameters = new Dictionary<string , object>
{
{ "client_id", appId },
{"redirect_uri" , "http://localhost:49773/Sample/Default.aspx"},
{ "client_secret", appSecret },
{ "code", code }
};
fb.Post( "https://graph.facebook.com/oauth/access_token/" , parameters );
How do I pass Client_Secret? Without that I cannot proceed and with that again I am getting exception!
Little tutorial for ASP.NET for server-side flow (I am using ver. 6 of FB C# SDK):
1) create login button and bind onclick event on login page:
var loginWindowPopup = null;
var loginWindowTimer = null;
$(function ()
{
$('#login_with_facebook').click(function ()
{
var popupWidth = 640;
var popupHeight = 337;
var xPosition = ($(window).width() - popupWidth) / 2;
var yPosition = ($(window).height() - popupHeight) / 2;
loginWindowPopup = window.open('/AuthSocialUser.aspx?facebookAuth=true',
'FacebookLoginWindow',
'location=1,scrollbars=1,menubar=0,status=0,toolbar=0' +
',width=' + popupWidth +
',height=' + popupHeight +
',left=' + xPosition +
',top=' + yPosition);
if (loginWindowTimer == null)
{
loginWindowTimer = setInterval(CheckLogonWindowClose, 1000);
}
}
);
function CheckLogonWindowClose()
{
if (loginWindowPopup.closed)
{
clearInterval(loginWindowTimer);
location.reload();
}
};
2) in AuthSocialUser.aspx popup window:
if (this.Request.QueryString["facebookAuth"] == "true")
{
var parameters = new Dictionary<string,object>();
parameters["client_id"] = "...";
// parameters["scope"] = "email";
string state = Guid.NewGuid().ToString();
parameters["state"] = state;
this.Session.Add("state", state); //CSRF protection
parameters["redirect_uri"] =
this.Request.Url.AbsoluteUri.Replace("facebookAuth=true", "facebookAuth=false");
parameters["response_type"] = "code"; // code can be exchanged for an access token
parameters["display"] = "popup";
this.Response.Redirect(new FacebookClient().GetLoginUrl(parameters).AbsoluteUri);
}
else
{
string code = this.Request.QueryString["code"];
string state = this.Request.QueryString["state"];
string currentState = (this.Session["state"] != null ?
this.Session["state"].ToString() : null);
if (string.IsNullOrWhiteSpace(code) == true)
{
// set info in session: app not authorized & inject close window JS script
return;
}
if (string.IsNullOrWhiteSpace(state) == true ||
string.IsNullOrWhiteSpace(currentState) == true)
{
// session state expired & inject close window JS script
return;
}
if (state != currentState)
{
throw new ArgumentException("State does not match (CSRF?)");
}
//// get access token
var fb = new FacebookClient();
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("client_id", "...");
parameters.Add("redirect_uri", "https://127.0.0.1
/AuthSocialUser.aspx?facebookAuth=false");
parameters.Add("client_secret", "...");
parameters.Add("code", code);
result = fb.Get("/oauth/access_token", parameters);
string accessToken = result["access_token"];
// use token in next requests, insert status to session state
// & inject close window JS script - simple: window.close();
}