使用AWS + Telegram反应本机反馈表单

图片

在开始将反馈表单集成到我的最后一个项目中之前,我试图找到一种解决问题的非标准方法。电子邮件需要某种SMTP服务器,而且很无聊,特别是对于消息流较低的初创企业而言。

Messenger,这是一个很好的选择,这就是我选择的路径。 Telegram提供了一种最简单的方式来创建机器人(如果不是最简单的话)。可以代替任何东西-其他Messenger,电话(Amazon Connect)或Yandex Dialogs。

我们不尝试创建用于通信的聊天机器人或界面,我们希望当发件人不希望即时响应时,它看起来像是正常的反馈形式。在下面的示例中,收件人将能够通过电子邮件回复用户,该电子邮件将留在表单字段中。

第1步:电报中的bot,再简单不过了


我们向@BotFather团队发送消息/newbot,设置名称,就是这样!我们得到了令牌我们将其保密。

另外,我们需要chat_id-标识将向其发送消息的聊天室。幸运地是,chat_id比获得令牌要更努力地学习您的知识,幸运的是,有一艘船的名字@my_id_bot将揭示您的身份chat_id

结果,我们有了一个令牌,我们将使用令牌与我们的机器人进行“交谈”,chat_id并将其用于向您个人发送消息。现在,您可以向我们的机器人发送命令/start,我们可以继续前进。

以电报为例,由于易于使用漫游器,因此可能存在另一个Messenger或其他触发器。

步骤2:使用Lambda作为中介


设置Telegram的选项之一是将整个请求代码嵌入并与Telegram API“对话”到React Native应用程序代码本身中-这是测试的一个不错的选择。就我而言,已经配置了具有多个活动Lambda函数的API,因此我的选择包括将Lambda作为应用程序和Telegram API之间的中间层。以下代码和说明可在React Native项目本身中使用。

我使用无服务器框架使用下面的参数(格式yaml创建一个新函数

sendTelegramMessage:
  description: used for contact form (${self:custom.stage})
  handler: lib/additional/sendMessageTelegram.handler
  environment: ${file(env_contact.yml):${self:custom.stage}}
  events:
    - http:
      path: contact
      method: POST
      private: false
  package:
    include:
      - lib/additional/sendMessageTelegram.js

请记住,令牌chat_id必须严格隐藏。在这种情况下,我正在使用将在Lambda中使用的环境变量文件。从上面的行中可以看到,Serverless将为POST请求配置网关API。另请注意,在这种情况下,API对所有人开放,没有任何限制。

这是Lambda代码的一部分,它将接受我们的请求。我们的前端仅收集信息(电子邮件和消息),并将请求发送到我们的函数,该函数将在Telegram API中处理请求。

exports.handler = async (event) => {
  if (!event.body) {
    return createResponse(400, " ");
  }

  const data = JSON.parse(event.body);

  if (!data.email || !data.message) {
    return createResponse(400, " 'email'  'message' ");
  }

  try {
    const telegram = getTelegramConfig();

    await fetch(`${telegram.url}/bot${telegram.token}/sendMessage?${telegram.params(data.email, data.message)}`)

    return createResponse(200, " ");
  } catch (e) {
    return createResponse(500, e.message);
  }
};

两种帮助程序功能,getTelegramConfig用于创建请求URL以及createResponse生成带有状态码和消息的标准响应。

const getTelegramConfig = () => {
  const token = process.env.TELEGRAM_BOT_TOKEN;
  const chatId = process.env.TELEGRAM_MAIN_CONTACT;

  if (!token || !chatId) {
    throw new Error("  ");
  }

  return {
    url: "https://api.telegram.org",
    token,
    params: (email, message) => qp.encode({
      chat_id: chatId,
      parse_mode: "Markdown",
      text: "  " + email + ": ```" + message + "```"
    })
  };
};

const createResponse = (statusCode, message) => ({
  statusCode,
  body: JSON.stringify({ message }, null, 2)
});

qp.encode用于将对象转换为字符串?param1=value¶m2=value

现在,如果我们发出包含以下内容的POST请求,我们将在Telegram上收到消息。

{
    "email": "privet@gmail.com",
    "message": "   .  . , ,  ,   . ,        .         ,   .  ,  .  .   ,     .          .  .    ,   "
}

图片

步骤3:在React Native App中“与我们联系”


保留了前端的一部分。尽可能多地要求消息至少10个字符并检查电子邮件地址。

部分JSXButton-这是它的组件,带有不活动(disabled)状态和下载状态(loading)的附加参数样式也由您决定。

<View style={styles.container}>
  <TextInput
    value={sendersEmail}
    keyboardType="email-address"
    autoCapitalize="none"
    autoCompleteType="email"
    style={styles.input}
    onChangeText={onEmailChange}
    selectionColor="#555"
    placeholder=" "
    placeholderTextColor="#CCC"
    clearButtonMode="always"
    returnKeyType="done"
    disableFullscreenUI
  />
  <TextInput
    value={message}
    style={{ ...styles.input, ...styles.messageInput }}
    onChangeText={onMessageChange}
    selectionColor="#555"
    placeholder=" ..."
    placeholderTextColor="#CCC"
    clearButtonMode="always"
    returnKeyType="done"
    multiline
    textAlignVertical="top"
    disableFullscreenUI
  />
  <Button
    title=""
    loading={loading}
    disabled={disabled}
    onPress={onSendPress}
  />
</View>

JavaScript部分。

const [ sendersEmail, setSendersEmail ] = useState("");
  const [ message, setMessage ] = useState("");

  const [ loading, setLoading ] = useState(false);

  const onEmailChange = (value) => {
    setSendersEmail(value);
  };

  const onMessageChange = (value) => {
    setMessage(value);
  };

  const onSendPress = () => {
    setLoading(true);

    const url = "https://api.example.com/contact";

    fetch(url, {
      method: "POST",
      body: JSON.stringify({
        email: sendersEmail,
        message
      })
    })
    .then(() => {
      setLoading(false);
    })
    .catch(() => {
      setLoading(false);

      Alert.alert("", "    .");
    });
  };

  const isValidEmail = () => {
    const emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

    return emailRegex.test(sendersEmail.toLowerCase());
  };


  const disabled = message.length < 10 || !isValidEmail();

在用户输入正确的电子邮件地址和至少10个字符的消息之前,“提交”按钮将处于非活动状态。请记住,在此示例中,API是打开的。

图片

像这样。

有什么不见了


  • 我没有涉及API的一部分,这是一个单独的主题,可以找到许多与此相关的文章。我还建议您熟悉无服务器框架。
  • 在此示例中,我们以电报形式收到一条消息,但我们将不得不通过电子邮件进行答复。有很多不同的选项,这只是一个例子。

有用的链接


英文
https://core.telegram.org/bots/api#sendmessage
https://core.telegram.org/bots/api#markdown-style
https://facebook.imtqy.com/react-native/docs/文字输入

All Articles