Slack Next-gen Platform – “reaction_added” Event Trigger

This is translation of Slack Next-gen Platform – “reaction_added” Event Trigger – DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»  written by Kaz (SDK Engineering & DevRel at Slack), I do not include any personal opinion here except guessing when meaning of original text is not clear for me)

이 글은 μŠ¬λž™μ˜ SDK Engineering / DevRel 인 Kaz 의 글을 λ²ˆμ—­ν•œκ²ƒμž…λ‹ˆλ‹€. μ €μ˜ 개인 μ˜κ²¬μ€ 듀어가지 μ•ŠμœΌλ©°, 일뢀 μ›λ¬Έμ˜ μ˜λ―Έκ°€ μ• λ§€ν•œ κ²½μš°μ—λ§Œ λΆ€μ—° μ„€λͺ…을 λ‹¬μ•˜μŠ΅λ‹ˆλ‹€.


이번 νŠœν† λ¦¬μ–Όμ—μ„œλŠ” 채널 ID λ₯Ό ν•„μš”λ‘œ ν•˜μ§€ μ•ŠλŠ” event 트리거λ₯Ό μ‚¬μš©ν•˜λŠ” 방법에 λŒ€ν•΄μ„œ λ°°μ›Œλ³Ό κ²ƒμž…λ‹ˆλ‹€. event νŠΈλ¦¬κ±°λŠ” μ—°κ²°λ˜μ–΄μžˆλŠ” Slack μ›Œν¬μŠ€νŽ˜μ΄μŠ€μ—μ„œ νŠΉμ •ν•œ μ΄λ²€νŠΈκ°€ λ°œμƒν–ˆμ„ λ•Œ 트리거 될 수 μžˆμŠ΅λ‹ˆλ‹€. 각각의 event 트리거 νƒ€μž…μ€ μž…λ ₯을 μœ„ν•œ 자체적인 데이터 μŠ€ν‚€λ§ˆλ₯Ό 가지고 있고, μ›Œν¬ν”Œλ‘œκ°€ νŠΈλ¦¬κ±°λ‘œλΆ€ν„° ν•„μš”ν•œ 정보듀을 λ°›μ•„λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

그리고 2가지 νƒ€μž…μ˜ event νŠΈλ¦¬κ±°κ°€ μžˆμŠ΅λ‹ˆλ‹€.

μ²«λ²ˆμ§ΈλŠ” μ›Œν¬μŠ€νŽ˜μ΄μŠ€ μ „μ²΄μ˜ 이벀트λ₯Ό 캑쳐할 수 μžˆλŠ” 트리거 μž…λ‹ˆλ‹€. μ΄λŸ¬ν•œ 이벀트의 예둜 “channel_created” 이벀트λ₯Ό 꼽을 수 μžˆκ² μŠ΅λ‹ˆλ‹€. (채널이 μƒμ„±λ˜μ—ˆμŒ) κ·Έμ™Έμ—λŠ” “dnd_updated”(ν•΄λ‹Ή λ©€λ²„μ˜ Do not Disturb μ…‹νŒ…μ΄ λ³€κ²½λ˜μ—ˆμŒ), “emoji_changed” (μ»€μŠ€ν…€ 이λͺ¨μ§€κ°€ μΆ”κ°€λ˜μ—ˆκ±°λ‚˜ λ³€κ²½λ˜μ—ˆμŒ), “user_joined_team”(μƒˆ 멀버가 μ‘°μΈν•˜μ˜€μŒ) 등이 있겠죠.

λ‹€λ₯Έ ν•œκ°€μ§€λŠ” νŠΉμ • μ±„λ„μ—μ„œ λ°œμƒν•˜λŠ” 이벀트λ₯Ό 캑쳐할 수 μžˆλŠ” 트리거 μž…λ‹ˆλ‹€. μ΄λŸ¬ν•œ 이벀트의 μ˜ˆλ‘œλŠ” “message_posted” (채널에 메세지가 μž‘μ„±λ˜μ—ˆμŒ), “reaction_added” (멀버가 이λͺ¨μ§€ λ¦¬μ•‘μ…˜μ„ 메세지에 μΆ”κ°€ν•˜μ˜€μŒ), “user_joined_channel” (μœ μ €κ°€ 곡개 λ˜λŠ” λΉ„κ³΅κ°œ 채널에 μ‘°μΈν•˜μ˜€μŒ), “user_left_channel” (μœ μ €κ°€ 곡개 λ˜λŠ” λΉ„κ³΅κ°œ μ±„λ„μ—μ„œ λ‚˜κ°”μŒ) 등이 μžˆκ² μŠ΅λ‹ˆλ‹€.

