# Update the pokemonSync flow

You have access to the newly created slack\_user and pokemon\_type configs. Let's update pokemonSync to make use of them.

The Pokémon Trainer Academy needs the new `pokemonSync` to do the following:

* The Pokémon of the day must always be of the type selected in the tenant's connection settings.
* The Slack message should only be sent to the Slack user specified in the tenant's connection settings.

To do this we will need to:

* [ ] Fetch Pokémon Type selected in the config.
* [ ] Select the Pokémon of the Day from the Pokémon within that type.
* [ ] Fetch the Pokémon of the Day.
* [ ] Send a Slack message about that Pokémon to the Slack user selected in the config.

1. In the .env update the run mode and enter selections for the two dynamic configs:

```properties
PAN_CTX_RUN_MODE= normal
PAN_CFG_POKEMON_TYPE = rock
PAN_CFG_SLACK_USER= <YOUR-SLACK-MEMBER-ID>
```

In the config object of your tenant's most recent normal sync logs you should have seen your Slack user ID. Replace the Slack user ID above with your own.

2. Fetch the selected Pokémon type by doing the following:
   * [ ] In src/index.ts pass the `config` to `pokemonSync`.
   * [ ] In src/processLogic/pokemonSync.ts add `config` as an argument to `pokemonSync` and import `Config` to define the type of this new argument.
   * [ ] Pass `config.pokemon_type` to the `pokeClient.getTypeByName`method to fetch the selected type.
   * [ ] Log out the results of that fetch.

The pokemonSync.ts file should look something like this:

```typescript
import Pokedex from 'pokedex-promise-v2'
import { WebClient } from '@slack/web-api'
import { pokemonToSlackMessage } from '../transformations.js'
import { Context, Config } from '../lib.js'

export const pokemonSync = async (
    pokeClient: Pokedex,
    slackClient: WebClient,
    context: Context,
    config: Config
) => {
    console.error(
        '------------------------POKEMON SYNC------------------------'
    )

    const pokemonType = await pokeClient.getTypeByName(config.pokemon_type)
    console.error(pokemonType)

    let lastPokemonId = 0
    if (context.last_successful_run_std_out) {
        const lastStdOut = JSON.parse(context.last_successful_run_std_out)
        lastPokemonId = Number(lastStdOut.last_pokemon_id) || 0
    }

    const nextPokemonId = lastPokemonId + 1
    const pokemonOfTheDay = await pokeClient.getPokemonByName(nextPokemonId)

    const slackMemberIds = ['<YOUR-SLACK-MEMBER-ID>']

    for (const slackID of slackMemberIds) {
        const slackMessage = pokemonToSlackMessage(pokemonOfTheDay, slackID)
        await slackClient.chat.postMessage(slackMessage)
    }

    return { last_pokemon_id: nextPokemonId }
}
```

3. Run `npm run build && npm run start`.

You should get a Pokémon Slack message, but we're more interested in examining the logs; they should look something like this:

```
> pokemon-of-the-day@1.0.0 start
> node build/src/

This run is in mode: normal
------------------------CONFIG------------------------
Config { pokemon_type: 'rock', slack_user: '<YOUR-SLACK-MEMBER-ID>' }
------------------------CONTEXT------------------------
Context {
  run_mode: 'normal',
  last_successful_run_std_out: '{"last_pokemon_id":247}'
}
------------------------POKEMON SYNC------------------------
{
  damage_relations: {... various damage relations properties of the rock Pokémon type}
  ... more properties of the rock Pokémon type
}
{"last_pokemon_id":248}
```

You can remove the `console.error(pokemonType)`

