SendGrid를 사용하여 채팅 기록 저장 및 전송

36135 단어
이 강좌에서, 우리는SendGrid를 사용하여 이메일로 채팅 기록 사본을 보내는 채팅 프로그램을 구축할 것입니다.고객 한 명이 지원 팀과 채팅을 할 때 영업 팀에 자동으로 통지할 수 있다고 상상해 보세요.이 프로그램은 Stream chat와SendGrid를 사용하여 채팅 기록을 판매자의 이메일 주소로 직접 보냅니다.

이 글은 너를 통과할 것이다Git Repository Here.시작합시다!

채팅이 뭐예요?


Build real-time chat in less time. Rapidly ship in-app messaging with our >highly reliable chat infrastructure. Drive in-app conversion, engagement, and >retention with the Stream Chat messaging platform API & SDKs.


요구 사항:

  • node.js
  • React
  • A(무료)Stream시용계좌
  • A(무료)SendGrid시용계좌
  • React HooksExpress에 대한 기본적인 이해에도 도움이 될 것이다.
  • 하면, 만약, 만약...

  • React useffect()를 사용하여 채팅 기록을 수집하는 방법 배우기
  • Stream 및 SendGrid
  • 를 사용하여 이메일로 채팅 기록 전송
  • 프런트엔드/백엔드 스트리밍 채팅 어플리케이션 설정
  • 이 항목들은 Express JS와 React를 사용하여 소개되지만 대부분의 언어와 프레임워크에 이식할 수 있습니다.

    포함되지 않은 내용


    이 강좌는 채팅 기록의 수집과 전송을 중점적으로 소개한다.이 프로젝트의 GitHub repo는 기능이 완비된 등록표와 채팅 전단을 포함하지만 모든 면에서 깊이 있게 논의되는 것은 아니다.React 레지스트리 및 스트리밍 채팅 클라이언트 시작에 대한 자세한 내용은 this post 를 참조하십시오.

    계정 구성


    흐름 설정


    일단 무료 테스트 계정을 만들면 Stream dashboard에 새로운 프로그램을 만들고 싶을 것이다.반드시'개발'모델을 선택해야 한다.

    생성된 API 키와 암호를 복사하여 나중에 .env 파일에 추가합니다.

    Stream은 기본적으로 애플리케이션에서 인증 검사 및 권한 검사를 제공합니다.이것은 생산 응용 프로그램의 좋은 기능이지만, 우리는 이러한 기능을 비활성화함으로써 이 응용 프로그램의 단순성을 유지할 것이다.흐름 계기판에서 응용 프로그램을 선택하십시오.채팅 탐색 모음 드롭다운 메뉴를 클릭하고 개요를 선택합니다.

    아래로 스크롤하여 인증 검사 사용 안 함 및 사용 권한 검사 사용 안 함 전환 을 활성화합니다.

    SendGrid 설정


    SendGrid setup guide 에서 보낼 전자 메일 주소나 도메인을 확인해야 합니다.우리는 이 응용 프로그램의 개인 전자 우편 주소만 사용할 것입니다. 그러나 생산에서 정확한 도메인 주소를 사용하지 마십시오.보낸 사람의 상세한 정보를 입력한 다음 등록 주소로 보내는 이메일로 계정을 검증합니다.

    SendGrid setup guide로 돌아가서 "우리의 웹 API 또는 SMTP 트렁크를 사용하여 통합"을 선택한 다음 "웹 API"를 선택합니다.


    통합 언어로 node.js 를 선택합니다.

    응용 프로그램의 이름을 만들고 API 키를 생성한 다음backend.env 파일의 키를 복사합니다.

    애플리케이션 구성


    .환경 설정


    git repo를 사용한다면 backend 폴더에 .env.example 이라는 파일이 있습니다.API 키와 암호를 입력하고 파일 이름을 .env 로 변경합니다.
    //backend/.env
    NODE_ENV=development
    PORT=8080
    
    STREAM_API_KEY= your Stream API key here
    STREAM_API_SECRET= your Stream API secret here
    SENDGRID_API_KEY= your SendGrid API key here
    

    SendGrid 구성

    backend에서 SendGrid를 통합하는 데는 몇 가지 절차가 필요합니다.

  • 다음 패키지를 설치합니다.
      npm install --save @sendgrid/mail
    
  • index.js 파일에서 SendGrid 패키지가 필요합니다.
      const sgMail = require('@sendgrid/mail');
    
  • //backend/routes.index.js 에서 tofrom 전자 메일 주소를 변경합니다.from 주소는 SendGrid에서 발신자로 등록하고 인증하는 전자 메일 주소여야 합니다.

      //backend/routes.index.js
        const msg = {
          to: '[email protected]',
          from: '[email protected]',
          subject: 'Stream Chat: Your client started a Support Chat Session',
          html: `Hello, \n Your client, ${firstName} ${lastName} started a chat with the support team chat widget on ${createdAt}. \n
          Here is the transcript of the chat: \n ${transcript} END OF TRANSCRIPT \n You can reach your client at ${email}. \n This message was sent to you from Stream Chat`,
        };
    
  • 초기 실행


    응용 프로그램은 frontend를 사용하여 만든 stream-chat-react 폴더와 backend를 사용하여 만든 npm express-generator 폴더로 나뉩니다.
    컴퓨터에서 응용 프로그램을 시작하려면 npm installnpm run start 폴더에서 frontendbackend 을 실행합니다.실행 후 http://localhost:3000로 이동하여 보기frontend를 수행합니다.이제 우리는 이 응용 프로그램의 작업 원리를 깊이 이해할 수 있다.

    등록



    사용자가 http://localhost:3000에 액세스할 때 인증서를 입력하여 backend/customer-login 라우트로 전송합니다.register 함수의 앞부분에 표 데이터를 보냅니다.후반부는 채팅 프로그램을 초기화하고 정확한 채널에 가입하기 위해 backend로부터 데이터를 받는다.마찬가지로 이 부분에 대한 더 많은 깊이는 보십시오this post.
    //frontend/src/App.js:14
    const register = async (e) => {
      try {
        e.preventDefault();
    
        const response = await fetch('http://localhost:8080/customer-login', {
          method: 'POST',
          headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            firstName,
            lastName,
            email,
          }),
        });
    
        const { customerId, customerToken, channelId, streamApiKey } = await response.json();
        const chatClient = new StreamChat(streamApiKey);
    
        await chatClient.setUser(
          {
            id: customerId,
            name: firstName,
          },
          customerToken,
        );
    
        const channel = chatClient.channel('messaging', channelId);
    
        setChatClient(chatClient);
        setChannel(channel);
    
      } catch (e) {
        console.error(e);
      }
    };
    
    customer-login에서 찾은 backend API 단점은 사용자의 입력을 정리하고 우리의 흐르는 채팅 클라이언트를 설정하여 새로운 흐르는 채팅 채널을 만들고 이 채널에 가입하는 데 필요한 정보를 우리에게 보낸다frontend.
    //backend/routes/index.js:27
    router.post('/customer-login', async (req, res) => {
      try {
        const firstName = req.body.firstName.replace(/\s/g, '_');
        const lastName = req.body.lastName.replace(/\s/g, '_');
    
        const client = new StreamChat(streamApiKey, streamApiSecret);
    
        [customer, admin] = createUsers(firstName, lastName);
    
        await client.upsertUsers([
          customer,
          admin
        ]);
    
        const channel = client.channel('messaging', uuidv4(), {
          members: [customer.id, admin.id],
        });
    
        const customerToken = client.createToken(customer.id);
    
        res.status(200).json({
          customerId: customer.id,
          customerToken,
          channelId: channel.id,
          streamApiKey,
        });
    
      } catch (err) {
        console.error(err);
        res.status(500).json({ error: err.message });
      }
    });
    
    위 코드 섹션의 createUsers() 방법은 우리의 채널에 등록할 고객과 관리 대상을 만드는 것입니다.우리는 유일한 식별자를 사용했습니다. 이 중 uuidv4client.channel() 의 두 번째 매개 변수입니다. 이것은 채널 id입니다. 채널 id가 매개 변수로 포함되지 않으면 채팅 참여자의 이름에 따라 흐름을 만듭니다.UUID를 사용하면 두 개의 "존 스미스"가 같은 채팅에서 끝나지 않을 것을 보장할 수 있습니다.
    //backend/routes/index.js:11
    function createUsers(firstName, lastName) {
      const customer = {
        id: `${firstName}-${lastName}`.toLowerCase(),
        name: firstName,
        role: 'user',
      };
    
      const admin = {
        id: 'admin-id',
        name: 'Support Admin',
        role: 'admin'
      };
    
      return [customer, admin];
    }
    
    간단하게 말하자면, 이 응용 프로그램은 우리 채팅 응용 프로그램의 customer 체험에 중점을 둘 것이다.위의 채널은 일반적인 Support Admin 이 채팅의 다른 한쪽에 가입할 것이라고 가정합니다.

    채팅창


    사용자가 등록하면 구성chatClientchannel, 52 행의 다음 부울 값을 사용하여 구성 요소 CustomerChat 를 로드할 수 있습니다.
    //frontend/src/App.js:52
     if (chatClient && channel) {
        return (
          <CustomerChat
            channel={channel}
            chatClient={chatClient}
            firstName={firstName}
            lastName={lastName}
            email={email}
          />);
      }
    
    필요한 도구는 CustomerChat 구성 요소로 발송되며, 이 구성 요소는 아래jsx로 되돌아옵니다.
    //frontend/src/CustomerChat.js:39
    return (
            <div className="App">
                <Chat client={chatClient} theme={'messaging light'}>
                    <Channel channel={channel}>
                        <Window>
                            <ChannelHeader />
                            <MessageList />
                            <MessageInput />
                        </Window>
                        <Thread />
                    </Channel>
                </Chat>
            </div>
        );
    }
    
    이것이 바로 Stream이 우아하고 사용자 정의 가능한 채팅창을 설정하는 데 필요한 모든 내용입니다.보기Stream's free UX kits에 광택제를 첨가합니다.

    채팅 기록을 백엔드로 보내기


    사용자가 브라우저 창이나 탭을 닫으면 이 프로그램은 자동으로 POST 채팅 기록을 백엔드로 보내는 것이지 단추로 채팅 기록을 보내는 것이 아니다.이것은 useEffect() 반응 고리를 사용하여 실현된 것이다.다음은...
    //frontend/src/CustomerChat.js:6
    useEffect(() => {
        const handleUnload = (event) => {
            event.preventDefault();
            fetch('http://localhost:8080/email-transcript', {
                method: 'POST',
                headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    messages: channel.state.messages,
                    firstName: firstName,
                    lastName: lastName,
                    email: email,
                    createdAt: channel.data.config.created_at
                })
            });
            event.returnValue = '';
        };
    
        window.addEventListener('beforeunload', handleUnload);
    
        return () => {
            window.removeEventListener('beforeunload', handleUnload);
        };
    }, [channel, firstName, lastName, email]
    );
    
    상기 useEffect() 는 이벤트 탐지기를 시작하여 탐지 beforeunload (사용자가 브라우저 창을 닫음) 하고 이벤트가 최종적으로 촉발될 때 handleUnload 기능을 실행합니다.handleUnloadPOST발기backend.전송본에 필요한 모든 데이터는 흐름channel 대상에 편리하게 묶여 있다.이 대상은 채널에서 보내는 모든 메시지를 포함하여 대량의 유용한 정보를 포함한다.

    useEffect()의 복잡성

  • 우리는 두 번째 매개 변수 그룹을 포함하여 useEffect()의 촉발을 제한한다: [channel, firstName, lastName, email].useEffect() 이 그룹의 한 요소의 상태가 변경될 때만 촉발됩니다.
  • , removeEventListener() 기능은 청소 옵션입니다.React는 구성 요소가 마운트 해제될 때 이벤트 탐지기만 있는지 확인합니다.
  • 주의, event.returnValue = ''; 크롬의 beforeunload 사건 감청기가 정상적으로 작동하는 요구입니다.
  • 이 방법을 사용하는 주의 사항 중 하나는 닫을 때 팝업 창입니다.

    만약 사용자가 한 시간 동안 채팅을 지원한다면 이것은 유용한 기능이다.제품에서 서로 다른 체험을 찾으려면 WebSocket은 서로 다른 체험을 제공하지만 본고에서 논의한 범위 내에 있지 않습니다.

    전단 성적표를 받다


    다음 코드 세그먼트 처리frontend의 채팅 기록:
    //backend/routes/index.js:59
    router.post('/email-transcript', async (req, res) => {
      const messages = req.body.messages;
      const { firstName, lastName, email, createdAt } = req.body;
    
      let transcript = messages.map((message) => {
        return (`<li>FROM: ${message.user.id}</li>\n<li>MESSAGE: ${message.text}</li>\n`);
      });
    
      sgMail.setApiKey(sendgridApiKey);
    
      const msg = {
        to: '[email protected]',
        from: '[email protected]',
        subject: 'Stream Chat: Your client started a Support Chat Session',
        html: `Hello, \n Your client, ${firstName} ${lastName} started a chat with the support team chat widget on ${createdAt}. \n
        Here is the transcript of the chat: \n ${transcript} END OF TRANSCRIPT \n You can reach your client at ${email}. \n This message was sent to you from Stream Chat`,
      };
    
      try {
        sgMail.send(msg);
        res.status(200).end;
      }
      catch{ (err) => console.log(err.response.body); }
    
    });
    
    우리는 이것에 대해 약간의 분석을 진행할 것이다.우선req.body을 해부하여 우리가 녹음하는 데 필요한 정보를 추출한다.다음은 html 메시지마다 간단한 mapping() 문자열을 조합합니다.결과는 다음과 같습니다.

    Stream에서 제공하는 message 객체에는 대량의 데이터가 포함되어 있습니다.Stream Documentation 전자 메일 기록에 포함할 수 있는 모든 옵션을 표시합니다.
    다음은 SendGrid에 API 키sgMail.setApiKey(sendgridApiKey)를 보내고 msg 객체를 구축합니다.이제 to 필드에서 볼 수 있는 전자 메일 주소만 사용하십시오.from 필드는 보낸 사람이 SendGrid에 등록하고 인증한 전자 메일 주소와 일치해야 합니다.마찬가지로 필요에 따라 subjecthtml 필드를 사용자 정의할 수 있습니다.
    마지막으로 우리는 sgMail.send(email)try 블록에서 catch 을 사용한다.이렇게 하는 이유는 오류가 SendGrid 응답에서 무시될 수 있기 때문이다.몇 초 후, 당신은 받은 편지함에서 이메일을 받을 것입니다!봐라!

    생각을 끝내다


    축하합니다. 당신은 지금 이메일로 채팅 기록을 보낼 수 있습니다!Stream과 SendGrid API는 React 지식이 조금만 있으면 많은 작업을 수행할 수 있습니다.Stream Blog에 올라온 다른 댓글로 더 많은 기능을 알아보세요!

    좋은 웹페이지 즐겨찾기