Skip to content

Instantly share code, notes, and snippets.

@bric3
Created February 14, 2025 09:15
Show Gist options
  • Save bric3/f1863ed36d6bb57d46724e522c544d75 to your computer and use it in GitHub Desktop.
Save bric3/f1863ed36d6bb57d46724e522c544d75 to your computer and use it in GitHub Desktop.
Public finicky config template
// Use https://finicky-kickstart.now.sh to generate basic configuration
// Learn more about configuration options: https://github.com/johnste/finicky/wiki/Configuration
// Get bundle id with: mdls /Applications/Firefox.app | grep kMDItemCF
const browsers = {
personal: {
name: 'org.mozilla.firefox', // or Firefox
openInBackground: false,
},
work: {
name: 'com.google.Chrome', // or Google Chrome
// profile: 'Profile 1', // must match folders, e.g. ~/Library/Application\ Support/Google/Chrome/Profile\ 1
openInBackground: false,
},
// When it is needed to select any other browsers, unfortunately it creates a Browseraurorus background instance.
selector: {
name: 'com.browserosaurus', // or Browserosaurus
openInBackground: false,
},
}
const apps = {
zoom: {
name: 'us.zoom.xos', // or zoom.us
},
slack: {
name: 'com.tinyspeck.slackmacgap', // or Slack
},
spotify: {
name: 'com.spotify.client', // or Spotify
},
appStore: {
name: 'App Store',
},
}
// Based on opalelement's answer https://github.com/johnste/finicky/issues/96#issuecomment-844571182
// Team ID can be found in the browser URL : https://slack.com/help/articles/221769328-Locate-your-Slack-URL-or-ID
// Free, Pro, and Business+ plans => Team or workspace ID starts with a T in https://app.slack.com/client/TXXXXXXX/CXXXXXXX
// Enterprise grid plans => Org ID starts with an E in https://app.slack.com/client/EXXXXXXX/CXXXXXXX
const workSlackTeamMapping = {
// Examples :
// 'subdomain': 'TXXXXXXX'
// 'acmecorp.enterprise': 'EXXXXXXX'
}
const personalSlackMapping = {
'jetbrains-platform' : 'T5P9YATH9',
'jdkmissioncontrol' : 'TGKK1QUU8',
'graalvm' : 'TN37RDLPK',
'foojay' : 'T017GJYMWBZ',
}
const slackSubdomainMapping = {
...workSlackTeamMapping,
...personalSlackMapping,
}
const slackRewriter = {
match: [
'*.slack.com/*',
],
url: function({ url, urlString }) {
const subdomain = url.host.slice(0, -10) // before .slack.com
const pathParts = url.pathname.split("/")
let team, patterns = {}
if (subdomain != 'app') {
if (!Object.keys(slackSubdomainMapping).includes(subdomain)) {
finicky.log(
`No Slack team ID found for ${url.host}`,
`Add a correct team ID to ~/.finicky.js to allow direct linking to Slack.`
)
return url
}
team = slackSubdomainMapping[subdomain]
if (subdomain.slice(-11) == '.enterprise') {
patterns = {
'file': [/\/files\/\w+\/(?<id>\w+)/]
}
} else {
patterns = {
'file': [/\/messages\/\w+\/files\/(?<id>\w+)/],
'team': [/(?:\/messages\/\w+)?\/team\/(?<id>\w+)/],
'channel': [/\/(?:messages|archives)\/(?<id>\w+)(?:\/(?<message>p\d+))?/]
}
}
} else {
patterns = {
'file': [
/\/client\/(?<team>\w+)\/\w+\/files\/(?<id>\w+)/,
/\/docs\/(?<team>\w+)\/(?<id>\w+)/
],
'team': [/\/client\/(?<team>\w+)\/\w+\/user_profile\/(?<id>\w+)/],
'channel': [/\/client\/(?<team>\w+)\/(?<id>\w+)(?:\/(?<message>[\d.]+))?/]
}
}
for (let [host, host_patterns] of Object.entries(patterns)) {
for (let pattern of host_patterns) {
let match = pattern.exec(url.pathname)
if (match) {
let search = `team=${team || match.groups.team}`
if (match.groups.id) {
search += `&id=${match.groups.id}`
}
if (match.groups.message) {
let message = match.groups.message
if (message.charAt(0) == 'p') {
message = message.slice(1, 11) + '.' + message.slice(11)
}
search += `&message=${message}`
}
let output = {
protocol: "slack",
username: "",
password: "",
host: host,
port: null,
pathname: "",
search: search,
hash: ""
}
let outputStr = `${output.protocol}://${output.host}?${output.search}`
finicky.log(`Rewrote Slack URL ${urlString} to deep link ${outputStr}`)
return output
}
}
}
return url
}
}
// Remove all marketing/tracking information from urls
// https://github.com/johnste/finicky/wiki/Configuration-ideas#remove-all-marketingtracking-information-from-urls
const trackingRemover = {
match: () => true, // Execute rewrite on all incoming urls to make this example easier to understand
url: ({url}) => {
const removeKeysStartingWith = ["utm_", "uta_"]; // Remove all query parameters beginning with these strings
const removeKeys = ["fbclid", "gclid"]; // Remove all query parameters matching these keys
const search = url.search
.split("&")
.map((parameter) => parameter.split("="))
.filter(([key]) => !removeKeysStartingWith.some((startingWith) => key.startsWith(startingWith)))
.filter(([key]) => !removeKeys.some((removeKey) => key === removeKey));
return {
...url,
search: search.map((parameter) => parameter.join("=")).join("&"),
};
},
}
// Rewrites zoom as a zoommtg url
//const zoomRewriter = {
// match: ({ url }) =>
// url.host.endsWith("zoom.us") && url.pathname.startsWith("/j/"),
// url: ({ url }) => {
// const id = url.pathname.match(/^\/j\/([^/]+)/)?.[1];
// return id ? `zoommtg://zoom.us/join?confno=${id}&${url.search}` : url;
// },
//}
/** @type {import("./.finicky-types").FinickyConfig} */
module.exports = {
defaultBrowser: browsers.personal,
options: {
hideIcon: false,
checkForUpdate: true,
logRequests: true,
},
rewrite: [
slackRewriter,
trackingRemover,
],
handlers: [
{
// Open the following URLs in work browser by default
// Open google.com and *.google.com urls in Google Chrome
match: [
"google.com*", // match google.com urls
finicky.matchDomains(/.*\.google.com/),
finicky.matchDomains("forms.gle"),
finicky.matchDomains("login.docker.com"),
finicky.matchDomains("hub.docker.com"),
finicky.matchDomains(/.*.figma.com/),
finicky.matchDomains(/.*\.gobetterway\.fr/),
],
browser: browsers.work
},
{
match: ({ url }) => url.protocol === "slack",
browser: apps.slack
},
{
// if these url cannot be converted, open them is work browser
// Login in work workspace unfortunately lands on the personal browser, just copy the link to the work browser
// E.g. https://app.slack.com/ssb/add?s=1&v=4.41.90&ssb_vid=.<hex id>&ssb_instance_id=<UUID>
match: Object.keys(workSlackTeamMapping).map(subdomain =>
finicky.matchDomains(subdomain + ".slack.com")
),
browser: browsers.work
},
{
// Select browser when slack wants to login
// https://app.slack.com/ssb/add?s=1&v=4.41.90&ssb_vid=.<hex id>&ssb_instance_id=<UUID>
match: [
"app.slack.com/ssb/*",
],
browser: browsers.selector,
},
{
match: [
"zoom.us/j/*",
"*.zoom.us/j/*", // join the meeting
"*.zoom.us/s/*", // starts meeting, requiring you to be either the host or alternate host
],
browser: apps.zoom
},
{
match: finicky.matchDomains("open.spotify.com"),
browser: apps.spotify
},
{
match: ({ opener }) =>
opener.bundleId === "org.whispersystems.signal-desktop",
browser: browsers.personal
},
{
// https://itunes.apple.com/app/calendar-366-ii/id1265895169?ls=1&mt=12
// https://apps.apple.com/us/app/calendar-366-ii/id1265895169
match: [
finicky.matchDomains("apps.apple.com"),
"itunes.apple.com/app/*"
],
url: ({url, urlString}) => {
finicky.log("Rewriting iTunes Store Url " + urlString)
if (url.host === "apps.apple.com") return url
return {
//...url,
protocol: url.protocol,
host: "apps.apple.com",
pathname: "/us" + url.pathname,
search: '' // query params
};
},
browser: apps.appStore,
},
{
match: ({ keys }) => keys.function,
browser: browsers.selector,
},
// { // Open coding stuff in Firefox
// browser: browsers.personal,
// match: [],
// },
],
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment