Esempio n. 1
0
 def _get(self, url, data=None):
     """封装底层get请求"""
     try:
         response = None
         for x in range(3):
             try:
                 response = requests.get(url,
                                         params=data,
                                         headers=self.headers,
                                         timeout=5)
             except Exception as e:
                 time.sleep(1)
                 if x == 2:
                     raise e
             else:
                 break
         logger.info(
             'Feishu get response. url={},data={},response={}'.format(
                 url, data, response.text))
         return json.loads(response.text)
     except requests.exceptions.Timeout:
         logger.error("Feishu get timeout! url={0} data={1}".format(
             url, data))
         raise FeishuException('飞书接口get请求超时,请重试')
     except Exception as e:
         logger.error(
             "Feishu get msg fail! url={0} data={1} error by {2}".format(
                 url, data, e))
         raise FeishuException(e)
Esempio n. 2
0
 def __check_approval_status(self, result, instance_code, oper):
     """
     检查审批状态,如果状态与操作不一致,则提示用户
     :param result:飞书的返回状态是65001,内部错误,所以判断一下是不是飞书状态跟操作不一致
     :param instance_code:审批任务id
     :param oper:执行的操作
     :return:
     """
     if result['code'] == 65001:
         try:
             approval_info = self.get_approval_info(instance_code)
             if approval_info['status'] == oper:
                 return True
             elif approval_info['status'] == 'APPROVED':
                 raise FeishuException('飞书审批已经通过,无法进行审批{}'.format(
                     OPER_DICT[oper]))
             elif approval_info['status'] == 'REJECTED':
                 raise FeishuException('飞书审批已经拒绝,无法进行审批{}'.format(
                     OPER_DICT[oper]))
             elif approval_info['status'] == 'CANCELED':
                 raise FeishuException('飞书审批已经撤回,无法进行审批{}'.format(
                     OPER_DICT[oper]))
             elif approval_info['status'] == 'DELETED':
                 raise FeishuException('飞书审批已经删除,无法进行审批{}'.format(
                     OPER_DICT[oper]))
             else:
                 return False
         except Exception as ex:
             logger.error(
                 "Feishu check status approval fail! result={0},instance_code={1},oper{2},error by {3}"
                 .format(result, instance_code, oper, ex))
             raise FeishuException(ex)
Esempio n. 3
0
 def _post(self, url, data):
     """封装底层post请求"""
     data_to_send = json.dumps(data).encode("utf-8")
     try:
         response = None
         for x in range(3):
             try:
                 response = requests.post(url,
                                          data=data_to_send,
                                          headers=self.headers,
                                          timeout=5)
             except Exception as e:
                 time.sleep(1)
                 if x == 2:
                     raise e
             else:
                 break
         logger.info(
             'Feishu post response. url={},data={},response={}'.format(
                 url, data, response.text))
         return json.loads(response.text)
     except requests.exceptions.Timeout:
         logger.error("Feishu post timeout! url={0} data={1}".format(
             url, data))
         raise FeishuException('飞书接口post请求超时,请重试')
     except Exception as e:
         logger.error(
             "Feishu post msg fail! url={0} data={1} error by {2}".format(
                 url, data, e))
         raise FeishuException(e)
Esempio n. 4
0
 def approval_revoke(self, approval_code, instance_code, apply_user_id):
     """
     审批撤回
     :param approval_code: 审批流程唯一标识
     :param instance_code: 审批任务id
     :param apply_user_id: 申请人id
     :return:
     """
     try:
         result = self._post(
             self.__host_url + '/approval/openapi/v2/instance/cancel', {
                 'approval_code': approval_code,
                 'instance_code': instance_code,
                 'user_id': apply_user_id
             })
         if result['code'] != 0:
             if self.__check_approval_status(result, instance_code,
                                             'CANCELED'):
                 return 'repeat'
             else:
                 raise FeishuException('飞书撤回审批失败,错误信息:{},请联系管理员处理'.format(
                     result['msg']))
         else:
             return 'success'
     except Exception as ex:
         logger.error(
             "Feishu approval revoke fail! instance_code={0},error by {1}".
             format(instance_code, ex))
         raise FeishuException(ex)
