summaryrefslogtreecommitdiff
path: root/src/app.js
blob: 1d07fbd9003d3f562b69198ed34aa13586ff1cce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
const bodyParser = require('body-parser');
const dotenv = require('dotenv');
const express = require('express');
const { MessagingResponse } = require('twilio').twiml;

dotenv.config();

const { isSubscribed, getSubscriptions, getSubscriptionFromNumber, subscribe, load: loadData, unsubscribe } = require('./db');
const { sendTextMessage } = require('./sendTextMessage');

loadData();
const app = express();

app.use(bodyParser.urlencoded({ extended: false }));

app.post('/sms', (req, res) => {
  /** @type {string} */
  const body = req.body.Body.trim();
  const bodyLowerCase = body.toLocaleLowerCase();
  /** @type {string} */
  const senderPhoneNumber = req.body.From;
  /** @type {string} */
  const senderCountry = req.body.FromCountry;

  console.debug(`
    Received a text from ${senderCountry} on number ${senderPhoneNumber}.
    Message content: ${body}. End of message
  `.replace(/\s+/g, ' '));

  if (isSubscribed(senderPhoneNumber)) {
    if (['ls', 'list'].includes(bodyLowerCase)) {
      const twiml = new MessagingResponse();
      twiml.message(
        getSubscriptions()
        .map(({ name, number }) => `${name} (${number})`)
        .join(', ')
      );
      res.type('text/xml').send(twiml.toString());
      return;
    }

    if (['quit', 'exit', 'unsubscribe'].includes(bodyLowerCase)) {
      unsubscribe(senderPhoneNumber);
      const twiml = new MessagingResponse();
      twiml.message(`
        You have unsubscribed from the Glen Coe texting group. To join again,
        text 'my name is <your name>' to this number.
      `);
      res.type('text/xml').send(twiml.toString());
      return;
    }
    const senderSubscription = getSubscriptionFromNumber(senderPhoneNumber);
    const otherSubscriptions = getSubscriptions().filter(sub => sub.number !== senderPhoneNumber);

    const forwardedMessage = `${senderSubscription.name} said: ${body}`;
    sendTextMessage(otherSubscriptions, forwardedMessage);

    const abbreviatedBody = body.length > 16 ? `${body.slice(0, 14)}...` : body;
    const confirmationMessage = `
      Your message was forwarded to ${otherSubscriptions.length}
      recipients: "${abbreviatedBody}". Only you can see this message.
    `.replace(/\s+/g, ' ');
    sendTextMessage([senderSubscription], confirmationMessage);
  } else {
    if (bodyLowerCase.startsWith('my name is ') || bodyLowerCase.startsWith('my name is: ')) {
      const senderName = body.matchAll(/^my name is:? (.*)$/gi)?.next()?.value?.[1];

      if (!senderName) {
        const twiml = new MessagingResponse();
        twiml.message("Please provide a name. Syntax: my name is <your name>");
        res.type('text/xml').send(twiml.toString());
        return;
      }

      const subscription = subscribe(senderPhoneNumber, senderName);
      const welcomeMessage = `
        Well done, ${senderName}! You have successfully subscribed to the Glen
        Coe meet texting group. You will now be able to send and receive messages
        to and from the group. Send 'list' to list participants, and send 'quit'
        to unsubscribe.
      `.replace(/\s+/g, ' ');
      sendTextMessage([subscription], welcomeMessage);
    } else {
      const twiml = new MessagingResponse();
      twiml.message(`
        You are not subscribed to this texting group. To subscribe, send a
        text to this number with this syntax: my name is <your name>
      `.replace(/\s+/g, ' '));
      res.type('text/xml').send(twiml.toString());
      return;
    }
  }

  const twiml = new MessagingResponse();
  res.type('text/xml').send(twiml.toString());
});

app.listen(3000, () => {
  console.log('Express server listening on port 3000');
});