In this tutorial, you'll learn how to build a Forge app that generates custom Smart Links. We'll cover the fundamentals of app setup and generate an example Smart Link.
This tutorial does not cover integration with external systems. For more details on connecting to external services, see the Google Drive example app.
This tutorial assumes you're already familiar with the basics of Forge development. If you're not, see Getting started with Forge for a detailed tutorial.
You will also need to ensure you are using the latest version of the Forge CLI.
To install, run:
1 2npm install -g @forge/cli@latest
Currently, apps that use Teamwork Graph modules will need to be installed into to Jira. This means that in order to test your Teamwork Graph app, you will need a Jira site. If you do not have one of these already, see below for information on how to create a new Atlassian cloud developer site.
An Atlassian cloud developer site lets you install and test your app on Confluence and Jira. If you don't have one yet, set it up now:
Go to http://go.atlassian.com/cloud-dev and create a site using the email address associated with your Atlassian account. Once your site is ready, log in and complete the setup wizard. You can install your app to multiple Atlassian sites. However, app data won't be shared between separate Atlassian sites, products, or Forge environments.
The limits on the numbers of users you can create are as follows:
Confluence: 5 users Jira Service Management: 1 agent Jira Software and Jira Work Management: 5 users
In this step we will create a blank Forge app and then in the following steps, we will add the required modules and logic to the app.
Create your app by running:
1 2forge create
Enter a name for your app (up to 50 characters). For example, my-first-smartlink-app.
Select Show All as the context.
Select the Show All category.
Select the blank template.
Change to the app subdirectory to see the app files:
1 2cd my-first-smartlink-app
The Forge app uses Node.js and has the following structure:
1 2├── manifest.yml ├── package.json └── src └── index.js
Your manifest.yml
file should look like the following with app ID:
1 2modules: function: - key: my-function handler: index.run app: runtime: name: nodejs22.x memoryMB: 256 architecture: arm64 id: <your app id>
Installing Typescript is a development dependency for apps utilizing the Smart Links module.
To install, run:
1 2npm install typescript --save-dev
Then, create a tsconfig.json
file containing the following configuration:
1 2{ "compilerOptions": { "target": "es2016", // Specifies the target JavaScript version for compilation "module": "commonjs", // Specifies the module system to use (e.g., commonjs, esnext) "outDir": "./dist", // Specifies the output directory for compiled JavaScript files "strict": true, // Enables a wide range of type-checking validation rules "esModuleInterop": true // Enables interoperability between CommonJS and ES Modules }, "include": [ "src/**/*.ts" // Specifies files to include in the compilation ], "exclude": [ "node_modules" // Specifies files/directories to exclude from the compilation ] }
In the app's top-level directory, open the manifest.yml
file and update the modules section to:
1 2modules: graph:smartLink: - key: my-first-smartlink icon: https://static.my-first-smartlink.com/favicon.ico name: My first Smart Links function: getEntityByUrlFn domains: - my-first-smartlink.com - www.my-first-smartlink.com subdomains: true patterns: - >- https:\/\/([\w\.-]+\.)?my-first-smartlink\.com\/([0-9a-zA-Z]{4,128})(?:\/.*)?$ function: - key: getEntityByUrlFn handler: index.resolveSmartLinks
In this step we've added the graph:smartLink
module, which contains:
For a detailed understanding of the manifest structure, refer to the Smart Link module.
Now that we have the manifest
configured, let's add the code logic.
Rename index.js
to index.ts
and replace the content with the following:
1 2// SOME HELPER OBJECTS export interface ResolveSmartLinkRequest { type: 'resolve'; payload: { urls: string[]; } } export interface ResolveSmartLinkResponse { entities: ResolveUrlEntityResult[]; } export type Identifier = { id: string; } | { url : string} | { id: string, url: string}; export interface ResolveUrlEntityResult { identifier: Identifier meta: { access: string, visibility: string }; entity?: any; } export const buildResolveSmartLinksResponse = (entities: ResolveUrlEntityResult[]): ResolveSmartLinkResponse => { return { entities: entities, }; } /** * This is the entrypoint for the Smart Link function. * It receives a request containing a list of URLs to resolve and returns a list of entities. * The function uses async processing to resolve all URLs concurrently. */ export async function resolveSmartLinks(request: ResolveSmartLinkRequest):Promise<ResolveSmartLinkResponse> { console.log(request); const urls = request.payload.urls; const processedEntities = await Promise.all( urls.map(url => { return processUrl(url); }), ); return buildResolveSmartLinksResponse(processedEntities); } /** * This function processes a single URL. * It extracts the fileId from the URL and then pulls the file information from Google using the user authenticated OAuth2 token. */ async function processUrl(url: string) : Promise<ResolveUrlEntityResult> { return { identifier: { url: url }, meta: { access: 'granted', visibility: 'public' }, entity: { schemaVersion: '2.0', id: '1231321', updateSequenceNumber: 1111, displayName: "Hello World!", description: "Well done you created your first Smart Link!", url, 'atlassian:remote-link': { type: 'document', }, createdAt: new Date().toISOString(), lastUpdatedAt: new Date().toISOString(), thumbnail: { externalUrl: `https://picsum.photos/200`, }, createdBy: { accountId: '6076c075c642ff0070ef3787', } } }; }
Ensure you import all dependencies.
To use your app, it must be installed onto an Atlassian site. The forge deploy
command builds,
compiles, and deploys your code; it'll also report any compilation errors. The forge install
command
then installs the deployed app onto an Atlassian site with the required API access.
Currently, apps that use Teamwork Graph modules will need to be installed into to Jira.
You must run the forge deploy
command before forge install
because an installation links your deployed app to an Atlassian site.
Navigate to the app's top-level directory and deploy your app by running:
1 2forge deploy
Install your app into your Jira instance by running:
1 2forge install
Select your Jira using the arrow keys and press the enter key.
Enter the URL for your development site. For example, example.atlassian.net. View a list of your active sites at Atlassian administration.
Once the successful installation message appears, your app is installed and ready to use on the specified site. You can always delete your app from the site by running the forge uninstall command.
Running the forge install
command only installs your app onto the selected organization. To install
onto multiple organizations, repeat these steps again, selecting another organization each time.
You must run forge deploy
before running forge install
in any of the Forge environments.
To test the app, open up Jira, create an Jira issue, and paste https://www.my-first-smartlink.com/12346
into the description. If your setup is correct, your Smart Link will appear; otherwise, it will
display as a regular link.
These links can now be added to any Smart Link-enabled surface such as Jira issues, Confluence pages, Confluence whiteboards, and more.
Rate this page: