I am running a script in R through Github actions, that aims to do a dummy action (connect to a Sharepoint location and list all files there). I have created a new App Registration in Azure and added the correct API Permissions for Microsoft Graph. The script is as below :
library(AzureAuth)
library(Microsoft365R)
library(httr)
# Set environment variables for service principal authentication
tenant_id <- "my-tenant-id"
client_id <- "my-client-id"
client_secret <- "my-client-secret"
# Define the scope for the token
scope <- "https://graph.microsoft.com" # For Microsoft Graph API
# Retrieve the Azure token using service principal credentials
token <- AzureAuth::get_azure_token(
resource = scope, # The scope/resource for which the token is required
tenant = tenant_id,
app = client_id,
password = client_secret,
auth_type = "client_credentials"
)
# Extract the access token
access_token <- token$access_token
# Use the token to authenticate to SharePoint
site <- Microsoft365R::get_sharepoint_site(
site_url = "https://mysite.sharepoint.com/sites/SampleLocation",
token = access_token
)
# Perform operations on SharePoint
drive <- site$get_drive()
drive$list_items()
When it runs on Github though, it always prompts me to Please point your browser to the following url:, which redirects me to an invalid URL. According to the documentation , I would expect that with this auth_type, there would be no need to perform any browser authentication. I even want to avoid that because I aim later on to schedule an action to run daily, so it should not need to perform any manual authentication.
Note that, user interaction is mandatory while using Microsoft365R functions as it uses Delegated permissions mentioned here. The token generated with client credentials flow won't work for these functions.
When I ran your code in my local environment via R Studio, it used authorization code flow by default and asked to pick account in browser for sign in, followed by consent prompt:
Once authentication is successful, I got the list of SharePoint files in response like this:
If you want to avoid user interaction, you can call Microsoft Graph REST API by generating token with client credentials flow as an alternative.
In my case, I used below modified code to generate token and used it to get SharePoint site information:
library(httr)
library(jsonlite)
tenant_id <- "tenantId"
client_id <- "appId"
client_secret <- "secret"
token_url <- paste0("https://login.microsoftonline.com/", tenant_id, "/oauth2/v2.0/token")
body <- list(
client_id = client_id,
scope = "https://graph.microsoft.com/.default",
client_secret = client_secret,
grant_type = "client_credentials"
)
response <- POST(
url = token_url,
body = body,
encode = "form"
)
if (status_code(response) == 200) {
cat("Token successfully retrieved.\n")
token_data <- content(response, "parsed")
access_token <- token_data$access_token
graph_url <- "https://graph.microsoft.com/v1.0/sites/root:/sites/siteName"
graph_response <- GET(
graph_url,
add_headers(
Authorization = paste("Bearer", access_token)
)
)
if (status_code(graph_response) == 200) {
cat("Request successful. Full response data:\n")
content_data <- content(graph_response, "parsed")
print(content_data)
} else {
cat("Request failed with status code:", status_code(graph_response), "\n")
content_data <- content(graph_response, "text")
print(content_data)
}
} else {
cat("Failed to retrieve the token. Status code:", status_code(response), "\n")
token_error <- content(response, "text")
print(token_error)
}
Response:
You can change the graph URL to get the list of drives present in that SharePoint site:
graph_url <- "https://graph.microsoft.com/v1.0/sites/siteID/drives"
graph_response <- GET(
graph_url,
add_headers(
Authorization = paste("Bearer", access_token)
)
)
if (status_code(graph_response) == 200) {
cat("Request successful. Full response data in JSON:\n")
content_data <- content(graph_response, "parsed")
json_response <- toJSON(content_data, pretty = TRUE, auto_unbox = TRUE)
cat(json_response, "\n")
}
Response:
Similarly, make use of below code to list the SharePoint files information by changing the graph URL:
graph_url <- "https://graph.microsoft.com/v1.0/drives/driveID/root/children"
graph_response <- GET(
graph_url,
add_headers(
Authorization = paste("Bearer", access_token)
)
)
if (status_code(graph_response) == 200) {
cat("Request successful. Full response data in JSON:\n")
content_data <- content(graph_response, "parsed")
json_response <- toJSON(content_data, pretty = TRUE, auto_unbox = TRUE)
cat(json_response, "\n")
}
Response:
Reference: