[Adobe PDF Embed API] Adobe PDF embed plugin
adobe-pdf-embed-api
Reactive icon
Forge component by Matthew Matias
Application Type
Mobile

Hi everyone. 

I've tried to use this adobe PDF Embed API plugin, but am having some difficulty and wondered if you were able to help me, please?

I have registered my environment at https://www.adobe.io/apis/documentcloud/dcsdk/gettingstarted.html using the domain name outsystemscloud.com. I've also added personal-4plka1hb.outsystemscloud.com, because I'm using the personal Outsystems environment.

However, when I try to view a PDF, I get the following recorded in the error log:

No ClientID detected. Please configure the AdobeClientID

and

Error adding script 'https://documentcloud.adobe.com/view-sdk/main.js' to document 'https://personal-4plka1hb.outsystemscloud.com/EDApp/Adobe_PDF?URL_in=https%3A%2F%2Femergencydepartment.app%2Fapi%2Fpdf%2F9712a309037afe960c47e150ba640817caa39d5cc00bee72adb9aff9203cd0af5fbbf468498f03b16ad290a6edbc4ecbe6aed51978f0db62e91797408bccefc9.pdf'M

I do have a ClientID, which I was given when I registered my environment with the adobe API. Is there somewhere in Service Centre I should be putting that. I can't see that it's a parameter in any of the plugin components...

Am I doing something really dumb?!

Thank you. 

mvp_badge
MVP
Solution

No problem Leigh.

Looking at that URL, I assume that you're consuming another API that supplies the PDFs you want to view in your app.

There's two ways that I can think of to solve this, but I don't know how feasible they are. You could:

 - get in touch with the API provider and ask them to set the Access-Control-Allow-Origin header in their API responses: this is the smoothest way to solve this, in that it would require no further code on your end to solve the issue. But it would all depend on the willingness of the API provider to make these changes and your relationship with them;

 - you store these PDFs on your database and serve them from your server instead of relying on an external endpoint. This would also settle the issue, in that you wouldn't run into any more CORS issues, but it would require you to consider a way to store these documents on your server, as well as the issues that arise from that architecture (storage, synchronization needs, API restrictions, etc);

I wasn't aware of the "no-cors" option, but reading up on it, it causes your browser to block the server response back to your code - this would only be useful if you want to transmit information to the API and didn't care about their response, so it wouldn't help here.

mvp_badge
MVP

Hello Leigh,

I've gone ahead and edited your post to refer to the Forge component you're using. This way, it will be easier for the component creator to assist you.

I've downloaded the component and there's a Site Property named ClientID:

It's used in both Actions (ViewPDFBinary and ViewPDFByLocation). You can use Service Center to access a module's Site Properties and define values there.

Hi Afonso,

Thank you for your prompt reply.

I noticed that my AdobeClientID site property already had the correct API key in. I assume I put it in there last month when I tried to get this working.

I've verified it's not a multi-tenant property, and that it is being stored and retrieved correctly by outputting it as an expression in the app. It seems to work fine in this regard.

However, I'm still getting errors, and still can't display the PDF's. Error message as follows

Error adding script 'https://documentcloud.adobe.com/view-sdk/main.js' to document 'https://personal-4plka1hb.outsystemscloud.com/EDApp/Adobe_PDF?URL_in=RedactedFileLink.pdf'

eSpaceVer: Id=2144, PubId=0, CompiledWith=11.14.0.33133
RequestUrl: https://personal-4plka1hb.outsystemscloud.com/EDApp/moduleservices/log?clientTimeInMillis=1647704086884 (Method: POST)
AppDomain: /LM/W3SVC/18/ROOT/EDApp-113-132921775105400244
FilePath: C:\OutSystems\Sandboxes\BTBVLF015\Platform Server\running\EDApp\
ClientIp: 176.25.180.197
Locale: en-US
DateFormat: dd-MM-yyyy
PID: 14920 ('w3wp', Started='2/21/2022 4:50:27 AM', Priv=855Mb, Virt=2116313Mb)
TID: 47
Thread Name:
.NET: 4.0.30319.42000
Client Runtime Packages: client-runtime-core= 3.20.0;client-runtime-view-framework-react= 3.2.1;client-runtime-widgets= 3.4.0;
Client-Side Log

Little update....