이번 νŠœν† λ¦¬μ–Ό μ—μ„œλŠ” 제λͺ©μ—μ„œ μ–ΈκΈ‰ν•œ 바와 같이 “reaction_added” λ₯Ό 가지고 진행 ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

Prerequisites

μ°¨μ„ΈλŒ€ ν”Œλž«νΌμ„ μ ‘ν•˜λŠ” 것이 μ²˜μŒμ΄μ‹œλΌλ©΄, μ΄μ „μ˜ νŠœν† λ¦¬μ–ΌμΈ β€œThe Simplest Hello World” λΆ€ν„° μ½μ–΄μ£Όμ„Έμš”. μš”μ•½ν•˜λ©΄ 유료 Slack μ›Œν¬μŠ€νŽ˜μ΄μŠ€μ™€ ν•΄λ‹Ή μ›Œν¬μŠ€νŽ˜μ΄μŠ€μ—μ„œ β€œbeta feature” λ₯Ό μ‚¬μš©ν•  수 μžˆλŠ” κΆŒν•œμ΄ ν•„μš”ν•©λ‹ˆλ‹€. 가지고 κ³„μ‹œλ‹€λ©΄ Slack CLI 와 μ›Œν¬μŠ€νŽ˜μ΄μŠ€λ₯Ό μ—°κ²°ν•˜κΈ°λ§Œ ν•˜λ©΄ λ©λ‹ˆλ‹€.

μ€€λΉ„λ˜μ—ˆλ‹€λ©΄ 앱을 ν•œλ²ˆ λ§Œλ“€μ–΄λ³΄λ„λ‘ ν•˜μ£ . μ‹œμž‘ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

Create a Blank Project

slack create λͺ…λ Ήμ–΄λ₯Ό μ‚¬μš©ν•˜μ—¬, μƒˆλ‘œμš΄ ν”„λ‘œμ νŠΈλ₯Ό μ‹œμž‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 이 νŠœν† λ¦¬μ–Όμ—μ„œλŠ” 아무것도 μ—†λŠ” μƒνƒœμ—μ„œ 앱을 λ§Œλ“€μ–΄λ³΄κ² μŠ΅λ‹ˆλ‹€. β€œBlank Project” λ₯Ό μ„ νƒν•˜μ—¬ μ£Όμ‹­μ‹œμš”.

$ slack create
? Select a template to build from:

  Hello World
  A simple workflow that sends a greeting

  Scaffolded project
  A solid foundational project that uses a Slack datastore

> Blank project
  A, well.. blank project

  To see all available samples, visit github.com/slack-samples.

ν”„λ‘œμ νŠΈκ°€ μƒμ„±λ˜λ©΄, slack run λͺ…λ Ήμ–΄κ°€ μ •μƒμ μœΌλ‘œ λ™μž‘ν•˜λŠ”μ§€ ν™•μΈν•΄λ³΄μ„Έμš”. 이 λͺ…λ Ήμ–΄λŠ” β€œdev” λ²„μ „μ˜ 앱을 μ›Œν¬μŠ€νŽ˜μ΄μŠ€μ— μ„€μΉ˜ν•©λ‹ˆλ‹€. 이 μ•±μ˜ 봇 μœ μ €κ°€ μƒμ„±λ˜κ³ , 이 봇은 API ν˜ΈμΆœμ„ μœ„ν•œ 봇 토큰 값을 가지고 μžˆμŠ΅λ‹ˆλ‹€.

$ cd affectionate-panther-654
$ slack run
? Choose a workspace  seratch  T03E94MJU
   App is not installed to this workspace

