You can re-use functions you have built using the Connect framework as Forge Remote endpoints, by adapting that code to work with Forge Remote. From a Forge app developer's perspective, Forge Remote is a layer on top of HTTPS which sends Forge-specific metadata along with the HTTPS request that your remote function can use to make Atlassian-authenticated requests back into the platform and access context information related to the app.
This page includes information on how to do the following, in the frameworks supported by Connect:
The information in this section is adapted from content in the Atlassian Connect Express framework Bitbucket repo.
For more information on the Connect javascript functions mentioned in this section, see the source code in the repo.
Your ACE app can act as a remote backend for Forge.
To do so, it must have an appId
set in the ./config.json
. The value should be the app.id
as it appears in the Forge manifest. For example:
1 2{ "appId": "ari:cloud:ecosystem::app/406d303d-0393-4ec4-ad7c-1435be94583a" }
If you are using the DynamoDB adapter for storage, you will also need to add a couple of tables for Forge installation related data. There is code in the Atlassian Connect Express framework Bitbucket repo that will attempt to create these tables here but this may not succeed if your app does not have the necessary permissions. In that case please manually create the following:
An InstallationClientKeys
table with installationId
as a string partition key.
A ForgeSettings
table with installationId
as a string partition key, and key
as a string sort key.
The addon.authenticateForge()
middleware will verify remote requests from Forge in accordance with the
Remote contract
and set the following properties on request.context.forge
.
Refer to the remote contract reference
for more information about these properties.
request.context.forge.tokens.app
: A ready-to-use access token representing the apprequest.context.forge.tokens.user
: A ready-to-use access token representing the current userrequest.context.forge.apiBaseUrl
: The API base URL where all product API requests should be routed.
Example: https://api.atlassian.com/ex/confluence/4c822e2f-510f-48b9-b8d2-8419d0932949request.context.forge.app
: Information about the app and installation contextrequest.context.forge.context
: Product- and extension-specific data including configuration.There is no pre-configured http client for Forge akin to the Connect addon.httpClient
, but making a Forge-authenticated
request in your http client of choice is as simple as prepending the apiBaseUrl
and providing one of the ready-to-use
tokens in the Authorization
header, prefixed by Bearer
. For example:
1 2app.get("/forge/backend/resource", addon.authenticateForge(), async (req, res) => { const response = await fetch(`${req.context.forge.apiBaseUrl}/wiki/api/content`, { headers: { Authorization: `Bearer ${req.context.forge.tokens.app}` } }); });
The addon.authenticateForge()
middleware caches the app token and API base URL against the
installation ID for later use. If you are making a request in response to an invocation which did not
come from Forge, have the appropriate installation ID, and would like to make a request to Atlassian
APIs, you can retieve the app token using addon.getForgeAppToken(installationId)
. For example:
1 2app.get("/external-event/{installationId}", async (req, res) => { const { appToken, apiBaseUrl } = await addon.getForgeAppToken(req.params.installationId); const response = await fetch(`${apiBaseUrl}/wiki/api/content`, { headers: { Authorization: `Bearer ${appToken}` } }); });
To have access to Connect context variables and http client as well as Forge context variables,
the addon.associateConnect()
middleware can be used in tandem with addon.authenticateForge()
:
1 2app.get("/forge/backend/resource", [addon.authenticateForge(), addon.associateConnect()], async (req, res) => { /* Both Connect and Forge context are available here, for example: addon.httpClient(req); addon.settings.set("key", { value: "val" }, req.context.clientKey); req.context.forge; */ });
The information in this section is adapted from content in the Atlassian Connect Spring Boot framework Bitbucket repo.
For more information on the Connect Java functions mentioned in this section, see the source code in the repo.
Your app can act as a remote backend for Forge.
To do this, you must set app.id
in application.properties
or application.yml
. The value should be the app.id
as it appears in the Forge manifest. For example (YAML):
1 2app: id: ari:cloud:ecosystem::app/406d303d-0393-4ec4-ad7c-1435be94583a
The @ForgeRemote
annotation will verify remote requests from Forge in accordance with the
Remote contract.
AtlassianForgeRestClients
is a pre-configured HTTP client for Forge akin to the Connect AtlassianHostRestClients
.
We provide the following public methods to make requests to the products:
asUser()
: send a request authenticated as the current userasApp()
: send a request authenticated as the appasApp(String installationId)
: send a request authenticated as the app. This method can be used outside the @ForgeRemote
context by using the stored access token.request()
: send a request to the Atlassian API gateway (use /graphql
as the path)requestConfluence()
: send a request to the Confluence APIrequestJira()
: send a request to the Jira APIYou can call either asUser()
or asApp()
and then chain it with the product you are targeting. For example, to make a request to the Confluence API as the current user, you would do the following:
1 2@ForgeRemote @RequestMapping(value = "/frc", method = RequestMethod.POST) public String testMethod() { final HttpEntity<String> entity = new HttpEntity<>(null, null); final ResponseEntity<String> response = atlassianForgeRestClients .asUser() .requestConfluence() .exchange( "/api/v2/pages", HttpMethod.GET, entity, String.class); return response.getBody(); }
When you receive a request from Forge, it includes a Forge Invocation Token containing context about the request.
You can access this token in your request handler using the ForgeContextRetriever
component, like so:
1 2@ForgeRemote @RequestMapping(value = "/frc", method = RequestMethod.POST) public String testMethod() { Optional<ForgeApiContext> forgeContext = forgeContextRetriever.getForgeApiContext(); var installationId = forgeContext.map(ForgeApiContext::getForgeInvocationToken) .map(ForgeInvocationToken::getApp) .map(ForgeApp::getInstallationId); }
To enable injecting an AtlassianHostUser
with information about the host product instance
and making Connect JWT or ACT_AS_USER
requests, add associateConnect = true
to the @ForgeRemote
annotation.
1 2@ForgeRemote(associateConnect = true) @RequestMapping(value = "/frc-associate-connect", method = RequestMethod.POST) public String testMethod(@AuthenticationPrincipal AtlassianHostUser hostUser) { /* Connect context is available here via the AtlassianHostUser */ var clientKey = hostUser.getHost().getClientKey(); }
Rate this page: