Skip to content

Instantly share code, notes, and snippets.

View mahboubii's full-sized avatar

Amin Mahboubi mahboubii

  • Netherlands
View GitHub Profile
app.post('/', (req, res) => {
const { user, message, form_data } = req.body;
const isAppointment = message.command === 'appointment'; // you can have up to 50 different custom command
// first step: user sent an appointment command without any message action being called yet, i.e. without buttons in the mml being clicked
// we will show a MML input component and ask for user's phone number
if (isAppointment && !form_data) {
message.text = ''; // remove user input
message.type = 'ephemeral'; // switch the message to ephemeral so it's not stored until it's final
message.mml = `
const setupTunnelAndWebhook = async () => {
const { url } = await localtunnel({ port: PORT });
console.log(`Server running remotely in ${url}`);
// you need to these steps only once in production or manually in stream dashboard
// https://getstream.io/chat/docs/custom_commands_webhook/
const cmds = await chatClient.listCommands();
if (!cmds.commands.find(({ name }) => name === 'appointment')) {
await chatClient.createCommand({
name: 'appointment',
const express = require('express');
const bodyParser = require('body-parser');
const localtunnel = require('localtunnel');
const { StreamChat } = require('stream-chat');
const PORT = 8000;
const API_KEY = 'YOUR_API_KEY';
const API_SECRET = 'YOUR_API_SECRET';
// Stream Chat client used to validate webhook calls
const express = require('express');
const bodyParser = require('body-parser');
const localtunnel = require('localtunnel');
const PORT = 8000;
const app = express();
// body-parser parsed the body to a json object for us, it also store the rawBody so later we can check the request integrity
app.use(bodyParser.json({ verify: (req, res, buf) => (req.rawBody = buf) }));
import { useState, useEffect, useCallback } from 'react';
import { StreamChat } from 'stream-chat';
import { Chat, Channel, MessageInput, ChannelHeader, ChannelList, VirtualizedMessageList } from 'stream-chat-react';
import 'stream-chat-react/dist/css/index.css';
import './App.css';
const apiKey = 'YOUR_API_KEY'; // grab your api key from https://getstream.io/dashboard/
const user = { id: 'jim', name: 'Jim' };
// you can generate user token using your app secret via https://getstream.io/chat/docs/token_generator/
// temporary fix for snapshot updates until React adds a solution with hooks
// https://reactjs.org/docs/hooks-faq.html#do-hooks-cover-all-use-cases-for-classes
class GetSnapshotUpdates extends React.Component {
getSnapshotBeforeUpdate(prevProps, prevState) {
if (!this.props.getSnapshot) return null;
const snapshot = this.props.getSnapshot(
prevProps,
prevState,
this.props,
const upload = await session.images.upload(avatar);
const response = await fetch(`${process.env.REACT_APP_SERVERLESS_API_URL}/image`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'X-API-Key': process.env.REACT_APP_SERVERLESS_API_KEY,
},
body: JSON.stringify({