之前有客户反馈想要石墨文档的接口,但石墨文档的开发平台目前只有服务端接口的配置,接口配置起来比较繁琐,下面我给大家理一下思路,有需要的客户可以跟着我下面的内容开发一下。
石墨文档开发平台地址 https://open.shimo.im/docs/02quick-start/quickly-create-documents
点击右边的齿轮按钮进入到应用信息配置界面,这里面有三个很关键的参数:
分别是App ID、App Secret、回调地址
App ID、App Secret是获取到签名Signature的关键参数,回调地址后续会详细讲解
石墨文档的Signature是通过jwt生成的,下面就用python来生成Signature
pip install PyJWTimport jwt
from datetime import datetime, timedelta
def get_token():
APP_ID = '6520a184f92343f98b18b969e5ccf40f'
APP_Secret = 'xxxxxxxxxxxxxxxxx'
# 获取token
timestamp = int((datetime.now() + timedelta(minutes=4)).timestamp())
headers = {
"alg": "HS256",
"typ": "JWT",
"kid": APP_ID,
}
payload = {
'exp': timestamp,
"scope": "license"
""
}
token = jwt.encode(payload, APP_Secret, algorithm='HS256', headers=headers)
return tokenApp ID、App Secret就是上面石墨提供给你的参数
代码中有一个timestamp参数,它是时间戳,这里有一个需要注意的地方就是石墨文档的签名有效时间是卡的很死的,不能超过当前时间的五分钟,所以代码里面的timestamp就是获取当前时间加四分钟的时间戳。
回调地址是重中之重,根据石墨文档的接口文档,我们是需要给石墨文档提供用户信息和文件信息这个两个接口,这部分需要自己搭建下面我就使用flask来简单的搭建这两个接口
pip install flaskid是指文件的id,文件id是完全由用户自己来定义的,为了避免id的重复,我们可以用uuid来实现。
import uuid
file_id=uuid.uuid1()为了编写的方便,下面我使用的id是当时测试使用的id{f14a0898-3291-11ef-ba2d-b4b5b6e5cabc}
from flask import Flask, request, jsonify
@app.route('/files/<user_id>', methods=['GET'])
def new_file(user_id):
data = {
"id": f"{user_id}",
"name": "第一个协同文档",
"type": "spreadsheet",
"permissions": {
"commentable": True,
"editable": True,
"readable": True,
"copyable": True,
"exportable": True
},
"views": 100,
"creatorId": "1",
"createdAt": "2024-06-25T00:00:00Z",
"updatedAt": "2021-06-25T00:00:00Z",
"teamGuid": "123"
}
return data我们定义了一个/files/<user_id>的路径,其中<user_id>你自己定义的文件id
然后我们根据文档制作一个用户信息的接口
@app.route('/users/current/info', methods=['GET'])
def get_user():
data={
"id": "93831451",
"name": "我丶你",
"avatar": "https://inews.gtimg.com/om_bt/OHyQqgC_5oi4Vm0tlH49XvJzqNBHo2Zryxx5F_be5N2cIAA/1000",
"email": "546312745@qq.com",
"teamGuid": "1"
}
return data其中id是企业人员的id,这个id可以在配置界面的企业管理中找到
name是人员名称,avatar是头像地址,代码块中的地址是我百度上随便找的
# 这部分是解决后续跨域的问题
app.json.ensure_ascii = False
def after_request(response):
response.headers['Access-Control-Allow-Origin'] = '*'
response.headers['Access-Control-Allow-Methods'] = 'PUT,GET,POST,DELETE'
response.headers['Access-Control-Allow-Headers'] = 'Content-Type,Authorization'
return response
app.after_request(after_request)
@app.route('/get_token', methods=['GET'])
def get_token():
APP_ID = '6520a184f92343f98b18b969e5ccf40f'
APP_Secret = 'b14823f6ec7947dfbd21ecd35308d402'
# 获取token
timestamp = int((datetime.now() + timedelta(minutes=4)).timestamp())
headers = {
"alg": "HS256",
"typ": "JWT",
"kid": APP_ID,
}
payload = {
'exp': timestamp,
"scope": "license"
""
}
token = jwt.encode(payload, APP_Secret, algorithm='HS256', headers=headers)
return token定义了三个接口之后,我们直接部署在服务器上
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8787)这里我们定义了8787端口
接下来打开你服务器的控制台,开放8787端口,我这边使用的是腾讯云,就有腾讯云来演示
开放端口之后,直接在浏览器中输入域名加路径,就能访问到数据了
验证完三个接口都能访问到数据之后,再把这个域名地址添加到回调地址中
也可以使用石墨文档提供的开发工具来验证一下接口是否能请求到
https://open.shimo.im/develop-tool
在石墨文档的开发工具中,找到这个接口的调试工具
设置变量值
signature是签名生成的参数,token是你的接口验证的参数,如果你的接口没有验证的话可以随便填。
endpoint_url填服务器的域名地址
再在body中填写
type是协作的文件类型,这里使用表格,也就是spreadsheet来演示,fileID是文件id,自己定义一个id
响应结果是204就说明文件已经创建成功了
接下来使用
这个接口查看一下创建的文件
同理配置signature和token还有endpoint_url
fileID填刚刚创建的id,我这边是xztest-123456
使用实际请求访问网站的时候就能看到刚刚创建的表格了
但是!此时只是预览,表格不能进行任何操作!
石墨文档提供了一个demo来接入协作文档,下面我就来演示一下
按照流程,我们直接访问石墨文档的github,将压缩包下载下来
解压完成之后会看到这么几个文件。
然后使用开发工具打开js
官方下载的原生js按照里面的说明将几个参数填写完成之后是可以直接使用的,但我们稍作改造一下,方便操作
首先,signature这个参数的有效期是很短的,所以我们之前分装了一个获取signature这个参数的接口,现在通过js的请求获取到这个参数
let responseData;
let signature;
#获取接口返回的参数
fetch('http://159.75.66.6:8787/get_token')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
// console.log(response.text(),111111111111111111111)
return response.text();
})
.then(data => {
responseData = data;
const signature = responseData
const token = '1111111'; #根据你自己服务器需要校验的参数填写,因为我开发的时候是没有做参数校验的,所以随意填写
const endpointUrl = 'https://office.shimoapi.com/sdk/v2';
const fileId ='file-import-12345' #之前创建的文件id
// const fileId ='f14a0898-3291-11ef-ba2d-b4b5b6e5cabc'
async function connectSDK() {
console.log('connectSDK')
const sdk = await connect({
fileId: fileId,
endpoint: endpointUrl,
signature: signature,
token: token,
container: document.querySelector('#iframe-container'), // iframe 挂载的目标容器元素id
targetOrigin: '*',
generateUrl: function (params) {
return Promise.resolve(`${myDomain}?sdkparams=${encodeURIComponent(JSON.stringify(params))}`)
},
})
console.log(sdk)
}
connectSDK()
})
js编写完成之后,再打开html文件,就可以操作文件了