Lead Ads Testing Tool - Server failure (102) - c#

I'm trying to get Facebook leadgen ad data.
1-)As seen below, facebook sends the data to me successfully and I receive it successfully.
Successful Process img
2-)But the submissions I made on just this page do not come. What could be the reason for this?
Failed Process img
*But only the opinions I made on this page are not coming. What could be the reason for this?
Facebook doesn't even post. As seen in the picture, Server failure (102) information is displayed. What is the reason of this?
3-)The code I received the incoming data
Asp.Net Api Method
public async Task<HttpResponseMessage> Post([FromBody] JsonData data)
{
try
{
dbmanager db = new dbmanager();
db.Jsonkaydetv2(data);
var entry = data.Entry.FirstOrDefault();
var change = entry?.Changes.FirstOrDefault();
if (change == null) return new HttpResponseMessage(HttpStatusCode.BadRequest);
//Generate user access token here https://developers.facebook.com/tools/accesstoken/
const string token = "XXXX";
var leadUrl = $"https://graph.facebook.com/v2.10/{change.Value.LeadGenId}?access_token={token}";
var formUrl = $"https://graph.facebook.com/v2.10/{change.Value.FormId}?access_token={token}";
using (var httpClientLead = new HttpClient())
{
var response = await httpClientLead.GetStringAsync(formUrl);
if (!string.IsNullOrEmpty(response))
{
var jsonObjLead = JsonConvert.DeserializeObject<LeadFormData>(response);
db.JsonkaydetLeadFormData(jsonObjLead);
//jsonObjLead.Name contains the lead ad name
//Jsonkaydet(jsonObjLead.Name+"x");
//If response is valid get the field data
using (var httpClientFields = new HttpClient())
{
var responseFields = await httpClientFields.GetStringAsync(leadUrl);
if (!string.IsNullOrEmpty(responseFields))
{
var jsonObjFields =JsonConvert.DeserializeObject<LeadData(responseFields);
db.JsonkaydetLeadData(jsonObjFields);
//jsonObjFields.FieldData contains the field value
}
}
}
}
return new HttpResponseMessage(HttpStatusCode.OK);
}
catch (Exception ex)
{
Jsonkaydet(ex.ToString());
Trace.WriteLine($"Error-->{ex.Message}");
Trace.WriteLine($"StackTrace-->{ex.StackTrace}");
return new HttpResponseMessage(HttpStatusCode.BadGateway);
}
}

Related

Power BI Embedded with Roles, allowing Row Level Security

