JAVA中调用阿里云语音通知Api并接收消息回执

配置文件


需要的包

     <dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-dyvmsapi</artifactId><version>1.2.2</version></dependency><dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-core</artifactId><version>4.5.0</version><scope>compile</scope></dependency><dependency><groupId>com.aliyun.mns</groupId><artifactId>aliyun-sdk-mns</artifactId><version>1.1.8</version></dependency><dependency><groupId>com.aliyun</groupId><artifactId>dyvmsapi20170525</artifactId><version>0.0.2</version></dependency><dependency><groupId>com.meiyuan</groupId><artifactId>alicom-mns-receive-sdk-0.0.1-SNAPSHOT</artifactId><version>1.0.0</version></dependency><dependency><groupId>com.meiyuan</groupId><artifactId>aliyun-java-sdk-dybaseapi-1.0.0-SNAPSHOT</artifactId><version>1.0.0</version></dependency>

具体代码及步骤

1.获取配置文件中的参数

package com.meiyuan.reservation.dto.call;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;import java.io.Serializable;/*** 功能描述:ali云 语音通知辅助类实体** @author tc* @version 1.0* @since 2020/12/15 17:24*/
@Data
@Configuration
@ConfigurationProperties(prefix = "aliyun")
public class ClientConfigDto implements Serializable {private static final long serialVersionUID = 7736942314547915021L;/*** 您的AccessKey ID*/private String accessKeyId;/*** 您的AccessKey Secret*/private String accessKeySecret;/*** 语音文件的语音ID*/private String ttsCode;private String product;private String domain;/*** 主叫号码*/private String calledShowNumber;/*** 相应产品的消息类型*/private String messageType;/*** 在云通信页面开通相应业务消息后,就能在页面上获得对应的queueName*/private String queueName;
}

2.调用阿里云语音Api,三种不同的呼叫方式,根据需要选择调用

package com.meiyuan.reservation.call;import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dyvmsapi.model.v20170525.IvrCallRequest;
import com.aliyuncs.dyvmsapi.model.v20170525.IvrCallResponse;
import com.aliyuncs.dyvmsapi.model.v20170525.SingleCallByTtsRequest;
import com.aliyuncs.dyvmsapi.model.v20170525.SingleCallByTtsResponse;
import com.aliyuncs.dyvmsapi.model.v20170525.SingleCallByVoiceRequest;
import com.aliyuncs.dyvmsapi.model.v20170525.SingleCallByVoiceResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.meiyuan.reservation.dto.call.CallMsgDto;
import com.meiyuan.reservation.dto.call.ClientConfigDto;
import com.meiyuan.reservation.mq.sender.ReservationMqSender;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;/*** 功能描述:ali云 语音通知辅助类** @author tc* @version 1.0* @since 2020/12/15 17:17*/
@Slf4j
@Component
public class VmsDemo {/*** 文本转语音外呼** @return* @throws ClientException*/@Autowiredprivate ReservationMqSender reservationMqSender;public SingleCallByTtsResponse singleCallByTts(ClientConfigDto dto, String managerPhone, String reservationId, String tailNumber, String time) throws ClientException {//设置访问超时时间System.setProperty("sun.net.client.defaultConnectTimeout", "10000");System.setProperty("sun.net.client.defaultReadTimeout", "10000");//初始化acsClient 暂时不支持多regionIClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", dto.getAccessKeyId(), dto.getAccessKeySecret());DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", dto.getProduct(), dto.getDomain());IAcsClient acsClient = new DefaultAcsClient(profile);SingleCallByTtsRequest request = new SingleCallByTtsRequest();// 被叫显号,若您使用的模板为公共号池号码外呼模板,则该字段值必须为空;// 若您使用的模板为专属号码外呼模板,则必须传入已购买的号码,仅支持一个号码,您可以在语音服务控制台上查看已购买的号码。if ("numberPool".equals(dto.getCalledShowNumber())) {request.setCalledShowNumber("");} else {request.setCalledShowNumber(dto.getCalledShowNumber());}//必填-被叫号码(店长)request.setCalledNumber(managerPhone);//必填-Tts模板IDrequest.setTtsCode(dto.getTtsCode());// 这里主要是填写我们语音文字模板里面的参数 ${param}System.out.println(time);request.setTtsParam("{\"time\":\"" + time + "\",\"tailNumber\":\"" + tailNumber + "\"}");//可选-音量 取值范围 0--200request.setVolume(200);//可选-播放次数request.setPlayTimes(2);//可选-外部扩展字段,此ID将在回执消息中带回给调用方request.setOutId(reservationId + ":" + managerPhone);SingleCallByTtsResponse singleCallByTtsResponse = acsClient.getAcsResponse(request);if (singleCallByTtsResponse.getCode() != null && singleCallByTtsResponse.getCode().equals("OK")) {//请求成功log.info("请求成功");} else {log.info("语音呼叫失败,code{}", singleCallByTtsResponse.getCode());if (singleCallByTtsResponse.getCode().equals("isv.BUSINESS_LIMIT_CONTROL")) {log.info("流控限制,3分钟后重试");CallMsgDto callMsgDto = new CallMsgDto();callMsgDto.setManagerPhone(Arrays.asList(managerPhone));callMsgDto.setReservationId(reservationId);callMsgDto.setContactPhone(tailNumber);callMsgDto.setReservationTime(time);reservationMqSender.sendLaunchMsg(callMsgDto, 3 * 60 * 1000L);}}return singleCallByTtsResponse;}/*** 语音文件外呼** @return* @throws ClientException*/public SingleCallByVoiceResponse singleCallByVoice(ClientConfigDto dto) throws ClientException {//可自助调整超时时间System.setProperty("sun.net.client.defaultConnectTimeout", "10000");System.setProperty("sun.net.client.defaultReadTimeout", "10000");//初始化acsClient,暂不支持region化IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", dto.getAccessKeyId(), dto.getAccessKeySecret());DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", dto.getProduct(), dto.getDomain());IAcsClient acsClient = new DefaultAcsClient(profile);//组装请求对象-具体描述见控制台-文档部分内容SingleCallByVoiceRequest request = new SingleCallByVoiceRequest();//必填-被叫显号,可在语音控制台中找到所购买的显号request.setCalledShowNumber("025000000");//必填-被叫号码request.setCalledNumber("15000000000");//必填-语音文件IDrequest.setVoiceCode("3a7c382b-ee87-493f-bfa0-b9fd6f31f8bb.wav");//可选-外部扩展字段request.setOutId("yourOutId");//hint 此处可能会抛出异常,注意catchSingleCallByVoiceResponse singleCallByVoiceResponse = acsClient.getAcsResponse(request);return singleCallByVoiceResponse;}/*** 交互式语音应答** @return* @throws ClientException*/public IvrCallResponse ivrCall(ClientConfigDto dto) throws ClientException {//可自助调整超时时间System.setProperty("sun.net.client.defaultConnectTimeout", "10000");System.setProperty("sun.net.client.defaultReadTimeout", "10000");//初始化acsClient,暂不支持region化IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", dto.getAccessKeyId(), dto.getAccessKeySecret());DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", dto.getProduct(), dto.getDomain());IAcsClient acsClient = new DefaultAcsClient(profile);//组装请求对象-具体描述见控制台-文档部分内容IvrCallRequest request = new IvrCallRequest();//必填-被叫显号,可在语音控制台中找到所购买的显号request.setCalledShowNumber("057156210000");//必填-被叫号码request.setCalledNumber("15000000000");request.setPlayTimes(3L);//必填-语音文件ID或者tts模板的模板号,有参数的模板需要设置模板变量的值//request.setStartCode("ebe3a2b5-c287-42a4-8299-fc40ae79a89f.wav");request.setStartCode("TTS_713900000");request.setStartTtsParams("{\"product\":\"aliyun\",\"code\":\"123\"}");List<IvrCallRequest.MenuKeyMap> menuKeyMaps = new ArrayList<IvrCallRequest.MenuKeyMap>();IvrCallRequest.MenuKeyMap menuKeyMap1 = new IvrCallRequest.MenuKeyMap();menuKeyMap1.setKey("1");menuKeyMap1.setCode("9a9d7222-670f-40b0-a3af.wav");menuKeyMaps.add(menuKeyMap1);IvrCallRequest.MenuKeyMap menuKeyMap2 = new IvrCallRequest.MenuKeyMap();menuKeyMap2.setKey("2");menuKeyMap2.setCode("44e3e577-3d3a-418f-932c.wav");menuKeyMaps.add(menuKeyMap2);IvrCallRequest.MenuKeyMap menuKeyMap3 = new IvrCallRequest.MenuKeyMap();menuKeyMap3.setKey("3");menuKeyMap3.setCode("TTS_71390000");menuKeyMap3.setTtsParams("{\"product\":\"aliyun\",\"code\":\"123\"}");menuKeyMaps.add(menuKeyMap3);request.setMenuKeyMaps(menuKeyMaps);//结束语可以使一个无参模板或者一个语音文件IDrequest.setByeCode("TTS_71400007");//可选-外部扩展字段request.setOutId("yourOutId");//hint 此处可能会抛出异常,注意catchIvrCallResponse ivrCallResponse = acsClient.getAcsResponse(request);return ivrCallResponse;}
}

3.把监听器交给spring管理,服务启动的时候就去监听阿里的回执队列,获取回执消息


package com.meiyuan.reservation;import com.alicom.mns.tools.DefaultAlicomMessagePuller;
import com.alicp.jetcache.anno.config.EnableMethodCache;
import com.meiyuan.marsh.jetcache.anno.config.EnableAdvancedCreateCacheAnnotation;
import com.meiyuan.reservation.dto.call.CallMsgDto;
import com.meiyuan.reservation.dto.call.ClientConfigDto;
import com.meiyuan.reservation.dto.call.ReservationProperties;
import com.meiyuan.reservation.mq.listener.MyMessageListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableAsync;/*** @author admin*/
@SpringBootApplication(scanBasePackages = "com.meiyuan")
@EnableDiscoveryClient
@EnableMethodCache(basePackages = "com.meiyuan")
@EnableAdvancedCreateCacheAnnotation
@EnableFeignClients(basePackages = {"com.meiyuan"})
@EnableConfigurationProperties
@EnableAsync
public class SaasReservationServerApplication {public static void main(String[] args) {SpringApplication.run(SaasReservationServerApplication.class, args);}@Autowiredprivate MyMessageListener messageListener;@Autowiredprivate ReservationProperties reservationProperties;@Beanpublic CallMsgDto listenerBean (ClientConfigDto dto) throws Exception {DefaultAlicomMessagePuller puller = new DefaultAlicomMessagePuller();if (reservationProperties.getReceive().equals("true")) {puller.startReceiveMsg(dto.getAccessKeyId(), dto.getAccessKeySecret(), dto.getMessageType(), dto.getQueueName(), messageListener);}return new CallMsgDto();}
}

4.获取到回执消息后的业务逻辑处理


package com.meiyuan.reservation.mq.listener;import com.alicom.mns.tools.MessageListener;
import com.alicp.jetcache.anno.CreateCache;
import com.aliyun.mns.model.Message;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.google.gson.Gson;
import com.meiyuan.commons.tools.redis.JetcacheNames;
import com.meiyuan.marsh.jetcache.AdvancedCache;
import com.meiyuan.marsh.jetcache.anno.AdvancedCreateCache;
import com.meiyuan.reservation.call.VmsDemo;
import com.meiyuan.reservation.dao.ReservationDao;
import com.meiyuan.reservation.dao.VoiceReportDao;
import com.meiyuan.reservation.dto.call.CallMsgDto;
import com.meiyuan.reservation.dto.call.ClientConfigDto;
import com.meiyuan.reservation.dto.call.ReservationProperties;
import com.meiyuan.reservation.entity.ReservationEntity;
import com.meiyuan.reservation.entity.VoiceReportEntity;
import com.meiyuan.reservation.enums.ResCallStatusEnum;
import com.meiyuan.reservation.enums.TimeEnum;
import com.meiyuan.reservation.mq.sender.ReservationMqSender;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;/*** 功能描述:回执消息监听器** @author tiancheng* @version V1.0.0* @since 2020/12/24 9:30*/
@Slf4j
@Component
public class MyMessageListener implements MessageListener {@AdvancedCreateCache(@CreateCache(name = JetcacheNames.PREFIX_SEQ_RESERVATION))private AdvancedCache cache;@Resourceprivate VoiceReportDao voiceReportDao;@Autowiredprivate ReservationDao reservationDao;@Autowiredprivate ReservationProperties reservationProperties;@Autowiredprivate ReservationMqSender reservationMqSender;private Gson gson = new Gson();@Overridepublic boolean dealMessage(Message message) {//消息的几个关键值log.info("消息接收时间[{}],message handle[{}],body[{}],id[{}],dequeue count[{}]", null, message.getReceiptHandle(),message.getMessageBodyAsString(), message.getMessageId(), message.getDequeueCount());log.info("监听到语音回执消息------------------------------{}", message);try {Map<String, Object> contentMap = gson.fromJson(message.getMessageBodyAsString(), HashMap.class);//依据自己的消息类型,获取对应的字段String callId = (String) contentMap.get("call_id");String startTime = (String) contentMap.get("start_time");String endTime = (String) contentMap.get("end_time");String caller = (String) contentMap.get("caller");String callee = (String) contentMap.get("callee");String duration = (String) contentMap.get("duration");String statusCode = (String) contentMap.get("status_code");String earlyMediaCode = (String) contentMap.get("early_media_code");String hangupDirection = (String) contentMap.get("hangup_direction");String statusMsg = (String) contentMap.get("status_msg");String outId = (String) contentMap.get("out_id");String dtmf = (String) contentMap.get("dtmf");String voiceType = (String) contentMap.get("voice_type");String dialogId = (String) contentMap.get("dialog_id");String tollType = (String) contentMap.get("toll_type");VoiceReportEntity voiceReportEntity = new VoiceReportEntity(IdWorker.getIdStr(), callId, startTime, endTime, caller, callee, duration, statusCode,earlyMediaCode, hangupDirection, statusMsg,outId, dtmf, voiceType, dialogId, tollType);log.info("消息回执的code++++++++{}", statusCode);//业务逻辑//将回执信息存入数据库voiceReportDao.insert(voiceReportEntity);String phoneNumber = voiceReportEntity.getCallee();String[] split = outId.split(":");String reservationId = split[0];String phone = split[1];ReservationEntity reservationEntity = reservationDao.selectById(reservationId);//根据状态码判断下一步处理逻辑//1.未接听,占线,关机(10分钟后重试,重试一次)if (statusCode.equals(ResCallStatusEnum.USER_NOT_ANSWER.getValue()) || statusCode.equals(ResCallStatusEnum.USER_BUSY.getValue())|| statusCode.equals(ResCallStatusEnum.USER_SWITCH_OFF.getValue()) || statusCode.equals(ResCallStatusEnum.USER_NOT_CONNECT.getValue())) {Integer num = (Integer) cache.get(outId);if (num == null || reservationEntity == null) {log.error("消息错误{}", outId);} else if (num <= 1) {cache.set(outId, 2);long millis;if (reservationProperties.getRetry().equals(true)) {millis = TimeEnum.INTERVAL_TIME.getValue();} else {millis = 90 * 1000L;}Date date = reservationEntity.getReservationTime();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String reservationTime = sdf.format(date);CallMsgDto callMsgDto = new CallMsgDto();ArrayList<String> managerPhone = new ArrayList<>();managerPhone.add(phoneNumber);callMsgDto.setManagerPhone(managerPhone);callMsgDto.setReservationId(reservationId);callMsgDto.setContactPhone(reservationEntity.getContactPhone());callMsgDto.setReservationTime(reservationTime);reservationMqSender.sendLaunchMsg(callMsgDto, millis);log.info("用户忙{}", phone);}} else if (statusCode.equals(ResCallStatusEnum.USER_SUCCESS.getValue()) || statusCode.equals(ResCallStatusEnum.USER_HANG_UP.getValue())) {log.info("用户应答{}", phone);} else {log.error("用户无法接通{}", phone);}} catch (com.google.gson.JsonSyntaxException e) {log.error("error_json_format:" + message.getMessageBodyAsString(), e);//理论上不会出现格式错误的情况,所以遇见格式错误的消息,只能先delete,否则重新推送也会一直报错return true;} catch (Throwable e) {//您自己的代码部分导致的异常,应该return false,这样消息不会被delete掉,而会根据策略进行重推log.error("系统内部异常,消息重试");return false;}//消息处理成功,返回true, SDK将调用MNS的delete方法将消息从队列中删除掉return true;}}

JAVA中调用阿里云语音通知Api并接收消息回执相关推荐

