Teambition企业内部应用Python开发指南

注意:此文章并非搬运,一小部分仅为借鉴。

Teambition提供了API接口,我们可以注册成为开发者,然后通过接口获取Teambition的数据,按照需求的格式保存和分析.

一、准备阶段

1.登录Teambition企业账号,要有管理员的权限,点击左上角的菜单按钮,然后点击进入企业的“全部应用”.最后点击“应用商店”





2.点击“开放平台”,此页面有后期需用的API文档,可以先收藏。点击“立即创建”



3.创建企业内部应用:填写名称和描述

4.打开应用凭证和基本信息,获取ID和Secret(F12在代码中可以直接复制)



5.打开左侧栏中的“应用开发”--“应用权限”,根据需要勾选

6.打开“应用发布”,填写信息,发布。

二、Python脚本编写

1.找到对应的jwt包,https://jwt.io/libraries,下载安装(推荐PyJWT:至少我用没有问题)

2.appAccessToken的获取(最重要的一步)

  • 因为文档中没有Python实现的任何描述,这里只提供个人写法
  1. from datetime import datetime, timedelta
  2. import jwt
  3. import requests
  4. import time
  5. from Config import getConfig
  6. class GetTeamBitionEvents(object):
  7. def __init__(self):
  8. self.app_id = getConfig('config', 'Get_TB_Data', 'app_id')
  9. self.app_secret = getConfig('config', 'Get_TB_Data', 'app_secret')
  10. def get_aptoken(self):
  11. now_time = int(time.time())
  12. expire_time = now_time + 36000 # 1 小时后超时
  13. token_dict = {'iat': now_time,
  14. '_appId': '%s' % self.app_id,
  15. 'exp': expire_time,
  16. }
  17. headers = {
  18. 'typ': 'jwt',
  19. 'alg': 'HS256'
  20. # 声明所使用的算法
  21. }
  22. encoded = jwt.encode(payload=token_dict, key=self.app_secret, headers=headers,
  23. algorithm='HS256') # .decode('ascii')
  24. return encoded
  • 个人习惯将固定的重要数据存放在config文件中,你也可以直接写入字符串

3.获取Token后就可以开始调用API了,我这里将“创建项目任务类型”作为示例

  • 文档链接:开放平台文档中心 (teambition.com)
  • 主要看六点
    • URL:https://open.teambition.com/api/v3/sfc/create
    • Method:POST
    • 权限:tb-core:sfc:create
    • 请求头
    • 查询参数
    • 请求体
  • 有了这些信息,就可以直接上代码了
  1. from __future__ import absolute_import, unicode_literals
  2. import requests, time, jwt
  3. class GetTeamBitionEvents(object):
  4. def __init__(self):
  5. self.app_id = '' # 必填
  6. self.app_secret = '' # 必填
  7. self.company_url = 'https://www.teambition.com/organization/' # 固定
  8. self.company_id = '' # 一些API会用到公司ID
  9. self.callback_url = self.company_url + self.company_id # 固定
  10. self.user_id='' # 一些API会用到个人ID
  11. self.auth_url = 'https://account.teambition.com/oauth2/authorize?client_id=' + self.app_id + '&redirect_uri=' + self.callback_url # 固定
  12. def get_aptoken(self):
  13. now_time = int(time.time())
  14. expire_time = now_time + 36000 # 1 小时后超时
  15. token_dict = {'iat': now_time,
  16. '_appId': '%s' % self.app_id,
  17. 'exp': expire_time,
  18. }
  19. headers = {
  20. 'typ': 'jwt',
  21. 'alg': 'HS256'
  22. # 声明所使用的算法
  23. }
  24. encoded = jwt.encode(payload=token_dict, key=self.app_secret, headers=headers,
  25. algorithm='HS256') # .decode('ascii')
  26. return encoded
  27. def post_proj_type(self,params,object):
  28. url = f'https://open.teambition.com/api/v3/sfc/create'
  29. app_token = (self.get_aptoken()).replace("\n", "").replace('\r', '')
  30. headers = {
  31. 'Authorization': 'Bearer %s' % app_token,
  32. 'X-Tenant-Id': '%s' % self.company_id,
  33. 'X-Tenant-Type': 'organization',
  34. 'X-Operator-Id': self.user_id
  35. }
  36. return requests.post(url,json=object,params=params, headers=headers)
  37. if __name__ == '__main__':
  38. tb = GetTeamBitionEvents()
  39. projectId=tb.company_id #测试企业-项目管理副本
  40. roleId=tb.user_id # 测试角色
  41. object={
  42. 'name':'测试类型'
  43. }
  44. params={
  45. 'projectId':projectId
  46. }
  47. result = tb.post_proj_type(params,object)
  48. print(result.json()["result"])
  • 其中params为查询参数,json为请求体。根据具体API要求

    • 'params'和'object'中参数用,分隔
    • requests的方法有get/post/del/put根据需要使用
    • 参数后有勾选必填的,必须要有,不然会报错
  • 记得打开相应权限

三、一些辅助脚本

Config.py

  1. import configparser
  2. import os
  3. # 读取配置文件
  4. def getConfig(filename, section, option):
  5. """
  6. :param filename 文件名称
  7. :param section: 服务
  8. :param option: 配置参数
  9. :return:返回配置信息
  10. """# 获取当前目录路径
  11. proDir = os.path.split(os.path.realpath(__file__))[0]
  12. # print(proDir)
  13. # 拼接路径获取完整路径
  14. configPath = os.path.join(proDir, filename)
  15. # print(configPath)
  16. # 创建ConfigParser对象
  17. conf = configparser.ConfigParser()
  18. # 读取文件内容
  19. conf.read(configPath)
  20. config = conf.get(section, option)
  21. return config

config文件格式

  1. [Get_TB_Data]
  2. app_id=XXXXXXXX
  3. app_secret=XXXXXXXX
  • 中括号内为Section,条目为option

其他

这方面可以自己拓展

我个人是写了专门的:数据筛选脚本(根据条件),数据处理脚本(生成json,txt,csv,将国际时间转为北京时间),邮件发送脚本

主要是我自己懒得把代码搬上来了,因为逻辑全是连在一起的,不太好动。如果有需求,可以发送评论,如果方便,我会找机会放上来。

如果追求搜索任务时的自由度的话,可以尝试在历史版本中的TQL查询:https://open.teambition.com/docs/apis/6321c6d4912d20d3b5a4b0b0

四、一些问题

Teambition的维护并不好,文档和API中有许多错漏,我已经在10月13向阿里的相关开发者提交了一下报告,不知道何时能修好。这报告也不全面,是后面才想起来写的。仅供参考。

服务器问题(大概)

企业

获取企业信息(X)
  1. from __future__ import absolute_import, unicode_literals
  2. import requests, time, jwt
  3. class GetTeamBitionEvents(object):
  4. def __init__(self):
  5. self.app_id = 'XXXXXXXXXXXXXXXXXXX'
  6. self.app_secret = 'XXXXXXXXXXXXXXXXXXX'
  7. self.company_url = 'https://www.teambition.com/organization/'
  8. self.company_id = 'XXXXXXXXXXXXXXXXXXX'
  9. self.callback_url = self.company_url + self.company_id
  10. self.user_code = ''
  11. self.auth_url = 'https://account.teambition.com/oauth2/authorize?client_id=' + self.app_id + '&redirect_uri=' + self.callback_url
  12. def get_aptoken(self):
  13. now_time = int(time.time())
  14. expire_time = now_time + 36000 # 1 小时后超时
  15. token_dict = {'iat': now_time,
  16. '_appId': '%s' % self.app_id,
  17. 'exp': expire_time,
  18. }
  19. headers = {
  20. 'typ': 'jwt',
  21. 'alg': 'HS256'
  22. # 声明所使用的算法
  23. }
  24. encoded = jwt.encode(payload=token_dict, key=self.app_secret, headers=headers,
  25. algorithm='HS256') # .decode('ascii')
  26. return encoded
  27. def post_userapp_visible(self):
  28. url = 'https://open.teambition.com/api/org/info'
  29. app_token = (self.get_aptoken()).replace("\n", "").replace('\r', '')
  30. headers = {
  31. "Authorization": 'Bearer %s' % app_token,
  32. }
  33. params = {
  34. "orgId": '%s' % self.company_id
  35. }
  36. return requests.get(url, params=params, headers=headers)
  37. if __name__ == '__main__':
  38. tb = GetTeamBitionEvents()
  39. result = tb.post_userapp_visible()
  40. print(result.json())
  41. print(result.json()["result"])

有问题

  1. {'code': 403, 'errorMessage': 'Forbidden: authbase.Verify failed: Forbidden: no permission to access resource, appID(6332aa802cd25c2c2880e56b) serviceID(5d4ce50b900cea004806c15a) tenant() resource(organization) action(1)', 'result': None}
  2. None

任务

