A integração de aplicações web móveis com o ecossistema do WeChat Work (Enterprise WeChat) permite que desenvolvedores acessem funcionalidades nativas do dispositivo, como câmera, geolocalização e manipualção de arquivos, através do JSSDK. Abaixo, detalhamos o processo técnico para configurar e utilizar essa biblioteca em um ambiente Vue.js.
1. Instalação da Dependência
O primeiro passo consiste em adicionar o pacote oficial do SDK ao seu projeto via gerenciador de pacotes:
npm install weixin-js-sdk --save
2. Configuração de Permissões no Frontend
Para utilizar as APIs do WeChat, é necessário realizar uma autenticação prévia via wx.config. Este processo exige parâmetros de segurança gerados pelo servidor (back end). Podemos encapsular essa lógica em uma função utilitária:
import wx from 'weixin-js-sdk';
import axios from 'axios';
export const setupWeChatSDK = async () => {
const targetUrl = window.location.href.split('#')[0];
const apiEndpoint = `${process.env.VUE_APP_API_BASE}/auth/wechat-config`;
try {
const response = await axios.post(apiEndpoint, { url: targetUrl });
const { appId, timestamp, nonceStr, signature } = response.data;
wx.config({
beta: true,
debug: false,
appId: appId,
timestamp: timestamp,
nonceStr: nonceStr,
signature: signature,
jsApiList: [
'chooseImage',
'previewImage',
'uploadImage',
'downloadImage',
'getLocation'
]
});
wx.error((err) => {
console.error('Erro na autenticação JSSDK:', err.errMsg);
});
} catch (error) {
console.error('Falha ao obter parâmetros de configuração:', error);
}
};
3. Geração da Assinatura no Servidor (Java)
O backend é responsável por gerar a assinatura digital (signature) baseada no jsapi_ticket. É fundamental que a URL enviada pelo frontend seja idêntica à utilizada na geração do hash.
public Map<String, String> generateConfigParams(String currentUrl, String corpId, String secret) {
// Recupera o ticket de acesso (deve ser armazenado em cache)
String jsApiTicket = TicketProvider.getTicket(corpId, secret);
String nonce = UUID.randomUUID().toString().replace("-", "");
String timeStamp = Long.toString(System.currentTimeMillis() / 1000);
// Construção da string para o hash SHA-1
String rawString = "jsapi_ticket=" + jsApiTicket +
"&noncestr=" + nonce +
"×tamp=" + timeStamp +
"&url=" + currentUrl;
String signature = "";
try {
MessageDigest digest = MessageDigest.getInstance("SHA-1");
byte[] hash = digest.digest(rawString.getBytes("UTF-8"));
signature = bytesToHex(hash);
} catch (Exception e) {
log.error("Erro ao processar assinatura", e);
}
Map<String, String> config = new HashMap<>();
config.put("appId", corpId);
config.put("timestamp", timeStamp);
config.put("nonceStr", nonce);
config.put("signature", signature);
return config;
}
4. Implementação de Funcionalidades Nativas
Com o SDK configurado, podemos invocar métodos como o chooseImage para selecionar fotos da galeria ou captruar novas imagens com a câmera. No exemplo abaixo, após a seleção, a imagem é enviada para o servidor do WeChat e, posteriormente, para o nosso próprio servidor.
methods: {
handleImageCapture(mode) {
const vm = this;
wx.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: [mode], // 'album' ou 'camera'
success: (res) => {
const localIds = res.localIds;
// Upload para os servidores do WeChat
wx.uploadImage({
localId: localIds[0],
isShowProgressTips: 1,
success: (uploadRes) => {
const serverId = uploadRes.serverId;
// Envia o MediaID para o backend processar o download
this.persistImageToServer(serverId);
}
});
}
});
},
async persistImageToServer(mediaId) {
try {
const response = await this.$http.post('/api/save-wechat-media', { mediaId });
this.processFileResponse(response.data);
} catch (error) {
console.error('Erro ao salvar arquivo no servidor:', error);
}
}
}
Para garantir que o SDK esteja pronto assim que a aplicação carregar, recomenda-se chamar a função de inicialização dentro do ciclo de vida global do Vue, geralmente no App.vue ou em um guarda de rota global, garantindo que o domínio esteja devidamente validado no painel administrativo do WeChat Work.