Closed vekonylaszlo closed 10 months ago
Hi @vekonylaszlo,
.GetFileByPath(item.Url).Download()
is a method to deal with a file through SharePoint API referencing it by ServerRelativeURL (like /sites/my-site/doc-lib/folder/my-file.dat
).
If you know file location in SharePoint and service account has permissions to it, you can download it with the API.
An abstract URL to a "shared file" won't necessarily work as literally you could have any link in the URL field. Even if it's a SharePoint file shared - it's then outside SharePoint API context.
Having a WOPI URL like https://{tenant}.sharepoint.com/:x:/s/{sile}/EQT6Kcs-4h5LjVEaV8pLF-UBchNR-uKeiuUjJrMeE3GI2A?e=tcWSaU
, theoretically it's accessible with the same FedAuth Cookie, then it contains _wopiContextJson
object in server-side crafted JS fragment with identities to the original file (FileName, ParentFolderFullUrl). There should be some other way to get original URL yet I'm not sure. I've never needed reversing files share URL, usually you know original SharePoint context explicitly. UPD: Actually, this won't work as not necessarily you have an office document.
You can try using something like this to get SharePoint Server Relative URLs from Shared Links:
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"net/url"
"regexp"
"io"
"github.com/koltyakov/gosip"
"github.com/koltyakov/gosip/auth"
)
func GetServerRelativeURLFromSharedLink(client *gosip.SPClient, sharedURL string) (string, error) {
req, _ := http.NewRequest("GET", sharedURL, nil)
resp, err := client.Execute(req)
// None Office Formats
if resp.StatusCode == 302 {
parsedURL, err := url.Parse(resp.Header.Get("Location"))
if err != nil {
return "", fmt.Errorf("can't parse redirect location: %w", err)
}
return parsedURL.Query().Get("id"), nil
}
if err != nil {
return "", fmt.Errorf("can't execute request: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(io.Reader(resp.Body))
re := regexp.MustCompile(`var _wopiContextJson =({.*?});`)
match := re.FindStringSubmatch(string(body))
var d struct {
FileName string `json:"FileName"`
ParentFolderFullUrl string `json:"ParentFolderFullUrl"`
}
if len(match) < 1 {
return "", fmt.Errorf("no match found for _wopiContextJson")
}
jsonStr := match[1]
err = json.Unmarshal([]byte(jsonStr), &d)
if err != nil {
return "", fmt.Errorf("can't unmarshal _wopiContextJson: %w", err)
}
parsedURL, err := url.Parse(d.ParentFolderFullUrl + "/" + d.FileName)
if err != nil {
return "", fmt.Errorf("can't parse ParentFolderFullUrl: %w", err)
}
return parsedURL.Path, nil
}
func main() {
sharedUrl := "https://{tenant}.sharepoint.com/:u:/s/ci/EcpaZ9PHKoFDoueaXcvy_68B4s7QLsEhB0dybIweMBXZiA?e=Iy8CXC"
cnfg, err := auth.NewAuthFromFile("./config/private.spo-user.json")
if err != nil {
log.Fatal(err)
}
client := &gosip.SPClient{AuthCnfg: cnfg}
serverRelativeURL, err := GetServerRelativeURLFromSharedLink(client, sharedUrl)
if err != nil {
log.Fatal(err)
}
fmt.Printf("ServerRelativeURL: %s\n", serverRelativeURL)
}
Checked it in Office and non-office formats.
Then serverRelativeURL
is what to use in sp.Web().GetFileByPath(serverRelativeURL)
.
Thank you very much for the help! Converting the SharedLink is working, I just need to fix one error (invalid URL escape "% P"
), but I think it will work from here.
Have a nice day!
Hello,
In our setup, we manage a list wherein one of the columns contains links to uploaded files. I am retrieving and processing the items using the following Go code:
However, I am encountering a 400 Bad Request error, and the SharePoint API returns the following error message:
I have also attempted to use api.NewHTTPClient, but I am unable to make it work. Could you kindly provide assistance on how I can address this issue? Any guidance or suggestions would be greatly appreciated.
Thank you for your time and support.