Updating dev app install for workspace "Acme Corp"

  Outgoing domains
   No allowed outgoing domains are configured
   If your function makes network requests, you will need to allow the outgoing domains
   Learn more about upcoming changes to outgoing domains: https://api.slack.com/future/changelog
  seratch of Acme Corp
Connected, awaiting events

Connected, awaiting events 둜그 메세지λ₯Ό 보신닀면, 이 앱이 μ„±κ³΅μ μœΌλ‘œ μ›Œν¬μŠ€νŽ˜μ΄μŠ€μ— μ—°κ²°λœ κ²ƒμž…λ‹ˆλ‹€. β€œCtrl +C” λ₯Ό 눌러 둜컬 μ•± ν”„λ‘œμ„ΈμŠ€λ₯Ό μ’…λ£Œν•©λ‹ˆλ‹€.

Define Workflow and Trigger

κ°„λ‹¨ν•œ 데λͺ¨ μ›Œν¬ν”Œλ‘œμ™€ link 트리거λ₯Ό μ •μ˜ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€. workflow_and_trigger.ts 둜 μ €μž₯ν•©λ‹ˆλ‹€.

// ----------------
// Workflow Definition
// ----------------
import { DefineWorkflow, Schema } from "deno-slack-sdk/mod.ts";
export const workflow = DefineWorkflow({
  callback_id: "example-workflow",
  title: "Example Workflow",
  input_parameters: {
    properties: {
      // All the possible inputs from the "reaction_added" event trigger
      channel_id: { type: Schema.slack.types.channel_id },
      user_id: { type: Schema.slack.types.user_id },
      message_ts: { type: Schema.types.string },
      reaction: { type: Schema.types.string },
    },
    required: ["channel_id", "user_id", "message_ts", "reaction"],
  },
});

// TODO: Add function steps here

// ----------------
// Trigger Definition
// ----------------
import { Trigger } from "deno-slack-api/types.ts";
const trigger: Trigger<typeof workflow.definition> = {
  type: "event", // Event Trigger
  name: "Trigger the example workflow",
  workflow: `#/workflows/${workflow.definition.callback_id}`,
  event: {
    // "reaction_added" event trigger
    event_type: "slack#/events/reaction_added",
    channel_ids: ["C04FB5UF1C2"], // TODO: Update this list
    // The condition to filter events
    filter: {
      version: 1,
      // Start the workflow only when the reaction is :eyes:
      root: { statement: "{{data.reaction}} == eyes" },
    },
  },
  inputs: {
    channel_id: { value: "{{data.channel_id}}" },
    user_id: { value: "{{data.user_id}}" },
    message_ts: { value: "{{data.message_ts}}" },
    reaction: { value: "{{data.reaction}}" },
  },
};
export default trigger;

트리거의 event.event_type 은 λ°˜λ“œμ‹œ “slack#/events/reaction_added” μ—¬μ•Ό ν•©λ‹ˆλ‹€. μ—¬κΈ°μ„œ νŠΈλ¦¬κ±°λ‘œλΆ€ν„° 5κ°€μ§€μ˜ μž…λ ₯값을 가지고 올 수 μžˆμŠ΅λ‹ˆλ‹€. 이 μž…λ ₯값에 λŒ€ν•΄μ„œ μžμ„Ένžˆ μ•Œμ•„λ³΄μ‹€λ €λ©΄ 곡식 λ¬Έμ„œμ˜ data ν”„λ‘œνΌν‹° ν•­λͺ©μ— λŒ€ν•΄μ„œ λ³΄μ‹œλ©΄ λ˜κ² μŠ΅λ‹ˆλ‹€.

