Added MMS support for messaging. IO-538

This commit is contained in:
Patrick Fic
2021-02-19 13:40:56 -08:00
parent b152dd042f
commit 6c459965c4
30 changed files with 786 additions and 57 deletions

View File

@@ -16,7 +16,7 @@ npx hasura migrate apply --endpoint https://db.imex.online/ --admin-secret 'Prod
NGROK TEsting: NGROK TEsting:
./ngrok.exe http https://localhost:5000 -host-header="localhost:5000" ./ngrok.exe http http://localhost:5000 -host-header="localhost:5000"
Finding deadfiles - run from client directory Finding deadfiles - run from client directory
npx deadfile ./src/index.js --exclude build templates npx deadfile ./src/index.js --exclude build templates

View File

@@ -21831,6 +21831,27 @@
<folder_node> <folder_node>
<name>labels</name> <name>labels</name>
<children> <children>
<concept_node>
<name>maxtenimages</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node> <concept_node>
<name>messaging</name> <name>messaging</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -21936,6 +21957,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>selectmedia</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node> <concept_node>
<name>sentby</name> <name>sentby</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>

View File

@@ -0,0 +1,88 @@
import { PictureFilled } from "@ant-design/icons";
import { useQuery } from "@apollo/react-hooks";
import { Badge, Popover } from "antd";
import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { GET_DOCUMENTS_BY_JOB } from "../../graphql/documents.queries";
import AlertComponent from "../alert/alert.component";
import JobDocumentsGalleryExternal from "../jobs-documents-gallery/jobs-documents-gallery.external.component";
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
});
export default connect(mapStateToProps, mapDispatchToProps)(ChatMediaSelector);
export function ChatMediaSelector({
selectedMedia,
setSelectedMedia,
conversation,
}) {
const { t } = useTranslation();
console.log("conversation", conversation);
const { loading, error, data, refetch } = useQuery(GET_DOCUMENTS_BY_JOB, {
variables: {
jobId:
conversation.job_conversations[0] &&
conversation.job_conversations[0].jobid,
},
fetchPolicy: "network-only",
skip:
!conversation.job_conversations ||
conversation.job_conversations.length === 0,
});
const [visible, setVisible] = useState(false);
const handleVisibleChange = (visible) => {
setVisible(visible);
};
useEffect(() => {
setSelectedMedia([]);
}, [setSelectedMedia, conversation]);
const content = (
<div>
{loading && <LoadingSpinner />}
{error && <AlertComponent message={error.message} type="error" />}
{selectedMedia.filter((s) => s.isSelected).length >= 10 ? (
<div style={{ color: "red" }}>{t("messaging.labels.maxtenimages")}</div>
) : null}
{data && (
<JobDocumentsGalleryExternal
data={data ? data.documents : []}
externalMediaState={[selectedMedia, setSelectedMedia]}
/>
)}
</div>
);
return (
<Popover
content={
conversation.job_conversations.length === 0 ? (
<div>{t("messaging.errors.noattachedjobs")}</div>
) : (
content
)
}
title={t("messaging.labels.selectmedia")}
trigger="click"
visible={visible}
onVisibleChange={handleVisibleChange}
>
<Badge
size="small"
count={selectedMedia.filter((s) => s.isSelected).length}
>
<PictureFilled style={{ margin: "0 .5rem" }} />
</Badge>
</Popover>
);
}

View File

