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
    Commented Dec 29, 2023 at 10:20
  • Did you work out how to get this working?
    – Phil W
    Commented 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. Commented Jan 5 at 16:38

1 Answer 1

3

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
    Commented 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
    Commented 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
    Commented 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
    Commented Jan 5 at 14:09
  • 1
    You can create the new named/external credentials via Apex API calls, without any Metadata API usage. Note that if you are trying to create a package that will be security reviewed, you might have some friction when that review is done since you are not using Salesforce's standard mechanism. I'd be interested to hear what happens!
    – Phil W
    Commented Jan 5 at 16:44

You must log in to answer this question.

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