我是前端視角來寫的,不包含后端內(nèi)容哈~
前言
最近剛好遇到了這么個(gè)任務(wù)
需要我在企業(yè)微信中內(nèi)嵌一個(gè)自建應(yīng)用,
用于打通跟我們醫(yī)院后臺(tái)系統(tǒng)的數(shù)據(jù)對(duì)接。
這樣就可以直接讓客服們?cè)谄髽I(yè)微信上點(diǎn)擊右邊頁(yè)面操作后臺(tái)的數(shù)據(jù)了。
這可是給我踩了好多坑。畢竟從來沒有做過企業(yè)微信的開發(fā),有點(diǎn)懵。
也是踩了好多坑后,這里寫一個(gè)帖子匯總一下我經(jīng)歷的全流程開發(fā)
當(dāng)然這是基礎(chǔ)的流程啊。因?yàn)槲业墓δ芤笠膊皇呛芨?。后面如果開發(fā)更多的東西再補(bǔ)充
效果圖
這是聊天時(shí)右邊的頁(yè)面,那個(gè)客戶管理就是我加的自建應(yīng)用
企業(yè)微信開發(fā)如何調(diào)試
在企業(yè)微信開發(fā)者中心點(diǎn)擊附錄,常見問題,滾動(dòng)到下面客戶端調(diào)試,按照要求弄就可以開啟調(diào)試了
開發(fā)者中心
簡(jiǎn)單說一下:下載文件放到企業(yè)微信文件夾內(nèi),然后重啟企微,然后打開按ctrl + alt + shift + D,會(huì)出現(xiàn)這樣的頁(yè)面,代表開啟成功
然后再右邊的頁(yè)面右鍵,會(huì)看到一個(gè)英文的這個(gè)showdevtools,就是調(diào)試臺(tái)了,點(diǎn)擊
然后就會(huì)彈出一個(gè)窗口,可以正常調(diào)試了。
遇見的問題:
報(bào)錯(cuò) wx.invoke is not a function。
解決辦法:頁(yè)面調(diào)試必須在企業(yè)微信上調(diào)試,其他在微信開發(fā)者工具或者直接網(wǎng)頁(yè)調(diào)試都是會(huì)報(bào)這個(gè)錯(cuò)誤的。
報(bào)錯(cuò):no permission
解決辦法:這就是你沒有注入,調(diào)用方法就會(huì)報(bào)錯(cuò),先注入agentConfig才可以。
流程說明:
1,如果你需要獲取到自己也就是登錄這個(gè)微信的用戶信息,那么你需要先授權(quán),然后拿到授權(quán)鏈接上返回給你的code參數(shù),傳給后端接口,后端也會(huì)調(diào)用企業(yè)微信的api拿到用戶信息再返給前端。
2,如果只是需要拿到客戶的userid或者某些簡(jiǎn)單的api不涉及隱私的。一般是可以不需要授權(quán)的。直接agentConfig注入了就可以用了。
開發(fā)流程
1,登錄企業(yè)微信官網(wǎng),然后點(diǎn)擊企業(yè)登錄按鈕,用企業(yè)微信掃碼登錄(前提:你這個(gè)微信要是管理員,不然沒有權(quán)限登錄),然后點(diǎn)擊應(yīng)用管理,在下面自建的地方點(diǎn)擊創(chuàng)建應(yīng)用
2,然后輸入名稱和頭像創(chuàng)建,選擇可見范圍就是你選了誰(shuí)誰(shuí)就可以看見這個(gè)應(yīng)用
3,創(chuàng)建完畢后你自建的這里就會(huì)多一個(gè)應(yīng)用。
4,點(diǎn)擊進(jìn)去開始設(shè)置主頁(yè)的網(wǎng)址,點(diǎn)擊這個(gè)設(shè)置就可以進(jìn)去輸入網(wǎng)址了,你是小程序就去關(guān)聯(lián)小程序,是H5就直接填個(gè)網(wǎng)址就行。這個(gè)網(wǎng)址就是你要展示的頁(yè)面。你可以先去創(chuàng)建頁(yè)面放到服務(wù)器上再來添加。
5,還是這個(gè)頁(yè)面滾動(dòng)到下方,設(shè)置你的接口白名單,按照他的要求來填寫就行。這個(gè)接口就是你前端和后端請(qǐng)求的那個(gè)域名。不備案的話是不能請(qǐng)求的。
6,好了,然后接下來我們就可以去添加到聊天的右邊欄了。
注意:這里右邊欄是只有你跟外部客戶聊天才有的,你跟本企業(yè)的人或者自己發(fā)信息的時(shí)候窗口是沒有右邊欄的。也就是說你需要讓一個(gè)不是你們公司的人企業(yè)微信加你一下,然后聊天就會(huì)有這個(gè)側(cè)邊欄了。
繼續(xù)介紹流程:
在你的右邊欄有一個(gè)自定義按鈕,點(diǎn)擊后選擇添加頁(yè)面
然后選中你剛才創(chuàng)建的應(yīng)用,去添加就行了。前提你得有頁(yè)面啊,如果你設(shè)置的主頁(yè)地址沒有頁(yè)面,是沒有的
然后你就可以點(diǎn)擊進(jìn)入頁(yè)面了。后續(xù)的操作就是在頁(yè)面里面了
7,頁(yè)面代碼:我發(fā)一個(gè)頁(yè)面的代碼,可以參考流程,我都注釋了,應(yīng)該看得懂的。
注意:引入這兩個(gè)js,不引入不能使用注入和企業(yè)微信的api
<script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
完整代碼
幾個(gè)注意點(diǎn):
注入agentConfig時(shí):所有參數(shù)可以都后端給,也可以簽名三個(gè)后端傳,corpid和agentid前端自己寫。這兩個(gè)id在哪找下面我會(huì)說
授權(quán):授權(quán)是前端寫就可以,不需要后端。直接按填寫id和跳轉(zhuǎn)網(wǎng)址就可以了。appid就是corpid。
客戶的userid:也是前端拿到的,注入后直接調(diào)用api就可以拿到了,傳給后端,后端根據(jù)這個(gè)userid可以拿到客戶的信息
jsApiList:注入時(shí)這個(gè)參數(shù)就是填寫你需要用到的企業(yè)微信的api名稱,不是后端的接口啊注意
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- 移動(dòng)端縮放 -->
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="viewport"
content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0" />
<meta name="format-detection" content="telephone=no,email=no,date=no,address=no">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<!-- vue方面文件 -->
<script src="/statics/vue_element/vue.js"></script>
<script src="/statics/vue_element/element.js"></script>
<link rel="stylesheet" href="/statics/vue_element/element.css">
<script src="/statics/vue_element/axios.js"></script>
<!-- 企業(yè)微信部分 -->
<script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
<title>話術(shù)庫(kù)</title>
</head>
<body>
<div id="app">
<div style="display:flex;">
<div style="width:35vw;overflow: hidden;border-right:1px solid #ccc;">
<el-tree :data="treeData" :props="defaultProps" @node-click="handleNodeClick" accordion></el-tree>
</div>
<div style="flex:1;margin-left: 5px;overflow-y: auto;" class="treelist">
<div style="font-size:14px;border-bottom:1px solid #ccc;padding:5px 0;" @click="setContent(item)"
v-for="(item,index) in content" :key="index">{{item.content}}</div>
</div>
</div>
</div>
</body>
<script type="text/javascript">
new Vue({
el: '#app',
data() {
return {
content: [], //內(nèi)容列表
treeData: [], //tree菜單列表
// tree字段設(shè)置
defaultProps: {
children: 'child',
label: 'name'
},
qwInfoCode: '' //授權(quán)拿到的code
}
},
mounted() {
let that = this
that.getTreeList() //獲取tree分類列表
let userinfo = sessionStorage.getItem('kfInfo')
// 授權(quán)過不再重復(fù)授權(quán)
if (userinfo) {
that.setConfig() //注入
console.log('已授權(quán)!');
} else {
location.href='https://zy.xxxx.cn/model/qiwe/login.html' //跳到授權(quán)頁(yè)
}
},
methods: {
// 獲取tree列表
getTreeList() {
axios.get(`/api/zhjk_speech_class?hospital_id=121&channel=16`, {}).then(res => {
this.treeData = res.data.data
}).catch(error => {
console.log(error, '請(qǐng)求失敗');
})
},
// 點(diǎn)擊tree拿到對(duì)應(yīng)話術(shù)庫(kù)數(shù)據(jù)
handleNodeClick(e) {
axios.get(`/api/zhjk_speech_class_data?hospital_id=121&channel=16&class_id=${e.id}`, {}).then(
res => {
this.content = res.data.data
}).catch(error => {
console.log(error, '請(qǐng)求失敗');
})
},
// 快捷回復(fù):把點(diǎn)擊的文本內(nèi)容添加到聊天框
setContent(item) {
let that = this
wx.invoke('sendChatMessage', {
msgtype: "text", //消息類型,必填
enterChat: true, //為true時(shí)表示發(fā)送完成之后順便進(jìn)入會(huì)話,僅移動(dòng)端3.1.10及以上版本支持該字段
text: {
content: item.content, //文本內(nèi)容
},
}, function (res) {
if (res.err_msg ==
'sendChatMessage:ok') {
//發(fā)送成功
}
})
},
// 獲取客戶信息
getYhUserId() {
// 獲取外部人員userid
wx.invoke('getCurExternalContact', {}, function (res) {
if (res.err_msg == "getCurExternalContact:ok") {
console.log(res.userId, '外部人員userid');
axios.post(
'/work/KwWecom/getWeWorkUserId', {
userid: res.userId
}
).then(
res => {
console.log(res, '外部人員信息');
}).catch(error => {
console.log(error, '請(qǐng)求失敗');
})
} else {
//錯(cuò)誤處理
}
});
},
// 注入應(yīng)用權(quán)限
setConfig() {
let that = this
// 后端生成簽名
axios.post('/work/KwWecom/index', {
url: "https://zy.xxxx.cn/model/qiwe/kjhf.html"
}).then(res => {
let data = res.data.data
// 注入應(yīng)用權(quán)限
wx.agentConfig({
corpid: 'ww9123021d144c9172', // 必填,企業(yè)微信的corpid,必須與當(dāng)前登錄的企業(yè)一致
agentid: '1000124', // 必填,企業(yè)微信的應(yīng)用id
timestamp: data.timestamp, // 必填,生成簽名的時(shí)間戳,后端返回
nonceStr: data.nonceStr, // 必填,生成簽名的隨機(jī)串,后端返回
signature: data.signature, // 必填,簽名,見附錄-JS-SDK使用權(quán)限簽名算法,后端返回
jsApiList: ['sendChatMessage',
'getCurExternalContact'
], //必填,傳入需要使用的接口名稱,名稱就是企業(yè)微信文檔中的那些api的名字
// 成功
success: function (res) {
console.log('注入應(yīng)用權(quán)限成功');
},
// 失敗
fail: function (res) {
console.log('注入應(yīng)用權(quán)限失敗', res);
if (res.errMsg.indexOf('function not exist') > -1) {
alert('版本過低請(qǐng)升級(jí)')
}
}
});
}).catch(error => {
console.log('請(qǐng)求失敗', error);
})
},
}
})
</script>
<style scoped>
/* tree組件子級(jí)樣式 */
.el-tree-node__content {
padding: 0 !important;
}
.treelist {
height: calc(100vh - 20px);
}
</style>
</html>
授權(quán)需要跳轉(zhuǎn)到新的頁(yè)面,在新的頁(yè)面授權(quán),然后code處理數(shù)據(jù)之后跳回來主頁(yè)面注入,不能授權(quán)和注入放在一個(gè)頁(yè)面,授權(quán)也跳主頁(yè)面授權(quán),那樣會(huì)一直注入失敗的。我也沒找到原因,反正就是要分開來就可以。
授權(quán)代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- 移動(dòng)端縮放 -->
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="viewport"
content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0" />
<meta name="format-detection" content="telephone=no,email=no,date=no,address=no">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<!-- vue方面文件 -->
<script src="/statics/vue_element/vue.js"></script>
<script src="/statics/vue_element/element.js"></script>
<link rel="stylesheet" href="/statics/vue_element/element.css">
<script src="/statics/vue_element/axios.js"></script>
<!-- 企業(yè)微信部分 -->
<script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
<title>授權(quán)</title>
</head>
<body>
<div id="app">
正在授權(quán)中。。。
</div>
</body>
<script type="text/javascript">
new Vue({
el: '#app',
data() {
return {
qwInfoCode: '' //code
}
},
mounted() {
let that = this
// 是否有授權(quán)
if (that.getCode()) {
that.getKfUserId() //獲取用戶信息
} else {
that.oauth() //授權(quán)
}
},
methods: {
// 授權(quán)
oauth() {
location.href =
"https://open.weixin.qq.com/connect/oauth2/authorize?appid=ww9112321d144c9172&redirect_uri=https://zy.xxxx.cn/model/qiwe/login.html&response_type=code&scope=snsapi_base&state=STATE&agentid=1000124#wechat_redirect"
},
// 獲取url后參數(shù)code
getCode() {
let that = this
// 獲取code參數(shù)
var url = decodeURI(decodeURI(location.search));
var theRequest = new Object();
if (url.indexOf("?") != -1) {
var str = url.substr(1);
strs = str.split("&");
for (var i = 0; i < strs.length; i++) {
theRequest[strs[i].split("=")[0]] = unescape(strs[i]
.split("=")[1]);
}
}
that.qwInfoCode = theRequest.code //保存code
return theRequest.code
},
// 獲取用戶信息
getKfUserId() {
// code傳給后端并獲取客服的信息
axios.post(
'/work/KwWecom/getWeWorkUserId', {
code: this.qwInfoCode
}
).then(
res => {
sessionStorage.setItem('kfInfo', res.data.data) //用戶信息保存
location.href = 'https://zy.xxxx.cn/model/qiwe/kjhf.html'//跳轉(zhuǎn)到主頁(yè)
}).catch(error => {
console.log(error, '請(qǐng)求失敗');
})
},
}
})
</script>
<style scoped>
</style>
</html>
corpid和agentid在哪里看
corpid就是企業(yè)id,在企業(yè)微信后臺(tái)–我的企業(yè)–企業(yè)信息
agentid:在應(yīng)用管理,點(diǎn)擊你自建的應(yīng)用進(jìn)去,這里就是agentid
2023/4/18 更新踩坑
最新踩的坑,記錄一下:
1,頁(yè)面?zhèn)鲄?,方法:在企業(yè)微信后臺(tái),點(diǎn)擊你創(chuàng)建的自建應(yīng)用,然后再里面點(diǎn)擊配置到聊天工具欄,在里面設(shè)置你的頁(yè)面地址,然后地址后面添加參數(shù)就行。直接在應(yīng)用主頁(yè)的地址后面加參數(shù)是拿不到的。
2,我遇到一直報(bào)錯(cuò):invalid signature more info at https://open.work.weixin.qq.com/devtool/query?e=40093。一直報(bào)的這個(gè),我差了說是簽名錯(cuò)誤。后來找了很久終于找到了原因。
是因?yàn)槲矣胕frame嵌套的頁(yè)面,我在頁(yè)面中注入的,而注入的時(shí)候會(huì)傳一個(gè)當(dāng)前頁(yè)面的url給后端,后端拿來生成一個(gè)signature簽名,由于我是授權(quán)之類的跳轉(zhuǎn)和主頁(yè)進(jìn)去參數(shù)都是跳的首頁(yè)。不是嵌套的頁(yè)面。
導(dǎo)致嵌套的頁(yè)面中當(dāng)前地址拿不到后面的url附帶的參數(shù)。所以生成的簽名是錯(cuò)誤的。后面我把注入放到了最外面的主頁(yè)內(nèi)直接注入,然后所有子頁(yè)面調(diào)用父頁(yè)面的wx來執(zhí)行方法就可以了。
這里后端注意:有個(gè)坑!!我發(fā)的網(wǎng)址帶了參數(shù)過去,后端拿著個(gè)生成簽名,需要注意去除后面參數(shù)的轉(zhuǎn)譯。我們找到報(bào)錯(cuò)的問題其中之一就是后端拿到帶有參數(shù)的url后,后面的參數(shù)轉(zhuǎn)譯了,然后拿著轉(zhuǎn)譯的url去生成簽名,導(dǎo)致一直失敗,可以后端打印一下就行。
3,發(fā)送信息電腦中是點(diǎn)擊后,直接插入到輸入框的,點(diǎn)擊發(fā)送在發(fā)送。移動(dòng)端企業(yè)微信上點(diǎn)擊后是跳出來一個(gè)彈框,問你是不是發(fā)送,發(fā)送點(diǎn)擊后直接就發(fā)出去了。不會(huì)插入到輸入框。發(fā)現(xiàn)企微自帶的快捷回復(fù)移動(dòng)端是可以插入輸入框的,經(jīng)過搜索,這個(gè)功能是內(nèi)部api。不對(duì)外開放,所以沒有。
發(fā)送消息到客戶朋友圈功能
用js-sdk這個(gè)api
注意:用的時(shí)候先要注入成功才行。然后使用這個(gè)。里面和發(fā)消息一樣,分為文字和圖片視頻鏈接地址之類的。需要什么用什么。
使用范圍:只有手機(jī)可以使用,電腦端的企業(yè)微信不生效。
點(diǎn)擊發(fā)送后會(huì)發(fā)送到自己的企業(yè)微信朋友圈里,所有你的客戶都可以在自己的私人微信中看到你發(fā)的朋友圈。
這里注意一點(diǎn):你添加的客戶必須是微信客戶。如果是企業(yè)微信的客戶。那是發(fā)送不了的,會(huì)顯示當(dāng)前沒有可發(fā)送的客戶。我當(dāng)時(shí)測(cè)試的時(shí)候加了個(gè)企業(yè)微信的客戶測(cè)試的。一直發(fā)不了。
看后綴名就行了。綠色的才是微信客戶,黃色的是企業(yè)微信的客戶。
2023-5-9更新:分享小程序到聊天框發(fā)給別人功能步驟
1,首先你需要去企業(yè)微信的后臺(tái)找到你的自建應(yīng)用
2,在這里設(shè)置管理小程序
3,然后去頁(yè)面內(nèi)調(diào)用企微的api發(fā)送
就是這個(gè)api,我這里用的是文檔里面的例子。然后發(fā)送就可以發(fā)送出去了。文章來源:http://www.zghlxwxcb.cn/news/detail-679091.html
wx.invoke('sendChatMessage', {
msgtype:"miniprogram", //消息類型,必填
enterChat: true, //為true時(shí)表示發(fā)送完成之后順便進(jìn)入會(huì)話,僅移動(dòng)端3.1.10及以上版本支持該字段
miniprogram:
{
appid: "wx8bd80126147df384",//小程序的appid,企業(yè)已關(guān)聯(lián)的任一個(gè)小程序
title: "this is title", //小程序消息的title
imgUrl:"https://search-operate.cdn.bcebos.com/d054b8892a7ab572cb296d62ec7f97b6.png",//小程序消息的封面圖。必須帶http或者h(yuǎn)ttps協(xié)議頭,否則報(bào)錯(cuò) $apiName$:fail invalid imgUrl
page:"/index/page.html", //小程序消息打開后的路徑,注意要以.html作為后綴,否則在微信端打開會(huì)提示找不到頁(yè)面
},
}, function(res) {
if (res.err_msg == 'sendChatMessage:ok') {
//發(fā)送成功
}
})
報(bào)錯(cuò)情況:
這種報(bào)錯(cuò)就是代表你發(fā)送的小程序并沒有被你綁定授權(quán)。也就是上面的關(guān)聯(lián)小程序你沒有做才會(huì)報(bào)這個(gè)錯(cuò)。文章來源地址http://www.zghlxwxcb.cn/news/detail-679091.html
到了這里,關(guān)于【企業(yè)微信開發(fā)流程前端篇】企業(yè)微信自建應(yīng)用開發(fā)流程詳細(xì)介紹,js-sdk獲取用戶信息,快捷回復(fù),授權(quán),發(fā)送朋友圈功能實(shí)現(xiàn)【一次看懂,簡(jiǎn)單開發(fā)】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!