slackapi / deno-slack-sdk

SDK for building Run on Slack apps using Deno
https://api.slack.com/automation
MIT License
158 stars 27 forks source link

[FEATURE] use an input to set the output_parameters in DefineFunction #226

Open mjamaah opened 11 months ago

mjamaah commented 11 months ago

Description of the problem being solved

I'm Currently working on implementing some custom functions to be used in workflow Builder. However, I wanted to use a generated Schema from a previous function as "output_parameters" in the "DefineFunction" Function. so, I can have dynamic outputs to be used in the next steps.

Use Case

I've developed a slack workflow using the Workflow Builder that listens for HTTP POST requests from GitHub through the Slack API. After receiving a request, it sends a message to a designated channel for approval. Subsequently, I've created a custom function to initiate an HTTP POST request back to GitHub, triggering a specific GitHub action. Now, I aim to send the dispatch job's status to a channel by parsing the JSON Response from GitHub. However, I encountered difficulties, especially with the "output_parameters" section, where I had to predefine its structure. To resolve this, it would be beneficial to have the option to set the output_parameters from a variable within the "DefineFunction" function.

Alternative solutions

Send the whole JSON Response via message.

Requirements

I have no idea!

WilliamBergamin commented 11 months ago

Hi @mjamaah thanks for writing in 💯

If I'm understanding correctly you would like to dynamically alter the output_parameters of a function, this idea has come up in the past Unfortunately I don't believe it will be possible in the near future. functions aim to be reusable components that can be used by any workflow, altering its definition on the fly may generate breaking changes to workflows that use it

A work around for this would be to pass the JSON payload as a string property in the output, alternately if this string is to large the data could be posted to a datastore and the primary_key could be passed to the output_parameters

Let me know if this answers your question 🗺️

mjamaah commented 11 months ago

Hi @WilliamBergamin,

Thank you for your response,

Indeed, my intention is to dynamically modify the output_parameters of a function without compromising its reusability. One potential approach is to introduce a preliminary step that involves providing sample input data and generating a schema for the output_parameters. This approach maintains consistency and avoids making on-the-fly alterations that could disrupt workflows using the function.

At the very least, this capability should be available for custom functions. Alternatively, you could consider implementing automatic schema generation from your end.

Below is a simple TypeScript function for generating a schema:

import { DefineFunction, Schema, SlackFunction } from "deno-slack-sdk/mod.ts";

export const generateSchema = DefineFunction({
  callback_id: "generate_Schema",
  source_file: "functions/generateSchema.ts",
  title: "generate Schema",
  input_parameters: {
    properties: {
      jsonString: {
        type: Schema.types.string ,
      },
    },
    required: ["jsonString"],
  },
  output_parameters: {
    properties: {
      schema: {
        type: Schema.types.string,
      },
    },
    required: ["schema"],
  },
});

export default SlackFunction(
  generateSchema,
  ({inputs}) => {
    const jsonString = inputs.jsonString;

    try {
      const jsonObject = JSON.parse(jsonString);
      const schema = {};

      for (const key in jsonObject) {
        if (jsonObject.hasOwnProperty(key)) {
          const type = typeof jsonObject[key];
          schema[key] = { type: `Schema.types.${type}`};
        }
      }

      console.log('Generated JSON Schema:');
      const SchemaString = JSON.stringify(schema, null, 2);
      console.log(SchemaString);
      return {
        outputs: {
          jsonString,
          schema: SchemaString,
        },
      };
    } catch (error) {
      console.error('Error parsing JSON for schema:', error);
      return {
        outputs: {
          jsonString,
          schema: error,
        },
      };

    }

  },
);
WilliamBergamin commented 11 months ago

Thanks for sharing this code snippet 💯 It may be useful workaround for others facing this issue

filmaj commented 11 months ago

@mjamaah what about using the generic, shapeless untyped object built-in type as an output parameter? Presumably any kind of object could be modeled with it and thus would not need a schema defined up front.