<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pavani K</title>
    <description>The latest articles on DEV Community by Pavani K (@pawani1919).</description>
    <link>https://dev.to/pawani1919</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1100570%2F7890f0f9-f0ba-462f-b0c3-f375d12318ff.png</url>
      <title>DEV Community: Pavani K</title>
      <link>https://dev.to/pawani1919</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pawani1919"/>
    <language>en</language>
    <item>
      <title>Post Message,Trigger Modals on Slack with Firebase Cloud Functions and Slack API</title>
      <dc:creator>Pavani K</dc:creator>
      <pubDate>Fri, 07 Jul 2023 13:12:02 +0000</pubDate>
      <link>https://dev.to/pawani1919/post-messagetrigger-modals-on-slack-with-firebase-cloud-functions-and-slack-api-35f6</link>
      <guid>https://dev.to/pawani1919/post-messagetrigger-modals-on-slack-with-firebase-cloud-functions-and-slack-api-35f6</guid>
      <description>&lt;p&gt;The Slack API offers various methods to interact with your workspace, giving you plenty of options.&lt;/p&gt;

&lt;p&gt;To create a Slack app, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Visit &lt;a href="https://api.slack.com/apps"&gt;https://api.slack.com/apps&lt;/a&gt; to start creating your app.&lt;/li&gt;
&lt;li&gt;Name your app and select the workspace.&lt;/li&gt;
&lt;li&gt;Once your app is created, you'll be taken to the app's environment.&lt;/li&gt;
&lt;li&gt;In the left side menu, select "Basic Information" to access your app credentials.
That's it! You're all set to start building your Slack app.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;To obtain a bot token for posting messages, follow these steps:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on the "OAuth &amp;amp; Permissions" option from the left side&lt;/li&gt;
&lt;li&gt;Scroll up to the top of the OAuth &amp;amp; Permissions pages and click the green "Install App to Workspace" button.&lt;/li&gt;
&lt;li&gt;click on allow and come back to the page OAuth &amp;amp; Permissions menu scroll down to section scopes and add scopes.&lt;/li&gt;
&lt;li&gt;To generate a bot token, you need to specify the bot scopes. For our implementation, select the following scopes: "chat:write," "users:read," "channels:read," and "commands."&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;once you add bot scopes automatically generates bot token.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Project:
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Create any project with Firebase setup (react-firebase)or your wish&lt;br&gt;
Configure firebase to the project and add firebase cloud functions setup to it..&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the terminal, run the command &lt;code&gt;npm i @slack/web-api&lt;/code&gt; to install package. This package allows you to interact with the Slack workspace and perform actions such as sending messages, trigger modals!!.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { WebClient } = require("@slack/web-api");
const botToken="xoxb-565644"//paste your bot token
const web = new WebClient(botToken);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;configured web, now we can use it to post message, trigger modals,get users/channels etc....&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To get all the channels of your slack workspace&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exports.channelsList = functions.https.onCall(async (data, context) =&amp;gt; {
  try {
    const response = await web.conversations.list();
    const channels = response.channels;
    return channels; //return channel list &amp;amp; info
  } catch (error) {
    console.error("Error:", error);
    return error.message;
  }
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;run &lt;code&gt;firebase emulators:start --only functions&lt;/code&gt; to get local url you can run the local url on postman &amp;amp; check response&lt;br&gt;
dont forget to add &lt;code&gt;{data:{}}&lt;/code&gt; in the body&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To get all the users of your slack workspace:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exports.usersList = functions.https.onCall(async (data, context) =&amp;gt; {
  try {
    const response = await web.users.list();
    const users = response.members;
    return users;//returns users of workspace with user related info
  } catch (error) {
    console.error("Error:", error);
  }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;To Post a message to the channel of your slack workspace:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exports.sendMessageToChannel = functions.https.onCall(
  async (data, context) =&amp;gt; {
    try {
    //we can get channelid in two ways
    //1. go to slack click on channel now on top click on channel name now scroll down you can see id
    //2.run the above channelsList endpoint copy the channelid from response
      await web.chat.postMessage({
        channel: channelId, //paste channel id
        text: message,
      });
      return "Message sent successfully.";
    } catch (error) {
      console.error("Error:", error);
      return "Error while posting message to channel";
    }
  }
);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can post message to  all the users,and channels, by maping the obtained list&lt;/p&gt;

&lt;h2&gt;
  
  
  To Trigger a modal with shortcut on slack, follow these steps:
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;REMEMBER NEED TO CREATE AN HTTPS END POINT URL &lt;br&gt;
which triggers request payload for any interaction on slack!!!!!&lt;br&gt;
Here, we are utilizing Firebase Cloud Functions to deploy and retrieve the deployed URL.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;From the left side menu, select "Interactivity &amp;amp; Shortcuts" and enable interactivity.&lt;/li&gt;
&lt;li&gt;Under "Shortcuts," click on "Create New Shortcut" and fill in the required details to create a global shortcut. Once done, create the shortcut.&lt;/li&gt;
&lt;li&gt;In any Slack channel, navigate to the message input area and enter a slash ('/') character. You will now see the name of the shortcut you created.&lt;/li&gt;
&lt;li&gt;To receive requests containing payloads, add the URL of your deployed endpoint under "Interactivity Request URL."&lt;/li&gt;
&lt;li&gt;By completing these steps, you can enable interactivity, create a global shortcut, and configure the endpoint URL to receive requests with payloads.&lt;/li&gt;
&lt;li&gt;Here we are creating one endpoint to trigger modal &amp;amp; get response from modal back&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--btJrQput--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o3ajj35i7kgw6c9ozh94.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--btJrQput--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o3ajj35i7kgw6c9ozh94.png" alt="Example" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Designed a modal which shows two meetings with rating selection option&lt;br&gt;&lt;br&gt;
Get back the selected rating of meeting from user and post a message to channel &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---EAkWWbJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/byypjfdh8zgeojt3l1mp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---EAkWWbJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/byypjfdh8zgeojt3l1mp.png" alt="Modal Preview" width="526" height="303"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exports.handleMeetingsShortcut = functions.https.onRequest(async (req, res) =&amp;gt; {
  try {
    const payload = JSON.parse(req.body.payload);
    const trigger_id = payload?.trigger_id;

    const view = { //to design custom blocks to show on modal
      type: "modal",
      callback_id: "meetings_rating",//created shortcut id
      title: {
        type: "plain_text",
        text: "Modal Title",
      },
      blocks: [
        {
          type: "section",
          text: {
            type: "mrkdwn",
            text: "*Meeting 1*\nTopic: Project Updates\nTime: 10:00 AM - 11:00 AM",
          },
          accessory: {
            type: "static_select",
            action_id: "meeting1_rating_select",
            placeholder: {
              type: "plain_text",
              text: "Rate this meeting",
            },
            options: [
              {
                text: {
                  type: "plain_text",
                  text: "⭐️⭐️⭐️⭐️⭐️",
                },
                value: "5",
              },
              {
                text: {
                  type: "plain_text",
                  text: "⭐️⭐️⭐️⭐️",
                },
                value: "4",
              },
              {
                text: {
                  type: "plain_text",
                  text: "⭐️⭐️⭐️",
                },
                value: "3",
              },
              {
                text: {
                  type: "plain_text",
                  text: "⭐️⭐️",
                },
                value: "2",
              },
              {
                text: {
                  type: "plain_text",
                  text: "⭐️",
                },
                value: "1",
              },
            ],
          },
        },
        {
          type: "section",
          text: {
            type: "mrkdwn",
            text: "*Meeting 2*\nTopic: Sales Strategy\nTime: 2:00 PM - 3:00 PM",
          },
          accessory: {
            type: "static_select",
            action_id: "meeting2_rating_select",
            placeholder: {
              type: "plain_text",
              text: "Rate this meeting",
            },
            options: [
              {
                text: {
                  type: "plain_text",
                  text: "⭐️⭐️⭐️⭐️⭐️",
                },
                value: "5",
              },
              {
                text: {
                  type: "plain_text",
                  text: "⭐️⭐️⭐️⭐️",
                },
                value: "4",
              },
              {
                text: {
                  type: "plain_text",
                  text: "⭐️⭐️⭐️",
                },
                value: "3",
              },
              {
                text: {
                  type: "plain_text",
                  text: "⭐️⭐️",
                },
                value: "2",
              },
              {
                text: {
                  type: "plain_text",
                  text: "⭐️",
                },
                value: "1",
              },
            ],
          },
        },
      ],
      submit: {
        type: "plain_text",
        text: "Submit",
      },
    };
    if (payload.type === "shortcut") {//triggered shortcut
      const response = await web.views.open({
        trigger_id,
        view,
      });
      if (response.ok) {
        res.sendStatus(200);
      } else {
        throw new Error(response.error || "Failed to open modal.");
      }
    } else if (
      //on click submit aftr selecting rating
      payload.type === "view_submission" &amp;amp;&amp;amp; 
      payload.view.callback_id === "meetings_rating"
    ) {
      const user = payload.user.username;
      const values = payload.view.state.values;
      let meeting1Rating, meeting2Rating;
     //get the selected ratings, based on action_id
      for (const key of Object.keys(values)) {
        const obj = values[key];
        if (obj &amp;amp;&amp;amp; obj.meeting1_rating_select) {
          meeting1Rating = obj.meeting1_rating_select.selected_option.value;
          break;
        }
      }

      for (const key of Object.keys(values)) {
        const obj = values[key];
        if (obj &amp;amp;&amp;amp; obj.meeting2_rating_select) {
          meeting2Rating = obj.meeting2_rating_select.selected_option.value;
          break;
        }
      }

      const messageText = `*Meeting Ratings*\n\n${user} has rated the meetings:\n\nMeeting 1: ${meeting1Rating}\nMeeting 2: ${meeting2Rating}`;
//post message to channel with username &amp;amp; selected ratings
      const result = await web.chat.postMessage({
        channel: "C05788W6A",
        text: messageText,
      });

      if (result.ok) {
        res.send();
      } else {
        console.error(result.error || "Failed to post message to channel.");
        res.status(500).send("Failed to post message to channel.");
      }
    } else {
      console.error("Failed load payload");
      res.sendStatus(200);
    }
  } catch (err) {
    console.error(err, "error");
    res.sendStatus(500);
  }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt; Deploy the function using &lt;code&gt;firebase deploy function:handleMeetingsShortcut&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; check the deployed url on your firebase project &lt;/li&gt;
&lt;li&gt; Paste the url under interactivity reaquest url&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here payload holds everything &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if you trigger shortcut it returns type shortcut in payload &lt;/li&gt;
&lt;li&gt;if you click on submit on modal triggers payload with type 
view submission.
Additionally, you can utilize blocks to create custom designs and enhance the user experience in your Slack app.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docs:&lt;br&gt;
&lt;a href="https://api.slack.com/block-kit/interactivity"&gt;https://api.slack.com/block-kit/interactivity&lt;/a&gt; -- design blocks&lt;br&gt;
&lt;a href="https://firebase.google.com/docs/functions/get-started?gen=1st"&gt;https://firebase.google.com/docs/functions/get-started?gen=1st&lt;/a&gt; -- to setup firebase&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion:
&lt;/h2&gt;

&lt;p&gt;As a beginner tried to explore the slack api. How we can interact with slack via code "Excited me".....&lt;br&gt;
Slack api Documentation provides more information regarding&lt;br&gt;
posting messages to slack as a text,blocks, and trigger modals.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thanks for your Read hope it helps...😍
&lt;/h2&gt;

</description>
      <category>firebase</category>
      <category>slack</category>
      <category>node</category>
      <category>slackbot</category>
    </item>
  </channel>
</rss>