λ˜ν•œ, channel_ids: [“C04DPBYUQUC”], // TODO: Update this list 뢀뢄도 μ—…λ°μ΄νŠΈ λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€. 일단 이 μ›Œν¬ν”Œλ‘œλ₯Ό μΆ”κ°€ν•  곡개 채널을 κ³ λ₯΄μ„Έμš” (ν˜„μ‹œμ μ—μ„œλŠ” κ³΅κ°œμ±„λ„λ§Œ μ§€μ›ν•©λ‹ˆλ‹€.) 그리고 ν•΄λ‹Ή μ±„λ„μ˜ ID λ₯Ό λ³΅μ‚¬ν•˜μ—¬ λΆ™μ–΄λ„£μœΌμ‹œκΈ° λ°”λžλ‹ˆλ‹€. Slack UI μƒμ—μ„œ 채널이름을 ν΄λ¦­ν•˜λ©΄, νŒμ—… λͺ¨λ‹¬μ΄ μ—΄λ¦½λ‹ˆλ‹€. κ±°κΈ°μ„œ μ•„λž˜μͺ½μœΌλ‘œ 슀크둀 λ‹€μš΄μ„ ν•˜λ©΄ λ‹€μŒκ³Ό 같이 채널 ID λ₯Ό ν™•μΈν•˜μ‹€ 수 μžˆμŠ΅λ‹ˆλ‹€.

그리고 이 μ›Œν¬ν”Œλ‘œλ₯Ό manifest.ts 에 μΆ”κ°€ν•©λ‹ˆλ‹€.

import { Manifest } from "deno-slack-sdk/mod.ts";
import { workflow as DemoWorkflow } from "./workflow_and_trigger.ts";

export default Manifest({
  name: "distracted-bison-253",
  description: "Demo workflow",
  icon: "assets/default_new_app_icon.png",
  workflows: [DemoWorkflow],
  outgoingDomains: [],
  botScopes: [
    "commands",
    "chat:write",
    "reactions:read", // required for the "reaction_added" event trigger
    "channels:history", // will use in custom functions later
    "channels:join", // will use in custom functions later
  ],
});

μ—¬κΈ°μ„œλŠ” μ›Œν¬ν”Œλ‘œ μΆ”κ°€λΏλ§Œ μ•„λ‹ˆλΌ event 트리거λ₯Ό μœ„ν•œ “reactions:read” μŠ€μ½”ν”„λ„ botScopes 내에 μΆ”κ°€ν•΄μ•Ό ν•©λ‹ˆλ‹€. λ‹€λ₯Έ 이벀트 트리거λ₯Ό μ‚¬μš©ν•˜λŠ” κ²½μš°λ„ μžˆμœΌμ‹€ν…λ°, ν•„μš”λ‘œ ν•˜λŠ” μŠ€μ½”ν”„λŠ” λ‹€μŒ λ§ν¬μ—μ„œ ν™•μΈν•΄λ³΄μ‹œκΈ° λ°”λžλ‹ˆλ‹€.

Create an Event Trigger

λ‹€μŒμœΌλ‘œ λ‘κ°œμ˜ μœˆλ„μš° 터미널을 μ—΄μ–΄μ£Όμ„Έμš”. ν•˜λ‚˜λŠ” slack run 을 μ‹€ν–‰ν•˜κ³ , λ‹€λ₯Έ ν•˜λ‚˜μ—μ„œλŠ” slack trigger create λͺ…λ Ήμ–΄λ₯Ό μ‹€ν–‰ν•  κ²ƒμž…λ‹ˆλ‹€.

μ›Œν¬ν”Œλ‘œλ₯Ό λ“±λ‘ν•˜κΈ° μœ„ν•΄μ„œ, 첫번째 ν„°λ―Έλ„μ—μ„œ slack run λͺ…λ Ήμ–΄λ₯Ό μ‹€ν–‰μ£Όμ‹œκ³ , κ·Έ λ‹€μŒ slack triggers create –trigger-def workflow_and_trigger.ts λ₯Ό λ‹€λ₯Έ ν„°λ―Έλ„μ—μ„œ μ‹€ν–‰ν•΄μ£Όμ‹­μ‹œμš”. λ‹€μŒκ³Ό 같은 결과물을 보싀 수 μžˆμŠ΅λ‹ˆλ‹€.

$ slack triggers create --trigger-def ./workflow_and_trigger.ts
? Choose an app  seratch (dev)  T03E*****
   distracted-bison-253 (dev) A04FNE*****

⚑ Trigger created
   Trigger ID:   Ft04EJ8*****
   Trigger Type: event
   Trigger Name: Trigger the example workflow   