  1. 阿里云语音通知API试接入

    阿里云语音通知API试接入 文档地址 1.安装SDK composer require alibabacloud/dyvmsapi-20170525 2.准备工作 在"语音号码"页 ...

  2. 使用java调用阿里云车牌识别API

    实现车牌识别功能我采用调用阿里云车牌识别API的方法,我使用的是eclipse,jdk 1.8,Tomcat 9.0 1.进入阿里云主页先创建阿里云账号 2.在控制台的头像那里找到AccessKey管 ...

  3. 秒懂云通信:如何用阿里云语音通知服务(小白指南)

    简介: 手把手教你如何使用阿里云语音通知服务,超详细控制台步骤解析,快速上手!更有1650元短信体验代金券和免费试用,点击速抢:https://yqh.aliyun.com/live/cloudcom ...

  4. 调用阿里云短信API发送短信通知

    调用阿里云短信API发送短信通知 昨天领导让我弄一个短信通知功能,原来也没有搞过,刚接过来的时候亚历山大,感觉很难搞.但是看过官方文档之后还是挺简单的.来让我们看一下这个短信接口怎么搞吧. 首先你需要 ...

  5. 云健康实名认证_秒懂云通信:如何用阿里云语音通知

    一.如何开通阿里云语音服务? 1.登录阿里云官网,选择产品分类 > 云计算基础 > 云通信 > 语音服务. 2.单击管理控制台. 3.单击立即开通(语音服务开通). 二.开通语音服务 ...

  6. 阿里云语音通知java实现

    1.环境描述 jdk1.8+springboot 2.阿里云短信服务地址 https://dyvms.console.aliyun.com/overview/home 3.已完成企业资质认证 4.添加 ...

  7. java中使用阿里云实现短信推送

    1.注入依赖 <!-- 阿里云实现短信推送 --><dependency><groupId>com.aliyun</groupId><artifa ...

  8. 如何实现调用阿里云三方的api

    我本来是想上传视频了,但是阿里云这个api的收费很魔性.所以我的appcode是无法上传的,本来还想着大家直接把代码运行就可以了.你们只要改下appcode就可以了. 这个其实有免费的服务,自己找下就 ...

  9. 调用阿里云语音转文本

    文章目录 一.accessKeyId和accessKeySecret申请 二.appKey申请 三.调用接口代码 一.accessKeyId和accessKeySecret申请 二.appKey申请 ...

最新文章

  1. 【怎样写代码】参数化类型 -- 泛型(四):泛型之类型参数约束
  2. 【PHPWord】文本输入
  3. 两条曲线所围成的面积_人教版数学六年级上册 5.3:圆的面积(一) 微课视频|知识点|课件解析|同步练习...
  4. Codeforces Round #555 (Div. 3) AB
  5. 静态数组的声明与例子练习
  6. java笔记之抽象类和接口
  7. java开放平台系统,java快速开发平台
  8. 开发中我们谈的产品化是什么?阿里是怎么看待产品化?
  9. postman调试网站API接口提示需要先登录怎么办
  10. eclipse中的ctrl+H使用中的问题
  11. 网站关键词编写方法,注意事项。
  12. pc即时聊天所用表情插件的记录
  13. Oracle获取日期大全(当月的第一天/后一天/上一天/最后一天/上个月这一天)
  14. 公钥加密与PKI实验
  15. EasyNVR H5无插件摄像机直播解决方案前端解析之:videojs的使用
  16. 如何让你的 Python 代码在腾讯云 Linux 中一直运行着
  17. 第二十四章 Caché 变量大全 $ZA 变量
  18. Secure CRT 7.0 通过 SSH服务登录 Vmware 下的Ubuntu 12.04服务器
  19. oracle数据库定时每天自动备份语句,Oracle数据库定时自动备份
  20. css让span标签强制换行

热门文章

  1. 基于QT的多线程视频监控的实现(一)
  2. 计算机vfp二级sql,计算机二级vfp-SQL命令集合.doc
  3. 算法时间计算:logA(N)与O(n)
  4. Java毕设项目电商平台客流统计系统(java+VUE+Mybatis+Maven+Mysql)
  5. 运动解剖测试题软件,2015教师招聘体育学科运动解剖学经典题
  6. Stephen R.Schach《软件工程 面向对象和传统的方法》总结
  7. List.add 方法添加元素时只会添加最后一条元素的问题与解决
  8. 5000词学英语——DAY7
  9. Win11电脑睡眠后无法唤醒
  10. 服务商模式下添加分账接收方