更新自由任务标题(X)
  1. from __future__ import absolute_import, unicode_literals
  2. import requests, time, jwt
  3. class GetTeamBitionEvents(object):
  4. def __init__(self):
  5. self.app_id = 'XXXXXXXXXXXXXXXXXXX'
  6. self.app_secret = 'XXXXXXXXXXXXXXXXXXX'
  7. self.company_url = 'https://www.teambition.com/organization/'
  8. self.company_id = 'XXXXXXXXXXXXXXXXXXX' # 测试用公司
  9. self.callback_url = self.company_url + self.company_id
  10. self.user_id='XXXXXXXXXXXXXXXXXXX'
  11. self.user_code = ''
  12. self.auth_url = 'https://account.teambition.com/oauth2/authorize?client_id=' + self.app_id + '&redirect_uri=' + self.callback_url
  13. def get_aptoken(self):
  14. now_time = int(time.time())
  15. expire_time = now_time + 36000 # 1 小时后超时
  16. token_dict = {'iat': now_time,
  17. '_appId': '%s' % self.app_id,
  18. 'exp': expire_time,
  19. }
  20. headers = {
  21. 'typ': 'jwt',
  22. 'alg': 'HS256'
  23. # 声明所使用的算法
  24. }
  25. encoded = jwt.encode(payload=token_dict, key=self.app_secret, headers=headers,
  26. algorithm='HS256') # .decode('ascii')
  27. return encoded
  28. def post_create_freetask(self,xoperatorid,content):
  29. url = f'https://open.teambition.com/api/organization-task/create'
  30. app_token = (self.get_aptoken()).replace("\n", "").replace('\r', '')
  31. headers = {
  32. 'x-operator-id': xoperatorid,
  33. 'Authorization': 'Bearer %s' % app_token,
  34. 'X-Tenant-Id': '%s' % self.company_id,
  35. 'X-Tenant-Type': 'organization',
  36. }
  37. params={
  38. 'content':content
  39. }
  40. return requests.post(url,json=params, headers=headers)
  41. if __name__ == '__main__':
  42. tb = GetTeamBitionEvents()
  43. xoperatorid='63310bc0b2b7b2cf2ca8a3b2'
  44. content='all right'
  45. result = tb.post_create_freetask(xoperatorid,content)
  46. print(result.json())
  47. print(result.json()["result"])

有问题

  1. {'code': 403, 'errorMessage': '系统错误', 'result': None}
创建自由任务(X)

同上报错

查询自由任务详情(X)

同上

更新自由任务截止时间(X)

同上

更新自由任务执行者(?)
更新自由任务参与者(?)
更新自由任务完成态(?)
更新自由任务备注(?)

这几个都没测了,感觉会是一样的结果

获取任务关联信息(X)
  1. {'code': 403, 'errorMessage': '应用的接口访问权限受限', 'result': None}
创建任务关联(?)
删除任务关联(?)
更新自由任务优先级(?)

这几个也都没测了

更新任务自定义字段值(弃用?)
  1. {'code': 404, 'errorMessage': '访问的资源不存在', 'result': None}

我估计这是被弃用的,因为后面有一条简介一模一样的接口

而且object中的参数缺失

项目

查询企业优先级(X)
  1. {'code': 403, 'errorMessage': '系统错误', 'result': None}
修改项目角色的权限项(X)
  1. {'code': 500, 'errorMessage': 'internal server error', 'result': None}
恢复归档项目(功能问题)
  1. {'updated': '2022-10-13T06:56:39.469Z'}

运行完毕后,并未让已归档项目回复

查询项目分组(怀疑是被弃用的)

项目中有一个搜索项目分组,不会报错

  1. {'code': 403, 'errorMessage': '系统错误', 'result': None}

文档问题

文档部分,只记录了在项目条目下的错误

项目

查询企业优先级(X)

查询参数organizationId是必填字段

安装项目应用

请求体object缺少参数说明,或者说可能不需要

删除项目应用

文档请求头描述中缺少X-Operator-Id

复制项目

请求体object中name是必填项

从模版创建项目

请求体object中name、templateId是必填项

创建项目

请求体object中name是必填项

创建项目分组关联关系(没有在网页端找到相应信息)(X)
  1. {'code': 400, 'errorMessage': '参数有误: 应当有必需属性 projectRoleIds', 'result': None}

在文档里找不到projectRoleIds

创建项目成员

文档缺少:X-Operator-Id必填

修改项目成员的角色

userIds、roleIds为必填参数

更新项目的项目分组(X)

x-operator-id必填

  1. {'code': 400, 'errorMessage': '参数有误: required: $add or $del', 'result': None}

文档内没有$add or $del相关解释

创建项目角色

x-operator-id必填

移除项目角色

x-operator-id必填

创建项目任务类型

x-operator-id必填

修改项目任务类型

其实应该放在任务一栏下面

x-operator-id必填,projectId 也是必须的

删除项目任务类型

x-operator-id必填,projectId 是必须的,文档里写了object但没有任何参数,我觉得也用不上

更新任务字段信息(怀疑与任务中一接口重复)

没有路径参数,文档中却给了两个