Add πŸ‘€ to A Message in the Channel

자 이제 μ–΄λ–»κ²Œ μ›Œν¬ν”Œλ‘œκ°€ λ™μž‘ν•˜λŠ”μ§€ ν™•μΈν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€. πŸ‘€ :eyes: 이λͺ¨μ§€λ₯Ό λ¦¬μ•‘μ…˜μ„ μ±„λ„λ‚΄μ˜ 메세지에 μΆ”κ°€ν•΄λ³΄μ„Έμš”. slack run ν„°λ―Έλ„μ—μ„œ λ‹€μŒκ³Ό 같은 결과물을 보싀 κ²λ‹ˆλ‹€.

$ slack run
? Choose a workspace  seratch  T03E94MJU
   distracted-bison-253 A04FACHPQ5R

Updating dev app install for workspace "Acme Corp"

⚠️  Outgoing domains
   No allowed outgoing domains are configured
   If your function makes network requests, you will need to allow the outgoing domains
   Learn more about upcoming changes to outgoing domains: https://api.slack.com/future/changelog
✨  seratch of Acme Corp
Connected, awaiting events

2022-12-15 10:03:50 [info] [Fn04FCVD67J8] (Trace=Tr04G077TW80) Function execution started for workflow function 'Example Workflow'
2022-12-15 10:03:50 [info] [Wf04FP576X3K] (Trace=Tr04FP5F70HX) Execution started for workflow 'Example Workflow'
2022-12-15 10:03:51 [info] [Fn04FCVD67J8] (Trace=Tr04G077TW80) Function execution completed for function 'Example Workflow'
2022-12-15 10:03:51 [info] [Wf04FP576X3K] (Trace=Tr04FP5F70HX) Execution completed for workflow 'Example Workflow'

λ‹€λ₯Έ 이λͺ¨μ§€μ˜ κ²½μš°λŠ” λ™μž‘ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. :wave: 이λͺ¨μ§€λ₯Ό μΆ”κ°€ν•˜λ”λΌλ„ 아무일도 λ²Œμ–΄μ§€μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

Access The Channel Content

λ§Œμ•½ 기쑴의 Events API κ°€ μ΅μˆ™ν•˜μ‹  뢄이라면, Events API 와 μ°¨μ„ΈλŒ€ν”Œλž«νΌμ˜ Event 트리거의 차이점에 λŒ€ν•΄μ„œ 해깔리싀 수 μžˆμŠ΅λ‹ˆλ‹€.

Events API λŠ” μ±„λ„λ‚΄μ—μ„œ μ•±μ˜ 멀버쉽을 κ³„μ†ν•΄μ„œ μš”κ΅¬ν•©λ‹ˆλ‹€. κ·Έ 말은 앱이 이벀트λ₯Ό μˆ˜μ‹ ν•  λ•Œ, 이 앱은 항상 채널 컨텐츠에 μ ‘κ·Όν•˜κ²Œ λ©λ‹ˆλ‹€. (μ±„λ„μ˜ 멀버여야 ν•œλ‹€λŠ” 이야기)

λ°˜λŒ€λ‘œ, μ°¨μ„ΈλŒ€ν”Œλž«νΌμ˜ Event νŠΈλ¦¬κ±°λŠ”, μ•±μ˜ λ΄‡μœ μ €κ°€ μ΄λ²€νŠΈκ°€ λ°œμƒν•˜λŠ” 채널에 멀버가 μ•„λ‹ˆμ—¬λ„ 트리거 될 수 μžˆμŠ΅λ‹ˆλ‹€.

μœ„μ˜ μ›Œν¬ν”Œλ‘œμ— μ±„λ„μ˜ 컨텐츠에 μ ‘κ·Όν•  수 μžˆλ„λ‘ ν•΄μ£ΌλŠ” κ°„λ‹¨ν•œ νŽ‘μ…˜μ„ ν•˜λ‚˜ μΆ”κ°€ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€. functions.ts λΌλŠ” μ΄λ¦„μœΌλ‘œ λ‹€μŒμ˜ μ†ŒμŠ€μ½”λ“œλ₯Ό μ €μž₯ν•©λ‹ˆλ‹€.

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

export const def = DefineFunction({
  callback_id: "reply_to_reaction",
  title: "Reply to a reaction in a channel",
  source_file: "function.ts",
  input_parameters: {
    properties: {
      channel_id: { type: Schema.slack.types.channel_id },
      user_id: { type: Schema.slack.types.user_id },
      reaction: { type: Schema.types.string },
      message_ts: { type: Schema.types.string },
    },
    required: ["channel_id", "user_id", "reaction", "message_ts"],
  },
  output_parameters: {
    properties: { ts: { type: Schema.types.string } },
    required: ["ts"],
  },
});

export default SlackFunction(def, async ({ inputs, client }) => {
  // https://api.slack.com/methods/conversations.join
  // requires "channels:join" scope in manifest.ts
  const joinResponse = await client.conversations.join({
    channel: inputs.channel_id,
  });
  if (joinResponse.error) {
    const error = `Failed to join the channel due to ${joinResponse.error}`;
    return { error };
  }
  // https://api.slack.com/methods/conversations.history
  // requires "channels:history" scope in manifest.ts
  const historyResponse = await client.conversations.history({
    channel: inputs.channel_id,
    latest: inputs.message_ts,
    inclusive: true,
    limit: 1,
  });
  if (historyResponse.error) {
    const error =
      `Failed to fetch the channel content due to ${joinResponse.error}`;
    return { error };
  }
  const messageText = (historyResponse.messages[0].text ||
    "(Failed to fetch the message text)").replaceAll("\n", "\n>");
  const replyText =
    `Hey <@${inputs.user_id}>, thanks for adding :${inputs.reaction}: to the following message:\n>${messageText}`;
  // https://api.slack.com/methods/chat.postMessage
  // requires "chat:write" scope in manifest.ts
  const replyResponse = await client.chat.postMessage({
    channel: inputs.channel_id,
    text: replyText,
  });
  if (replyResponse.error) {
    const error = `Failed to post a message due to ${replyResponse.error}`;
    return { error };
  }
  return { outputs: { ts: replyResponse.ts } };
});

κ³΅κ°œμ±„λ„μ— λ‹¨μˆœνžˆ 메세지λ₯Ό 남기기 μœ„ν•΄μ„œλŠ”, chat:write_public μŠ€μ½”ν”„λ₯Ό 가진 chat.postMessage API 외에 λ³„λ„μ˜ 좔가적인 API μ½œμ„ ν•„μš”λ‘œ ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ λ§Œμ•½ 앱이 이전에 ν¬μŠ€νŒ… λ˜μ—ˆλ˜ λ©”μ„Έμ§€μ˜ λ‚΄μš©μ΄λ‚˜ κ·Έμ™Έ λ‹€λ₯Έ 것듀을 μ•Œμ•„μ•Ό ν•œλ‹€λ©΄, 이 νŽ‘μ…˜μ€ λ‘κ°œμ˜ Slack API (conversations.join κ³Ό conversations.history) μ½œμ„ ν•©λ‹ˆλ‹€.

그리고 λ‚˜μ„œ, λ‹€μŒ νŽ‘μ…˜ μŠ€ν…μ„ workflow_and_trigger.ts λ‚΄μ˜ μ›Œν¬ν”Œλ‘œμ— μΆ”κ°€ν•©λ‹ˆλ‹€.

import { def as reply } from "./function.ts";
workflow.addStep(reply, {
  channel_id: workflow.inputs.channel_id,
  user_id: workflow.inputs.user_id,
  reaction: workflow.inputs.reaction,
  message_ts: workflow.inputs.message_ts,
});

λ‹€μ‹œ μ›Œν¬ν”Œλ‘œλ₯Ό μ‹€ν–‰ν•΄λ³΄μ‹œλ©΄, μ•±μ˜ λ΄‡μœ μ €κ°€ μžλ™μœΌλ‘œ 채널에 쑰인을 ν•˜κ³ , ν¬μŠ€νŒ… λ˜μ—ˆλ˜ 메세지λ₯Ό ν¬ν•¨ν•œ μƒˆλ‘œμš΄ 메세지λ₯Ό 채널에 λ‚¨κΈ°λŠ” 것을 보싀 수 μžˆμŠ΅λ‹ˆλ‹€.

