react-slack-support

0.3.0 • Public • Published

npm package NPM Downloads Code style

react-slack-support

react-slack-support add a beautiful widget to provide support to your visitors or customers.

This package is only compatible with Material-ui > 4.0

alt text alt text

Demonstration and Documentation

For examples in action and full documentation, go to StoryBook

OR

To run that demo on your own computer, clone this repository and :

$ yarn install
$ yarn storybook

Getting started

Installation

$ npm i --save react-slack-support

or

$ yarn add react-slack-support

Usage

NOTE: Your Slack Webhook URL should never be available on the front end. For this reason you must have a server which sends the request to slack. This component will use getMessage, postMessage, and postFile to send to Slack but it won't send the request for you.

Client side

const Helper = () => {
  const getSlackMessages = async (userName) => {
    // call your server to get fresh messages
  };
  const postSlackMessage = async ({ conversationId, userName, text }) => {
    // call your server to send new message
  };
  const postSlackFile = async ({ file, conversationId }) => {
    // call your server to send new file
  };

  return (
    <ReactSlackSupport
      botName={`Tester`}
      userImage={
        "http://www.iconshock.com/img_vista/FLAT/mail/jpg/robot_icon.jpg"
      }
      defaultMessage={"Hi ! How can i help you ?"}
      getMessage={getSlackMessages}
      postMessage={postSlackMessage}
      postFile={postSlackFile}
    />
  );
};

Sever side

Use your favorite router to expose theses functions (examples). You can do more stuff (or event connect to another provider like Microsoft Teams)

import { WebClient } from "@slack/web-api";
import FormData from "form-data";
import atob from 'atob';
const token = atob("YOUR_SLACK_TOKEN");
const slack = new WebClient(token);
const CHANNEL_NAME = "support-client";
const CACHE_TIME_USER_IN_MS = 60000;
const CACHE_TIME_MESSAGE_IN_MS = 5000;

let usersCache = { data: null, lastUpdated: 0 };
const messagesCache = {};
let channelId = null;
slack.conversations.list().then(resultConversation => {
  const channel = resultConversation.channels.find(
    c => CHANNEL_NAME === c.name
  );
  channelId = channel?.id;
});

const postMessage = async function({ conversationId, userName, text }) {
  return slack.chat.postMessage({
    text,
    channel: channelId,
    username: userName,
    thread_ts: conversationId
  });
};

const getMessages = async function(userName) {
  if (
    !usersCache.lastUpdated ||
    Date.now() > usersCache.lastUpdated + CACHE_TIME_USER_IN_MS
  ) {
    const resultUsers = await slack.users.list();
    usersCache = {
      data: resultUsers.members,
      lastUpdated: Date.now()
    };
  }

  if (
    !messagesCache[userName]?.lastUpdated ||
    Date.now() > messagesCache[userName].lastUpdated + CACHE_TIME_MESSAGE_IN_MS
  ) {
    const conversations = await slack.conversations.history({
      channel: channelId
    });

    const myConversation = conversations.messages.find(
      m => m.username === userName
    );

    let messages = [];
    if (myConversation?.ts) {
      const results = await slack.conversations.replies({
        channel: channelId,
        ts: myConversation.ts
      });

      messages = results.messages;
    }

    messagesCache[userName] = {
      data: messages,
      lastUpdated: Date.now(),
      conversationId: myConversation?.ts || null
    };
  }

  return {
    conversationId: messagesCache[userName].conversationId,
    messages: messagesCache[userName].data,
    users: usersCache.data.map(m => ({ ...m, image: m.profile.image_32 }))
  };
};

const postFile = async function({ file, conversationId }) {
  const form = new FormData();

  const filename = "Screenshot.png";
  form.append("token", token);
  form.append("filename", filename);
  form.append("title", "Screenshot");
  form.append("filetype", "auto");
  form.append("channels", channelId);
  form.append("file", Buffer.from(file, "base64"), { filename });
  form.append("thread_ts", conversationId);

  form.submit("https://slack.com/api/files.upload", (err, res) => {
    if (err) throw err;
    res.resume();
  });
};

Contributors

Code Contributors

This project exists thanks to all the people who contribute. [Contribute].

Financial Contributors

License

This project is licensed under the terms of the MIT license.

Package Sidebar

Install

npm i react-slack-support

Weekly Downloads

15

Version

0.3.0

License

MIT

Unpacked Size

33.3 kB

Total Files

8

Last publish

Collaborators

  • sylchauf
  • mathieumayjonade