I've re-published the app, because I find that sometimes fixes problems I don't know how to fix!
(Do I need to re-generate and re-publish a new build after making changes to a content security policy?)

I'm now not getting the error above, just this one persisting:

No ClientID detected. Please configure the AdobeClientID

eSpaceVer: Id=2144, PubId=0, CompiledWith=11.14.0.33133
RequestUrl: https://personal-4plka1hb.outsystemscloud.com/EDApp/screenservices/AdobePDFEmbedAPI/PDFViewer/ViewPDFByLocation/DataActionGetClientID (Method: POST)
AppDomain: /LM/W3SVC/18/ROOT/EDApp-113-132921775105400244
FilePath: C:\OutSystems\Sandboxes\BTBVLF015\Platform Server\running\EDApp\
ClientIp: 176.25.180.197
DeviceUUID: 2bde00bb04c2d3ef
Locale: en-US
DateFormat: dd-MM-yyyy
PID: 14920 ('w3wp', Started='2/21/2022 4:50:27 AM', Priv=845Mb, Virt=2116293Mb)
TID: 31
Thread Name:
.NET: 4.0.30319.42000

No ClientID detected. Please configure the AdobeClientID
at ssAdobePDFEmbedAPI.ScreenServices.AdobePDFEmbedAPI_PDFViewer_ViewPDFByLocation_ScreenModel.DataActionGetClientID(HeContext heContext, String& outParamClientId_Out)
at ssAdobePDFEmbedAPI.ScreenServices.AdobePDFEmbedAPI_PDFViewer_ViewPDFByLocation_Controller.<DataActionGetClientID>b__1(HeContext heContext, String screenName, JObject screenModel, JObject inputParameters, JObject clientVariables)
   at OutSystems.RESTService.Controllers.ScreenServicesApiController.endpoint(String input, String endpointName, String apiVersion, EndpointImplementationDelegate implementation)


I must (still) be doing something daft.

I don't know if it's relevant. But when I try and open the page in the app, I get this screen.



Even though the screen permissions are configured as

 

I don't know if these are relevant either.... But thought I'd include it just in case?!




mvp_badge
MVP

I believe the permissions screen could be related to the problem - if you take a look at the GetClientID Action in the ViewPDFByLocation webblock in the AdobePDFEmbedAPI module, there's an If element that evaluates the ClientID site property - if it's empty, it will throw a Not Registered exception and the exact error message you're seeing ("No ClientID detected. Please configure the AdobeClientID").

Do you think you could debug this action to validate what value it's getting from the Site Property?

I feel we're getting closer....

I tried to debug the GetClientID action in the ViewPDFByLocation webblock. Firstly, I just hardcoded my API into the assign function, so that it just assigned my API, regardless of what was returned. I found this made no difference so I began to look elsewhere.

I found that in the GetClientIDOnAfterFetch client action, it has the following

clientId: parameters.AdobeClientID,

I replaced this with 

clientID: **MyApiKey**,

and it no longer throws the not logged in error and the screen looks like this:

I've never explored someone else's plugin before, so this is new ground for me. Not sure what best to do now?

Update: Error logs now report CSF violation. Currently adding other adobe domains to CSF policy...

mvp_badge
MVP

It does appear that something was going on with the Fetch action of that webblock - looks like the API is no longer complaining of missing parameters.

Regarding the CSF errors, do you also get them if you try to use the component demo? Could it be something specific to your implementation, or the origin of your PDF?

Whenever I try out someone's component, I like to start off with their demo application, and adapt it to my needs step-by-step: it's usually a good codebase to start with, because it's a successful implementation of the component.

Ok. So overcame CSF violations.

Looking at the error logs for the AdobePDFEmbedAPI, I just have lots of these:


Error creating tenant view 'OSUSR_say_Settings_T20' for table 'OSUSR_say_Settings': Invalid object name 'OSUSR_SAY_SETTINGS'.
Cannot find the object 'OSUSR_SAY_SETTINGS_T20', because it does not exist or you do not have permission.

eSpaceVer: Id=0, PubId=0, CompiledWith=11.14.0.33133
RequestUrl: (Method: )
AppDomain: CompilerService.exe
Path: C:\...\PS\
Locale:
DateFormat: yyyy-MM-dd
PID: 4528 ('CompilerService', Started='11/25/2021 5:59:07 PM', Priv=409Mb, Virt=2864Mb)
TID: 210
Thread Name:
.NET: 4.0.30319.42000

   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at OutSystems.HubEdition.Extensibility.Data.ExecutionService.BaseExecutionService.ExecuteNonQuery(IDbCommand cmd)