Teambition企业内部应用开发指南的更多相关文章

  1. 转:Yelp开发团队发布内部网站设计指南

    原文来自于:http://www.infoq.com/cn/news/2014/02/yelp-style-guide 近日,Yelp开发团队在博客发布消息:Yelp公开了内部网站设计指南.这份文档此 ...

  2. 钉钉企业内部H5微应用开发

    企业内部H5微应用开发 分为 服务端API和前端API的开发,主要涉及到进入应用免登流程和JSAPI鉴权. JSAPI鉴权开发步骤: 1.创建H5微应用 登入钉钉开放平台(https://open-d ...

  3. WebAPI 权限控制解决方案——Phenix.NET企业应用软件快速开发平台.使用指南.21.WebAPI服务(三)

    21.1   数据服务 21.1.1基本操作功能 Phenixヾ的数据服务,提供了如下的基本操作: 功能 Type URI 参数 完整获取实体集合对象 GET api/Data 分页获取实体集合对象 ...

  4. JVM 平台上的各种语言的开发指南

    JVM 平台上的各种语言的开发指南 为什么我们需要如此多的JVM语言? 在2013年你可以有50中JVM语言的选择来用于你的下一个项目.尽管你可以说出一大打的名字,你会准备为你的下一个项目选择一种新的 ...

  5. 企业门户(Portal)项目实施方略与开发指南

    <企业门户(Portal)项目实施方略与开发指南> 基本信息 作者: 郑文平    丛书名: 企业大型应用集成丛书 出版社:电子工业出版社 ISBN:9787121211843 上架时间: ...

  6. 精益创业之父Steve Blank: 怎样让企业内部创新获得50倍增速

    编者注:本文英文版来自创新大师Steve Blank的个人博客,中文版由天地会珠海分舵进行编译.应用在初创企业打造上面的精益创业相信我们已经耳熟能详,可是假设我们面对的是一个已经发展起来的企业.或者是 ...

  7. 基于Asterisk的VoIP开发指南——Asterisk 模块编写指南(1)

    原文:基于Asterisk的VoIP开发指南--Asterisk 模块编写指南(1) 1 开源项目概述 Asterisk是一个开源的软件包,通常运行在Linux操作系统平台上.Asterisk可以用三 ...

  8. 基于Asterisk的VoIP开发指南——(1)实现基本呼叫功能

    原文:基于Asterisk的VoIP开发指南--(1)实现基本呼叫功能 说明: 1.本文档探讨基于Asterisk如何实现VoIP的一些基本功能,包括基本呼叫功能的方案选取.主叫号码透传.如何编写As ...

  9. 腾讯云安全:开发者必看|Android 8.0 新特性及开发指南

    欢迎大家关注腾讯云技术社区-博客园官方主页,我们将持续在博客园为大家推荐技术精品文章哦~ 背景介绍 谷歌2017 I/O开发者大会今年将于5月17-19日在美国加州举办.大会将跟往年一样发布最新的 A ...

随机推荐

  1. Luogu1088 火星人 (康托展开)

    皮一波 #include <iostream> #include <cstdio> #include <cstring> #include <algorith ...

  2. 刷题记录:Codeforces Round #731 (Div. 3)

    Codeforces Round #731 (Div. 3) 20210803.网址:https://codeforces.com/contest/1547. 感觉这次犯的低级错误有亿点多-- A 一 ...

  3. 【Java】idea同时运行多个一样的类

    点击"Edit Configurations..." 在左侧选中需要重复运行的类 单击"Modify options" 选择"Allow multip ...

  4. AtCoder Beginner Contest 264(D-E)

    D - "redocta".swap(i,i+1) 题意: 给一个字符串,每次交换相邻两个字符,问最少多少次变成"atcoder" 题解: 从左到右依次模拟 # ...

  5. 第四十八篇:webpack的基本使用(二) --安装和配置webpack-dev-server插件

    好家伙, 1.webpack中的默认约定 默认的打包入口文件为src  -->index.js 默认的输出文件路径为dist -->main.js 既然有默认,那么就说明肯定能改 2.en ...

  6. Python入门系列(八)日期时间、数学、json

    日期时间 Python中的日期本身不是数据类型,但我们可以导入一个名为datetime的模块,将日期作为日期对象使用. import datetime x = datetime.datetime.no ...

  7. Knative部署应用以及应用的更新、应用的分流(二)

    1. 应用的更新 1.1 更新hello-example应用 1.更新应用的环境变量 可通过命令行的方式亦可以通过读取配置文件的方式,这里主要来看命令行的方式 [root@kn-server-mast ...

  8. 【设计模式】Java设计模式 - 观察者模式

    [设计模式]Java设计模式 - 观察者模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 @一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长 ...

  9. docker-compose总结

    docker-compose.yml 样例: 各个标签的含义在注释里 version: '3' # 选择的docker-compose 版本 services: # 要编排的一组服务 fim-mysq ...

  10. 使用 Vue3 构建 Web Components

    有时候想写一个无关框架组件,又不想用原生或者 Jquery 那套去写,而且还要避免样式冲突,用 Web Components 去做刚觉就挺合适的.但是现在 Web Components 使用起来还是不 ...