Я пытался понять это уже много лет. По сути, мне нужно создать веб-приложение Twilio (в настоящее время пытающееся использовать React для внешнего интерфейса и Nodejs для внутреннего интерфейса), которое отправляет сообщения на все телефонные номера из загруженного CSV. Цель: в идеале, при нажатии одной кнопки все номера телефонов отправляются на сервер узла, а затем сервер узла отправляет сообщение на каждый отдельный номер.
Я так ЗАКРЫТ. Я могу загрузить номера и отправить их из React на сервер узла. В настоящее время он отправляет текст на первый номер, а затем примерно через 2 минуты после этого отправляет другой текст на тот же номер. Я знаю, что делаю что-то не так, но не уверен, что именно.
Обратите внимание: в этом случае массив отображается иначе, чем в приложении для групповой упаковки, используемом в учебнике по массовым SMS-сообщениям Twilio, когда я регистрировал значение "числа" после его отображения. Вот два их снимка, чтобы показать, что я имею в виду:
Обратите внимание, что закрашенный текст имеет номер [0]. Если просто число будет внутри двух наборов скобок.
Затем мультиупаковка. js:
Текст желтого цвета, и они находятся на отдельных строках.
Я предполагаю, что это связано с КАК я отправляю массив на узел, поскольку он хранит массив по-другому. Я просто очень расстраиваюсь на данный момент. Я чувствую себя так близко, и я хочу закончить это сегодня, если возможно. Пожалуйста, помогите.
Вот индекс. js:
const bodyParser = require('body-parser');
const pino = require('express-pino-logger')();
const client = require('twilio')(
process.env.TWILIO_ACCOUT_SID,
process.env.TWILIO_AUTH_TOKEN
);
const numbers = null;
const phoneNumbers = [];
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(pino);
app.get('/api/greeting', (req, res) => {
const name = req.query.name || 'World';
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({ greeting: `Hello ${name}!` }));
});
app.post('/test', (req, res) => {
res.header('Content-Type', 'application/json');
const numbers = req.body.to;
const phoneNumbers = req.phoneNumbers;
// numbers.forEach((numbers, i) => {
console.log("This is the to numbers:" + numbers + " and this is the phoneNumbers: " + phoneNumbers);
// });
Promise.all(
req.body.to.map(number => {
console.log(number[0]);
return client.messages.create({
to: number,
from: process.env.TWILIO_PHONE_NUMBER,
body: req.body.body
});
})
)
.then(messages => {
console.log('Messages sent!');
})
.catch(err => console.error(err));
});
app.listen(3001, () =>
console.log('Express server is running on localhost:3001. The value of numbers is ' + numbers + " and the value of phoneNumbers is " + phoneNumbers),
);
Вот внешний код:
import CSVReader from "react-csv-reader";
const dataDump = [];
const phoneNumbers = [];
console.log(dataDump);
const papaparseOptions = {
header: true,
dynamicTyping: true,
skipEmptyLines: true,
transformHeader: header => header.toLowerCase().replace(/\W/g, "_"),
complete: function(results) {
dataDump.push(results.data);
console.log("Here is the array when I log just DataDump:");
console.log(dataDump);
var rows = results.data;
let numbers = rows.map(a => a.phone_number); //make the results ONLY the phone numbers
phoneNumbers.push(numbers);
console.log("This is a test of the numbers variable:");
console.log(numbers);
document.getElementById("data2").innerHTML=numbers; //display the phone numbers
}
};
class Import extends React.Component {
constructor(props) {
super(props);
this.state = {phoneNumbers:[], data:[], message: {
to: [phoneNumbers],
body: ''
},
submitting: false,
error: false
};
this.onSubmit = this.onSubmit.bind(this);
this.onHandleChange = this.onHandleChange.bind(this);
this.handleClick = this.handleClick.bind(this);
}
handleForce = data => {
console.log("Here is the array for 'data' when I use handleForce.")
this.setState({data: data});
//parse the phone_numbers column for the phoneNumbers state
var rows = data;
let numbers = rows.map(a => a.phone_number); //make the results ONLY the phone numbers
this.setState({phoneNumbers: numbers});
console.log("Here is the phoneNumbers state");
console.log(this.state.phoneNumbers);
};
handleClick = () => {
console.log("This is the phoneNumbers state.");
console.log(this.state.phoneNumbers);
}
onSubmit(event) {
event.preventDefault();
this.setState({ submitting: true });
fetch('/test', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
phoneNumbers: JSON.stringify(this.state.phoneNumbers),
body: JSON.stringify(this.state.message),
dataArray: JSON.stringify(this.state.data)
})
.then(res => res.json())
.then(data => {
if (data.success) {
this.setState({
error: false,
submitting: false,
message: {
to: '',
body: ''
}
});
} else {
this.setState({
error: true,
submitting: false
});
}
});
}
onHandleChange(event) {
const name = event.target.getAttribute('name');
this.setState({
message: { ...this.state.message, [name]: event.target.value }
});
}
render() {
// const dataDump = this.state.data;
return (
<div className="container">
<CSVReader
className="csv-input"
label="Select CSV file to import"
onFileLoaded={this.handleForce}
parserOptions={papaparseOptions}
/>
<div>
</div>
<button onClick={this.handleClick.bind(this)}>
Test
</button>
<div id="data" />
<div id="data2" />
<div id="data3">
</div>
<form
onSubmit={this.onSubmit}
className={this.state.error ? 'error sms-form' : 'sms-form'}
>
<div>
<label htmlFor="to">To:</label>
<input
type="tel"
name="to"
id="to"
value={this.state.message.to}
onChange={this.onHandleChange}
/>
</div>
<div>
<label htmlFor="body">Body:</label>
<textarea
name="body"
id="body"
value={this.state.message.body}
onChange={this.onHandleChange}
/>
</div>
<button type="submit" disabled={this.state.submitting}>
Send message
</button>
</form>
</div>
);
}
}
export default Import;