terra-connections
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTerra Connections
Terra 连接功能
Connect users to 150+ wearable devices and health data providers.
将用户与150+款可穿戴设备和健康数据服务商对接。
Supported Providers (150+)
支持的服务商(150+)
Wearables & Fitness Trackers
可穿戴设备与健身追踪器
- Garmin - All models, full historical data
- Fitbit - All devices, nutrition support
- Apple Health - iOS SDK required
- Oura Ring - Sleep, readiness, activity
- WHOOP - Recovery, strain, sleep
- Polar - Training, sleep, activity
- Withings - Watches, scales, blood pressure
- Samsung Health - Android SDK required
- Google Fit / Health Connect - Android SDK required
- Suunto, Coros, Biostrap, Zepp - Full support
- Garmin - 全型号支持,可获取完整历史数据
- Fitbit - 全设备支持,包含营养数据
- Apple Health - 需要iOS SDK
- Oura Ring - 睡眠、恢复状态、活动数据
- WHOOP - 恢复情况、身体负荷、睡眠数据
- Polar - 训练、睡眠、活动数据
- Withings - 手表、体重秤、血压计
- Samsung Health - 需要Android SDK
- Google Fit / Health Connect - 需要Android SDK
- Suunto, Coros, Biostrap, Zepp - 全面支持
Nutrition Apps
营养类应用
- MyFitnessPal - Food logging, macros
- Cronometer - Detailed nutrition
- MacrosFirst, FatSecret - Meal tracking
- MyFitnessPal - 饮食记录、宏量营养数据
- Cronometer - 详细营养数据
- MacrosFirst, FatSecret - 饮食追踪
Medical Devices
医疗设备
- Freestyle Libre - CGM glucose data
- Dexcom - CGM glucose (special process)
- Omron - Blood pressure monitors
- Freestyle Libre - 动态血糖监测(CGM)数据
- Dexcom - 动态血糖监测(CGM)数据(需特殊流程)
- Omron - 血压计
Connection Methods
连接方式
Method 1: Widget Flow (Recommended)
方法1:Widget流程(推荐)
Pre-built UI, easiest integration:
python
from terra import Terra
client = Terra(
dev_id="botaniqalmedtech-testing-SjyfjtG33s",
api_key="_W7Pm-kAaIf1GA_Se21NnzCaFZjg3Izc"
)预构建UI,集成最简单:
python
from terra import Terra
client = Terra(
dev_id="botaniqalmedtech-testing-SjyfjtG33s",
api_key="_W7Pm-kAaIf1GA_Se21NnzCaFZjg3Izc"
)Generate widget session
Generate widget session
response = client.authentication.generatewidgetsession(
reference_id="user_12345", # Your internal user ID
auth_success_redirect_url="https://app.botaniqal.com/success",
auth_failure_redirect_url="https://app.botaniqal.com/failure",
providers=["FITBIT", "GARMIN", "OURA"] # Optional: filter providers
)
widget_url = response.url
response = client.authentication.generatewidgetsession(
reference_id="user_12345", # Your internal user ID
auth_success_redirect_url="https://app.botaniqal.com/success",
auth_failure_redirect_url="https://app.botaniqal.com/failure",
providers=["FITBIT", "GARMIN", "OURA"] # Optional: filter providers
)
widget_url = response.url
Redirect user to widget_url
Redirect user to widget_url
**User Flow**:
1. User visits widget URL
2. Selects provider (Fitbit, Garmin, etc.)
3. Completes OAuth with provider
4. Redirected to success URL
5. Webhook sent to your endpoint with `type: "auth"`
**用户流程**:
1. 用户访问Widget URL
2. 选择服务商(Fitbit、Garmin等)
3. 完成服务商的OAuth认证
4. 重定向至成功URL
5. 向你的端点发送`type: "auth"`的WebhookMethod 2: Custom UI Flow
方法2:自定义UI流程
Build your own provider selection UI:
python
undefined自行构建服务商选择UI:
python
undefinedStep 1: Get available integrations
Step 1: Get available integrations
integrations = client.integrations.fetch()
integrations = client.integrations.fetch()
Display provider list in your UI
Display provider list in your UI
Step 2: User selects provider, generate auth URL
Step 2: User selects provider, generate auth URL
response = client.authentication.authenticateuser(
resource="FITBIT", # Provider selected by user
reference_id="user_12345"
)
auth_url = response.auth_url
response = client.authentication.authenticateuser(
resource="FITBIT", # Provider selected by user
reference_id="user_12345"
)
auth_url = response.auth_url
Open auth_url in browser (NOT WebView/iFrame!)
Open auth_url in browser (NOT WebView/iFrame!)
**Important**: Always open auth URLs in a real browser, not WebView or iFrame (OAuth security requirement).
**重要提示**:始终在真实浏览器中打开认证URL,不要使用WebView或iFrame(OAuth安全要求)。Method 3: Mobile SDK (Required for Apple/Samsung/Health Connect)
方法3:移动SDK(Apple/Samsung/Health Connect必需)
These sources have no web API - mobile SDK required:
iOS (Swift) - Apple Health:
swift
import TerraiOS
// 1. Get token from your backend
let token = await fetchTerraToken()
// 2. Initialize Terra
Terra.initTerra(devId: "botaniqalmedtech-testing-SjyfjtG33s", referenceId: "user_12345")
// 3. Connect to Apple Health
Terra.initConnection(
type: Connections.APPLE_HEALTH,
token: token,
schedulerOn: true // Enable background sync
) { success, error in
if success {
print("Connected to Apple Health!")
}
}Android (Kotlin) - Samsung Health / Health Connect:
kotlin
import co.tryterra.terra.Terra
// 1. Get token from your backend
val token = fetchTerraToken()
// 2. Initialize Terra (minSDK 28 required)
Terra.initTerra(
devId = "botaniqalmedtech-testing-SjyfjtG33s",
referenceId = "user_12345",
context = this
)
// 3. Connect to Samsung Health or Health Connect
Terra.initConnection(
connection = Connections.SAMSUNG, // or Connections.HEALTH_CONNECT
token = token,
context = this,
schedulerOn = true
) { success ->
if (success) {
println("Connected to Samsung Health!")
}
}React Native:
javascript
import { Terra, Connections } from "terra-react";
// Initialize
Terra.initTerra("botaniqalmedtech-testing-SjyfjtG33s", "user_12345");
// Connect (iOS: Apple Health, Android: Samsung/Health Connect)
await Terra.initConnection(
Connections.APPLE_HEALTH,
authToken,
true // schedulerOn for background sync
);这些数据源没有Web API - 必须使用移动SDK:
iOS (Swift) - Apple Health:
swift
import TerraiOS
// 1. Get token from your backend
let token = await fetchTerraToken()
// 2. Initialize Terra
Terra.initTerra(devId: "botaniqalmedtech-testing-SjyfjtG33s", referenceId: "user_12345")
// 3. Connect to Apple Health
Terra.initConnection(
type: Connections.APPLE_HEALTH,
token: token,
schedulerOn: true // Enable background sync
) { success, error in
if success {
print("Connected to Apple Health!")
}
}Android (Kotlin) - Samsung Health / Health Connect:
kotlin
import co.tryterra.terra.Terra
// 1. Get token from your backend
val token = fetchTerraToken()
// 2. Initialize Terra (minSDK 28 required)
Terra.initTerra(
devId = "botaniqalmedtech-testing-SjyfjtG33s",
referenceId = "user_12345",
context = this
)
// 3. Connect to Samsung Health or Health Connect
Terra.initConnection(
connection = Connections.SAMSUNG, // or Connections.HEALTH_CONNECT
token = token,
context = this,
schedulerOn = true
) { success ->
if (success) {
println("Connected to Samsung Health!")
}
}React Native:
javascript
import { Terra, Connections } from "terra-react";
// Initialize
Terra.initTerra("botaniqalmedtech-testing-SjyfjtG33s", "user_12345");
// Connect (iOS: Apple Health, Android: Samsung/Health Connect)
await Terra.initConnection(
Connections.APPLE_HEALTH,
authToken,
true // schedulerOn for background sync
);Operations
操作方法
connect-user
connect-userconnect-user
connect-userConnect a user to a wearable provider.
python
def connect_user(
client: Terra,
reference_id: str,
provider: str = None,
success_url: str = None,
failure_url: str = None
) -> dict:
"""
Connect user to wearable provider.
Args:
reference_id: Your internal user ID
provider: Specific provider or None for widget with all
success_url: Redirect URL on success
failure_url: Redirect URL on failure
Returns:
dict with url and session_id
"""
if provider:
# Custom UI flow - specific provider
response = client.authentication.authenticateuser(
resource=provider,
reference_id=reference_id
)
return {"url": response.auth_url, "type": "direct"}
else:
# Widget flow - user selects provider
response = client.authentication.generatewidgetsession(
reference_id=reference_id,
auth_success_redirect_url=success_url,
auth_failure_redirect_url=failure_url
)
return {
"url": response.url,
"session_id": response.session_id,
"type": "widget"
}将用户与可穿戴服务商对接。
python
def connect_user(
client: Terra,
reference_id: str,
provider: str = None,
success_url: str = None,
failure_url: str = None
) -> dict:
"""
Connect user to wearable provider.
Args:
reference_id: Your internal user ID
provider: Specific provider or None for widget with all
success_url: Redirect URL on success
failure_url: Redirect URL on failure
Returns:
dict with url and session_id
"""
if provider:
# Custom UI flow - specific provider
response = client.authentication.authenticateuser(
resource=provider,
reference_id=reference_id
)
return {"url": response.auth_url, "type": "direct"}
else:
# Widget flow - user selects provider
response = client.authentication.generatewidgetsession(
reference_id=reference_id,
auth_success_redirect_url=success_url,
auth_failure_redirect_url=failure_url
)
return {
"url": response.url,
"session_id": response.session_id,
"type": "widget"
}disconnect-user
disconnect-userdisconnect-user
disconnect-userDisconnect user and remove their data.
python
def disconnect_user(client: Terra, terra_user_id: str) -> bool:
"""
Disconnect user from Terra (revokes access, removes data).
Args:
terra_user_id: Terra's user ID (not your reference_id)
Returns:
bool: Success status
"""
response = client.authentication.deauthenticateuser(user_id=terra_user_id)
return response.success断开用户连接并移除其数据。
python
def disconnect_user(client: Terra, terra_user_id: str) -> bool:
"""
Disconnect user from Terra (revokes access, removes data).
Args:
terra_user_id: Terra's user ID (not your reference_id)
Returns:
bool: Success status
"""
response = client.authentication.deauthenticateuser(user_id=terra_user_id)
return response.successget-user-info
get-user-infoget-user-info
get-user-infoGet user's connection status and details.
python
def get_user_info(client: Terra, terra_user_id: str) -> dict:
"""Get information about a connected user."""
response = client.user.getuser(user_id=terra_user_id)
return {
"user_id": response.user.user_id,
"provider": response.user.provider,
"reference_id": response.user.reference_id,
"scopes": response.user.scopes,
"last_webhook_update": response.user.last_webhook_update
}获取用户的连接状态及详情。
python
def get_user_info(client: Terra, terra_user_id: str) -> dict:
"""Get information about a connected user."""
response = client.user.getuser(user_id=terra_user_id)
return {
"user_id": response.user.user_id,
"provider": response.user.provider,
"reference_id": response.user.reference_id,
"scopes": response.user.scopes,
"last_webhook_update": response.user.last_webhook_update
}list-connected-users
list-connected-userslist-connected-users
list-connected-usersGet all users connected to your app.
python
def list_connected_users(client: Terra) -> list:
"""List all connected Terra users."""
response = client.user.getsubscriptions()
users = []
for user in response.users:
users.append({
"user_id": user.user_id,
"provider": user.provider,
"reference_id": user.reference_id,
"last_update": user.last_webhook_update
})
return users获取所有连接到你的应用的用户。
python
def list_connected_users(client: Terra) -> list:
"""List all connected Terra users."""
response = client.user.getsubscriptions()
users = []
for user in response.users:
users.append({
"user_id": user.user_id,
"provider": user.provider,
"reference_id": user.reference_id,
"last_update": user.last_webhook_update
})
return usersget-users-by-reference
get-users-by-referenceget-users-by-reference
get-users-by-referenceFind Terra users by your internal reference ID.
python
def get_users_by_reference(client: Terra, reference_id: str) -> list:
"""
Get all Terra users for a reference_id.
(One person can have multiple providers connected)
"""
response = client.user.getuser(reference_id=reference_id)
return response.users # List of TerraUser objects通过你的内部参考ID查找Terra用户。
python
def get_users_by_reference(client: Terra, reference_id: str) -> list:
"""
Get all Terra users for a reference_id.
(One person can have multiple providers connected)
"""
response = client.user.getuser(reference_id=reference_id)
return response.users # List of TerraUser objectsMulti-Device Setup
多设备配置
One user can connect multiple wearables:
python
undefined一个用户可连接多款可穿戴设备:
python
undefinedUser connects Fitbit
User connects Fitbit
connect_user(client, "user_123", provider="FITBIT")
connect_user(client, "user_123", provider="FITBIT")
Same user connects Oura Ring
Same user connects Oura Ring
connect_user(client, "user_123", provider="OURA")
connect_user(client, "user_123", provider="OURA")
Get all connections for user
Get all connections for user
users = get_users_by_reference(client, "user_123")
users = get_users_by_reference(client, "user_123")
Returns: [TerraUser(provider="FITBIT"), TerraUser(provider="OURA")]
Returns: [TerraUser(provider="FITBIT"), TerraUser(provider="OURA")]
**Each provider creates a separate Terra User ID**, but all share the same `reference_id`.
**每个服务商都会生成独立的Terra用户ID**,但所有用户ID共享同一个`reference_id`。Provider-Specific Notes
服务商专属说明
Apple Health (iOS)
Apple Health (iOS)
- Requires: Mobile SDK, iOS 13+
- No web API: Must use native app
- Background sync: Enable
schedulerOn: true - Permissions: Request during connection
- 要求:移动SDK,iOS 13+
- 无Web API:必须使用原生应用
- 后台同步:启用
schedulerOn: true - 权限:在连接过程中请求
Samsung Health / Health Connect (Android)
Samsung Health / Health Connect (Android)
- Requires: Mobile SDK, minSDK 28
- Health Connect: Google's unified health API
- Samsung specific: Uses Samsung Health SDK
- 要求:移动SDK,最低SDK版本28
- Health Connect:谷歌统一健康API
- 三星专属:使用Samsung Health SDK
WHOOP
WHOOP
- Special process: Contact Terra for activation
- Data: Recovery, strain, sleep, HRV
- 特殊流程:联系Terra激活
- 数据:恢复情况、身体负荷、睡眠、心率变异性(HRV)
Dexcom (CGM)
Dexcom (CGM)
- Special process: Contact Terra for activation
- Data: Continuous glucose monitoring
- 特殊流程:联系Terra激活
- 数据:连续血糖监测
Freestyle Libre (EU)
Freestyle Libre (欧盟)
- Dedicated API keys: Required for EU
- Data: CGM glucose readings
- 专属API密钥:欧盟地区必需
- 数据:动态血糖监测读数
Strava
Strava
- Dedicated API keys: Required
- Data: Activities, routes
- 专属API密钥:必需
- 数据:活动记录、路线
Webhook Events for Connections
连接相关Webhook事件
When user connects/disconnects, you receive webhooks:
Connection Success ():
type: "auth"json
{
"type": "auth",
"user": {
"user_id": "terra_abc123",
"provider": "FITBIT",
"reference_id": "user_12345"
},
"status": "authenticated"
}Disconnection ():
type: "deauth"json
{
"type": "deauth",
"user": {
"user_id": "terra_abc123",
"provider": "FITBIT"
},
"status": "deauthenticated"
}Connection Error ():
type: "connection_error"json
{
"type": "connection_error",
"user": {
"user_id": "terra_abc123",
"provider": "FITBIT"
},
"message": "Token refresh failed"
}当用户连接/断开时,你会收到Webhook:
连接成功 ():
type: "auth"json
{
"type": "auth",
"user": {
"user_id": "terra_abc123",
"provider": "FITBIT",
"reference_id": "user_12345"
},
"status": "authenticated"
}断开连接 ():
type: "deauth"json
{
"type": "deauth",
"user": {
"user_id": "terra_abc123",
"provider": "FITBIT"
},
"status": "deauthenticated"
}连接错误 ():
type: "connection_error"json
{
"type": "connection_error",
"user": {
"user_id": "terra_abc123",
"provider": "FITBIT"
},
"message": "Token refresh failed"
}Database Schema Recommendation
数据库Schema推荐
sql
CREATE TABLE terra_connections (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id), -- Your user
terra_user_id VARCHAR(255) UNIQUE, -- Terra's user ID
provider VARCHAR(50), -- FITBIT, GARMIN, etc.
reference_id VARCHAR(255), -- Your reference ID
connected_at TIMESTAMP DEFAULT NOW(),
last_sync TIMESTAMP,
status VARCHAR(20) DEFAULT 'active', -- active, disconnected
scopes TEXT[] -- Granted permissions
);
CREATE INDEX idx_terra_user ON terra_connections(user_id);
CREATE INDEX idx_terra_reference ON terra_connections(reference_id);sql
CREATE TABLE terra_connections (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id), -- Your user
terra_user_id VARCHAR(255) UNIQUE, -- Terra's user ID
provider VARCHAR(50), -- FITBIT, GARMIN, etc.
reference_id VARCHAR(255), -- Your reference ID
connected_at TIMESTAMP DEFAULT NOW(),
last_sync TIMESTAMP,
status VARCHAR(20) DEFAULT 'active', -- active, disconnected
scopes TEXT[] -- Granted permissions
);
CREATE INDEX idx_terra_user ON terra_connections(user_id);
CREATE INDEX idx_terra_reference ON terra_connections(reference_id);Related Skills
相关技能
- terra-auth: Authentication and credentials
- terra-data: Retrieve health data
- terra-webhooks: Handle connection events
- terra-sdk: Mobile SDK integration
- terra-auth: 认证与凭证管理
- terra-data: 健康数据获取
- terra-webhooks: 连接事件处理
- terra-sdk: 移动SDK集成