at OutSystems.Internal.Db.Command.ExecuteNonQuery(String description, Boolean isApplication, Boolean skipLog, Boolean applyTransformationsToParameters)
   at OutSystems.Server.Services.ApplicationRuntimeOperations.Infrastructure.Repositories.Tenants.TenantUpdateViewsFromSQL.CreateTenantView(Dictionary`2 tableInfos, Int32 tenantId, ObjectKey eSpaceKey, IEnumerable`1 catalogs, Action`2 onCreatingTenantViewForTableError, Dictionary`2& toInsert, Dictionary`2& toUpdate)


I notice that the AdobePDFEmbedAPI only lists these errors for tenant number 20, which is the default tenant, but also largely unused - it's used for demo purposes really.

When I look at the error logs for my module, it looks like this:

I note that these errors exist here for tenant 287 too, which is the tenant that I've been trying to develop the PDF function for.

I've no idea what the errors mean, so I'm not even sure if they're relevant.

Screen still shows same as previous post: RE File preview error.



mvp_badge
MVP

I'm not too sure about the tenancy errors, but I'd say they're unrelated to the error you're seeing: this still looks like something specific to the application logic. Let's try and go through everything.

I managed to connect to a working environment and the demo looks okay:

So we can rule out component problems. The demo works, so it has to be something specific to the implementation.

But the demo uses a PDF that's stored directly on the module app. I'm not too sure on your use case, are you loading the PDFs from somewhere?

This is how I laid out my API key:

Are you loading PDFs from separate domains? Could you try bundling one directly into your application to rule out any domain permission issues?

Do you get any errors in your browser console while visiting the PDF page and seeing the File preview error (you can open it with CTRL+SHIFT+J in most browsers)? There could be a response from the Adobe PDF API there that could provide clues as well.


Went through your steps. Loaded a local PDF. It worked fine. Troubleshooted some more using the console as you advised. Looked like CSF policy again...

Disabled CSF policy entirely.

PDF's load fine from URLs.

Re-enabled my CSF policy, and all the previous content was gone.

At least I know what the problem is... Just now need to build it through.

Thanks so much for helping me get this far. I really appreciate it.

Though.... I wonder if you might be able to help with this too!

Access to fetch at 'https://emergencydepartment.app/api/pdf/***.pdf' from origin 'https://personal-4plka1hb.outsystemscloud.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

I think this is the only thing standing in my way...

mvp_badge
MVP
Solution

No problem Leigh.

Looking at that URL, I assume that you're consuming another API that supplies the PDFs you want to view in your app.

There's two ways that I can think of to solve this, but I don't know how feasible they are. You could:

 - get in touch with the API provider and ask them to set the Access-Control-Allow-Origin header in their API responses: this is the smoothest way to solve this, in that it would require no further code on your end to solve the issue. But it would all depend on the willingness of the API provider to make these changes and your relationship with them;

 - you store these PDFs on your database and serve them from your server instead of relying on an external endpoint. This would also settle the issue, in that you wouldn't run into any more CORS issues, but it would require you to consider a way to store these documents on your server, as well as the issues that arise from that architecture (storage, synchronization needs, API restrictions, etc);

I wasn't aware of the "no-cors" option, but reading up on it, it causes your browser to block the server response back to your code - this would only be useful if you want to transmit information to the API and didn't care about their response, so it wouldn't help here.

Thank you again. I really appreciate it. 

Thankfully I am the provider of the other API also 😂 So I just need to figure out how to set that header. Sounds easy enough...


Thank you again. 😍😍😍😘😘🤩🤩🥰🥰

mvp_badge
MVP

No problem Leigh, and good luck. Let us know if you need any help.

Just come to address the problem. I'm not actually consuming an API, the link I'm trying to open is fetched from a database on page start. So assume the CORS problem exists because the originating source is my PersonalOutsystems domain, the destination is emergencydepartment.app domain, but the request goes via the AdobeCloud domain in order to use the API.

I've just finished a night shift (I'm a paramedic), and have been awake for 36 hours now, so will go to sleep and see if I can figure it out in 'the morning'!

Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.