@@ -1,4 +1,6 @@
import Icon from "@ant-design/icons"; import Icon from "@ant-design/icons";
import i18n from "i18next";
import moment from "moment";
import React, { useEffect, useRef } from "react"; import React, { useEffect, useRef } from "react";
import { MdDone, MdDoneAll } from "react-icons/md"; import { MdDone, MdDoneAll } from "react-icons/md";
import { import {
@@ -8,8 +10,6 @@ import {
List, List,
} from "react-virtualized"; } from "react-virtualized";
import "./chat-message-list.styles.scss"; import "./chat-message-list.styles.scss";
import i18n from "i18next";
import moment from "moment";
export default function ChatMessageListComponent({ messages }) { export default function ChatMessageListComponent({ messages }) {
const virtualizedListRef = useRef(null); const virtualizedListRef = useRef(null);
@@ -46,6 +46,16 @@ export default function ChatMessageListComponent({ messages }) {
{MessageRender(messages[index])} {MessageRender(messages[index])}
{StatusRender(messages[index].status)} {StatusRender(messages[index].status)}
</div> </div>
{messages[index].isoutbound && (
<div style={{ fontSize: 10 }}>
{i18n.t("messaging.labels.sentby", {
by: messages[index].userid,
time: moment(messages[index].created_at).format(
"MM/DD/YYYY @ hh:mm a"
),
})}
</div>
)}
</div> </div>
)} )}
</CellMeasurer> </CellMeasurer>
@@ -74,27 +84,19 @@ export default function ChatMessageListComponent({ messages }) {
} }
const MessageRender = (message) => { const MessageRender = (message) => {
if (message.image) { return (
return ( <div>
<a href={message.image_path} target="__blank"> {message.image_path &&
<img alt="Received" className="message-img" src={message.image_path} /> message.image_path.map((i, idx) => (
</a> <div key={idx} style={{ display: "flex", justifyContent: "center" }}>
); <a href={i} target="__blank">
} else { <img alt="Received" className="message-img" src={i} />
return ( </a>
<div>
<div>{message.text}</div>
{message.isoutbound && (
<div style={{ color: "slategray", fontSize: 10 }}>
{i18n.t("messaging.labels.sentby", {
by: message.userid,
time: moment(message.created_at).format("MM/DD/YYYY @ hh:mm a"),
})}
</div> </div>
)} ))}
</div> <div>{message.text}</div>
); </div>
} );
}; };
const StatusRender = (status) => { const StatusRender = (status) => {

View File

@@ -34,9 +34,10 @@
//display: inline-block; //display: inline-block;
.message-img { .message-img {
max-width: 3rem; max-width: 10rem;
max-height: 3rem; max-height: 10rem;
object-fit: contain; object-fit: contain;
margin: 0.2rem;
} }
} }

View File

@@ -1,6 +1,6 @@
import { LoadingOutlined, SendOutlined } from "@ant-design/icons"; import { LoadingOutlined, SendOutlined } from "@ant-design/icons";
import { Input, Spin } from "antd"; import { Input, Spin } from "antd";
import React, { useEffect, useRef } from "react"; import React, { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
@@ -14,6 +14,7 @@ import {
selectMessage, selectMessage,
} from "../../redux/messaging/messaging.selectors"; } from "../../redux/messaging/messaging.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors";
import ChatMediaSelector from "../chat-media-selector/chat-media-selector.component";
import ChatPresetsComponent from "../chat-presets/chat-presets.component"; import ChatPresetsComponent from "../chat-presets/chat-presets.component";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
@@ -36,6 +37,7 @@ function ChatSendMessageComponent({
setMessage, setMessage,
}) { }) {
const inputArea = useRef(null); const inputArea = useRef(null);
const [selectedMedia, setSelectedMedia] = useState([]);
useEffect(() => { useEffect(() => {
inputArea.current.focus(); inputArea.current.focus();
}, [isSending, setMessage]); }, [isSending, setMessage]);
@@ -43,36 +45,55 @@ function ChatSendMessageComponent({
const { t } = useTranslation(); const { t } = useTranslation();
const handleEnter = () => { const handleEnter = () => {
if (message === "" || !message) return;
logImEXEvent("messaging_send_message"); logImEXEvent("messaging_send_message");
sendMessage({ const selectedImages = selectedMedia.filter((i) => i.isSelected);
to: conversation.phone_num, if (selectedImages < 11) {
body: message, sendMessage({
messagingServiceSid: bodyshop.messagingservicesid, to: conversation.phone_num,
conversationid: conversation.id, body: message,
}); messagingServiceSid: bodyshop.messagingservicesid,
conversationid: conversation.id,
selectedMedia: selectedImages,
});
setSelectedMedia(
selectedMedia.map((i) => {
return { ...i, isSelected: false };
})
);
}
}; };
return ( return (
<div className="imex-flex-row" style={{ width: "100%" }}> <div className="imex-flex-row" style={{ width: "100%" }}>
<ChatPresetsComponent className="imex-flex-row__margin" /> <ChatPresetsComponent className="imex-flex-row__margin" />
<ChatMediaSelector
<Input.TextArea conversation={conversation}
className="imex-flex-row__margin imex-flex-row__grow" selectedMedia={selectedMedia}
allowClear setSelectedMedia={setSelectedMedia}
autoFocus />
ref={inputArea} <span style={{ flex: 1 }}>
autoSize={{ minRows: 1, maxRows: 4 }} <Input.TextArea
value={message} className="imex-flex-row__margin imex-flex-row__grow"
disabled={isSending} allowClear
placeholder={t("messaging.labels.typeamessage")} autoFocus
onChange={(e) => setMessage(e.target.value)} ref={inputArea}
onPressEnter={(event) => { autoSize={{ minRows: 1, maxRows: 4 }}
event.preventDefault(); value={message}
if (!!!event.shiftKey) handleEnter(); disabled={isSending}
}} placeholder={t("messaging.labels.typeamessage")}
onChange={(e) => setMessage(e.target.value)}
onPressEnter={(event) => {
event.preventDefault();
if (!!!event.shiftKey) handleEnter();
}}
/>
</span>
<SendOutlined
className="imex-flex-row__margin"
disabled={message === "" || !message}
onClick={handleEnter}
/> />
<SendOutlined className="imex-flex-row__margin" onClick={handleEnter} />
<Spin <Spin
style={{ display: `${isSending ? "" : "none"}` }} style={{ display: `${isSending ? "" : "none"}` }}
indicator={ indicator={

View File

@@ -1,5 +1,5 @@
import React from "react";
import { useQuery } from "@apollo/react-hooks"; import { useQuery } from "@apollo/react-hooks";
import React from "react";
import { GET_DOCUMENTS_BY_JOB } from "../../graphql/documents.queries"; import { GET_DOCUMENTS_BY_JOB } from "../../graphql/documents.queries";
import AlertComponent from "../alert/alert.component"; import AlertComponent from "../alert/alert.component";
import LoadingSpinner from "../loading-spinner/loading-spinner.component"; import LoadingSpinner from "../loading-spinner/loading-spinner.component";

View File

@@ -0,0 +1,58 @@
import React, { useEffect } from "react";
import Gallery from "react-grid-gallery";
import { useTranslation } from "react-i18next";
import { DetermineFileType } from "../documents-upload/documents-upload.utility";
function JobsDocumentGalleryExternal({
data,
externalMediaState,
}) {
const [galleryImages, setgalleryImages] = externalMediaState;
const { t } = useTranslation();
useEffect(() => {
let documents = data.reduce((acc, value) => {
if (value.type.startsWith("image")) {
acc.push({
src: `${
process.env.REACT_APP_CLOUDINARY_ENDPOINT
}/${DetermineFileType(value.type)}/upload/${value.key}`,
thumbnail: `${
process.env.REACT_APP_CLOUDINARY_ENDPOINT
}/${DetermineFileType(value.type)}/upload/${
process.env.REACT_APP_CLOUDINARY_THUMB_TRANSFORMATIONS
}/${value.key}`,
thumbnailHeight: 225,
thumbnailWidth: 225,
isSelected: false,
key: value.key,
extension: value.extension,
id: value.id,
type: value.type,
tags: [{ value: value.type, title: value.type }],
});
}
return acc;
}, []);
setgalleryImages(documents);
}, [data, setgalleryImages, t]);
return (
<div className="clearfix">
<Gallery
images={galleryImages}
backdropClosesModal={true}
onSelectImage={(index, image) => {
setgalleryImages(
galleryImages.map((g, idx) =>
index === idx ? { ...g, isSelected: !g.isSelected } : g
)
);
}}
/>
</div>
);
}
export default JobsDocumentGalleryExternal;

View File

@@ -1310,11 +1310,13 @@
"new": "New Conversation" "new": "New Conversation"
}, },
"labels": { "labels": {
"maxtenimages": "You can only select up to a maximum of 10 images at a time.",
"messaging": "Messaging", "messaging": "Messaging",
"noallowtxt": "This customer has not indicated their permission to be messaged.", "noallowtxt": "This customer has not indicated their permission to be messaged.",
"nojobs": "Not associated to any job.", "nojobs": "Not associated to any job.",
"phonenumber": "Phone #", "phonenumber": "Phone #",
"presets": "Presets", "presets": "Presets",
"selectmedia": "Select Media",
"sentby": "Sent by {{by}} at {{time}}", "sentby": "Sent by {{by}} at {{time}}",
"typeamessage": "Send a message..." "typeamessage": "Send a message..."
} }

View File

@@ -1310,11 +1310,13 @@
"new": "" "new": ""
}, },
"labels": { "labels": {
"maxtenimages": "",
"messaging": "Mensajería", "messaging": "Mensajería",
"noallowtxt": "", "noallowtxt": "",
"nojobs": "", "nojobs": "",
"phonenumber": "", "phonenumber": "",
"presets": "", "presets": "",
"selectmedia": "",
"sentby": "", "sentby": "",
"typeamessage": "Enviar un mensaje..." "typeamessage": "Enviar un mensaje..."
} }

View File

@@ -1310,11 +1310,13 @@
"new": "" "new": ""
}, },
"labels": { "labels": {
"maxtenimages": "",
"messaging": "Messagerie", "messaging": "Messagerie",
"noallowtxt": "", "noallowtxt": "",
"nojobs": "", "nojobs": "",
"phonenumber": "", "phonenumber": "",
"presets": "", "presets": "",
"selectmedia": "",
"sentby": "", "sentby": "",
"typeamessage": "Envoyer un message..." "typeamessage": "Envoyer un message..."
} }

View File

@@ -0,0 +1,37 @@
- args:
role: user
table:
name: messages
schema: public
type: drop_insert_permission
- args:
permission:
check:
conversation:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
columns:
- conversationid
- created_at
- id
- image
- image_path
- isoutbound
- msid
- read
- status
- text
- updated_at
- userid
set: {}
role: user
table:
name: messages
schema: public
type: create_insert_permission

View File

@@ -0,0 +1,36 @@
- args:
role: user
table:
name: messages
schema: public
type: drop_insert_permission
- args:
permission:
check:
conversation:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
columns:
- conversationid
- created_at
- id
- image
- isoutbound
- msid
- read
- status
- text
- updated_at
- userid
set: {}
role: user
table:
name: messages
schema: public
type: create_insert_permission

View File

@@ -0,0 +1,38 @@
- args:
role: user
table:
name: messages
schema: public
type: drop_select_permission
- args:
permission:
allow_aggregations: true
columns:
- conversationid
- created_at
- id
- image
- image_path
- isoutbound
- msid
- read
- status
- text
- updated_at
- userid
computed_fields: []
filter:
conversation:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
role: user
table:
name: messages
schema: public
type: create_select_permission

View File

@@ -0,0 +1,37 @@
- args:
role: user
table:
name: messages
schema: public
type: drop_select_permission
- args:
permission:
allow_aggregations: true
columns:
- conversationid
- created_at
- id
- image
- isoutbound
- msid
- read
- status
- text
- updated_at
- userid
computed_fields: []
filter:
conversation:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
role: user
table:
name: messages
schema: public
type: create_select_permission

View File

@@ -0,0 +1,36 @@
- args:
role: user
table:
name: messages
schema: public
type: drop_update_permission
- args:
permission:
columns:
- image
- isoutbound
- read
- image_path
- msid
- status
- text
- created_at
- updated_at
- conversationid
- id
filter:
conversation:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
set: {}
role: user
table:
name: messages
schema: public
type: create_update_permission

View File

@@ -0,0 +1,35 @@
- args:
role: user
table:
name: messages
schema: public
type: drop_update_permission
- args:
permission:
columns:
- conversationid
- created_at
- id
- image
- isoutbound
- msid
- read
- status
- text
- updated_at
filter:
conversation:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
set: {}
role: user
table:
name: messages
schema: public
type: create_update_permission

View File

@@ -0,0 +1,10 @@
- args:
cascade: false
read_only: false
sql: ALTER TABLE "public"."messages" ADD COLUMN "image_path" text;
type: run_sql
- args:
cascade: false
read_only: false
sql: ALTER TABLE "public"."messages" ALTER COLUMN "image_path" DROP NOT NULL;
type: run_sql

View File

@@ -0,0 +1,5 @@
- args:
cascade: false
read_only: false
sql: ALTER TABLE "public"."messages" DROP COLUMN "image_path" CASCADE;
type: run_sql

View File

@@ -0,0 +1,5 @@
- args:
cascade: false
read_only: false
sql: ALTER TABLE "public"."messages" DROP COLUMN "image_path";
type: run_sql

View File

@@ -0,0 +1,5 @@
- args:
cascade: false
read_only: false
sql: ALTER TABLE "public"."messages" ADD COLUMN "image_path" jsonb NULL;
type: run_sql

View File

@@ -0,0 +1,36 @@
- args:
role: user
table:
name: messages
schema: public
type: drop_insert_permission
- args:
permission:
check:
conversation:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
columns:
- conversationid
- created_at
- id
- image
- isoutbound
- msid
- read
- status
- text
- updated_at
- userid
set: {}
role: user
table:
name: messages
schema: public
type: create_insert_permission

View File

@@ -0,0 +1,37 @@
- args:
role: user
table:
name: messages
schema: public
type: drop_insert_permission
- args:
permission:
check:
conversation:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
columns:
- conversationid
- created_at
- id
- image
- image_path
- isoutbound
- msid
- read
- status
- text
- updated_at
- userid
set: {}
role: user
table:
name: messages
schema: public
type: create_insert_permission

View File

@@ -0,0 +1,37 @@
- args:
role: user
table:
name: messages
schema: public
type: drop_select_permission
- args:
permission:
allow_aggregations: true
columns:
- conversationid
- created_at
- id
- image
- isoutbound
- msid
- read
- status
- text
- updated_at
- userid
computed_fields: []
filter:
conversation:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
role: user
table:
name: messages
schema: public
type: create_select_permission

View File

@@ -0,0 +1,38 @@
- args:
role: user
table:
name: messages
schema: public
type: drop_select_permission
- args:
permission:
allow_aggregations: true
columns:
- conversationid
- created_at
- id
- image
- image_path
- isoutbound
- msid
- read
- status
- text
- updated_at
- userid
computed_fields: []
filter:
conversation:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
role: user
table:
name: messages
schema: public
type: create_select_permission

View File

@@ -0,0 +1,35 @@
- args:
role: user
table:
name: messages
schema: public
type: drop_update_permission
- args:
permission:
columns:
- conversationid
- created_at
- id
- image
- isoutbound
- msid
- read
- status
- text
- updated_at
filter:
conversation:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
set: {}
role: user
table:
name: messages
schema: public
type: create_update_permission

View File

@@ -0,0 +1,36 @@
- args:
role: user
table:
name: messages
schema: public
type: drop_update_permission
- args:
permission:
columns:
- conversationid
- created_at
- id
- image
- image_path
- isoutbound
- msid
- read
- status
- text
- updated_at
filter:
conversation:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
set: {}
role: user
table:
name: messages
schema: public
type: create_update_permission

View File

@@ -3057,17 +3057,17 @@ tables:
- role: user - role: user
permission: permission:
columns: columns:
- conversationid
- created_at
- id
- image - image
- isoutbound
- read
- image_path - image_path
- isoutbound
- msid - msid
- read
- status - status
- text - text
- created_at
- updated_at - updated_at
- conversationid
- id
filter: filter:
conversation: conversation:
bodyshop: bodyshop:

View File

@@ -29,11 +29,13 @@ exports.receive = (req, res) => {
phone: phone(req.body.From)[0], phone: phone(req.body.From)[0],
}) })
.then((response) => { .then((response) => {
console.log("re", req.body);
let newMessage = { let newMessage = {
msid: req.body.SmsMessageSid, msid: req.body.SmsMessageSid,
text: req.body.Body, text: req.body.Body,
image: !!req.body.MediaUrl0, image: !!req.body.MediaUrl0,
image_path: req.body.MediaUrl0 || null, image_path: generateMediaArray(req.body),
}; };
if (response.bodyshops[0]) { if (response.bodyshops[0]) {
//Found a bodyshop - should always happen. //Found a bodyshop - should always happen.
@@ -164,3 +166,17 @@ exports.receive = (req, res) => {
// [0] MediaContentType0: 'image/jpeg', // [0] MediaContentType0: 'image/jpeg',
// MediaContentType0: 'video/3gpp', // MediaContentType0: 'video/3gpp',
const generateMediaArray = (body) => {
const { NumMedia } = body;
if (parseInt(NumMedia) > 0) {
//stuff
const ret = [];
for (var i = 0; i < parseInt(NumMedia); i++) {
ret.push(body[`MediaUrl${i}`]);
}
return ret;
} else {
return null;
}
};

View File

@@ -17,7 +17,13 @@ const client = twilio(
const gqlClient = require("../graphql-client/graphql-client").client; const gqlClient = require("../graphql-client/graphql-client").client;
exports.send = (req, res) => { exports.send = (req, res) => {
const { to, messagingServiceSid, body, conversationid } = req.body; const {
to,
messagingServiceSid,
body,
conversationid,
selectedMedia,
} = req.body;
console.log("[Sending Sms] " + conversationid + " | " + body); console.log("[Sending Sms] " + conversationid + " | " + body);
if (!!to && !!messagingServiceSid && !!body && !!conversationid) { if (!!to && !!messagingServiceSid && !!body && !!conversationid) {
client.messages client.messages
@@ -25,6 +31,7 @@ exports.send = (req, res) => {
body: body, body: body,
messagingServiceSid: messagingServiceSid, messagingServiceSid: messagingServiceSid,
to: phone(to)[0], to: phone(to)[0],
mediaUrl: selectedMedia.map((i) => i.src),
}) })
.then((message) => { .then((message) => {
let newMessage = { let newMessage = {
@@ -33,6 +40,11 @@ exports.send = (req, res) => {
conversationid, conversationid,
isoutbound: true, isoutbound: true,
userid: req.user.email, userid: req.user.email,
image: req.body.selectedMedia.length > 0,
image_path:
req.body.selectedMedia.length > 0
? selectedMedia.map((i) => i.src)
: [],
}; };
gqlClient gqlClient
.request(queries.INSERT_MESSAGE, { msg: newMessage }) .request(queries.INSERT_MESSAGE, { msg: newMessage })
@@ -55,3 +67,23 @@ exports.send = (req, res) => {
.json({ success: false, message: "Missing required parameter(s)." }); .json({ success: false, message: "Missing required parameter(s)." });
} }
}; };
// //Image
// acc.push({
// src: `${process.env.REACT_APP_CLOUDINARY_ENDPOINT}/${DetermineFileType(
// value.type
// )}/upload/${value.key}`,
// thumbnail: `${
// process.env.REACT_APP_CLOUDINARY_ENDPOINT
// }/${DetermineFileType(value.type)}/upload/${
// process.env.REACT_APP_CLOUDINARY_THUMB_TRANSFORMATIONS
// }/${value.key}`,
// thumbnailHeight: 225,
// thumbnailWidth: 225,
// isSelected: false,
// key: value.key,
// extension: value.extension,
// id: value.id,
// type: value.type,
// tags: [{ value: value.type, title: value.type }],
// });