😎
External Network Access 〜 Slack通知(デコ版)を作ってみる
がく@ちゅらデータです。
ご無沙汰しております、前にちゃんとしたのを書いてから知らない間に秋がすぎてました(汗
さて、先日、沖縄SnowVillageにて下記のようなLTをさせていただきました。
でやったのですが
な感じで、未完成と感じておった次第です。
なので、今回作ってみました。
External Network Access機能を使って、Slack通知をする という記事は
国内では
海外Mediumでは
があります。
こちらを参考にさせていただこうかな
Slack側の準備
https://api.slack.com/apps へアクセス
Slack Apps のページから Incomming Webhook URLを生成する
※情シスの承認が必要でしたので、ちょっと承認まで動作検証が遅れましたが、すぐにやってくれた、ありがとうー > 弊社情シス担当のみんな
Snowflake 側の設定
SnowflakeのNetwork ruleの作成
CREATE OR REPLACE NETWORK RULE slack_webhook_network_rule
MODE = EGRESS
TYPE = HOST_PORT
VALUE_LIST = ('hooks.slack.com');
Webhook URL を secret へ登録
CREATE OR REPLACE SECRET slack_app_webhook_url
type = GENERIC_STRING
secret_string = 'https://hooks.slack.com/services/*********/*********'
comment = 'Slack Webhook URL you have created from the Slack App UI';
Externao Access Integrationの作成
CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION slack_webhook_access_integration
ALLOWED_NETWORK_RULES = (slack_webhook_network_rule)
ALLOWED_AUTHENTICATION_SECRETS = (slack_app_webhook_url)
ENABLED = true;
simple message (非デコ) をSlackに送るストアドプロシージャの作成
CREATE OR REPLACE PROCEDURE send_slack_message(MSG string)
RETURNS STRING
LANGUAGE PYTHON
RUNTIME_VERSION = 3.10
HANDLER = 'main'
EXTERNAL_ACCESS_INTEGRATIONS = (slack_webhook_access_integration)
SECRETS = ('slack_url' = slack_app_webhook_url)
PACKAGES = ('snowflake-snowpark-python', 'requests')
EXECUTE AS CALLER
AS
$$
import snowflake.snowpark as snowpark
import json
import requests
import _snowflake
from datetime import date
def main(session, msg):
# Retrieve the Webhook URL from the SECRET object
webhook_url = _snowflake.get_generic_secret_string('slack_url')
slack_data = {
"text": f"Snowflake says: {msg}"
}
response = requests.post(
webhook_url, data=json.dumps(slack_data),
headers={'Content-Type': 'application/json'}
)
if response.status_code != 200:
raise ValueError(
'Request to slack returned an error %s, the response is:\n%s'
% (response.status_code, response.text)
)
return "SUCCESS"
$$;
CALL send_slack_message('Hello world!');
を実行すると
WebUIにて、成功
Slackにも シンプルな通知ができました
通知をデコってみよう
CREATE OR REPLACE PROCEDURE send_slack_deco_message(LEVEL string, MSG string, CHANNEL_NAME string)
RETURNS STRING
LANGUAGE PYTHON
RUNTIME_VERSION = 3.10
HANDLER = 'main'
EXTERNAL_ACCESS_INTEGRATIONS = (slack_webhook_access_integration)
SECRETS = ('slack_url' = slack_app_webhook_url)
PACKAGES = ('snowflake-snowpark-python', 'requests')
EXECUTE AS CALLER
AS
$$
import snowflake.snowpark as snowpark
import json
import requests
import _snowflake
from datetime import date
def main(session, level, msg, channel_name):
# Retrieve the Webhook URL from the SECRET object
webhook_url = _snowflake.get_generic_secret_string('slack_url')
color = "good"
if level == "info":
color = "good"
elif level == "warn":
color = "warning"
elif level == "crit":
color = "danger"
else:
color = "good"
slack_data = {
"channel" : f"{channel_name}",
"attachments":[
{
"fallback":f"Snowflake ({level})",
"pretext":f"Snowflake ({level})",
"color":color,
"fields":[
{
"title":f"Snowflake ({level})",
"value":f"{msg}"
}
]
}
]
}
response = requests.post(
webhook_url, data=json.dumps(slack_data),
headers={'Content-Type': 'application/json'}
)
if response.status_code != 200:
raise ValueError(
'Request to slack returned an error %s, the response is:\n%s'
% (response.status_code, response.text)
)
return "SUCCESS"
$$;
CALL send_slack_deco_message('warn','Hello world!','_gaku_t');
CALL send_slack_deco_message('warn','Hello world!','_gaku_t_2');
CALL send_slack_deco_message('crit','Hello world!','_gaku_t');
まとめ
External Network Access をつかってみましたが、設定、めちゃくちゃ簡単です!
あとは、Slack通知のJSONで attachmentに入れてやればいい感じで書けます
info, warn, critでそれぞれ色がつけることができました
今後改善するとしたら
- send_slack_deco_message_info(message)
- send_slack_deco_message_warn(message)
- send_slack_ddeco_message_crit(message)
みたいなオーバーラップさせるのを作るとよりわかりやすいかもな〜
あとまだ試していないですが
- 通知先のチャンネルを指定したい
- slack_dataの中で、 { "channel": "#new_channel" }
- ↑うまく行かなかった。何かSlackAppの設定が必要かも
- ポストごとにBotの表示名を変えたい
- slack_data の中で "username": "がーにゃbot"
- 追加すればできそう
とかでできそう
出典
Discussion