{"id":25567339,"url":"https://github.com/offbi/snowflake-to-slack","last_synced_at":"2025-04-12T11:54:06.951Z","repository":{"id":44746081,"uuid":"355565192","full_name":"offbi/snowflake-to-slack","owner":"offbi","description":"Send Slack messages spiced :hot_pepper: with data from Snowflake :snowflake:","archived":false,"fork":false,"pushed_at":"2022-01-27T10:34:06.000Z","size":1138,"stargazers_count":16,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-26T06:41:43.334Z","etag":null,"topics":["business-intelligence","dbt","slack","snowflake"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/offbi.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-04-07T13:59:12.000Z","updated_at":"2025-02-24T16:24:24.000Z","dependencies_parsed_at":"2022-09-19T10:10:24.736Z","dependency_job_id":null,"html_url":"https://github.com/offbi/snowflake-to-slack","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/offbi%2Fsnowflake-to-slack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/offbi%2Fsnowflake-to-slack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/offbi%2Fsnowflake-to-slack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/offbi%2Fsnowflake-to-slack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/offbi","download_url":"https://codeload.github.com/offbi/snowflake-to-slack/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248161287,"owners_count":21057556,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["business-intelligence","dbt","slack","snowflake"],"created_at":"2025-02-20T23:21:48.522Z","updated_at":"2025-04-12T11:54:06.930Z","avatar_url":"https://github.com/offbi.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n \u003cimg src=\"https://github.com/offbi/snowflake-to-slack/blob/main/.github/snowflake-to-slack.png?raw=true\" alt=\"dbt-pre-commit\" width=400/\u003e\n \u003ch1 align=\"center\"\u003esnowflake-to-slack\u003c/h1\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n \u003ca href=\"https://github.com/offbi/snowflake-to-slack/actions?workflow=CI\"\u003e\n \u003cimg src=\"https://github.com/offbi/snowflake-to-slack/workflows/CI/badge.svg?branch=main\" alt=\"CI\" /\u003e\n \u003c/a\u003e\n \u003ca href=\"https://codecov.io/gh/offbi/snowflake-to-slack\"\u003e\n \u003cimg src=\"https://codecov.io/gh/offbi/snowflake-to-slack/branch/main/graph/badge.svg\"/\u003e\n \u003c/a\u003e\n \u003ca href=\"https://github.com/psf/black\"\u003e\n \u003cimg src=\"https://img.shields.io/badge/code%20style-black-000000.svg\" alt=\"black\"/\u003e\n \u003c/a\u003e\n \u003ca href=\"https://github.com/pre-commit/pre-commit\"\u003e\n \u003cimg src=\"https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit\u0026logoColor=white\" alt=\"black\"/\u003e\n \u003c/a\u003e\n\u003c/p\u003e\n\nEasily send Slack messages templated with data from Snowflake.\n\n`snowflake-to-slack` can be executed as:\n\n- [Github Action](#github-actions)\n- [Docker container](#docker-container)\n- [Python script](#python-script)\n\n## Use cases\n\n- send daily / weekly / monthly reports to your SDR or any channel in human words.\n- send information on whether anomalies were detected in the selected metrics. With e.g. [SQL anomaly detection](https://hakibenita.com/sql-anomaly-detection).\n- view information about yesterday's credit spend in Slack.\n- monitor [dbt](https://docs.getdbt.com) model execution and dependencies from Slack with [dbt_artifacts](https://github.com/tailsdotcom/dbt_artifacts).\n\n## How to setup `snowflake-to-slack`\n\n1. First you need to [generate Slack Token](https://github.com/offbi/snowflake-to-slack/blob/main/generate-slack-token.md).\n2. Design your Slack message with [Slack Block Kit](https://app.slack.com/block-kit-builder/T107X2XNZ#%7B%22blocks%22:%5B%7B%22type%22:%22section%22,%22text%22:%7B%22type%22:%22mrkdwn%22,%22text%22:%22You%20have%20a%20new%20request:%5Cn*%3CfakeLink.toEmployeeProfile.com%7CFred%20Enriquez%20-%20New%20device%20request%3E*%22%7D%7D,%7B%22type%22:%22section%22,%22fields%22:%5B%7B%22type%22:%22mrkdwn%22,%22text%22:%22*Type:*%5CnComputer%20(laptop)%22%7D,%7B%22type%22:%22mrkdwn%22,%22text%22:%22*When:*%5CnSubmitted%20Aut%2010%22%7D,%7B%22type%22:%22mrkdwn%22,%22text%22:%22*Last%20Update:*%5CnMar%2010,%202015%20(3%20years,%205%20months)%22%7D,%7B%22type%22:%22mrkdwn%22,%22text%22:%22*Reason:*%5CnAll%20vowel%20keys%20aren't%20working.%22%7D,%7B%22type%22:%22mrkdwn%22,%22text%22:%22*Specs:*%5Cn%5C%22Cheetah%20Pro%2015%5C%22%20-%20Fast,%20really%20fast%5C%22%22%7D%5D%7D,%7B%22type%22:%22actions%22,%22elements%22:%5B%7B%22type%22:%22button%22,%22text%22:%7B%22type%22:%22plain_text%22,%22emoji%22:true,%22text%22:%22Approve%22%7D,%22style%22:%22primary%22,%22value%22:%22click_me_123%22%7D,%7B%22type%22:%22button%22,%22text%22:%7B%22type%22:%22plain_text%22,%22emoji%22:true,%22text%22:%22Deny%22%7D,%22style%22:%22danger%22,%22value%22:%22click_me_123%22%7D%5D%7D%5D%7D)\n3. Inside your repository (it can be also `dbt` repository) create new folder. e.g. `slack_templates` and copy designed message here. I recommend you to use `.j2` suffix, e.g. `test.j2`.\n4. Inside your Slack template, replace all dynamic values you want to replace with Snowflake data with `{{\u003cCOLUMN NAME\u003e}}`. E.g.\n\n```\n[\n\t{\n\t\t\"type\": \"section\",\n\t\t\"text\": {\n\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\"text\": \"Hello {{GREETINGS}}\"\n\t\t}\n\t}\n]\n```\n\nThen if I will have SQL query in Snowflake like this:\n\n```\nSELECT 'guys!' AS GREETINGS\n```\n\nThe message `Hello guys!` will be sent to Slack.\n\n**BEWARE you need to uppercase your variable names in template since Snowflake is uppercasing column names by default!!**\n\nInside templates you can use anything from Jinja templating language (as you probably know from `dbt`), e.g.:\n\n```\n-- default\n\"text\": \"Hello {{GREETINGS|default('girls!')}}\"\n\n-- conditions\n{% if SLACK_CHANNEL == '#general' %}\n    \"text\": \"Hello people\"\n{% else %}\n   \"text\": \"Hello {{USERNAME}}!\"\n{% endif %}\n\n-- for loop\n\"text\": \"You have:\n{% for i in range(3) %}\n {{ i }}\n{% endfor %}\nseconds to answer!\n\"\n```\nYou can also [include](https://jinja.palletsprojects.com/en/2.11.x/templates/#include) and [import](https://jinja.palletsprojects.com/en/2.11.x/templates/#import) other templates!\n\nSee [Template Designer Documentation](https://jinja.palletsprojects.com/en/2.11.x/templates/) for full reference of Jinja2 syntax.\n\n5. Create Snowflake SQL script. Here are some things you should know:\n\n    - Every row from SQL will be send as separated Slack Message. It means that if you want to send PM to different Slack users you do not have to create separete SQL for her/him, but you create one SQL and add column `SLACK_CHANNEL` with Slack user id. With this you are able to burst it.\n    - There are some special columns that influence the message distribution:\n        - `SLACK_MESSAGE_TEMPLATE`: full name of Jinja template (e.g. `test.j2`) from template path. This value can be overriden with cli parameters (see later).\n        - `SLACK_MESSAGE_TEXT`: useful if you want to send just simple message without block kit and without templating. So you can use `SLACK_MESSAGE_TEMPLATE` or `SLACK_MESSAGE_TEXT`. If you use both, `SLACK_MESSAGE_TEMPLATE` will be used for main message in Slack and `SLACK_MESSAGE_TEXT` for notification message. This value can be overriden with cli parameters (see later).\n        - `SLACK_CHANNEL`: name of Slack channel (with `#`) where you want to send your message. Can also be the name (`john.doe`) or ID of Slack user.\n        - `SLACK_FREQUENCY`: useful e.g. in cases when you have one SQL and you want to burst it to many users. Some users wants this report daily but some weekly. Specify list of values separated with comma e.g. `weekly,monthly`. Allowed values are: `daily,weekly,monthly,quartely,yearly,monday,tuesday,wednesday,thursday,friday,saturday,sunday,never,always`\n    - Name of column can be used in template (but it doesn't have to).\n\n    Example\n    ```\n    SELECT\n       'test.j2' AS SLACK_MESSAGE_TEMPLATE,\n       'This is notification' AS SLACK_MESSAGE_TEXT,\n       'weekly,monthly' AS SLACK_FREQUENCY,\n       '#random' as SLACK_CHANNEL,\n       -------\n       'guys!' as GREETINGS\n    ```\n\n6. You of course need some Snowflake credentials :). You can use simple name/password or [key-pair](https://docs.snowflake.com/en/user-guide/key-pair-auth.html) authorization.\n\n## Sending messages\n\nYou can send Slack messages with:\n\n- [Github Action](#github-actions)\n- [Docker container](#docker-container)\n- [Python script](#python-script)\n\n### Github Actions\n\n#### Quickstart\n\n- inside your Github repository create folder `.github/workflows` (unless it already exists).\n- create new file e.g. `main.yml`\n- specify your workflow, e.g.:\n```\non:\n  # to allow manual run\n  workflow_dispatch:\n  schedule:\n    # * is a special character in YAML so you have to quote this string\n    - cron:  '0 0 * * *'\n\njobs:\n  snowflake-to-slack:\n    runs-on: ubuntu-latest\n    name: snowflake to slack\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v2.3.3\n      - name: Slack message 1\n        uses: offbi/snowflake-to-slack@1.0.0\n        with:\n          user: ${{ secrets.USER }}\n          password: \"${{ secrets.PASSWORD }}\"\n          account: \"\u003cyour Snowflake account name\u003e\"\n          warehouse: \"\u003cyour Snowflake warehouse name\u003e\"\n          database: \"\u003cyour Snowflake database name\u003e\"\n          role: \"\u003cyour Snowflake role name\u003e\"\n          slack-token: ${{ secrets.SLACK_TOKEN }}\n          sql: \"\u003cyour Snowflake select statement\u003e\"\n          template-path: /github/workspace/\u003cname of template folder in your repo\u003e\n```\n**Beware before you run `snowflake-to-slack` you need to run `actions/checkout` action. `template-path` hash to be specified ad `/github/workspace/\u003cname of template folder\u003e`**\n- it is adviced to use [Github Secrets](https://docs.github.com/en/actions/reference/encrypted-secrets) to specify passwords and slack-tokens.\n- push to Github :)\n- if you want to use rsa key instead of password (recommended) - fill RSA_KEY secret and use this workflow:\n\n```\non:\n  workflow_dispatch:\n  schedule:\n    # * is a special character in YAML so you have to quote this string\n    - cron:  '0 0 * * *'\n\njobs:\n  snowflake-to-slack:\n    runs-on: ubuntu-latest\n    name: snowflake to slack\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v2.3.3\n      - run: 'echo \"$RSA_KEY\" \u003e rsa_key.p8'\n        shell: bash\n        env:\n          RSA_KEY: ${{secrets.RSA_KEY}}\n      - name: Slack message 1\n        uses: offbi/snowflake-to-slack@1.0.1\n        with:\n          user: ${{ secrets.USER }}\n          rsa-key-uri: /github/workspace/rsa_key.p8\n          private-key-pass: ${{ secrets.PRIVATE_KEY_PASS }}\n          account: \"\u003cyour Snowflake account name\u003e\"\n          warehouse: \"\u003cyour Snowflake warehouse name\u003e\"\n          database: \"\u003cyour Snowflake database name\u003e\"\n           role: \"\u003cyour Snowflake role name\u003e\"\n          slack-token: ${{ secrets.SLACK_TOKEN }}\n          sql: | \n            SELECT\n              'test.j2' AS SLACK_MESSAGE_TEMPLATE,\n              'This is notification' AS SLACK_MESSAGE_TEXT,\n              '#random' as SLACK_CHANNEL,\n              -------\n              'guys!' as GREETINGS\n          template-path: /github/workspace/\u003cname of template folder in your repo\u003e\n```\n\nTo learn more about Github actions see https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions.\n\n#### Github Action parameters\n\n- `user`: Snowflake Username. Required: true\n- `password`: Snowflake Password. Required: false\n- `rsa-key-uri`: URI of RSA key for authorization. Required: false\n- `private-key-pass`: RSA key password. Required: false\n- `account`: Snowflake Account. Required: true\n- `warehouse`: Snowflake Warehouse. Required: true\n- `database`: Snowflake Database. Required: true\n- `role`: Snowflake Role. Required: true\n- `slack-token`: Slack Token. Required: true\n- `slack-channel`: Slack Channel. This parameter overrides value from database Required: false\n- `fail-fast`: Raise error and stop execution if error shows during sending message. Required: false\n- `dry-run`: Just print message into stdout. Do not send message to Slack. Required: false\n- `date-valid`: Date valid for deciding if message should be executed. Default current date. Required: false\n- `sql`: SQL command to run. Required: true\n- `template-path`: Path with your Jinja templates. Required: true\n- `slack-frequency`: Frequency. Together with date-valid determines whether the message is sent. This parameter overrides value from database. Required: false.\n- `slack-message-template`: Message template. It overrides `SLACK_MESSAGE_TEMPLATE` from Snowflake. Required: false.\n- `slack-message-text`: Message text. It overrides `SLACK_MESSAGE_TEXT` from Snowflake. Required: false.\n\n### Docker container\n\nTo run Docker container execute:\n\n```\ndocker run \u003clist of envs\u003e offbi/snowflake-to-slack \u003cparams\u003e\n```\n\n### Python script\n\nInstall `snowflake-to-slack` with:\n\n```\npip install snowflake-to-slack=='1.0.0'\nsnowflake-to-slack \u003cparams\u003e\n```\n\n## List of `snowflake-to-slack` params\n\n- `--user`: Snowflake Username. Required: true. Env variable `SNOWFLAKE_USER`.\n- `--password`: Snowflake Password. Required: false. Env variable `SNOWFLAKE_PASS`.\n- `--rsa-key-uri`: URI of RSA key for authorization. Required: false. Env variable `SNOWFLAKE_RSA_KEY_URI`.\n- `--private-key-pass`: RSA key password. Required: false. Env variable `SNOWFLAKE_PRIVATE_KEY_PASS`.\n- `--account`: Snowflake Account. Required: true. Env variable `SNOWFLAKE_ACCOUNT`.\n- `--warehouse`: Snowflake Warehouse. Required: true. Env variable `SNOWFLAKE_WAREHOUSE`.\n- `--database`: Snowflake Database. Required: true. Env variable `SNOWFLAKE_USER`.\n- `--role`: Snowflake Role. Required: true. Env variable `SNOWFLAKE_ROLE`.\n- `--slack-token`: Slack Token. Required: true. Env variable `SLACK_TOKEN`.\n- `--slack-channel`: Slack Channel. This parameter overrides value from database Required: false. Env variable `SLACK_CHANNEL`.\n- `--fail-fast`: Raise error and stop execution if error shows during sending message. Required: false. Env variable `FAIL_FAST`.\n- `--dry-run`: Just print message into stdout. Do not send message to Slack. Required: false. Env variable `DRY_RUN`.\n- `--date-valid`: Date valid for deciding if message should be executed. Default current date. Required: false. Env variable `DATE_VALID`.\n- `--sql`: SQL command to run. Required: true. Env variable `SQL`.\n- `--template-path`: Path with your Jinja templates. Required: true. Env variable `TEMPLATE_PATH`.\n- `--slack-frequency`: Frequency. Together with date-valid determines whether the message is sent. This parameter overrides value from database. Required: false. Env variable `SLACK_FREQUENCY`.\n- `--slack-message-template`: Message template. It overrides `SLACK_MESSAGE_TEMPLATE` from Snowflake. Required: false. Env variable `SLACK_MESSAGE_TEMPLATE`.\n- `--slack-message-text`: Message text. It overrides `SLACK_MESSAGE_TEXT` from Snowflake. Required: false. Env variable `SLACK_MESSAGE_TEXT`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foffbi%2Fsnowflake-to-slack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foffbi%2Fsnowflake-to-slack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foffbi%2Fsnowflake-to-slack/lists"}