slackapi / deno-slack-sdk

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

Accessing .env Variables Outside of Slack Functions #281

Open anthonygualandri opened 6 months ago

anthonygualandri commented 6 months ago

Question

In reviewing some documentation on the Slack Deno SDK and next gen app structure, I found this treatment of working with functions that are not Slack Functions in an error handling example. It references accessing an external API i the comments of the code example and that led me to wonder, is there a way to access .env variables saved in the Slack app outside of the env context property inside of Slack Functions as referenced here? Thanks!

Context

Environment

Requirements

Please read the Contributing guidelines and Code of Conduct before creating this issue or pull request. By submitting, you are agreeing to those rules.

WilliamBergamin commented 6 months ago

Hi @anthonygualandri thanks for writing in 💯

Just to clarify, you would like to fetch environment variable using an HTTP request instead of the env context?

anthonygualandri commented 6 months ago

No. I'd like to use a stored env inside the app within a function that isn't a slack function and so doesn't have the context env input to the function. If you look at the first link referenced above you'll see an example of what I mean in terms of the function structure. Thanks!

WilliamBergamin commented 6 months ago

I see, the env context is injected by Slack directly into the slack function, the slack function is the entrypoint for the serverless request execution

If you want to use the env context in a function you will need to pass it into it as a parameter or build your own env context, something like this should work but I have not tested it out yet, there may be a more elegant solution for this

let function_scoped_env: Env;

function console_log_env() {
  for (const [key, value] of Object.entries(function_scoped_env)) {
    console.log(`${key}: ${value}`);
  }
}

export default SlackFunction(
  PostIssueMessage,
  async ({ env, inputs, client }) => {
    function_scoped_env = env;
    console_log_env();
    return {
      outputs: { ... },
    };
  },
);
mcsescott commented 6 months ago

I use a dotenv file to store variables in a .env file that I am able to reference in my functions.

https://docs.deno.com/runtime/manual/basics/env_variables

WilliamBergamin commented 6 months ago

The .env file will not be bundled with the function when it is uploaded to the Slack infrastructure, you will have to add the environment variables using the env add command. Environment variables added with env add will be made available to your deployed app's custom function see docs here

You should be able to set the environment variables from the env input something like this

export default SlackFunction(MyFunctionDefinition, ({ env }) => {
  if (env){
    Deno.env.set("MY_ENV_VAR", env["MY_ENV_VAR"]);
    console.log(Deno.env.get("MY_ENV_VAR"));
  }
});

Let me know if this is what you are looking for

anthonygualandri commented 6 months ago

Yeah I think that's exactly what I need. I took a look at the docs link you sent. If I can slack env add MY_ENV_VAR asdf1234 And the Deno.env.get outside of a SlackFunction that's perfect.

mcsescott commented 5 months ago

In my testing you can't use Deno.set.env inside your code - it will fail when running after slack deploy.

I found a way around it by putting the variables at the top level (and importing another file) into my code. In my case, having a large number of variables and having to run a CLI command multiple times to set the variables was getting a little ridiculous.

WilliamBergamin commented 5 months ago

Thanks for sharing your workaround @mcsescott 💯

I understand it may be tedious to manually run slack env add MY_ENV_VAR asdf1234 on a large number of variables

You should be able to a bash script or a shell command like the one below to help with this Take the following .env file

MY_ENV=test
MY_ENV1=test1
MY_ENV2=test2
MY_ENV3=test3

The following command should execute slack env add for each variable in the file

cat .env | tr '=' ' ' | xargs -n 2 slack env add $1 $2 -w <your_workspace>

Let me know if this is useful 🙏

mhalavanja commented 5 months ago

In my testing you can't use Deno.set.env inside your code

I am having the same problem where Deno.set.env and Deno.get.env don't work when I am running the app locally. I am wondering if they would work after I deploy the app or not?

Also, are we able to programmatically set the new value of our environment variable from within our Slack Functions so that we can use it later? Example usage is if you have a token which you want to rotate sometimes, you could use scheduled trigger to get the new token and save it as a new value of environment variable.

WilliamBergamin commented 5 months ago

Hi @mhalavanja thanks for bringing this up

I don't think you will be able to edit the value of en environment variable on the fly. If you want to store a token and rotate it on a schedule, I would recommend storing it in a datastore instead of an environment variable

mhalavanja commented 5 months ago

Okay, thanks for the suggestion @WilliamBergamin. I thought it might be possible as the suggested way of handling tokens for third party APIs is via env vars.