https://developer.laserfiche.com/guide_exporting-documents.html
How do I export a document that is imported as an image?
Export of pdf and doc works, but for documents that are a tif, the content is empty, no errors in the API call.
https://developer.laserfiche.com/guide_exporting-documents.html
How do I export a document that is imported as an image?
Export of pdf and doc works, but for documents that are a tif, the content is empty, no errors in the API call.
Correct, authentication for v2-alpha and later will use an OAuth access token. Depending on your application type you have to register a service/web or SPA web app on the developer console and follow the steps for obtaining an access token. The documentation is being published but for a service type application you can see it here: https://developer.laserfiche.com/guide_oauth-service.html
I don't think this is possible with the API. The reason this endpoint is return you empty is because this endpoint exports electronic documents. Electronic documents are different to Image documents. Image documents don't have an edoc component so you are getting blank returned. More on the differences here https://doc.laserfiche.com/laserfiche.documentation/11/userguide/en-us/Subsystems/client_wa/Content/Introduction/Entries.htm
It's possible to export the image pages with the SDK.
Thanks!
This has been addressed in a new API which allows specifying the part of the document to be exported (in this case "pages"), the page range, the format.
The documentation for v2-alpha isn't yet published but you can see the request format on the swagger page:
ttps://api.laserfiche.com/repository/swagger/index.html?urls.primaryName=v2-alpha#/Entries/Simple%20Export
Great, thanks for this info. Is the Auth process different for v2-alpha? The Bearer token generated works with v1. I get this error (personal info masked). Is there any info for v2 authorizations? Thanks in advance!
Request:
curl -X 'POST' \
'https://api.laserfiche.com/repository/v2-alpha/Repositories/************/Entries/****/Export?part=Pages&format=Tiff&pageRange=1' \
-H 'accept: application/json' \
-H 'Authorization: Bearer ************************' \
-H 'Content-Type: application/json' \
-d '{
"auditReasonId": 0,
"comment": "string"
}'
Response:
{
"type": "accessDenied",
"title": "Error: Access Denied.",
"status": 401,
"instance": "/v2-alpha/Repositories/************/Entries/****/Export",
"operationId": "************",
"errorSource": "Api Server",
"errorCode": 201,
"traceId": "****"
}
Correct, authentication for v2-alpha and later will use an OAuth access token. Depending on your application type you have to register a service/web or SPA web app on the developer console and follow the steps for obtaining an access token. The documentation is being published but for a service type application you can see it here: https://developer.laserfiche.com/guide_oauth-service.html
Thank you. Would you be able to provide a rough date on when v2-alpha documentation will be available? I have setup a Service Principal account, granted permissions to the repo etc. following existing docs, but keep getting this error on v2 calls, any tips appreciated.
{"type":"accessDenied","title":"No existing Laserfiche Repository connection could be found with the OAuth information.","status":401,"instance":"/v2-alpha/Repositories.....
The documentation for the Web and SPA (single page app) flows will be published soon, we'll update this thread when it happens.
It seems like you were able to get an access token - an earlier version of your post said you were having problems with the POST request from step 6.
If you were able to get an access token did you create a "repository session" as described in documentation page from my previous reply?
It would be easier using the library which wraps these http requests:
https://support.laserfiche.com/download/4166
Thank you, works now! I had missed that final part, sorry. I was also able to successfully save the tif from the "value" URL.
I did see the library earlier, but couldn't find any documentation/samples for a quick start, so went this route. Will use the library going forward thanks.
@████████ What "value" URL are you talking about? I would love to be able to get the tif (or png or whatever) but having no luck.
Sure - this API (https://api.laserfiche.com/repository/v2-alpha/Repositories/{repoId}/Entries/{entryId}/Export?part=Pages&format=Tiff ) with a valid Bearer token retuns the json below (masked the final download url string).
{
"@odata.context": "https://api.laserfiche.com/repository/v2-alpha/$metadata#Edm.String",
"value": "https://app.laserfiche.com/file/download/******************"
}
I was then able to subsequently programmatically download this bytearray and save as a tif.
Hope I was clear.
@████████ thank you I didn't see that it was only on the v2-alpha. I can't seem to get my bearer token to work with v2-alpha but I expect that is a different issue and your answer will solve my issue getting the images.
Thanks!
Sorry for the late reply, hope this worked. If needed I can send the sample C# code I have...
Thanks, but my current issue is that I get an Access Denied message for anything I do in v2-alpha so it's not specific to the Export. If you have any info/ideas on why that's happening (or if I need to register or something?) that would be great. Otherwise, once I get past that error I'm sure the Export will work fine.
I just followed all the instructions from https://developer.laserfiche.com/guide_oauth-service.html
though initially I had to setup the service principal a second time carefully and also registered and used another app in the developer console to get it all to work...
I've been successful using the v2 API in the call to get the URL of the exported document that is returned but then attempting to retrieve that URL never works. Do you have any sample code somewhere that shows how to make that work properly?
I think there is now a github repo sample also (https://github.com/Laserfiche/lf-sample-repository-api-dotnet-srv ), haven't tried it yet. But, here is some C# console app code we had used initially for testing, we have a separate implementation that works based on this. Apologize for the crude code, but hope this helps. Just tested quickly now and still works, sorry for all the hard coded paths etc.
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RestSharp;
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Claims;
using System.Security.Cryptography;
namespace ConsoleApp1
{
static class Program
{
static void Main(string[] args)
{
Test();
}
private static bool Test()
{
try
{
string repoId = "YourRepoId";
string entryId = "LaserficheDocIDToRetrieve";
string clientId = "ClientIDFromDevConsoleAppConfiguration";
string servicePrincipalKey = "ServicePrincipalKeyFromLaserficheAccountAdminArea";
string key = System.IO.File.ReadAllText(@"ServiceKey.txt");//ServiceKey downloaded from App Configuration Authentication, placed on same folder as this app
string uri = $"https://api.laserfiche.com/repository/v2-alpha/Repositories/{repoId}/Entries/{entryId}";
var token = CreateClientCredentialsAuthorizationJwt(clientId, servicePrincipalKey, new JsonWebKey(key));
Console.WriteLine(token);
var apiToken = CreateApiAccessToken(token);
CreateRepositorySession(apiToken.access_token, repoId);
EntryInfo resDoc = GetEntryInfo(uri, apiToken.access_token, repoId, entryId);
GetDoc(apiToken.access_token, repoId, entryId, resDoc);
ImportDoc(apiToken.access_token, repoId, @"C:\temp\Test.pdf", "LaserficheParentFolderIdToImportTo", "UploadTest.pdf");
}
catch (Exception ex)
{
string err = ex.Message;
}
return true;
}
static TokenInfo CreateAccessToken(string customerId, string repoId, string userName, string password, string applicationName)
{
TokenInfo token = null;
var client = new RestClient($"https://api.laserfiche.com/repository/v1-alpha/Repositories/{repoId}/AccessTokens/Create?customerId={customerId}");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
JObject jsonBody = new JObject();
jsonBody.Add("username", userName);
jsonBody.Add("password", password);
jsonBody.Add("applicationName", applicationName);
request.AddParameter("application/json; charset=utf-8", jsonBody, ParameterType.RequestBody);
request.RequestFormat = DataFormat.Json;
try
{
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
token = JsonConvert.DeserializeObject<TokenInfo>(response.Content);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return token;
}
static AttributesInfo GetAttributes(string token, string repoId)
{
AttributesInfo resultVal = null;
CreateRepositorySession(token, repoId);
var client = new RestClient($"https://api.laserfiche.com/repository/v1-alpha/Repositories/{repoId}/Attributes");
client.Timeout = -1;
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", $"Bearer {token}");
request.RequestFormat = DataFormat.Json;
try
{
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
resultVal = JsonConvert.DeserializeObject<AttributesInfo>(response.Content);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return resultVal;
}
static EntryInfo GetEntryInfo(string uriVersion, string apiToken, string repoId, string entryId)
{
EntryInfo resultVal = null;
var client = new RestClient(uriVersion);
client.Timeout = -1;
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", $"Bearer {apiToken}");
request.RequestFormat = DataFormat.Json;
try
{
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
resultVal = JsonConvert.DeserializeObject<EntryInfo>(response.Content);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return resultVal;
}
static string GetEntryHeaderInfo(string token, string repoId, string entryId)
{
string resultVal = "";
var client = new RestClient($"https://api.laserfiche.com/repository/v2-alpha/Repositories/{repoId}/Entries/{entryId}/Laserfiche.Repository.Document/edoc");
client.Timeout = -1;
var request = new RestRequest();
request.AddHeader("Authorization", $"Bearer {token}");
request.AddHeader("accept", "*/*");
try
{
var response = client.Head(request);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return resultVal;
}
static void GetDoc(string token, string repoId, string entryId, EntryInfo docInfo)
{
var client = new RestClient($"https://api.laserfiche.com/repository/v2-alpha/Repositories/{repoId}/Entries/{entryId}/Export?part=Pages&format=Tiff");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("accept", "application/json");
request.AddHeader("Authorization", $"Bearer {token}");
request.AddHeader("Content-Type", "application/json");
try
{
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
ExportInfo exportInfo = JsonConvert.DeserializeObject<ExportInfo>(response.Content);
var clientDL = new RestClient(exportInfo.value);
var requestDL = new RestRequest(Method.GET);
byte[] byteArray = clientDL.DownloadData(requestDL);
File.WriteAllBytes(@"C:\temp\dl.tif", byteArray);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
static void ImportDoc(string token, string repoId, string uploadFilePath, string parentEntryId, string fileNameTarget)
{
byte[] readText = File.ReadAllBytes(uploadFilePath);
var client = new RestClient($"https://api.laserfiche.com/repository/v2-alpha/Repositories/{repoId}/Entries/{parentEntryId}/Import");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.RequestFormat = DataFormat.Json;
request.AddHeader("accept", "application/json");
request.AddHeader("Authorization", $"Bearer {token}");
request.AddHeader("Content-Type", "multipart/form-data");
string s = @"{
'name': '" + fileNameTarget;
string s2 = @"',
'autoRename': true,
'generateText': false,
'importAsElectronicDocument': false
}";
request.AddParameter("request", s + s2, ParameterType.RequestBody);
request.AddFile("file", uploadFilePath, "multipart/form-data");
try
{
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
static ApiTokenInfo CreateApiAccessToken(string token)
{
ApiTokenInfo apiToken = null;
var client = new RestClient($"https://signin.laserfiche.com/oauth/token");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", $"Bearer {token}");
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddHeader("grant_type", "client_credentials");
request.AddParameter("application/x-www-form-urlencoded", "grant_type=client_credentials", ParameterType.RequestBody);
request.RequestFormat = DataFormat.Json;
try
{
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
apiToken = JsonConvert.DeserializeObject<ApiTokenInfo>(response.Content);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return apiToken;
}
static bool CreateRepositorySession(string apiToken, string repoId)
{
bool retVal = false;
var client = new RestClient($"https://api.laserfiche.com/repository/v2-alpha/Repositories/{repoId}/ServerSession/Create");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", $"Bearer {apiToken}");
JObject jsonBody = new JObject();
request.AddParameter("application/json; charset=utf-8", jsonBody, ParameterType.RequestBody);
request.RequestFormat = DataFormat.Json;
try
{
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return retVal;
}
public static string CreateClientCredentialsAuthorizationJwt(string clientId, string clientSecret, JsonWebKey key,
string audience = "laserfiche.com", DateTime? validTo = null)
{
validTo ??= DateTime.UtcNow.AddMinutes(60);
DateTime notBefore = DateTime.Now;
var signingCredentials = GetSigningCredentials(key);
var tokenDescriptor = new SecurityTokenDescriptor
{
NotBefore = notBefore,
Audience = audience,
Expires = validTo,
Subject = new ClaimsIdentity(new[]
{
new Claim("client_id", clientId),
new Claim("client_secret", clientSecret),
}),
SigningCredentials = signingCredentials
};
var v = new JsonWebTokenHandler();
var s = v.CreateToken(tokenDescriptor);
return s;
}
private static SigningCredentials GetSigningCredentials(JsonWebKey key)
{
ECDsaSecurityKey ecDsaSecurityKey = new ECDsaSecurityKey(ECDsa.Create(new ECParameters()
{
Curve = ECCurve.NamedCurves.nistP256,
Q = new ECPoint()
{
X = Base64UrlEncoder.DecodeBytes(key.X),
Y = Base64UrlEncoder.DecodeBytes(key.Y)
},
D = Base64UrlEncoder.DecodeBytes(key.D)
}));
((SecurityKey)ecDsaSecurityKey).KeyId = key.Kid;
return new SigningCredentials((SecurityKey)ecDsaSecurityKey, "ES256");
}
}
public class ExportInfo
{
public string context;
public string value;
}
public class ApiTokenInfo
{
public string access_token;
public string token_type;
public int expires_in;
}
public class TokenInfo
{
public string context;
public string authToken;
public DateTime expireTime;
}
public class DataElem
{
public string key;
public string value;
}
public class AttributesInfo
{
public string context;
public List<DataElem> value;
}
public class EntryInfo
{
public long id { get; set; }
public string name { get; set; }
public long? parentId { get; set; }
public string fullPath { get; set; }
public string folderPath { get; set; }
public string creator { get; set; }
public string creationTime { get; set; }
public string lastModifiedTime { get; set; }
public string entryType { get; set; }
public string templateName { get; set; }
public long? templateId { get; set; }
public List<string> templateFieldNames { get; set; }
public string volumeName { get; set; }
public long? rowNumber { get; set; }
public long? ElecDocumentSize { get; set; }
public bool? IsElectronicDocument { get; set; }
public bool? IsRecord { get; set; }
public string MimeType { get; set; }
public int? PageCount { get; set; }
public bool? IsCheckedOut { get; set; }
public bool? IsUnderVersionControl { get; set; }
}
}