When to Run
Integrations only execute when they match specific contexts. The match property in your metadata controls when and where your integration runs.
Read the contexts documentation to understand what they are and how they work.
Context Data
The full context object is always available as the first parameter of the run function
Example:
run: async function (context, secrets = {}, dataFiles = []) {
// Current URL
logger.info('Current URL:', context.url);
// Page title
logger.info('Page title:', context.page?.title);
// Repository information (GitHub context)
if (context.page?.repository) {
logger.info('Repository:', context.page.repository);
logger.info('Owner:', context.page.user);
}
// User information
if (context.user) {
logger.info('User ID:', context.user.id);
logger.info('Username:', context.user.username);
}
}
Context Matching
In order to ensure your integration only runs under a specific set of conditions, you can use the match property, which has two main components:
match: {
contextType: 'github', // What type of context
context: { /* specific rules */ } // When to run
}
Context Types
Context types define on which websites the integration runs
'github'- GitHub website'aws'- AWS console website'generic'- Any other website
Context Rules
Context rules use operators to match specific conditions:
For example, for the github context, you can use the following expression to only run the integration on all repositories hosted by Microsoft:
match: {
contextType: 'github',
context: {
'page.repository': { startsWith: 'microsoft/' },
}
}
URL Matching
For the generic context, which only provides the url, we can use the url matching, like this:
match: {
contextType: 'generic',
context: {
url: { startsWith: 'https://some-website.com/' }
}
}
If you have at least one integration using a generic adapter, you need to manually allow the extension to run on that page.
The integration will only run on the some-website.com domain.
Available URL operators:
startsWith- URL begins with a specific stringendsWith- URL ends with a specific stringpattern- URL matches a regular expression
Available data operators:
exists- Property exists (true/false)equals- Property equals a specific valuein- Property is in an array of valuespattern- Property matches a regular expression
Advanced Matching
Multiple Conditions
match: {
contextType: 'github',
context: {
'page.repository': { in: ['my-org/repo1', 'my-org/repo2', 'my-org/repo3'] },
}
}
What it means: Run on GitHub pages with repositories owned by specific users or orgs. Useful for only running ToolJump on your GitHub org.
Matching via code
Sometimes, using matchers as expressions might not be expressive enough. Whenever that's the case, you can use the shouldRun method in the integration and return true or false.
// show integration only after 4pm (useful when you need to run an integration depending on the moment of the day)
// operation that can only be performed by code
const now = new Date();
if (now.getHours() >= 16) {
return true;
}
}
Best Practices
1. Be Specific
❌ Too broad:
match: {
contextType: 'generic',
context: {}
}
✅ Better:
// Run this integration on any repository page
match: {
contextType: 'github',
context: {
'page.repository': { startsWith: 'my-org/' }
}
}
2. Use Appropriate Context Types
- Use
'generic'for general web pages - Use specific types like
'github'when available
3. Split your code across multiple integrations
When integrating multiple tools, the recommended approach is to split the code across multiple integrations that share the same match criteria.
For example, you can create three integrations with identical context type and match conditions:
- One integration for Datadog alerts and logs
- One integration for last deployment information
- One integration for public service URLs
ToolJump will execute all matching integrations, aggregate their results, and present the combined output to users.
Splitting code across multiple integrations provides several advantages:
- Fault isolation: If one integration fails, the remaining integrations continue to function
- Code maintainability: Smaller, focused codebases are easier to understand and maintain
The order in which the integration results are displayed to the user is decided by the priority parameter from the metadata section. The higher priority are displayed first, the lower later.
Complete Example
Here's a well-structured context match:
module.exports = {
metadata: {
name: 'repo-stats',
description: 'Show repository statistics',
match: {
contextType: 'github',
context: {
'page.repository': { exists: true },
'page.user': { exists: true } // only show when a user is logged in to Github
}
}
},
run: async function (context, secrets = {}, dataFiles = []) {
// This will only run on GitHub repository pages
const repo = context.page.repository;
const user = context.page.user;
// Your integration logic here
}
};
Next Steps
Now that you understand context matching, learn about:
- Generic Context - Optimizing performance
- Caching - Optimizing performance
- Secrets - Managing configuration
- Result Types - What to return
See these concepts applied in our integration examples.