Issue using Insights Edge API - facebook

I am trying to get some insights data using Insights Edge API, but running into permissions issue:
Here is the code I am using:
string applicationId = "";
string applicationSecret = "";
string accountId = "";
System.Net.WebClient client = new System.Net.WebClient();
string accessToken = client.DownloadString("https://graph.facebook.com/oauth/access_token?client_id=" + applicationId + "&client_secret=" + applicationSecret + "&grant_type=client_credentials").Replace("access_token=","");
System.Net.WebRequest req = System.Net.WebRequest.Create("https://graph.facebook.com/v2.4/act_"+accountId+"/insights?access_token=" + accessToken);
System.Net.WebResponse response = req.GetResponse();
using(System.IO.StreamReader sr = new System.IO.StreamReader(response.GetResponseStream()))
{
string s = sr.ReadToEnd();
Console.WriteLine(s);
}
I am getting the following JSON back:
{
"error": {
"message": "(#10) You do not have sufficient permissions to perform this action",
"type": "OAuthException",
"code": 10
}
}
Application in question was created under the same Facebook account as the ad account. What do I need to check in account/application settings to see if I have all the correct permissions to access Ad Insights API? The code will need to run in the service that doesn't require user intervention, is application access token the right way to access ad insight data in this case?

Related

Unauthorized / token contains no permission when trying to use Microsoft Graph to send email

We have a registered application in Azure AD and set up client secrets to run it as a daemon app (with no user interaction). We have the API permissions Mail.Send and User.Read admin consented for Microsoft Graph API.
My understanding is to use construct a ConfidentialClientApplication to get an access token for the registered app, by which I can create a GraphServiceClient. Then I can use the client to send email as a user.
But I got the following exception saying there's no permission in the token: (but I did provide a scope for getting permission)
Message: The token contains no permissions, or permissions can not be understood.
Inner error:
AdditionalData:
request-id: omitted-xxxx-xxx-...31c53
date: 2020-03-13T23:41:08
ClientRequestId: omitted-xxxx-xxx-...31c57
at Microsoft.Graph.HttpProvider.SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
at Microsoft.Graph.BaseRequest.SendRequestAsync(Object serializableObject, CancellationToken cancellationToken, HttpCompletionOption completionOption)
at Microsoft.Graph.BaseRequest.SendAsync(Object serializableObject, CancellationToken cancellationToken, HttpCompletionOption completionOption)
at GraphCallsFromServiceAccount.MyGraphClient.SendEmail(GraphServiceClient graphClient) in C:\Users\xxxx\source\repos\GraphCallsFromAccount\MyGraphClient.cs:line 109
Relevant Code:
// create a ConfidentialClientApplication:
var app = ConfidentialClientApplicationBuilder.Create(AppClientId)
.WithAuthority(new Uri("https://login.microsoftonline.com/"+ TenantId + "/oauth2/v2.0/token"))
.WithClientSecret(ClientSecretString)
.Build();
var scopes = new string[] { "https://graph.microsoft.com/.default" }; // if changed to "Mail.Send", it throws errors saying invalid scope.
GraphServiceClient graphClient = new GraphServiceClient(
new DelegateAuthenticationProvider(
async (requestMg) =>
{
// add access token to header
var result = await app.AcquireTokenForClient(scopes).ExecuteAsync();
requestMg.Headers.Authorization = new AuthenticationHeaderValue("bearer", result.AccessToken);
}));
// send email:
try
{
var toAddress = "john_doe#helloworld.com";
var SenderAddress = "jane_doe#helloworld.com";
var recipient = new Recipient()
{
EmailAddress = new EmailAddress()
{
Name = "John Doe",
Address = toAddress,
}
};
Message email = new Message
{
Body = new ItemBody
{
Content = "<b>hello world</b>",
ContentType = BodyType.Html,
},
Subject = "hello world",
ToRecipients = new List<Recipient>() { recipient },
};
Console.WriteLine("hello 2");
await graphClient.Users["john_doe#helloworld.com"].SendMail(email, false).Request().PostAsync();
}
catch (Exception ex)
{
Console.WriteLine("ex: " + ex);
}
How do I request the correct permissions put in the access token then? Thanks for help
Since you are acquiring a token as an app,
you are most likely not using application permissions.
You cannot use delegated permissions when running as an app,
as those only apply if running in the context of a user.
You'll need to add the Mail.Send application permission on Microsoft Graph API,
and an admin must then consent that.

Service to Service Calls Using Client Credentials

I tried to create an alias for group in office 365 using below code but it shows some error.how to solve this. I tried to use service to service calls method. I got the token generated. How to check its valid or not? Is it possible to create alias using api for group without powershell option? if no kindly advice me to for other options..
string clientId = "************";
string clientsecret = "******";
string tenantId = "********";
//string resourceUri = "http://office.microsoft.com/outlook/";
string redirectUri = "https://login.live.com/oauth20_desktop.srf";
var authUri = "https://login.windows.net/" + tenantId + "/oauth2/authorize/";
var RESOURCE_URL = "https://graph.windows.net";
HttpClient client = new HttpClient();
var authContext = new AuthenticationContext(authUri);
var credential = new ClientCredential(clientId: clientId, clientSecret: clientsecret);
var result = authContext.AcquireTokenAsync(RESOURCE_URL, credential).Result;
client.DefaultRequestHeaders.Add("Authorization", "bearer " + result.AccessToken);
string content = #"{
'displayName': 'mailgrouptest',
'groupTypes': ['Unified'],
'mailEnabled': true,
'mailNickname': 'mailalias1',
'securityEnabled': false
}";
var httpContent = new StringContent(content, Encoding.GetEncoding("utf-8"), "application/json");
var response = client.PostAsync("https://graph.microsoft.com/v1.0/groups", httpContent).Result;
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
When i run this code in console it shows an error like this....is the problem with token ? or tenant id?
{
"error": {
"code": "InvalidAuthenticationToken",
"message": "Access token validation failure.",
"innerError": {``
"request-id": "*****-***-",
"date": "2016-05-25T04:53:08"
}
}
}
kindly advice me to create alias for group in api
The mailNickName of group is not able to update using the Microsoft Graph at present.
As a workaround, we can create a new group with the specific the mailNickName you wanted and use the new group. Here is the code to create a group with mailNicekName for your reference:
string clientId = "";
string clientsecret = "";
string tenant = "yourdomain.onmicrosoft.com";
var authUri = "https://login.microsoftonline.com/"+tenant+"/oauth2/token";
var RESOURCE_URL = "https://graph.microsoft.com";
HttpClient client = new HttpClient();
var authContext = new AuthenticationContext(authUri);
var credential = new ClientCredential(clientId: clientId, clientSecret: clientsecret);
var result = authContext.AcquireTokenAsync(RESOURCE_URL, credential).Result;
client.DefaultRequestHeaders.Add("Authorization", "bearer " + result.AccessToken);
string content = #"{
'description': 'description-value',
'displayName': 'displayName-value',
'groupTypes': [
'Unified'
],
'mailEnabled': true,
'mailNickname': 'mailNickname-value',
'securityEnabled': false
}";
var httpContent = new StringContent(content, Encoding.GetEncoding("utf-8"), "application/json");
//var response = client.GetAsync("https://graph.microsoft.com/v1.0/groups").Result;
var response = client.PostAsync("https://graph.microsoft.com/v1.0/groups",httpContent).Result;
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
More detail about Goupr REST API, please refer to here.
For the error “InvalidAuthenticationToken” you were request the access token with incorrect resource. To use the Microsoft Graph API, we need to specify the resource with “https://graph.microsoft.com” instead of “https://graph.windows.net”.
In addition, if you want the mailNickName of group is updateable, you can try to submit the feedback from here.

facebook sharing on servlet, jsp; getting auth code;

public FacebookConnector() {
try {
FacebookClient.AccessToken token = getFacebookUserToken("???", "http://localhost:8083/CrunchifyJSPServletExample/");
String accessToken = token.getAccessToken();
Date expires = token.getExpires();
fbClient = new DefaultFacebookClient(this.accessToken, Version.LATEST);
myuser = fbClient.fetchObject("me", User.class);
mypage = fbClient.fetchObject(pageID, Page.class);
counter = 0;
} catch (Exception ex) { //So that you can see what went wrong
ex.printStackTrace(System.err); //in case you did anything incorrectly
}
}
public void makeTestPost() {
FacebookType publishMessageResponse = fbClient.publish("me/feed", FacebookType.class, Parameter.with("message", "Test from Graph API"));
System.out.println("Published message ID: " + publishMessageResponse.getId());
}
private FacebookClient.AccessToken getFacebookUserToken(String code, String redirectUrl) throws IOException {
String appId = "My App Id";
String secretKey = "My Secret Key";
WebRequestor wr = new DefaultWebRequestor();
WebRequestor.Response accessTokenResponse = wr.executeGet(
"https://graph.facebook.com/oauth/access_token?client_id=" + appId + "&redirect_uri=" + redirectUrl
+ "&client_secret=" + secretKey + "&code=" + code);
return DefaultFacebookClient.AccessToken.fromQueryString(accessTokenResponse.getBody());
}
I am working on enabling facebook sharing for my application that is built on JSP and servlet.
I am using above code.
I need your inputs on 2 things:
1) If my approach is correct.
2) How to get auth code? So that can help me in getting authentication token.
Help of any sort is appreciated. Thanks. AY
For facebook authentication you can do like that:-
Click
It will generate code then use this code to send request to graph.facebook as you written correctly in your code then it will generate accesscode and use accesscode as per your requirement

How to access a secret group's posts using facebook-api?

I am a part of a secret group. I want to get all of the posts and their metadata. I use the following code:
import facebook
if __name__ == '__main__':
APP_SECRET = ""
APP_ID = ""
PAGE_ID = "" ## Page ID of the secret group
access_token = facebook.get_app_access_token(APP_ID, APP_SECRET)
graph = facebook.GraphAPI(access_token)
resp = graph.get_object('me/accounts')
page_access_token = None
for page in resp['data']:
if page['id'] == PAGE_ID:
page_access_token = page['access_token']
graph = facebook.GraphAPI(page_access_token)
but I get this error:
facebook.GraphAPIError: An active access token must be used to query information about the current user.
on line resp = graph.get_object('me/accounts').
Where am I going wrong?
The error message means that you did not authorize the user. How to do that: https://developers.facebook.com/docs/facebook-login/
/me/accounts is the endpoint to get access to pages, for groups you need the user_managed_groups permission and the /me/groups endpoint. You need to use an active User Token for that, of course.
More information: https://developers.facebook.com/docs/graph-api/reference/v2.4/user/groups

How to trace the rest request authentication parameters(username/password)

I have build a rest api with spring security. I'm getting the 401 errors in the nginx logs.
Now I want to intercept and trace the username, password, request body and URL before the authentication when i send a post request via rest client.
I'm able to get the url as String url = httpRequest.getRequestURL().toString();
Could any one please let me know how can i get the username, password and request body from HttpServletRequest.
Below code worked for me to get the username and password from the httpRequest for the information sent from the rest client.
String header = httpRequest.getHeader("Authorization");
if ((header != null) && (header.startsWith("Basic "))) {
String base64Token = header.substring(6);
String token = new String(Base64.decodeBase64(base64Token.getBytes()));
String username = "";
String password = "";
int delim = token.indexOf(":");
if (delim != -1) {
username = token.substring(0, delim);
password = token.substring(delim + 1);
}
}