Don’t Want to Hard-code the channel_ids?

채널 ID λ₯Ό ν•˜λ“œμ½”λ”© ν•˜κΈ°λ₯Ό μ›ν•˜μ‹œμ§€ μ•Šμ„ μˆ˜λ„ μžˆλŠ”λ°μš”, λ¬Όλ‘  ν•˜λ“œμ½”λ”©μ΄ λ˜μ–΄μžˆμœΌλ©΄ 트리거λ₯Ό λ‹€μ‹œ ν™œμš©ν•˜κΈ°λ„ μ–΄λ ΅κ³ , κ΄€λ¦¬ν•˜κΈ°λ„ μ–΄λ ΅μŠ΅λ‹ˆλ‹€. (λ‹€λ₯Έ μ±„λ„μ—μ„œλ„ ν•˜κΈ°μœ„ν•΄μ„œλŠ” 트리거λ₯Ό μƒˆλ‘œ λ§Œλ“€μ–΄μ•Ό ν•˜κ³ μš”)

κ·ΈλŸ¬λ‚˜ μ•ˆνƒ€κΉκ²Œλ„, μ†ŒμŠ€μ½”λ“œ νŒŒμΌμ„ μ΄μš©ν•˜μ—¬ 트리거λ₯Ό 생성할 λ•ŒλŠ” 채널ID λ₯Ό λΊ„μˆ˜κ°€ μ—†μŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ λ‹€λ₯Έ λ°©λ²•μœΌλ‘œ 트리거 λŸ°νƒ€μž„μ„ λ§Œλ“€ μˆ˜λŠ” μžˆμŠ΅λ‹ˆλ‹€. λ°”λ‘œ μ»€μŠ€ν…€ νŽ‘μ…˜μ—μ„œ 트리거λ₯Ό 생성/μˆ˜μ •(generation/modification) ν•˜λŠ” API μ½œμ„ ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. κ³΅μ‹λ¬Έμ„œλ₯Ό μ°Έμ‘°ν•˜μ„Έμš”. λ‹€λ₯Έ νŠœν† λ¦¬μ–Όμ—μ„œλ„ ν•œλ²ˆ 닀루어 λ³΄κ² μŠ΅λ‹ˆλ‹€.

Wrapping Up

이번 νŠœν† λ¦¬μ–Όμ—μ„œλŠ” λ‹€μŒκ³Ό 같은 λ‚΄μš©μ„ λ°°μ›Œλ³΄μ•˜μŠ΅λ‹ˆλ‹€.

  • 채널 기반의 event 트리거λ₯Ό μ •μ˜ν•˜κ³  μ‚¬μš©ν•˜λŠ” 방법

이 ν”„λ‘œμ νŠΈλŠ” λ‹€μŒ μ£Όμ†Œμ—μ„œλ„ ν™•μΈν•˜μ‹€ 수 μžˆμŠ΅λ‹ˆλ‹€. https://github.com/seratch/slack-next-generation-platform-tutorials/tree/main/08_channel_created_Event_Trigger

이번 νŠœν† λ¦¬μ–Όλ„ μ¦κ±°μš°μ…¨μœΌλ©΄ μ’‹κ² λ„€μš”. λ§ˆμ°¬κ°€μ§€λ‘œ ν”Όλ“œλ°±μ΄λ‚˜ μ½”λ©˜νŠΈκ°€ μžˆμœΌμ‹œλ‹€λ©΄ νŠΈμœ„ν„° (@seratch) 둜 μ—°λ½μ£Όμ‹œκ±°λ‚˜, μ—¬κΈ° λ‚¨κ²¨μ£Όμ„Έμš”.

Happy hacking with Slack’s next-generation platform πŸš€

λ‹΅κΈ€ 남기기

이메일 μ£Όμ†ŒλŠ” κ³΅κ°œλ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. ν•„μˆ˜ ν•„λ“œλŠ” *둜 ν‘œμ‹œλ©λ‹ˆλ‹€