Add Dynamic Configs | Pandium Docs
Updated Connections Settings
Your updated Connections Settings page has the new configs you need. Now we're going to write an init sync flow to populate options for each of those configs.
Init Sync Flow Overview
A Pandium integration can be run in normal mode or init mode. The initSync flow is for the init mode.
The goal in this initSync flow is to print a standard out with data that will populate the options for our two dynamic configurations:
- The Slack user to receive the Pokémon of the day message.
- The type of Pokémon allowed for Pokémon of the day.
Steps to Implement
To do this we will need to:
- Fetch the users from Slack and the Pokémon types from PokéAPI.
- Reformat each Slack user to be in the form expected for a OneOf Option.
- Print a standard out that lists all the options for
pokemon_typesandslack_users.
Step 1
Within src/processLogic, add initSync.ts.
The file structure should now look like this:
├── build
├── node_modules
├── src
│ ├── processLogic
│ │ ├── initSync.ts
│ │ └── pokemonSync.ts
│ ├── index.ts
│ ├── lib.ts
│ └── transformations.ts
├── .env
├── package.json
├── PANDIUM.yaml
└── tsconfig.json
Step 2
Within src/processLogic/initSync.ts, add the shell of an asynchronous initSync function.
export const initSync = async () => {
console.error('------------------------INIT SYNC------------------------')
}
Step 3
Within src/index.ts, import initSync and invoke it within the run function when the run mode is init.
Updated src/index.ts
import * as dotenv from 'dotenv'
dotenv.config()
import { WebClient } from '@slack/web-api'
import Pokedex from 'pokedex-promise-v2'
import { Config, Secret, Context } from './lib.js'
import { pokemonSync } from './processLogic/pokemonSync.js'
import { initSync } from './processLogic/initSync.js'
const run = async () => {
const context = new Context()
const secrets = new Secret()
const config = new Config()
console.error(`This run is in mode: ${context['run_mode']}`)
console.error('------------------------CONFIG------------------------')
console.error(config)
console.error('------------------------CONTEXT------------------------')
console.error(context)
const pokeClient = new Pokedex()
const slackClient = new WebClient(secrets.slack_oauth_access_token)
if (context.run_mode === 'normal') {
const standardOut = await pokemonSync(pokeClient, slackClient, context)
console.log(JSON.stringify(standardOut))
} else {
await initSync()
}
}
run().then(
() => {},
() => {
process.exitCode = 1
}
)
Step 4
In the .env, update the run mode:
PAN_CTX_RUN_MODE= init
Step 5
Run npm run build && npm run start.
You should see the following logged, which shows that initSync is running:
> pokemon-of-the-day@1.0.0 start
> node build/src/
This run is in mode: init
------------------------CONFIG------------------------
Config {}
------------------------CONTEXT------------------------
Context {
run_mode: 'init',
last_successful_run_std_out: '{"last_pokemon_id":247}'
}
------------------------INIT SYNC------------------------
Step 6: Fetch Slack Users
Fetch the Slack users by:
- In
src/index.ts, pass theslackClienttoinitSync. - In
src/processLogic/initSync.ts, addslackClientas an argument toinitSync. - In
src/processLogic/initSync.ts, import theWebClientfrom the Slack library and use it to define the type of theslackClient. - In
initSync, useslackClient.users.listto fetch slack users. - Log out the results of that fetch.
Updated initSync.ts
import { WebClient } from '@slack/web-api'
export const initSync = async (slackClient: WebClient) => {
console.error('------------------------INIT SYNC------------------------')
try {
const response = await slackClient.users.list()
console.error(response.members)
} catch (error) {
console.error(error)
}
}
Step 7
Run npm run build && npm run start.
You should see the logs along with the array of Slack members from your workspace, confirming that the Slack client is working within initSync.
Step 8: Create OneOfOption Interface
Create a TypeScript interface for OneOfOption:
- Add
models.tsto thesrcfolder. - Within
src/sharedModels.ts, defineOneOfOption:
export interface OneOfOption {
const: string
title: string
}
Step 9: Print Slack User Options
Print the slack user options to the standard out by:
- Looping through the member list, reformatting active non-bot users as
OneOfOption. - Return a standard out object that includes the
slack_userslist. - Use
console.logto print a stringified version of that standard out object.
Updated initSync.ts
import { WebClient } from '@slack/web-api'
import { OneOfOption } from '../models.js'
export const initSync = async (slackClient: WebClient) => {
console.error('------------------------INIT SYNC------------------------')
const slackUsers: OneOfOption[] = []
try {
const response = await slackClient.users.list()
response.members?.forEach((user) => {
if (
user.deleted ||
user.is_bot ||
!user.is_email_confirmed ||
!user.id ||
!user.name
)
return
slackUsers.push({
const: user.id,
title: user.name,
})
})
} catch (error) {
console.error(error)
return {}
}
return {
slack_users: slackUsers
}
}
Final Run
Run npm run build && npm run start. The logs should show the slack users' details.
Step 10: Fetch Pokémon Types
Do the same for the Pokémon types:
- In
src/index.ts, pass thepokeClienttoinitSync. - In
src/processLogic/initSync.ts, addpokeClientas an argument toinitSync. - Use
pokeClient.getTypesList()to fetch Pokémon types.
Updated initSync.ts
import { WebClient } from '@slack/web-api'
import Pokedex from 'pokedex-promise-v2'
import { OneOfOption } from '../models.js'
export const initSync = async (
pokeClient: Pokedex,
slackClient: WebClient) => {
console.error('------------------------INIT SYNC------------------------')
try {
const { results: types } = await pokeClient.getTypesList()
console.error(types)
} catch (error) {
console.error(error)
}
const slackUsers: OneOfOption[] = []
try {
const response = await slackClient.users.list()
response.members?.forEach((user) => {
if (
user.deleted ||
user.is_bot ||
!user.is_email_confirmed ||
!user.id ||
!user.name
)
return
slackUsers.push({
const: user.id,
title: user.name,
})
})
} catch (error) {
console.error(error)
return {}
}
return {
slack_users: slackUsers
}
}
Final Output
By the end of these steps, the standard out of the initSync will include options for both the slack_user and pokemon_type configs.