将外呼机器人的配置场景通过Iframe方式集成到用户自己的系统上使用。
参考阿里云免登方案。
实践步骤
创建RAM子用户及授权,如子账号已存在,可跳过该步骤
1.1、为RAM用户授权,AliyunSTSAssumeRoleAccess
1.2、创建RAM角色
使用RAM主账号登录控制台,并创建RAM角色。或者通过RAM的API CreateRole创建RAM角色。
1.3、为角色授权
1.4、roleArn参数获取
1.5 pom.xml
<dependencies>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-sts</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.5</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
</dependencies>
1.6、Code Sample
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.auth.sts.AssumeRoleRequest;
import com.aliyuncs.auth.sts.AssumeRoleResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.net.URISyntaxException;
public class Test {
private static final String SIGN_IN_DOMAIN = "http://signin.aliyun.com/federation";
private static String getRoleArn(String accountId, String roleName) {
return String.format("acs:ram::%s:role/%s", accountId, roleName);
}
/**
* 使用安全令牌获取登录令牌
* https://help.aliyun.com/document_detail/91913.html
*
* @param accesskeyId
* @param accessKeySecret
* @param securityToken
* @return
* @throws IOException
* @throws URISyntaxException
*/
private static String getSignInToken(String accesskeyId, String accessKeySecret, String securityToken)
throws IOException, URISyntaxException {
URIBuilder builder = new URIBuilder(SIGN_IN_DOMAIN);
builder.setParameter("Action", "GetSigninToken")
.setParameter("AccessKeyId", accesskeyId)
.setParameter("AccessKeySecret", accessKeySecret)
.setParameter("SecurityToken", securityToken)
.setParameter("TicketType", "mini");
HttpGet request = new HttpGet(builder.build());
CloseableHttpClient httpclient = HttpClients.createDefault();
try (CloseableHttpResponse response = httpclient.execute(request)) {
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String context = EntityUtils.toString(response.getEntity());
JSONObject jsonObject = JSON.parseObject(context);
return jsonObject.getString("SigninToken");
} else {
System.out.println(response.getStatusLine());
}
}
return null;
}
private static String getChatbotLoginUrl(String pageUrl, String signInToken) throws URISyntaxException {
URIBuilder builder = new URIBuilder(SIGN_IN_DOMAIN);
builder.setParameter("Action", "Login");
// 登录失效跳转的地址,一般配置为自建WEB配置302跳转的URL
builder.setParameter("LoginUrl", "https://signin.aliyun.com/login.htm");
// 实际访问Chatbot的页面,比如对话工厂管理页,某个实例详情等
builder.setParameter("Destination", pageUrl);
builder.setParameter("SigninToken", signInToken);
HttpGet request = new HttpGet(builder.build());
return request.getURI().toString();
}
/**
* 通过AssumeRole接口获取用户临时身份
* 参考 https://help.aliyun.com/document_detail/28763.html
*
* @param accountId
* @param accessKeyId
* @param accessKeySecret
* @param ramRole
* @return
* @throws ClientException
*/
private static AssumeRoleResponse.Credentials assumeRole(String accountId, String accessKeyId,
String accessKeySecret, String ramRole)
throws ClientException {
String defaultRegion = "cn-hangzhou";
IClientProfile profile = DefaultProfile.getProfile(defaultRegion, accessKeyId, accessKeySecret);
DefaultAcsClient client = new DefaultAcsClient(profile);
AssumeRoleRequest request = new AssumeRoleRequest();
// 设置RAMArn, accountId为资源Owner的UID,即主账号
request.setRoleArn(getRoleArn(accountId, ramRole));
// 用户自定义参数。此参数用来区分不同的令牌,可用于用户级别的访问审计。格式:^[a-zA-Z0-9\.@\-_]+$
request.setRoleSessionName("session-name");
// 指定的过期时间,单位为秒。过期时间范围:900 ~ 3600,默认值为 3600
request.setDurationSeconds(3600L);
AssumeRoleResponse response = client.getAcsResponse(request);
return response.getCredentials();
}
public static void main(String[] args) throws IOException, URISyntaxException {
try {
/*
* Step 0 准备子账号和权限授权
*/
//* accountId指主账号ID
String accountId = "xxxx";
// 用来访问对话机器人产品的Role,可以按照需要添加AliyunOutboundbotFullAccess 权限
// 当前ramRole为示例值,请使用真实值替代
String ramRole = "xxxx";
// 某个子账号AK,SK, 要求需要有 AliyunSTSAssumeRoleAccess 权限
// 当前accessKeyId、accessKeySecret为示例值,请使用真实值替代
String accessKeyId = "按需替换";
String accessKeySecret = "按需替换";
/*
* Step 1 通过AssumeRole接口获取临时AK, SK, SecurityToken
*/
AssumeRoleResponse.Credentials credentials = assumeRole(accountId, accessKeyId, accessKeySecret, ramRole);
System.out.println("Expiration: " + credentials.getExpiration());
System.out.println("Access Key Id: " + credentials.getAccessKeyId());
System.out.println("Access Key Secret: " + credentials.getAccessKeySecret());
System.out.println("Security Token: " + credentials.getSecurityToken());
/*
* Step 2 获取SigninToken
*/
String signInToken = getSignInToken(credentials.getAccessKeyId(),
credentials.getAccessKeySecret(),
credentials.getSecurityToken());
System.out.println("Your SigninToken is: " + signInToken);
/*
* Step 4 构造免登录链接,https://outboundbot4service.console.aliyun.com是智能外呼虚商免登控制台地址
*/
String pageUrl = "https://outboundbot4service.console.aliyun.com/#/outboundbot_script?instanceId=按需替换&nluServiceType=DialogStudio";
String accessUrl = getChatbotLoginUrl(pageUrl, signInToken);
System.out.println("Your PageUrl is : " + accessUrl);
} catch (ClientException e) {
System.out.println("Failed:");
System.out.println("Error code: " + e.getErrCode());
System.out.println("Error message: " + e.getErrMsg());
System.out.println("RequestId: " + e.getRequestId());
}
}
}
Step4中注意几点:
• instanceId的值需要按需替换。
1.7 前端集成
1. 上述生成的链接可直接在浏览器中打开使用
2. 若需将链接以iframe的形式嵌入业务系统,请开放iframe以下两个配置
allow="microphone *" allowfullscreen
注:iframe嵌套时,外呼系统在请求接口时,发现用户登录过期,会通过postMessage向主应用发送消息,主应用可根据自己的需求进行刷新页面处理或者跳转登录页面处理。
示例代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Iframe Test</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<script>
// 外呼页面调用接口返回登录cookie失效会给父页面postmessage,父页面接受自己处理即可
function handleMessage(e) {
// 只接受外呼预发和线上域名,按需加,实际可去除预发域名
if (!['https://outboundbot4service.console.aliyun.com'].includes(e.origin)) {
return;
}
// e.data = {code: 'ConsoleNeedLogin', message: '登录超时,请重新登录'}
if (e.data && e.data.code === 'ConsoleNeedLogin') {
// todo 页面跳转登录或者刷新主站页面
}
}
window.addEventListener('message', handleMessage);
</script>
</head>
<body>
<iframe src="http://signin.aliyun.com/federation?Action=Login&LoginUrl=https%3A%2F%2Fsignin.aliyun.com%2Flogin.htm&Destination=http%3A%2F%2Foutboundbot4service.console.aliyun.com%2F%23%2Foutboundbot_script%3FinstanceId%3D2a10e7f2-8f13-4a99-9f57-fea3b0f9c6f8%26nluServiceType%3DDialogStudio&SigninToken=svX6LAkjGGjnQTYHFNh2tdAMRoNeseZyFMuVWpZpceayC3wSTpvPidzMqcSpDxsUtwZCSUwEVNvJQpTuoozLV3R9BRyscrJQWedCxuguTRTrFBqvLFrVMkTD2ouWFb6KEJGS7vHbCUH5TkA6Y4LRa7Lyjsyz614LrpBkdkudWDZ4rGbXriQbyhCTJVn5LhXGwvyDprNcAPFAybfUzMLtQPgFtEhji9bU" width="100%" style="height: calc(100vh);" allow="microphone *" allowfullscreen></iframe>
</body>
</html>
文档内容是否对您有帮助?