2

I am trying to create a managed package that has a callout to a webhook. Very simple use case, when opportunities or accounts change we want our server to be notified.

I have setup some Apex triggers and an Apex class to make the webhook callout. Part of the Apex class is as follows:

public static void callout(String content) {

        if (Test.isRunningTest()) {
            Test.setMock(HttpCalloutMock.class, new Webhook());
        }

        Http h = new Http();

        HttpRequest req = new HttpRequest();
        req.setEndpoint('callout:my_credential');
        req.setMethod('POST');
        req.setHeader('Content-Type', 'application/json');
        req.setBody(content);

        h.send(req);
    }

The named credential "my_credential" exists and simply consists of an external credential that has custom authentication with some headers with values, e.g. "X-My-Key". Very confusingly, it doesn't seem like named credentials can be included in the managed package (since external credentials can't), so part of my planned installation instructions was to have the users manually create the named credentials after install.

This does not work at all - nothing happens. The server never receives any requests, no Apex exception email is generated.

In the scratch org I am using to develop the package, if I modify the class to replace the callout with the hardcoded URL (e.g. req.setEndpoint('https://myserver.com');), the server starts getting requests when objects change.

I have tried replacing callout:my_credential with callout:__my_credential and callout:packagename__my_credential. Nothing - nothing happens in either the scratch org I am using to make the package, nor in a dev edition org I installed the package to for testing.

What am I doing wrong here?

3
  • Have you tried the "default namespace" prefix, c__, on the named credential reference? Also, check the documentation.
    – Phil W
    Dec 29, 2023 at 10:20
  • Did you work out how to get this working?
    – Phil W
    Jan 3 at 16:01
  • No. In the end I believe the issue was to do with permissions in referencing named credentials and the fact that the new named credentials and external credentials don't package well (or at all). I decided that including a Custom Metadata Type and then querying this was the best way to accomplish my use case, and was able to get it working this way. Jan 5 at 16:38

1 Answer 1

2

It seems that it is not possible for a managed package to use a named credential that is created outside the managed package's code, as per the documentation:

Managed packages can access only the named credentials and external credentials that are included in or created from the package’s Apex code. If a managed package tries to access non-packaged named credentials and external credentials that a Salesforce admin created in the org, an error occurs.

Perhaps you could dynamically create the named and external credentials (in your post-install script or some post-install admin page)?

9
  • That's odd, I'm sure we do this but I think the code in question is still using a legacy named credential. If you package a credential presumably it can be edit in a client's org if required?
    – Matt Lacey
    Jan 4 at 9:36
  • @MattLacey non-legacy credentials cannot be packaged since external credentials cannot be. I suspect that named credentials created by package apex code are invisible on the subscriber org, similar to protected CMT records or protected custom settings, but I've not experimented with that yet.
    – Phil W
    Jan 4 at 14:25
  • Maybe legacy ones created in the client org can be accessed from the package. Going to have to dig into this - been building out a new integration using the new named creds and wasn't aware of this limitation around packaging. Seems odd if you can't package them and can't access ones from the org. Install script isn't going to cut it because we won't always know the creds at install time. Gonna have to use some global method or something.
    – Matt Lacey
    Jan 5 at 13:34
  • Yeah, you'll probably want to create some "write only" UI that can be used to set credentials in an External Credential that is creates (using package code). It's a bit mind boggling how damned awkward new Named Credentials are. I've been researching using one to enable JWT flow OAuth 2.0 against a Google API and it's looking really awkward what with the need for a(n expiring, naturally) certificate and principals that enable use of the named setting by specific users. We don't want any of this faff.
    – Phil W
    Jan 5 at 14:09
  • In the end this was what I found - the new named/external credentials are basically not an option for packaging. In my use case I was able to use Custom Metadata Types to accomplish the same goal. Jan 5 at 16:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .