飞书,点这里 | Larksuite(Overseas)
- 如果使用的是飞书,请看 飞书,点这里 ,飞书与Larksuite使用的域名不一样,引用的文档地址也是不同的。(If you are using FeiShu, please see 飞书,点这里 , Feishu and larksuite use different domain names and reference different document addresses.)
-
Larksuite open platform facilitates the integration of enterprise applications and larksuite, making collaboration and management more efficient.
-
Larksuite development interface SDK, convenient call server API and subscribe server events, such as: Message & group, address book, calendar, docs and others can visit larksuite open platform document ,Take a look at [REFERENCE].
- python 2.7+
Latest version, see pypi.org .
pip install larksuite-oapi==1.0.19
- Larksuite: the overseas name of lark, which mainly provides services for overseas enterprises and has an independent domain name address .
- Development documents: reference to the open interface of the open platform developers must see, and can use search to query documents efficiently . more information .
- Developer background: the management background for developers to develop applications, more introduction .
- Cutome APP: the application can only be installed and used in the enterprise,more introduction .
- Marketplace App: The app will be displayed in App Directory Display, each enterprise can choose to install.
Example of using "Custom App" to access send text message API
- Since the SDK has encapsulated the app_access_token、tenant_access_token So when calling the business API, you don't need to get the app_access_token、tenant_access_token. If the business interface needs to use user_access_token, which needs to be set(request.SetUserAccessToken("user_access_token")), Please refer to README.md -> How to build a request( Request)
- Some of the old API do not have a direct SDK to use. They can use the
native
mode.
from larksuiteoapi.api import Request, set_timeout
from larksuiteoapi import Config, ACCESS_TOKEN_TYPE_TENANT, DOMAIN_LARK_SUITE, DOMAIN_FEISHU, DefaultLogger, LEVEL_DEBUG
# Configuration of "Custom App", parameter description:
# AppID、AppSecret: "Developer Console" -> "Credentials"(App ID、App Secret)
# VerificationToken、EncryptKey: "Developer Console" -> "Event Subscriptions"(Verification Token、Encrypt Key)
# app_settings = Config.new_internal_app_settings("AppID", "AppSecret", "VerificationToken", "EncryptKey")
app_settings = Config.new_internal_app_settings_from_env()
# Currently, you are visiting larksuite, which uses default storage and default log (debug level). More optional configurations are as follows: README.md->Advanced use->How to build overall configuration(Config)。
conf = Config.new_config_with_memory_store(DOMAIN_LARK_SUITE, app_settings, DefaultLogger(), LEVEL_DEBUG)
def test_send_message():
body = {
"user_id": "77bbc392",
"msg_type": "text",
"content": {
"text": "test send message",
}
}
req = Request('message/v4/send', 'POST', ACCESS_TOKEN_TYPE_TENANT, body, request_opts=[set_timeout(3)])
resp = req.do(conf)
print('request id = %s' % resp.get_request_id())
print(resp.code)
if resp.code == 0:
print(resp.data)
else:
print(resp.msg)
print(resp.error)
if __name__ == '__main__':
test_send_message()
- Subscribe to events, to understand the process and precautions of subscribing to events.
- For more use examples, please refer to sample/event(including: use in combination with flask)
Example of using "Custom App" to subscribe App First Enabled event.
- For some old events, there is no SDK that can be used directly. You can use the
native
mode
from larksuiteoapi.event import handle_event, set_event_callback
from larksuiteoapi.model import OapiHeader, OapiRequest
from flask import Flask, request
from flask.helpers import make_response
from larksuiteoapi import Config, Context, DOMAIN_FEISHU,DOMAIN_LARK_SUITE, DefaultLogger, LEVEL_DEBUG
# Configuration of "Custom App", parameter description:
# AppID、AppSecret: "Developer Console" -> "Credentials"(App ID、App Secret)
# VerificationToken、EncryptKey: "Developer Console" -> "Event Subscriptions"(Verification Token、Encrypt Key)
# app_settings = Config.new_internal_app_settings("AppID", "AppSecret", "VerificationToken", "EncryptKey")
app_settings = Config.new_internal_app_settings_from_env()
# Currently, you are visiting larksuite, which uses default storage and default log (debug level). More optional configurations are as follows: README.md->Advanced use->How to build overall configuration(Config)。
conf = Config.new_config_with_memory_store(DOMAIN_LARK_SUITE, app_settings, DefaultLogger(), LEVEL_DEBUG)
def app_open_event_handle(ctx, conf, event):
# type: (Context, Config, dict) -> None
print(ctx.get_request_id())
print(conf.app_settings)
print(event)
# set event type 'app_status_change' handle
set_event_callback(conf, 'app_open', app_open_event_handle)
app = Flask(__name__)
@app.route('/webhook/event', methods=['GET', 'POST'])
def webhook_event():
oapi_request = OapiRequest(uri=request.path, body=request.data, header=OapiHeader(request.headers))
resp = make_response()
oapi_resp = handle_event(conf, oapi_request)
resp.headers['Content-Type'] = oapi_resp.content_type
resp.data = oapi_resp.body
resp.status_code = oapi_resp.status_code
return resp
# Start the httpserver, "Developer Console" -> "Event Subscriptions", setting Request URL: https://domain/webhook/event
# startup event http server, port: 8089
if __name__ == '__main__':
app.run(port=8089, host="0.0.0.0")
- Message Card Development Process , to understand the process and precautions of processing message cards
- For more use examples, please refer to sample/card(including: use in combination with flask)
from typing import Any, Union, Dict
from larksuiteoapi import Config, Context, DOMAIN_FEISHU, DOMAIN_LARK_SUITE, DefaultLogger, LEVEL_DEBUG
from larksuiteoapi.card import Card, set_card_callback, handle_card
from larksuiteoapi.model import OapiHeader, OapiRequest
from flask import Flask, request
from flask.helpers import make_response
# Configuration of "Custom App", parameter description:
# AppID、AppSecret: "Developer Console" -> "Credentials"(App ID、App Secret)
# VerificationToken、EncryptKey: "Developer Console" -> "Event Subscriptions"(Verification Token、Encrypt Key)
# app_settings = Config.new_internal_app_settings("AppID", "AppSecret", "VerificationToken", "EncryptKey")
app_settings = Config.new_internal_app_settings_from_env()
# Currently, you are visiting larksuite, which uses default storage and default log (debug level). More optional configurations are as follows: README.md->Advanced use->How to build overall configuration(Config)。
conf = Config.new_config_with_memory_store(DOMAIN_LARK_SUITE, app_settings, DefaultLogger(), LEVEL_DEBUG)
# Return value: can be None or JSON(dict) of new message card
def handle(ctx, conf, card):
# type: (Context, Config, Card) -> Union[None, Dict]
print('card = %s' % card)
return {
"config": {
"wide_screen_mode": True
},
"card_link": {
"url": "https://www.google.com",
"android_url": "https://developer.android.com/",
"ios_url": "https://developer.apple.com/",
"pc_url": "https://www.windows.com"
},
"header": {
"title": {
"tag": "plain_text",
"content": "this is header"
}
},
"elements": [
{
"tag": "div",
"text": {
"tag": "plain_text",
"content": "This is a very very very very very very very long text;"
}
},
{
"tag": "action",
"actions": [
{
"tag": "button",
"text": {
"tag": "plain_text",
"content": "Read"
},
"type": "default"
}
]
}
]
}
set_card_callback(conf, handle)
app = Flask(__name__)
@app.route('/webhook/card', methods=['POST'])
def webhook_card():
oapi_request = OapiRequest(uri=request.path, body=request.data, header=OapiHeader(request.headers))
resp = make_response()
oapi_resp = handle_card(conf, oapi_request)
resp.headers['Content-Type'] = oapi_resp.content_type
resp.data = oapi_resp.body
resp.status_code = oapi_resp.status_code
return resp
# "Developer Console" -> "Features" -> "Bot", setting Message Card Request URL: https://domain/webhook/card
# startup event http server, port: 8089
if __name__ == '__main__':
app.run(port=8089, host="0.0.0.0")
from larksuiteoapi import Config
# To prevent application information leakage, in the configuration environment variables, the variables (4) are described as follows:
# APP_ID: "Developer Console" -> "Credentials"(App ID)
# APP_Secret: "Developer Console" -> "Credentials"(App Secret)
# VERIFICATION_Token: VerificationToken、EncryptKey: "Developer Console" -> "Event Subscriptions"(Verification Token)
# ENCRYPT_Key: VerificationToken、EncryptKey: "Developer Console" -> "Event Subscriptions"(Encrypt Key)
# The configuration of "Custom App" is obtained through environment variables
app_settings = Config.new_internal_app_settings_from_env()
# The configuration of "Marketplace App" is obtained through environment variables
app_settings = Config.new_isv_app_settings_from_env()
# Parameter Description:
# AppID、AppSecret: "Developer Console" -> "Credentials"(App ID、App Secret)
# VerificationToken、EncryptKey: "Developer Console" -> "Event Subscriptions"(Verification Token、Encrypt Key)
# The configuration of "Custom App"
app_settings = Config.new_internal_app_settings("AppID", "AppSecret", "VerificationToken", "EncryptKey")
# The configuration of "Marketplace App"
app_settings = Config.new_isv_app_settings("AppID", "AppSecret", "VerificationToken", "EncryptKey")
- Visit Larksuite, Feishu or others
- App settings
- The implementation of logger is used to output the logs generated in the process of SDK processing, which is convenient for troubleshooting.
- The implementation of store is used to save the access credentials (app/tenant_access_token), temporary voucher (
app_ticket)
- Redis is recommended. Please see the example code: sample/config/config.py RedisStore
- It can reduce the times of obtaining access credentials and prevent the frequency limit of calling access credentials interface.
- "Marketplace App", accept open platform distributed
app_ticket
will be saved to the storage, so the implementation of the storage (store) needs to support distributed storage.
- Redis is recommended. Please see the example code: sample/config/config.py RedisStore
from larksuiteoapi import Config, AppSettings, \
Logger, DefaultLogger, LEVEL_DEBUG, LEVEL_INFO, LEVEL_WARN, LEVEL_ERROR, \
DOMAIN_FEISHU, DOMAIN_LARK_SUITE
# for Cutome APP
app_settings = Config.new_internal_app_settings_from_env()
# Method 1: it is recommended to use redis to implement the store interface, so as to reduce the times of accessing the access_token API: [RedisStore](sample/config/config.py)
# Parameter Description:
# domain: DOMAIN_FEISHU / DOMAIN_LARK_SUITE / URL domain address
# app_settings: AppSetting
# logger: [Logger](src/larksuiteoapi/logger.py)
# log_level: LEVEL_DEBUG/LEVEL_INFO/LEVEL_WARN/LEVEL_ERROR
# store: [Store](src/larksuiteoapi/store.py),用来存储 app_ticket/access_token
conf = Config.new_config(DOMAIN_FEISHU, app_settings, logger, log_level, store)
# Method 2: use the implementation of the default storage interface (store), which is suitable for light-weight use (not suitable: "Marketplace App" applies or calls the server API frequently)
# 参数说明:
# domain: DOMAIN_FEISHU / DOMAIN_LARK_SUITE / URL domain address
# app_settings: AppSetting
# logger: [Logger](src/larksuiteoapi/logger.py)
# log_level: LEVEL_DEBUG/LEVEL_INFO/LEVEL_WARN/LEVEL_ERROR
conf = Config.new_config_with_memory_store(DOMAIN_FEISHU, app_settings, logger, log_level)
- Some of the old interfaces do not have an SDK that can be used directly. They can use
native
mode. At this time, they need to build requests. - For more examples, see sample/api/api.py (including: file upload and download)
from larksuiteoapi import ACCESS_TOKEN_TYPE_APP, ACCESS_TOKEN_TYPE_TENANT, ACCESS_TOKEN_TYPE_USER
from larksuiteoapi.api import Request, FormData, FormDataFile, \
set_path_params, set_query_params, set_timeout, set_no_data_field, \
set_user_access_token, set_tenant_key, set_is_response_stream, set_response_stream
# Parameter Description:
# http_path: API path(the path after `open-apis/`), for example: https://domain/open-apis/contact/v3/users/:user_id, then httpPath: "contact/v3/users/:user_id"
# http_Method: GET/POST/PUT/BATCH/DELETE
# access_token_type: What kind of access certificate does the API use and the value range: ACCESS_TOKEN_TYPE_APP, ACCESS_TOKEN_TYPE_TENANT, ACCESS_TOKEN_TYPE_USER
# request_body: Request body (possibly FormData()(e.g. file upload)), if the request body (e.g. some get requests) is not needed, it will be transferred to: None
# request_opts: Extension function, some rarely used parameter encapsulation, as follows:
# set_path_params({"user_id": 4}): set the URL Path parameter(with: prefix) value, When httpPath="contact/v3/users/:user_id", the requested URL="https://{domain}/open-apis/contact/v3/users/4"
# set_query_params({"age":4,"types":[1,2]}): Set the URL query, will append to the url?age=4&types=1&types=2
# set_is_response_stream(), set whether the response is a stream, response.data = bytes(file binary)
# set_response_stream(IO[any]), set whether the response is a stream, such as downloading a file, response.data = IO[any]
# set_no_data_field, set whether the response does not have a `data` field, business interfaces all have `data `Field, so you don’t need to set
# set_tenant_key, as an `app store application`, it means using `tenant_access_token` to access the API, you need to set
# set_user_access_token, which means using` user_access_token` To access the API, you need to set
# set_timeou, set the request timeout (in seconds)
# (str, str, str, Any, T, List[Callable[[Option], Any]]) -> None
req = Request(http_path, http_Method, access_token_type, request_body, request_opts=None)
from larksuiteoapi import Context
ctx = Context()
# Get the request ID of the request for troubleshooting
request_id = ctx.get_request_id()
# Get the response status code of the request
status_code = ctx.get_http_status_code()
- Since the SDK has encapsulated the app_access_token、tenant_access_token So when calling the business API, you don't need to get the app_access_token、tenant_access_token. If the business interface needs to use user_access_token, which needs to be set(request.SetUserAccessToken("user_access_token")), Please refer to README.md -> How to build a request( Request)
- For more use examples, please see: sample/api/api.py
from larksuiteoapi.api import Request
req = Request(...)
# Send Request
# Parameter Description:
# conf: Overall configuration(Config)
# Return value Description:
# Response: response(= http response body)
resp = req.do(conf)
print('request id = %s' % resp.get_request_id())
print(resp.code)
if resp.code == 0:
print(resp.data.message_id)
else:
print(resp.msg)
print(resp.error)
- MIT