使用Twilio API和WhatsApp构建一个词典应用程序
WhatsApp是世界上最流行的信息传递应用之一。全世界有数百万人在使用它,这意味着如果我们将我们的网络应用与WhatsApp整合,我们可能会有大量的用户供我们使用。
Twilio是一个基于云的消息平台,它将帮助我们将我们的网络应用与WhatsApp整合。
简介
本教程将教导我们如何通过构建一个字典式的应用程序,将WhatsApp API与Spring Boot网络应用程序相整合。
先决条件
读者需要以下条件才能跟上。
- 在你的机器上安装Java Developer Kit[JDK]。
- 对[Spring Boot]的了解。
- 一个[Twillio]账户。
- 在你的机器上安装[MySQL]。
应用程序设置
- 导航到spring initializr。
- 输入项目名称为
dictionary。 - 添加
mysql,spring-web,spring-data-jpa和lombok作为项目依赖。 - 点击生成,以压缩文件的形式下载模板项目代码。
- 提取在上一步中下载的压缩文件。
- 在你喜欢的IDE中打开该项目。
在pom.xml 文件中,在dependencies 部分添加以下依赖关系。
<dependency>
<groupId>com.twilio.sdk</groupId>
<artifactId>twilio</artifactId>
<version>8.23.0</version>
<scope>compile</scope>
</dependency>
上述依赖关系将使我们能够连接到Twilio,在我们的应用程序中发送和接收消息。
模型层
- 在根应用程序包中,创建一个名为
model的新包。 - 在上面创建的包中,创建一个名为
Definition的新的Java类,并用下面的代码片断来更新它。
package com.example.dictionary.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "dictionary")
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Definition {
@Id
@Column(name = "def", nullable = false)
private String def;
@Column(name = "word", nullable = false)
private String name;
}
-
Spring Boot实体被映射到数据库中的表。
@Entity注解表示这个类是一个实体,@Table注解表示表的名称是dictionary。 -
@NoArgsConstructor和 注解分别用于创建一个没有参数的构造函数和一个有所有参数的构造函数。@AllArgsConstructor -
@Data注解被用来为字段生成getters和setters。 -
@Column 注解用来表示字段被映射到数据库中具有指定名称的列。
存储库层
Spring Data JPA使其有可能从存储库中创建数据库查询。
- 在根应用程序包中,创建一个名为
repository的新包。 - 在上面创建的包中,创建一个名为
DictionaryReposiotory的新接口,并将以下代码片断更新。
package com.example.dictionary.repository;
import com.example.dictionary.model.Definition;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
@Repository
public interface DictionaryRepository extends JpaRepository<Definition, String> {
Optional<List<Definition>> findByName(String name);
}
@Repository注解用来表示这个接口是一个资源库。findByName方法用于查找一个词的所有定义。该函数返回一个Optional类型,因为结果可以返回null。如果用户搜索一个不存在于字典中的词,就会返回null。
服务层
服务层将处理向用户发送响应,包括他们搜索的单词的定义。
- 在根应用程序包中,创建一个名为
service的新包。 - 在服务包中,创建一个名为
DictionaryService的新类,并用下面的代码片断来更新它。
package com.example.dictionary.service;
import com.example.dictionary.model.Definition;
import com.example.dictionary.repository.DictionaryRepository;
import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.Message;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class DictionaryService {
public static final String ACCOUNT_SID = "ACda8b1bb661d4926171cfa09326f7daac";
public static final String AUTH_TOKEN = "0d667f37cdcd2dc6758b2b3e03d99631";
private final DictionaryRepository repository;
public DictionaryService(DictionaryRepository repository) {
this.repository = repository;
}
public void sendReply(String from, String to, String text) {
Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
List<Definition> defs = repository.findByName(text)
.orElseThrow(() -> new IllegalStateException("No item found"));
Message message = Message.creator(
new com.twilio.type.PhoneNumber(from),
new com.twilio.type.PhoneNumber(to),
defs.toString())
.create();
System.out.println(defs);
}
}
@Service注解用来表示这个类是一个服务。sendReply方法用于通过Twilio API向用户发送回复。
控制器层
- 在项目根包中,创建一个名为
controller的新包。 - 在上面创建的
controller包中,创建一个名为DictionaryController的新的Java类,并将其更新为以下代码片断。
package com.example.dictionary.controller;
import com.example.dictionary.service.DictionaryService;
import lombok.AllArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/v1/dictionary")
@AllArgsConstructor
public class DictionaryController {
private final DictionaryService service;
@PostMapping(consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
public void getMessage(@RequestParam("From") String From, @RequestParam("To") String To, @RequestParam("Body") String Body) {
System.out.println("From: " + From + " To: " + To + " Message: " + Body);
service.sendReply(From, To, Body);
}
}
@RestController注解标志着这个类是Spring Boot控制器类,将处理REST HTTP请求。@RequestMapping("/api/v1/dictionary")注解将我们的API的基本路径设置为/api/v1/dictionary。@PostMapping(consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})注解表明该注解方法将处理POST请求。MediaType.APPLICATION_FORM_URLENCODED_VALUE表明POST请求中预期的数据是表单数据。每当有消息发送到我们的WhatsApp API时,Twillio都会向我们的应用程序发送表单数据,包括消息和发件人的详细信息。
配置层
我们需要配置我们的应用程序,以连接到MySQL数据库,从数据库中检索单词和它们的定义。
在application.properties 文件中,添加以下几行。
spring.jpa.hibernate.ddl-auto=none
spring.datasource.url=jdbc:mysql://localhost:3306/dictionary # MySQL database URL
spring.datasource.username=paul #MySQL username
spring.datasource.password=37119787 #MySQL password
server.port=8081 #Port on which our application will run
数据库设置
- 在你机器上安装的Mysql数据库管理系统上,创建一个
dictionary数据库。 - 将data.sql文件中的数据导入上述数据中。这将创建一个字典表,并插入我们应用程序所需的所有单词和定义数据。
设置Twillio账户
- 导航到Twilio仪表板,创建一个新的账户。
- 创建一个新的Twilio电话号码。
- 创建一个新的Twilio API密钥和秘密密钥。
DictionaryService用你在Twilio仪表盘上创建的值更新ACCOUNT_SID和AUTH_TOKEN类中的变量。
Ngrok设置
由于我们需要公开我们的应用程序端点,以便Twilio可以将所有传入的消息转发给我们的应用程序,我们需要安装Ngrok。
Ngrok将本地开发环境暴露在互联网上。这使得互联网上的用户和其他应用程序有可能与我们的应用程序互动。一旦Ngrok安装在你的机器上,执行下面的命令,把我们的本地开发环境暴露在互联网上。
ngrok http 8081
如果Ngrok安装正确,你会看到下面的输出。
Session Status online
Account username (Plan: Free)
Version 2.3.40
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding http://41c3-102-220-12-234.ngrok.io -> http://localhost:8081
Forwarding https://41c3-102-220-12-234.ngrok.io -> http://localhost:8081
Connections ttl opn rt1 rt5 p50 p90
21 0 0.00 0.00 44.37 62.95
测试
在你的WhatsApp应用程序上,通过向你在Twilio仪表板上创建的Twilio号码发送消息来注册你的电话号码。一旦你的账户被注册,你就可以发送消息来获得它与你想要的单词的定义。

总结
现在你学会了如何在Spring Boot应用程序中使用Twillio WhatsApp API,试着用本教程中获得的技能创建一个简单的音乐歌词搜索应用程序。