You can learn about the shape of a Pokémon type by examining the one you just logged out or reviewing [the PokéAPI docs for the `type` endpoint](https://pokeapi.co/docs/v2#types).

You'll see that each Pokémon type has the property `pokemon`; it's an array of the type's Pokémon. We should select the Pokémon of the day from that list!

Each member of the `pokemon` array has the following shape:

```json
{
  "slot": 1,
  "pokemon": {
    "name": "sandshrew",
    "url": "https://pokeapi.co/api/v2/pokemon/27/"
  }
}
```

4. Change how `nextPokemonId` is defined; it should be the ID of the first member of the fetched type's `pokemon` array whose ID is greater than `lastPokemonId`.

Here is one way you could do this:

```typescript
import Pokedex from 'pokedex-promise-v2'
import { WebClient } from '@slack/web-api'
import { pokemonToSlackMessage } from '../transformations.js'
import { Context, Config } from '../lib.js'

export const pokemonSync = async (
    pokeClient: Pokedex,
    slackClient: WebClient,
    context: Context,
    config: Config
) => {
    console.error(
        '------------------------POKEMON SYNC------------------------'
    )

    const pokemonType = await pokeClient.getTypeByName(config.pokemon_type)
    const pokemonOptions = pokemonType.pokemon

    let lastPokemonId = 0
    if (context.last_successful_run_std_out) {
        const lastStdOut = JSON.parse(context.last_successful_run_std_out)
        lastPokemonId = Number(lastStdOut.last_pokemon_id) || 0
    }

    let nextPokemonId: string | undefined
    for (const pokemon of pokemonOptions) {
        const pokemonId = Number(pokemon.pokemon.url.split('/').slice(-2, -1)[0])
        if (pokemonId <= lastPokemonId) continue
        nextPokemonId = String(pokemonId)
        break
    }
    if(!nextPokemonId) return {last_pokemon_id: lastPokemonId }
    
    const pokemonOfTheDay = await pokeClient.getPokemonByName(nextPokemonId)

    const slackMemberIds = ['<YOUR-SLACK-MEMBER-ID>']

    for (const slackID of slackMemberIds) {
        const slackMessage = pokemonToSlackMessage(pokemonOfTheDay, slackID)
        await slackClient.chat.postMessage(slackMessage)
    }

    return { last_pokemon_id: nextPokemonId }
}

```

5. Run `npm run build && npm run start`.

Unless you changed the standard out in your .env this run's results may not look too different from the last run's (except the logs won't include the Pokémon type). This is because the list of Pokémon within a type often has many Pokémon of consecutive IDs . Regardless, you have shown that the new method of defining `nextPokemonId` does not interfere with the rest of the flow's functionality.

6. Now adjust pokemonSync to use the slack\_user config
   * [ ] Remove the array of hard coded `slackMemberIds`.
   * [ ] Instead of sending a Slack message for every member in that array just pass `config.slack_user` to `pokemonToSlackMessage`, and only call `slackClient.chat.postMessage` for that one `slackMessage.`

Your pokemonSync.ts could look like this now:

```typescript
import Pokedex from 'pokedex-promise-v2'
import { WebClient } from '@slack/web-api'
import { pokemonToSlackMessage } from '../transformations.js'
import { Context, Config } from '../lib.js'

export const pokemonSync = async (
    pokeClient: Pokedex,
    slackClient: WebClient,
    context: Context,
    config: Config
) => {
    console.error(
        '------------------------POKEMON SYNC------------------------'
    )

    const pokemonType = await pokeClient.getTypeByName(config.pokemon_type)
    const pokemonOptions = pokemonType.pokemon

    let lastPokemonId = 0
    if (context.last_successful_run_std_out) {
        const lastStdOut = JSON.parse(context.last_successful_run_std_out)
        lastPokemonId = Number(lastStdOut.last_pokemon_id) || 0
    }

    let nextPokemonId: string | undefined
    for (const pokemon of pokemonOptions) {
        const pokemonId = Number(pokemon.pokemon.url.split('/').slice(-2, -1)[0])
        if (pokemonId <= lastPokemonId) continue
        nextPokemonId = String(pokemonId)
        break
    }
    if(!nextPokemonId) return {last_pokemon_id: lastPokemonId }

    const pokemonOfTheDay = await pokeClient.getPokemonByName(nextPokemonId)

    const slackMessage = pokemonToSlackMessage(pokemonOfTheDay, config.slack_user)
    await slackClient.chat.postMessage(slackMessage)
    
    return { last_pokemon_id: nextPokemonId }
}

```

7. Run `npm run build && npm run start`.

Once again, this run's results may not look too different from the last run's. This shows that accessing the slack User's ID from `config`, instead of a hardcoded list does not interfere with the rest of the flow's functionality.

Your pokemonSync.ts should match [this one](https://github.com/pandium/sample_integrations/blob/master/POKEMON_OF_THE_DAY/src/processLogic/pokemonSync.ts). In fact your integration files should match all the ones in [this repository](https://github.com/pandium/sample_integrations/tree/master/POKEMON_OF_THE_DAY).

The final step is to see what this all looks like when it is run on Pandium!


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.pandium.com/getting-started/pandium-integration-tutorial/pokemon-of-the-day-part-2/update-the-pokemonsync-flow.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