Esempio n. 5
0
 def get_user_info(self, user_open_id):
     """
     获取用户的个人信息,只能通过open_id获取 (https://open.feishu.cn/document/ukTMukTMukTM/uIzNz4iM3MjLyczM)
     :param user_open_id: 用户在飞书的唯一标识,可以通过方法self.get_user_id_info获取用户的open_id标识
     :return:
     "user_infos":[
         {
             "name":"zhang san",
             "name_py":"zhang san",
             "en_name":"John",
             "employee_id":"a0615a67",
             "employee_no":"235634",
             "open_id":"ou_e03053f0541cecc3269d7a9dc34a0b21",
             "union_id":"on_7dba11ff38a2119f89349876b12af65c",
             .......
         }
     """
     try:
         user_info = self._get(
             self.__opes_url + '/open-apis/contact/v1/user/batch_get',
             {'open_ids': user_open_id})
         if user_info['code'] == 0:
             return user_info['data']['user_infos'][0]
         else:
             raise FeishuException('获取该用户飞书个人信息失败,请联系管理员处理')
     except Exception as ex:
         logger.error(
             "Feishu get user info fail! user_open_id={0} error by {1}".
             format(user_open_id, ex))
         raise FeishuException(ex)
Esempio n. 6
0
 def get_user_id_info(self, user_code, email_type='@company.com'):
     """
     通过邮箱获取用户的飞书唯一标识 ,(https://open.feishu.cn/document/ukTMukTMukTM/uUzMyUjL1MjM14SNzITN)
     :param user_code: company id
     :param email_type: 邮箱类型,主要是有些用户不是绑定的company.com
     :return: {
                 "open_id": "ou_979112345678741d29069abcdef089d4",
                 "user_id": "a7eb3abe"
             },
     """
     try:
         email_code = user_code + email_type
         result = self._get(
             self.__opes_url + '/open-apis/user/v1/batch_get_id',
             {'emails': email_code})
         if 'email_users' in result['data'].keys():
             user_info = result['data']['email_users'][email_code][0]
             return user_info
         else:
             raise FeishuException('飞书账号未与邮箱绑定,请联系飞书管理员绑定邮箱')
     except Exception as ex:
         logger.error(
             "Feishu get user id info fail! user_code={0} error by {1}".
             format(user_code, ex))
         raise FeishuException(ex)
Esempio n. 7
0
 def send_user_msg(self, user_code, content, type='text'):
     """
     给用户发送消息
     :param user_code: company id ,前提是飞书必须跟邮箱绑定在一起,是否绑定可以去查看飞书的个人信息简介
     :param content: 发送消息内容
     :param type: 发送消息的类型,text,是纯文本消息(https://open.feishu.cn/document/ukTMukTMukTM/uUjNz4SN2MjL1YzM),
                              card,是卡片消息。(https://open.feishu.cn/document/ukTMukTMukTM/uYTNwUjL2UDM14iN1ATN)
     :return:
     """
     try:
         result = {'code': -1}
         if type == 'text':
             result = self._send_msg(
                 data={
                     'email': user_code + "@company.com",
                     'msg_type': 'text',
                     "content": {
                         "text": content
                     }
                 })
         elif type == 'card':
             result = self._send_msg(
                 data={
                     'email': user_code + "@company.com",
                     'msg_type': 'interactive',
                     'card': content
                 })
         if result['code'] != 0:
             logger.error("Send user msg fail! result={0}".format(result))
             raise FeishuException(result)
     except Exception as e:
         raise FeishuException(e)
Esempio n. 8
0
 def approval_create(self,
                     approval_code,
                     apply_user_id,
                     data,
                     approval_user_id=None,
                     approval_node_id=None):
     """
     临时发布申请创建审批
     :param approval_code: 审批流程唯一标识
     :param apply_user_id: 申请人
     :param data: 表单数据
     :param approval_user_id:审批人,不传默认领导审批
     :param approval_node_id:审批节点id,不传默认领导审批
     :return:
     """
     try:
         print(data)
         approval_data = {
             "approval_code": approval_code,
             "user_id": apply_user_id,
             "form": json.dumps(data),
         }
         if approval_user_id:
             approval_data['node_approver_user_id_list'] = {
                 approval_node_id: [approval_user_id],
                 "manager_node_id": [approval_user_id]
             }
         print(approval_data)
         result = self._post(
             self.__host_url + '/approval/openapi/v2/instance/create',
             approval_data)
         if result['code'] != 0:
             raise FeishuException('飞书创建审批失败,错误信息:{},请联系管理员处理'.format(
                 result['msg']))
         else:
             return result['data']
     except Exception as ex:
         logger.error(
             "Feishu approval create fail! approval_code={0},apply_user_id={1},data={2},approval_user_id={3} error by {4}"
             .format(approval_code, apply_user_id, data, approval_user_id,
                     ex))
         raise FeishuException(ex)
Esempio n. 9
0
 def get_approval_info(self, instance_code):
     """
     获取审批实例详情
     :param instance_code:审批任务id
     :return:
     """
     try:
         result = self._post(
             self.__host_url + '/approval/openapi/v2/instance/get',
             {'instance_code': instance_code})
         if result['code'] == 0:
             return result['data']
         else:
             raise FeishuException('飞书获取审批实例详情失败,错误信息是:{0},请联系管理员处理'.format(
                 result['msg']))
     except Exception as ex:
         logger.error(
             "Feishu approval revoke fail! instance_code={0},error by {1}".
             format(instance_code, ex))
         raise FeishuException(ex)
Esempio n. 10
0
 def get_department_info(self, open_department_id):
     try:
         department = self._get(
             self.__opes_url + '/open-apis/contact/v1/department/info/get',
             {'open_department_id': open_department_id})
         return department
     except Exception as ex:
         logger.error(
             "Feishu get department info fail! open_department_id={0} error by {1}"
             .format(open_department_id, ex))
         raise FeishuException(ex)
Esempio n. 11
0
 def send_user_msg_many(self, open_ids, content, type='text'):
     """
     给多个用户发送消息,一次性只能发送200个人,所以下面做了循环发送
     :param open_ids: 用户的飞书唯一标识列表,[,,,,]
     :param content: 发送消息内容
     :param type: 发送消息的类型,text,是纯文本消息(https://open.feishu.cn/document/ukTMukTMukTM/uUjNz4SN2MjL1YzM),
                              card,是卡片消息。(https://open.feishu.cn/document/ukTMukTMukTM/uYTNwUjL2UDM14iN1ATN)
     :return:
     """
     try:
         for i in range(0, len(open_ids), 199):
             result = {'code': -1}
             if type == 'text':
                 result = self._post(self.__opes_url +
                                     '/open-apis/message/v4/batch_send/',
                                     data={
                                         'open_ids': open_ids[i:i + 199],
                                         'msg_type': 'text',
                                         "content": {
                                             "text": content
                                         }
                                     })
             elif type == 'card':
                 result = self._post(self.__opes_url +
                                     '/open-apis/message/v4/batch_send/',
                                     data={
                                         'open_ids': open_ids[i:i + 199],
                                         'msg_type': 'interactive',
                                         'card': content
                                     })
             if result['code'] != 0:
                 logger.error(
                     "Send user msg many fail! result={0}".format(result))
                 raise FeishuException('发送成功{}条,发送失败{}条,错误信息:{}'.format(
                     i + 199,
                     len(open_ids) - i - 199, str(result)))
     except Exception as e:
         raise FeishuException(e)
Esempio n. 12
0
 def _get_tenant_access_token(self):
     """认证接口"""
     try:
         response = requests.post(
             self.__opes_url +
             '/open-apis/auth/v3/app_access_token/internal/',
             data={
                 'app_id': self.__app_id,
                 'app_secret': self.__app_secret
             })
         app_access_token = json.loads(response.text)['app_access_token']
         return app_access_token
     except Exception as e:
         logger.error("Feishu get tenant_access_token fail!")
         raise FeishuException(e)