I have implemented the Microsoft Example for Embed for your customers from Github, which works perfectly. Link
I am now extending it which there are articles showing using both V1 and V2 of the API, both result in the same error:
Operation returned an invalid status code 'BadRequest'
at
Microsoft.PowerBI.Api.ReportsOperations.GenerateTokenInGroupWithHttpMessagesAsync(Guid
groupId, Guid reportId, GenerateTokenRequest requestParameters,
Dictionary`2 customHeaders, CancellationToken cancellationToken)
[HttpGet]
public async Task<string> GetEmbedInfo()
{
try
{
// Validate whether all the required configurations are provided in appsettings.json
string configValidationResult = ConfigValidatorService.ValidateConfig(azureAd, powerBI);
if (configValidationResult != null)
{
HttpContext.Response.StatusCode = 400;
return configValidationResult;
}
EmbedParams embedParams = await pbiEmbedService.GetEmbedParams(new Guid(powerBI.Value.WorkspaceId), new Guid(powerBI.Value.ReportId));
//EmbedParams embedParams = await pbiEmbedService.GetEmbedToken4(new Guid(powerBI.Value.WorkspaceId), new Guid(powerBI.Value.ReportId));
return JsonSerializer.Serialize<EmbedParams>(embedParams);
}
catch (Exception ex)
{
HttpContext.Response.StatusCode = 500;
return ex.Message + "\n\n" + ex.StackTrace;
}
}
The above code is getting called and per the demo.
public async Task<EmbedParams> GetEmbedParams(Guid workspaceId, Guid reportId, [Optional] Guid additionalDatasetId)
{
PowerBIClient pbiClient = this.GetPowerBIClient();
// Get report info
var pbiReport = await pbiClient.Reports.GetReportInGroupAsync(workspaceId, reportId);
//var generateTokenRequestParameters = new GenerateTokenRequest("View", null, identities: new List<EffectiveIdentity> { new EffectiveIdentity(username: "**************", roles: new List<string> { "****", "****" }, datasets: new List<string> { "datasetId" }) });
//var tokenResponse = pbiClient.Reports.GenerateTokenInGroupAsync("groupId", "reportId", generateTokenRequestParameters);
// Create list of datasets
var datasetIds = new List<Guid>();
// Add dataset associated to the report
datasetIds.Add(Guid.Parse(pbiReport.DatasetId));
// Append additional dataset to the list to achieve dynamic binding later
if (additionalDatasetId != Guid.Empty)
{
datasetIds.Add(additionalDatasetId);
}
// Add report data for embedding
var embedReports = new List<EmbedReport>() {
new EmbedReport
{
ReportId = pbiReport.Id, ReportName = pbiReport.Name, EmbedUrl = pbiReport.EmbedUrl
}
};
// Get Embed token multiple resources
var embedToken = await GetEmbedToken4(workspaceId, reportId);
// Capture embed params
var embedParams = new EmbedParams
{
EmbedReport = embedReports,
Type = "Report",
EmbedToken = embedToken
};
return embedParams;
}
The above code is per the demo apart from one line, which is calling the next method:
var embedToken = await GetEmbedToken4(workspaceId, reportId);
public EmbedToken GetEmbedToken(Guid reportId, IList<Guid> datasetIds, [Optional] Guid targetWorkspaceId)
{
PowerBIClient pbiClient = this.GetPowerBIClient();
// Create a request for getting Embed token
// This method works only with new Power BI V2 workspace experience
var tokenRequest = new GenerateTokenRequestV2(
reports: new List<GenerateTokenRequestV2Report>() { new GenerateTokenRequestV2Report(reportId) },
datasets: datasetIds.Select(datasetId => new GenerateTokenRequestV2Dataset(datasetId.ToString())).ToList(),
targetWorkspaces: targetWorkspaceId != Guid.Empty ? new List<GenerateTokenRequestV2TargetWorkspace>() { new GenerateTokenRequestV2TargetWorkspace(targetWorkspaceId) } : null
);
// Generate Embed token
var embedToken = pbiClient.EmbedToken.GenerateToken(tokenRequest);
return embedToken;
}
The above code is per the example with no roles being passed in or EffectiveIdentity. This works.
public async Task<EmbedToken> GetEmbedToken4(Guid workspaceId, Guid reportId, string accessLevel = "view")
{
PowerBIClient pbiClient = this.GetPowerBIClient();
var pbiReport = pbiClient.Reports.GetReportInGroup(workspaceId, reportId);
string dataSet = pbiReport.DatasetId.ToString();
// Generate token request for RDL Report
var generateTokenRequestParameters = new GenerateTokenRequest(
accessLevel: accessLevel,
datasetId: dataSet,
identities: new List<EffectiveIdentity> { new EffectiveIdentity(username: "******", roles: new List<string> { "********" }) }
);
// Generate Embed token
var embedToken = pbiClient.Reports.GenerateTokenInGroup(workspaceId, reportId, generateTokenRequestParameters);
return embedToken;
}
This is the method to return the token with the roles and effective Identity. This results in the error, but no message or helpful feedback.
OK, after much research overnight the Bad Request response does hide an English message which is not show in the browser. The debugger doesn't have the symbols for the part that causes the error, but I found it by using Fiddler proxy when the actual API responded to the request. In my case, if you send an ID to enable RLS, but the version of the report on the server doesn't have it, this doesn't ignore it, it refuses to give a token to anything. From reading many posts, the Bad Request is just a poor error message when the actual response from the API itself (not the package or the example code that the sample uses with it presents). Hope this helps someone in the future.

Instasharper does not return Likers and Tags list

I have this piece of code in C# using InstaSharper to return information of a media id from Instagram.
public async Task<UserSessionData> SignIn(string userName, string password)
{
userSessionData = new UserSessionData();
userSessionData.UserName = "username";
userSessionData.Password = "password";
api = InstaApiBuilder.CreateBuilder()
.SetUser(userSessionData)
.Build();
var loginRequest = await api.LoginAsync();
if (loginRequest.Succeeded && api.IsUserAuthenticated)
{
IResult<InstaUser> userSearch = await api.GetUserAsync(userName);
IResult<InstaMediaList> media = await api.GetUserMediaAsync(userName, PaginationParameters.MaxPagesToLoad(1));
IResult<InstaMedia> mediaInfo = await api.GetMediaByIdAsync("1924613027431050955");
return userSessionData;
}
else
{
return null;
}
}
GetMediaByIdAsync method correctly returns data about the requested media but the Likers and Tags collection is empty. Is there any way to include those data?
Had the same issue, I found the solution.
Try using this code:
var posts = await api.GetUserMediaAsync("username", PaginationParameters.MaxPagesToLoad(Int32.MaxValue)); // If you want to load all of the posts. If not, replace the "Int32.MaxValue" with the amount of posts you want to load
foreach (var post in posts.Value)
{
var likers = await api.GetMediaLikersAsync(post.InstaIdentifier);
foreach (var liker in likers.Value)
{
Console.WriteLine(liker.UserName);
}
}
This works fine for me, try it out, Im sure it will work for you as well.

How do invoke the Paypal IPN using the REST API c# .net

I am having problems invoking the PayPal IPN. I dont know which URL to give or which URL i am meant to give. I have looked all over the internet for help but there does not seem to be anything available hence why i have come here.
So firstly, i have the PaymentWithPaypal Action
public ActionResult PaymentWithPaypal(int? id, Page page)
{
//getting the apiContext as earlier
APIContext apiContext = Models.Configuration.GetAPIContext();
try
{
string payerId = Request.Params["PayerID"];
if (string.IsNullOrEmpty(payerId))
{
string baseURI = Request.Url.Scheme + "://" + Request.Url.Authority + "/ControllerName/PaymentWithPayPal?";
var guid = Guid.NewGuid().ToString();
//CreatePayment function gives us the payment approval url
//on which payer is redirected for paypal acccount payment
var createdPayment = this.CreatePayment(apiContext, baseURI + "guid=" + guid);
//get links returned from paypal in response to Create function call
var links = createdPayment.links.GetEnumerator();
string paypalRedirectUrl = null;
while (links.MoveNext())
{
Links lnk = links.Current;
if (lnk.rel.ToLower().Trim().Equals("approval_url"))
{
//saving the payapalredirect URL to which user will be redirected for payment
paypalRedirectUrl = lnk.href;
}
}
// saving the paymentID in the key guid
Session.Add(guid, createdPayment.id);
return Redirect(paypalRedirectUrl);
}
else
{
// This section is executed when we have received all the payments parameters
// from the previous call to the function Create
// Executing a payment
var guid = Request.Params["guid"];
var executedPayment = ExecutePayment(apiContext, payerId, Session[guid] as string);
if (executedPayment.state.ToLower() != "approved")
{
return View("FailureView");
}
}
}
catch (Exception ex)
{
Logger.Log("Error" + ex.Message);
return View("FailureView");
}
return View("SuccessView");
}
This is the code for the IPN.
[HttpPost]
public HttpStatusCodeResult Receive()
{
//Store the IPN received from PayPal
LogRequest(Request);
//Fire and forget verification task
Task.Run(() => VerifyTask(Request));
//Reply back a 200 code
return new HttpStatusCodeResult(HttpStatusCode.OK);
}
private void VerifyTask(HttpRequestBase ipnRequest)
{
var verificationResponse = string.Empty;
try
{
var verificationRequest = (HttpWebRequest)WebRequest.Create("https://www.sandbox.paypal.com/cgi-bin/webscr");
//Set values for the verification request
verificationRequest.Method = "POST";
verificationRequest.ContentType = "application/x-www-form-urlencoded";
var param = Request.BinaryRead(ipnRequest.ContentLength);
var strRequest = Encoding.ASCII.GetString(param);
//Add cmd=_notify-validate to the payload
strRequest = "cmd=_notify-validate&" + strRequest;
verificationRequest.ContentLength = strRequest.Length;
//Attach payload to the verification request
var streamOut = new StreamWriter(verificationRequest.GetRequestStream(), Encoding.ASCII);
streamOut.Write(strRequest);
streamOut.Close();
//Send the request to PayPal and get the response
var streamIn = new StreamReader(verificationRequest.GetResponse().GetResponseStream());
verificationResponse = streamIn.ReadToEnd();
streamIn.Close();
}
catch (Exception exception)
{
Logger.Log("Error" + exception.Message);
//Capture exception for manual investigation
}
ProcessVerificationResponse(verificationResponse);
}
private void LogRequest(HttpRequestBase request)
{
// Persist the request values into a database or temporary data store
}
private void ProcessVerificationResponse(string verificationResponse)
{
if (verificationResponse.Equals("VERIFIED"))
{
Logger.Log("Verified");
// check that Payment_status=Completed
// check that Txn_id has not been previously processed
// check that Receiver_email is your Primary PayPal email
// check that Payment_amount/Payment_currency are correct
// process payment
}
else if (verificationResponse.Equals("INVALID"))
{
Logger.Log(verificationResponse);
}
else
{
//Log error
}
}
Now to clear things up. My understanding of the IPN is that when a customer purchases an item, the SELLER will get an email telling them that they have sold a product and then from this you can access transactionId etc.
So in my view i have a form with a button that looks like this.
#Html.ActionLink("Buy Now", "PaymentWithPaypal", new { Id = Model.Id, #class = "" })
This is what takes the customer to paypal where they can then purchase but this is where i am stuck because im not sure how to call the IPN or if it needs its own view.
ANY CLARITY WOULD BE OF MUCH HELP AT THIS MOMENT IN TIME.
One way is to put this under PayPal account settings. Once you click on your "App", below it you see the redirect url option. Just add it there. Paypal .net sdk doesn't have the option to pass notify_url. All other modes have. Because, paypal.net sdk accepts return_url which is usually the same action method as also mentioned in your code.
Check this:
https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNSetup/#
In case you want to achieve real time events, you need to use webhooks now. Documentation below:
https://github.com/paypal/PayPal-NET-SDK/wiki/Webhook-Event-Validation

Trying to call public async Task<Boolean> from a public string submit method

I'm pretty new to this Async thing. I'm trying to write in to an API using a createasync method. However, for some reason I either get an aggregate exception, or the thread just hangs depending on what I've tried. Here is a code example because I have yet to be able to successfully write in to the Salesforce API. I have been able however, to pull back data using similar operations.
Submit Method where I want this all to take place in my controller:
[System.Web.Http.HttpPost]
public string Submit([FromBody]SurveyFormModel survey)
{
// todo - Validate data and stop if bad data comes in.
var report = BuildReport(survey.Questions);
try
{
var task = Task.Run(async () => { await SendReportToSalesforce(survey); });
task.Wait();
}
catch (Exception ex)
{
ex.GetBaseException();
}
EmailExcel(survey);
return JsonConvert.SerializeObject(report);
}
This is the method I'm using to call my salesforceservice.cs
public async Task SendReportToSalesforce([FromBody] SurveyFormModel survey)
{
SalesforceService service = new SalesforceService();
var auth = service.Authenticate();
var sfSurvey = service.SalesForceMapper(survey, survey.AccountDetails);
var result = await service.SendSurveytoSF(auth.Result, sfSurvey); //.Wait();
Console.WriteLine(result);
}
Also included is the salesforceservice class I use to authenticate as well as the method (SendSurveytoSF) that doesnt seem to be working.
public async Task<ForceClient> Authenticate()
{
//get credential values
var consumerkey = ConfigurationManager.AppSettings["consumerkey"];
var consumersecret = ConfigurationManager.AppSettings["consumersecret"];
var username = ConfigurationManager.AppSettings["username"];
var password = ConfigurationManager.AppSettings["password"];
//create auth client to retrieve token
var auth = new AuthenticationClient();
//get back URL and token
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
try
{
await
auth.UsernamePasswordAsync(consumerkey, consumersecret, username, password,
"https://test.salesforce.com/services/oauth2/token");
}
catch (Exception ex)
{
return null;
}
var instanceUrl = auth.InstanceUrl;
var accessToken = auth.AccessToken;
var apiVersion = auth.ApiVersion;
return new ForceClient(instanceUrl, accessToken, apiVersion);
}
public async Task<Boolean> SendSurveytoSF(ForceClient sfclient, Models.Salesforce.Survey survey)
{
survey.Account__c = "0012200000Ah3zG";
var response = await sfclient.CreateAsync("VBR_Assessment__c", survey);
return response.Id != null;
}
I believe I'm maybe just not calling these methods properly, but at this point I really have no clue as I've tried implementing it a ton of different ways. Thank you for any help in advanced!
UPDATE
This is the exception I'm getting:
A first chance exception of type 'Salesforce.Common.ForceException' occurred in mscorlib.dll

Verify app invite server-side

When our mobile app user sends app-invite to fb user and he accepts it, the server should give a reward to the first one. So I need a way to verify whether the invite was sent.
var fb = new FacebookClient(APP_ID + "|" + SECRET_ID);
fb.AppId = APP_ID;
fb.AppSecret = SECRET_ID;
dynamic result = fb.Get(???);
I searched on GraphAPI docs and it seems that I need to retrieve users apprequests. How to do that from the server side and where to look at to perform such verification?
UPDATE
Ok, now I know that it's allowed to reward only for accepted invites. I can record who invites who in the db and give a reward only when a new invited user joins. But I still need a way to verify that these invites were actually sent.
UPDATE2
As the documentation states apprequests call from application returns all the requests sent from this application. So I think it would be enough for me to just check that there are any requests from this app:
dynamic result = fb.Get("/" + facebookId + "/apprequests");
IEnumerable data = result.data;
return data.Cast<object>().Count() != 0;
But I can't check it now. Can anyone confirm that if a user sends invite to app to another user this invite will be seen through apprequests from the application access token?
my code for this:
public static FacebookRequestData GetInviteHash()
{
string requestId = Request["request_ids"];
var accessToken = GetAccessToken(ConfigurationManager.AppSettings["FacebookAppId"], ConfigurationManager.AppSettings["FacebookSecret"]);
string response;
using (var webClient = new WebClient())
{
response = webClient.DownloadString(string.Format("https://graph.facebook.com/{0}?{1}", requestId, accessToken));
}
var javaScriptSerializer = new JavaScriptSerializer();
return javaScriptSerializer.Deserialize<FacebookRequestData>(javaScriptSerializer.Deserialize<FacebookRequestInfo>(response).data);
}
private static string GetAccessToken(string appId, string password)
{
using (var webClient = new WebClient())
{
return webClient.DownloadString(string.Format("https://graph.facebook.com/oauth/access_token?client_id={0}&client_secret={1}&grant_type=client_credentials", appId, password));
}
}
private class FacebookRequestInfo
{
public string data { get; set; }
}
FacebookRequestData - my custom class with structure of fields that I posted to fb earlier
Done it:
public static bool CheckInvite(string fromId, string toId)
{
var fb = new FacebookClient(APP_ID + "|" + SECRET_ID);
fb.AppId = APP_ID;
fb.AppSecret = SECRET_ID;
dynamic result = fb.Get(string.Format("/{0}/apprequests", toId));
foreach (var el in result.data)
if ((string)el.from.id == fromId)
{
DateTime dateTime = DateTime.Parse((string)el.created_time, CultureInfo.InvariantCulture);
if ((DateTime.Now - dateTime).TotalMinutes < 15)
{
return true;
}
}
return false;
}

Categories