connectors
object
%Connector
/phlo/resources/connectors/Connector.phlo
const
Connector :: section
line 10
在 Connector 中定义一个部分,允许组织相关的组件和功能。
voidconst
Connector :: api
line 11
定义一个用于API交互的连接器,允许不同服务之间无缝通信。
voidmethod
%Connector -> __construct (?array $config = null)
line 13
使用可选的配置设置初始化Connector实例。如果未提供配置,它将尝试从预定义的部分加载凭据。
if ($config === null){
$section = static::section
$creds = $section ? %creds->{$section} : null
$config = $creds ? (array)$creds->toArray : []
}
$this->config = $config
$this->timeout = 15
$this->retries = 0static
Connector :: make (?array $config = null):static
line 24
使用提供的配置创建 Connector 类的新实例。
new static($config)method
%Connector -> base
line 26
访问Connector的基础API,允许与其核心功能进行交互。
static::apimethod
%Connector -> headers
line 27
此属性检索与 Connector 相关的头部信息。
[]static
Connector :: fields
line 29
Connector::$fields 是一个静态属性,包含 Connector 类的字段定义数组。
[]method
%Connector -> configured (...$keys):bool
line 31
检查连接器的配置中是否配置了所有指定的键。如果所有键都存在,则返回true,否则返回false。
foreach ($keys AS $key){
if (($this->config[$key] ?? void) === void) return false
}
return truemethod
%Connector -> missing (...$keys):?obj
line 38
检查指定的凭据是否已配置,如果已配置则返回null;否则,触发一个失败,指明缺少哪些凭据。
return $this->configured(...$keys) ? null : static::fail(static::section.' credentials not configured ('.implode(', ', $keys).')')static
Connector :: bearer ($token):string
line 42
Connector::$bearer 属性保存格式化的包含 Bearer 令牌的授权头值,用于 API 请求。
'Authorization: Bearer '.$tokenstatic
Connector :: basic ($user, $pass):string
line 43
通过将提供的用户名和密码编码为base64格式来生成Basic Authorization头。
'Authorization: Basic '.base64_encode($user.colon.$pass)static
Connector :: build (string $method, string $url, ?array $query = null, array $headers = [], mixed $json = null, mixed $form = null):array
line 45
根据提供的参数构建HTTP请求配置,包括方法、URL、头部和主体。
if ($query) $url .= (str_contains($url, qm) ? '&' : qm).http_build_query($query)
$body = null
if ($json !== null){
$body = is_string($json) ? $json : json_encode($json, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
$headers[] = 'Content-Type: application/json'
}
elseif ($form !== null){
$body = is_string($form) ? $form : http_build_query($form)
$headers[] = 'Content-Type: application/x-www-form-urlencoded'
}
$headers[] = 'Accept: application/json'
return ['method' => strtoupper($method), 'url' => $url, 'headers' => $headers, 'body' => $body]static
Connector :: ok ($data, int $status = 200):obj
line 60
Connector::$ok 属性包含一个对象,该对象具有布尔 'ok' 值、'status' 和 'data' 属性。
obj(ok: true, status: $status, data: $data)static
Connector :: fail ($error, int $status = 0):obj
line 61
Connector::$fail 属性表示失败状态,包含一个对象,其中 'ok' 设置为 false,并包含 'status' 和 'error' 详细信息。
obj(ok: false, status: $status, error: $error)static
Connector :: errorMessage ($data, string $raw, int $status):string
line 63
Connector::$errorMessage 从给定的数据对象中检索错误消息,检查各种属性以获取错误的字符串表示,如果未找到错误,则默认为格式化的 HTTP 状态消息。
if (is_object($data)){
if (isset($data->error->message)) return (string)$data->error->message
if (isset($data->error) && is_string($data->error)) return $data->error
if (isset($data->message)) return (string)$data->message
if (isset($data->errors)){
$errors = $data->errors
if (is_string($errors)) return $errors
if (is_array($errors)) return is_string($errors[0] ?? null) ? $errors[0] : json_encode($errors)
if (is_object($errors)) return json_encode($errors)
}
}
return $raw !== void ? $raw : 'HTTP '.$statusstatic
Connector :: parse ($raw, int $status = 200):obj
line 78
将原始输入字符串解析为JSON对象,根据HTTP状态码返回成功响应或错误消息。
$raw = (string)$raw
$data = $raw === void ? null : json_decode($raw)
if ($status < 200 || $status >= 300) return static::fail(static::errorMessage($data, $raw, $status), $status)
return obj(ok: true, status: $status, data: $data ?? $raw)static
Connector :: retryable ($method, int $status):bool
line 85
in_array($method, ['GET', 'HEAD', 'QUERY']) && ($status === 429 || $status >= 500)static
Connector :: backoff (int $attempt, $response):int
line 87
Connector::$backoff 属性根据响应中的 'retry-after' 头计算以微秒为单位的退避时间,最大限制为 30 秒或默认值乘以尝试次数。
$after = (int)($response->headers['retry-after'] ?? 0)
return $after > 0 ? min($after, 30) * 1000000 : 200000 * $attemptmethod
%Connector -> dispatch (array $req):obj
line 92
$method = $req['method']
$body = $req['body']
$attempt = 0
$response = null
while (true){
try {
if ($method === 'GET') $raw = HTTP($req['url'], $req['headers'], cookies: false, timeout: $this->timeout, response: $response)
elseif ($method === 'DELETE') $raw = HTTP($req['url'], $req['headers'], DELETE: true, cookies: false, timeout: $this->timeout, response: $response)
elseif ($method === 'PUT') $raw = HTTP($req['url'], $req['headers'], PUT: $body ?? void, cookies: false, timeout: $this->timeout, response: $response)
elseif ($method === 'PATCH') $raw = HTTP($req['url'], $req['headers'], PATCH: $body ?? void, cookies: false, timeout: $this->timeout, response: $response)
elseif ($method === 'QUERY') $raw = HTTP($req['url'], $req['headers'], QUERY: $body ?? void, cookies: false, timeout: $this->timeout, response: $response)
else $raw = HTTP($req['url'], $req['headers'], POST: $body ?? void, cookies: false, timeout: $this->timeout, response: $response)
}
catch (\Throwable $e){
return static::fail($e->getMessage(), 0)
}
$status = $response->status ?? 0
if (($status >= 200 && $status < 300) || !static::retryable($method, $status) || $attempt >= $this->retries) break
usleep(static::backoff(++$attempt, $response))
}
$result = static::parse($raw, $status)
$result->headers = $response->headers ?? []
return $resultmethod
%Connector -> request (string $method, string $url, ?array $query = null, array $headers = [], mixed $json = null, mixed $form = null):obj
line 118
使用指定的方法、URL、查询参数、头部以及可选的JSON或表单数据发送HTTP请求。
if (!str_starts_with($url, 'http')) $url = rtrim((string)$this->base, slash).slash.ltrim($url, slash)
$headers = array_merge((array)$this->headers, $headers)
return $this->dispatch(static::build($method, $url, $query, $headers, $json, $form))method
%Connector -> get (string $url, ?array $query = null, array $headers = []):obj
line 124
向指定的URL发送GET请求,带有可选的查询参数和头部信息。
$this->request('GET', $url, query: $query, headers: $headers)method
%Connector -> post (string $url, mixed $json = null, array $headers = []):obj
line 125
向指定的URL发送带有可选JSON数据和头部的POST请求。
$this->request('POST', $url, headers: $headers, json: $json)method
%Connector -> put (string $url, mixed $json = null, array $headers = []):obj
line 126
向指定的URL发送PUT请求,附带可选的JSON数据和头部信息。
$this->request('PUT', $url, headers: $headers, json: $json)method
%Connector -> patch (string $url, mixed $json = null, array $headers = []):obj
line 127
向指定的URL发送PATCH请求,带有可选的JSON数据和头部信息。
$this->request('PATCH', $url, headers: $headers, json: $json)method
%Connector -> query (string $url, mixed $json = null, array $headers = []):obj
line 128
$this->request('QUERY', $url, headers: $headers, json: $json)method
%Connector -> del (string $url, array $headers = []):obj
line 129
向指定的URL发送DELETE请求,并可选地附加头部信息。
$this->request('DELETE', $url, headers: $headers)method
%Connector -> form (string $url, array $fields, array $headers = []):obj
line 130
向指定的URL发送带有给定表单字段和头部的POST请求。
$this->request('POST', $url, headers: $headers, form: $fields)method
%Connector -> paginate (string $url, callable $extract, ?array $query = null, string $param = 'page', int $start = 1, int $max = 0):array
line 132
从指定的URL获取分页数据,使用提供的可调用函数提取项目,并在达到最大数量或没有更多数据可用时进行累积。
$items = []
$page = $start
while (true){
$res = $this->get($url, ($query ?? []) + [$param => $page])
if (!$res->ok) break
$batch = $extract($res->data)
if (!$batch) break
foreach ($batch AS $item) $items[] = $item
if ($max && count($items) >= $max) break
$page++
}
return $itemsobject
%EBoekhouden
/phlo/resources/connectors/finance/EBoekhouden.phlo
const
EBoekhouden :: section
line 11
'EBoekhouden'const
EBoekhouden :: api
line 12
'https://api.e-boekhouden.nl/v1'prop
%EBoekhouden -> sessionToken
line 14
voidmethod
%EBoekhouden -> headers
line 16
$this->sessionToken !== void ? ['Authorization: '.$this->sessionToken] : []static
EBoekhouden :: fields
line 18
arr(
section: 'EBoekhouden',
config: arr(source: 'Source label shown in the e-Boekhouden audit trail (optional)'),
secret: arr(api_token: 'API token (Beheer > Instellingen > API)'),
)method
%EBoekhouden -> session:obj
line 25
if ($m = $this->missing('api_token')) return $m
if ($this->sessionToken !== void) return static::ok($this->sessionToken)
$res = $this->post('session', ['accessToken' => trim((string)$this->config['api_token']), 'source' => (string)($this->config['source'] ?? 'Phlo')])
if (!$res->ok) return $res
$token = (string)($res->data->token ?? void)
if ($token === void) return static::fail('e-Boekhouden session token missing in response', $res->status)
$this->sessionToken = $token
return static::ok($token)method
%EBoekhouden -> guard:?obj
line 36
$res = $this->session
return $res->ok ? null : $resmethod
%EBoekhouden -> relations (array $query = []):obj
line 41
if ($m = $this->guard) return $m
return $this->get('relation', $query)method
%EBoekhouden -> createRelation (array $relation):obj
line 46
if ($m = $this->guard) return $m
return $this->post('relation', $relation)method
%EBoekhouden -> invoices (array $query = []):obj
line 51
if ($m = $this->guard) return $m
return $this->get('invoice', $query)method
%EBoekhouden -> createInvoice (array $invoice):obj
line 56
if ($m = $this->guard) return $m
return $this->post('invoice', $invoice)object
%ExactOnline
/phlo/resources/connectors/finance/ExactOnline.phlo
const
ExactOnline :: section
line 11
在ExactOnline资源中定义一个部分,以便进行结构化数据管理。
'ExactOnline'const
ExactOnline :: tokenUrl
line 12
返回用于从ExactOnline获取OAuth2令牌的URL。
'https://start.exactonline.nl/api/oauth2/token'method
%ExactOnline -> base
line 14
使用配置中的指定部门构建ExactOnline API的基本URL。
'https://start.exactonline.nl/api/v1/'.($this->config['division'] ?? void)static
ExactOnline :: fields
line 16
定义与ExactOnline集成所需的字段,包括OAuth凭据和范围的配置。
arr(
section: 'ExactOnline',
config: arr(division: 'Division (administration) number'),
secret: arr(
client_id: 'OAuth client ID',
client_secret: 'OAuth client secret',
refresh_token: 'OAuth refresh token (managed and rotated after first authorization)',
),
scopes: 'OAuth2 authorization code flow; token endpoint refreshes automatically',
)method
%ExactOnline -> guard
line 27
检查必需参数 'division'、'client_id'、'client_secret' 和 'refresh_token' 的存在。
$this->missing('division', 'client_id', 'client_secret', 'refresh_token')method
%ExactOnline -> invoices (array $query = []):obj
line 29
根据提供的查询参数从ExactOnline获取销售发票列表。
if ($m = $this->guard) return $m
return $this->get('salesinvoice/SalesInvoices', $query)method
%ExactOnline -> accounts (array $query = []):obj
line 34
使用指定的查询参数从ExactOnline检索账户信息。
if ($m = $this->guard) return $m
return $this->get('crm/Accounts', $query)method
%ExactOnline -> createInvoice (array $invoice):obj
line 39
使用提供的发票数据在ExactOnline中创建新发票。
if ($m = $this->guard) return $m
return $this->post('salesinvoice/SalesInvoices', $invoice)object
%GoogleCalendar
/phlo/resources/connectors/cloud/GoogleCalendar.phlo
const
GoogleCalendar :: section
line 11
在Google日历资源中定义一个部分,以便组织事件和细节。
'Google'const
GoogleCalendar :: tokenUrl
line 12
这是用于从Google Calendar的OAuth 2.0授权服务器获取访问令牌的URL端点。
'https://oauth2.googleapis.com/token'method
%GoogleCalendar -> base
line 14
这定义了访问 Google Calendar API 版本 3 的基础 URL。
'https://www.googleapis.com/calendar/v3'static
GoogleCalendar :: fields
line 16
GoogleCalendar::$fields 提供访问 Google Calendar 的配置详细信息,包括 OAuth 凭据和所需的范围。
arr(
section: 'Google',
secret: arr(
client_id: 'OAuth client ID',
client_secret: 'OAuth client secret',
refresh_token: 'OAuth refresh token (scopes: calendar, spreadsheets)',
),
scopes: 'https://www.googleapis.com/auth/calendar, https://www.googleapis.com/auth/spreadsheets',
)method
%GoogleCalendar -> guard
line 26
检查必需凭据的存在:client_id、client_secret 和 refresh_token。
$this->missing('client_id', 'client_secret', 'refresh_token')method
%GoogleCalendar -> events (string $calendarId = 'primary', array $query = []):obj
line 28
使用提供的日历ID和可选查询参数从指定的Google日历中检索事件。
if ($m = $this->guard) return $m
return $this->get('calendars/'.rawurlencode($calendarId).'/events', $query)method
%GoogleCalendar -> createEvent (array $event, string $calendarId = 'primary'):obj
line 33
使用提供的事件详细信息在指定的 Google 日历中创建新事件。
if ($m = $this->guard) return $m
return $this->post('calendars/'.rawurlencode($calendarId).'/events', $event)object
%GoogleSheets
/phlo/resources/connectors/cloud/GoogleSheets.phlo
const
GoogleSheets :: section
line 11
定义一个用于在 Google Sheets 资源中组织数据的部分。
'Google'const
GoogleSheets :: tokenUrl
line 12
这是从 Google Sheets 获取 OAuth 2.0 令牌的 URL 端点。
'https://oauth2.googleapis.com/token'method
%GoogleSheets -> base
line 14
此项表示访问 Google Sheets API 的基本 URL,特别是与电子表格交互的端点。
'https://sheets.googleapis.com/v4/spreadsheets'static
GoogleSheets :: fields
line 16
定义Google Sheets集成的配置字段,包括OAuth凭据和所需的范围。
arr(
section: 'Google',
secret: arr(
client_id: 'OAuth client ID',
client_secret: 'OAuth client secret',
refresh_token: 'OAuth refresh token (scopes: calendar, spreadsheets)',
),
scopes: 'https://www.googleapis.com/auth/spreadsheets',
)method
%GoogleSheets -> guard
line 26
检查必需凭据的存在:client_id、client_secret 和 refresh_token。
$this->missing('client_id', 'client_secret', 'refresh_token')method
%GoogleSheets -> values ($spreadsheetId, string $range):obj
line 28
从指定的 Google Sheets 电子表格中检索给定电子表格 ID 的范围内的值。
if ($m = $this->guard) return $m
return $this->get($spreadsheetId.'/values/'.rawurlencode($range))method
%GoogleSheets -> append ($spreadsheetId, string $range, array $rows, string $valueInputOption = 'USER_ENTERED'):obj
line 33
将数据行附加到指定的 Google Sheets 电子表格范围,使用提供的值输入选项。
if ($m = $this->guard) return $m
return $this->post($spreadsheetId.'/values/'.rawurlencode($range).':append?valueInputOption='.$valueInputOption, ['values' => $rows])object
%Lightspeed
/phlo/resources/connectors/shops/Lightspeed.phlo
const
Lightspeed :: section
line 11
在Lightspeed应用程序中定义一个部分,允许在该部分内组织和管理内容。
'Lightspeed'method
%Lightspeed -> base
line 13
Lightspeed->base 构建访问 Lightspeed API 的基础 URL,如果可用,则包含配置中的集群 ID。
'https://api.lightspeedapp.com/API/V3/Account/'.($this->config['cluster_id'] ?? void)method
%Lightspeed -> headers
line 15
此方法使用配置中提供的API密钥和密钥检索Lightspeed API身份验证所需的头部。
[static::basic($this->config['api_key'] ?? void, $this->config['api_secret'] ?? void)]static
Lightspeed :: fields
line 17
Lightspeed::$fields 定义了连接到 Lightspeed API 所需的配置字段,包括集群 ID、语言、API 密钥、API 秘密和访问范围。
arr(
section: 'Lightspeed',
config: arr(
cluster_id: 'Account / cluster ID',
language: 'Language (optional, default nl)',
),
secret: arr(
api_key: 'API key',
api_secret: 'API secret',
),
scopes: 'Customer read/write, Sale read',
)method
%Lightspeed -> customers (array $query = []):obj
line 30
使用提供的查询参数从Lightspeed API检索客户数据。
if ($m = $this->missing('cluster_id', 'api_key', 'api_secret')) return $m
return $this->get('Customer.json', $query)method
%Lightspeed -> findCustomer ($participant):obj
line 35
根据提供的参与者标识符的格式,通过电子邮件或电话号码查找客户。
if ($m = $this->missing('cluster_id', 'api_key', 'api_secret')) return $m
$field = str_contains((string)$participant, '@') ? 'Email' : 'Phone'
return $this->get('Customer.json', [$field => $participant, 'limit' => 1])method
%Lightspeed -> customer ($id):obj
line 41
使用指定的客户ID从Lightspeed API检索客户信息。
if ($m = $this->missing('cluster_id', 'api_key', 'api_secret')) return $m
return $this->get('Customer/'.$id.'.json')method
%Lightspeed -> sales (array $query = []):obj
line 46
使用提供的查询参数从API获取销售数据,确保所需的凭据存在。
if ($m = $this->missing('cluster_id', 'api_key', 'api_secret')) return $m
return $this->get('Sale.json', $query)method
%Lightspeed -> createCustomer (array $customer):obj
line 51
通过将提供的客户数据发送到Lightspeed API来创建新客户,确保所需参数存在。
if ($m = $this->missing('cluster_id', 'api_key', 'api_secret')) return $m
return $this->post('Customer.json', $customer)object
%MessageBird
/phlo/resources/connectors/chat/MessageBird.phlo
const
MessageBird :: section
line 11
在Phlo应用程序中定义MessageBird的一个部分。
'MessageBird'method
%MessageBird -> base
line 13
这定义了MessageBird API的基础URL,用于发送和接收消息。
'https://rest.messagebird.com'method
%MessageBird -> headers
line 15
这获取了使用提供的访问密钥对MessageBird API请求进行身份验证所需的头部信息。
['Authorization: AccessKey '.($this->config['access_key'] ?? void)]static
MessageBird :: fields
line 17
定义了MessageBird配置的字段,包括发件人和访问密钥。
arr(
section: 'MessageBird',
config: arr(originator: 'Originator (sender number or name)'),
secret: arr(access_key: 'Access key'),
)static
MessageBird :: errorMessage ($data, string $raw, int $status):string
line 23
从MessageBird API响应中检索错误消息(如果可用);否则,回退到父类的错误消息方法。
if (is_object($data) && isset($data->errors[0]->description)) return (string)$data->errors[0]->description
return parent::errorMessage($data, $raw, $status)method
%MessageBird -> sms ($to, $body, array $extra = []):obj
line 28
使用MessageBird API向指定的接收者发送SMS消息,需提供访问密钥和发件人配置。
if ($m = $this->missing('access_key', 'originator')) return $m
$recipients = is_array($to) ? $to : [$to]
return $this->post('messages', ['originator' => $this->config['originator'], 'recipients' => $recipients, 'body' => $body] + $extra)object
%MicrosoftGraph
/phlo/resources/connectors/cloud/MicrosoftGraph.phlo
const
MicrosoftGraph :: section
line 11
此功能与 Microsoft Graph API 交互,以管理资源中的部分。
'Microsoft'method
%MicrosoftGraph -> base
line 13
这定义了访问 Microsoft Graph API 的基本 URL,允许与 Microsoft 服务和资源进行交互。
'https://graph.microsoft.com/v1.0'method
%MicrosoftGraph -> headers
line 15
此项使用承载令牌检索与 Microsoft Graph 进行身份验证所需的头部信息。
[static::bearer((string)$this->token)]static
MicrosoftGraph :: fields
line 17
定义连接到 Microsoft Graph 所需的配置字段,包括租户 ID、客户端 ID、邮箱、客户端密钥和应用程序权限。
arr(
section: 'Microsoft',
config: arr(
tenant_id: 'Azure AD tenant ID',
client_id: 'App registration client ID',
mailbox: 'Default mailbox / user UPN for calendar and mail (optional)',
),
secret: arr(client_secret: 'App registration client secret'),
scopes: 'Application permissions: User.Read.All, Calendars.ReadWrite, Mail.Send',
)prop
%MicrosoftGraph -> token
line 28
使用fetchToken方法从Microsoft Graph获取访问令牌。
$this->fetchToken()method
%MicrosoftGraph -> fetchToken
line 30
使用客户端凭据从 Microsoft Graph 获取 OAuth2 令牌,如果 APCu 可用,则缓存该令牌以供将来使用。
$tenant = $this->config['tenant_id'] ?? void
$id = $this->config['client_id'] ?? void
$secret = $this->config['client_secret'] ?? void
if ($tenant === void || $id === void || $secret === void) return void
$key = 'phlo:graph:'.$tenant.colon.$id
if (function_exists('apcu_fetch')){
$cached = apcu_fetch($key)
if ($cached) return $cached
}
$res = $this->dispatch(static::build('POST', 'https://login.microsoftonline.com/'.$tenant.'/oauth2/v2.0/token', null, [], null, ['grant_type' => 'client_credentials', 'client_id' => $id, 'client_secret' => $secret, 'scope' => 'https://graph.microsoft.com/.default']))
if (!$res->ok) return void
$token = $res->data->access_token ?? void
$expires = (int)($res->data->expires_in ?? 3600)
if ($token !== void && function_exists('apcu_store')) apcu_store($key, $token, max(60, $expires - 60))
return $tokenmethod
%MicrosoftGraph -> mailbox ($user = null)
line 48
检索与指定用户关联的邮箱,如果未提供用户,则默认为配置的邮箱。
$user ?? ($this->config['mailbox'] ?? void)method
%MicrosoftGraph -> users (array $query = []):obj
line 50
根据提供的查询参数从 Microsoft Graph 检索用户列表。
if ($m = $this->missing('tenant_id', 'client_id', 'client_secret')) return $m
return $this->get('users', $query)method
%MicrosoftGraph -> user ($id):obj
line 55
使用指定的用户ID从Microsoft Graph获取用户信息。
if ($m = $this->missing('tenant_id', 'client_id', 'client_secret')) return $m
return $this->get('users/'.rawurlencode((string)$id))method
%MicrosoftGraph -> events ($user = null, array $query = []):obj
line 60
使用 Microsoft Graph API 从指定用户的 Microsoft 邮箱中获取事件。
if ($m = $this->missing('tenant_id', 'client_id', 'client_secret')) return $m
$mailbox = $this->mailbox($user)
if ($mailbox === void) return static::fail('Microsoft mailbox required')
return $this->get('users/'.rawurlencode((string)$mailbox).'/events', $query)method
%MicrosoftGraph -> sendMail ($message, $user = null, bool $save = true):obj
line 67
使用 Microsoft Graph API 发送电子邮件消息,可以选择指定用户以及是否将消息保存到已发送邮件文件夹。
if ($m = $this->missing('tenant_id', 'client_id', 'client_secret')) return $m
$mailbox = $this->mailbox($user)
if ($mailbox === void) return static::fail('Microsoft mailbox required')
return $this->post('users/'.rawurlencode((string)$mailbox).'/sendMail', ['message' => $message, 'saveToSentItems' => $save])method
%MicrosoftGraph -> createEvent (array $event, $user = null):obj
line 74
使用提供的事件详细信息在指定用户的 Microsoft 日历中创建新事件。
if ($m = $this->missing('tenant_id', 'client_id', 'client_secret')) return $m
$mailbox = $this->mailbox($user)
if ($mailbox === void) return static::fail('Microsoft mailbox required')
return $this->post('users/'.rawurlencode((string)$mailbox).'/events', $event)object
%Moneybird
/phlo/resources/connectors/finance/Moneybird.phlo
const
Moneybird :: section
line 11
在Moneybird集成中定义一个部分,用于组织相关功能。
'Moneybird'method
%Moneybird -> base
line 13
这会检索Moneybird API的基础URL,如果可用,则包含配置中的管理ID。
'https://moneybird.com/api/v2/'.($this->config['administration_id'] ?? void)method
%Moneybird -> headers
line 15
返回与Moneybird API身份验证所需的headers,使用从配置中的访问令牌派生的bearer token。
[static::bearer($this->config['access_token'] ?? void)]static
Moneybird :: fields
line 17
定义了Moneybird集成的字段,包括管理ID和用于访问联系人和发票的个人访问令牌。
arr(
section: 'Moneybird',
config: arr(administration_id: 'Administration ID'),
secret: arr(access_token: 'Personal access token with read/write for contacts and invoices'),
)method
%Moneybird -> contacts (array $query = []):obj
line 23
根据提供的查询参数从Moneybird获取联系人列表。
if ($m = $this->missing('administration_id', 'access_token')) return $m
return $this->get('contacts.json', $query)method
%Moneybird -> findContact ($query):obj
line 28
根据提供的查询在Moneybird中查找联系人,返回找到的第一个结果。
if ($m = $this->missing('administration_id', 'access_token')) return $m
return $this->get('contacts.json', ['query' => $query, 'per_page' => 1])method
%Moneybird -> contact ($id):obj
line 33
从Moneybird检索与指定ID关联的联系人信息,需提供管理ID和访问令牌。
if ($m = $this->missing('administration_id', 'access_token')) return $m
return $this->get('contacts/'.$id.'.json')method
%Moneybird -> invoices (array $query = []):obj
line 38
根据提供的查询参数从Moneybird获取发票,要求提供'administration_id'和'access_token'。
if ($m = $this->missing('administration_id', 'access_token')) return $m
return $this->get('sales_invoices.json', $query)method
%Moneybird -> createContact (array $contact):obj
line 43
使用提供的联系信息在Moneybird中创建新联系人。它需要一个管理ID和访问令牌才能正常工作。
if ($m = $this->missing('administration_id', 'access_token')) return $m
return $this->post('contacts.json', ['contact' => $contact])method
%Moneybird -> createInvoice (array $invoice):obj
line 48
使用提供的发票数据在Moneybird中创建新发票。
if ($m = $this->missing('administration_id', 'access_token')) return $m
return $this->post('sales_invoices.json', ['sales_invoice' => $invoice])object
%OAuthConnector
/phlo/resources/connectors/OAuthConnector.phlo
const
OAuthConnector :: tokenUrl
line 11
指定获取OAuth令牌的URL。
voidmethod
%OAuthConnector -> oauthKey
line 13
获取OAuthConnector中当前部分的OAuth密钥。
static::sectionprop
%OAuthConnector -> token
line 15
使用提供的凭据和刷新令牌从 TokenStore 中检索 OAuth 令牌。
TokenStore::access($this->oauthKey, static::tokenUrl, $this->config['client_id'] ?? void, $this->config['client_secret'] ?? void, ['refresh_token' => $this->config['refresh_token'] ?? null])method
%OAuthConnector -> headers
line 17
返回OAuth认证所需的头部,包括从实例的token派生的bearer token。
[static::bearer((string)$this->token)]method
%OAuthConnector -> authed
line 19
通过验证OAuth令牌是否非空来检查其是否已认证。
(string)$this->token !== voidobject
%Resend
/phlo/resources/connectors/chat/Resend.phlo
const
Resend :: section
line 11
Resend::section 允许您在 Resend 资源中定义一个部分,以组织相关内容。
'Resend'method
%Resend -> base
line 13
设置 Resend API 的基础 URL。
'https://api.resend.com'method
%Resend -> headers
line 15
使用配置中提供的API密钥设置Resend请求的头部。
[static::bearer($this->config['api_key'] ?? void)]static
Resend :: fields
line 17
定义Resend配置的字段,包括默认发件人电子邮件和API密钥。
arr(
section: 'Resend',
config: arr(from_email: 'Default sender, e.g. "App <noreply@yourdomain.com>"'),
secret: arr(api_key: 'API key (re_...)'),
)method
%Resend -> send ($to, $subject, $html = void, array $extra = []):obj
line 23
使用配置的发件人电子邮件地址向指定的收件人发送电子邮件,主题和可选的 HTML 内容。
if ($m = $this->missing('api_key', 'from_email')) return $m
$email = ['from' => $this->config['from_email'], 'to' => is_array($to) ? $to : [$to], 'subject' => $subject]
if ($html !== void) $email['html'] = $html
return $this->post('emails', $email + $extra)object
%Shopify
/phlo/resources/connectors/shops/Shopify.phlo
const
Shopify :: section
line 11
在Shopify主题中定义一个部分,允许在商店内自定义内容和布局。
'Shopify'method
%Shopify -> base
line 13
使用配置中的商店域名和API版本构建Shopify API的基础URL。
'https://'.($this->config['shop_domain'] ?? void).'/admin/api/'.($this->config['api_version'] ?? '2024-01')method
%Shopify -> headers
line 15
这获取了Shopify API身份验证所需的头信息,包括来自配置的访问令牌。
['X-Shopify-Access-Token: '.($this->config['access_token'] ?? void)]static
Shopify :: fields
line 17
定义与Shopify集成的配置字段,包括商店域名、API版本、访问令牌和所需的权限范围。
arr(
section: 'Shopify',
config: arr(
shop_domain: 'Shop domain, e.g. your-store.myshopify.com',
api_version: 'Admin API version (optional, default 2024-01)',
),
secret: arr(access_token: 'Admin API access token (shpat_...)'),
scopes: 'read_customers, read_orders, read_products, write_draft_orders, write_inventory',
)method
%Shopify -> customers (array $query = []):obj
line 27
使用提供的查询参数从 Shopify 获取客户列表。
if ($m = $this->missing('shop_domain', 'access_token')) return $m
return $this->get('customers.json', $query)method
%Shopify -> searchCustomers ($query, int $limit = 10):obj
line 32
根据查询字符串和可选的结果数量限制在Shopify中搜索客户。
if ($m = $this->missing('shop_domain', 'access_token')) return $m
return $this->get('customers/search.json', ['query' => $query, 'limit' => $limit])method
%Shopify -> customer ($id):obj
line 37
使用指定的客户ID从Shopify获取客户信息。
if ($m = $this->missing('shop_domain', 'access_token')) return $m
return $this->get('customers/'.$id.'.json')method
%Shopify -> orders (array $query = []):obj
line 42
根据提供的查询参数从Shopify获取订单列表。
if ($m = $this->missing('shop_domain', 'access_token')) return $m
return $this->get('orders.json', $query)method
%Shopify -> products (array $query = []):obj
line 47
使用提供的查询参数从Shopify获取产品列表。
if ($m = $this->missing('shop_domain', 'access_token')) return $m
return $this->get('products.json', $query)method
%Shopify -> createDraftOrder (array $order):obj
line 52
使用提供的订单详细信息在Shopify中创建草稿订单。
if ($m = $this->missing('shop_domain', 'access_token')) return $m
return $this->post('draft_orders.json', ['draft_order' => $order])method
%Shopify -> createProduct (array $product):obj
line 57
使用提供的产品详细信息在 Shopify 中创建新产品。
if ($m = $this->missing('shop_domain', 'access_token')) return $m
return $this->post('products.json', ['product' => $product])method
%Shopify -> setInventory ($inventoryItemId, $locationId, int $available):obj
line 62
为Shopify中特定库存项目在给定位置设置可用库存水平。
if ($m = $this->missing('shop_domain', 'access_token')) return $m
return $this->post('inventory_levels/set.json', ['inventory_item_id' => $inventoryItemId, 'location_id' => $locationId, 'available' => $available])object
%Slack
/phlo/resources/connectors/chat/Slack.phlo
const
Slack :: section
line 11
在Slack消息中创建一个部分块,允许包含文本和其他元素。
'Slack'const
Slack :: api
line 12
此项提供对Slack API的访问,允许与Slack服务和功能集成。
'https://slack.com/api'method
%Slack -> headers
line 14
返回使用 bearer token 向 Slack API 发出请求时所需的身份验证头。
[static::bearer($this->config['bot_token'] ?? void)]static
Slack :: fields
line 16
定义与Slack集成的配置字段,包括机器人令牌、签名密钥和所需的作用域。
arr(
section: 'Slack',
secret: arr(
bot_token: 'Bot user OAuth token (xoxb-...)',
signing_secret: 'Signing secret for inbound webhook verification (optional)',
),
scopes: 'chat:write, channels:history, channels:read',
)method
%Slack -> result (obj $res):obj
line 25
处理来自Slack API调用的结果,如果成功则返回响应,如果发生错误则返回错误消息。
if (!$res->ok) return $res
$data = $res->data
if (is_object($data) && ($data->ok ?? null) === false) return static::fail($data->error ?? 'Slack API error', $res->status)
return $resmethod
%Slack -> send ($channel, $text, array $extra = []):obj
line 32
使用Slack API向指定的Slack频道发送消息。它需要配置的bot令牌,并通过数组接受额外参数。
if (!$this->configured('bot_token')) return static::fail('Slack bot_token not configured')
return $this->result($this->post('chat.postMessage', ['channel' => $channel, 'text' => $text] + $extra))method
%Slack -> history ($channel, int $limit = 20):obj
line 37
从指定的Slack频道获取消息历史记录,并可选择限制返回的消息数量。
if (!$this->configured('bot_token')) return static::fail('Slack bot_token not configured')
return $this->result($this->get('conversations.history', ['channel' => $channel, 'limit' => $limit]))method
%Slack -> channels (int $limit = 100, string $types = 'public_channel'):obj
line 42
从Slack获取频道列表,可以选择限制频道数量并指定要返回的频道类型。
if (!$this->configured('bot_token')) return static::fail('Slack bot_token not configured')
return $this->result($this->get('conversations.list', ['limit' => $limit, 'types' => $types]))object
%Telegram
/phlo/resources/connectors/chat/Telegram.phlo
const
Telegram :: section
line 11
在Telegram资源中定义一个部分,允许对相关内容进行有组织的分组。
'Telegram'method
%Telegram -> base
line 13
使用配置中提供的机器人令牌构建Telegram Bot API的基本URL。
'https://api.telegram.org/bot'.($this->config['bot_token'] ?? void)static
Telegram :: fields
line 15
定义与Telegram配置相关的字段,包括机器人令牌和用于验证的可选Webhook密钥。
arr(
section: 'Telegram',
secret: arr(
bot_token: 'Bot token from BotFather',
webhook_secret: 'Webhook secret token for inbound verification (optional)',
),
help: 'Create a bot via BotFather and store its token. The chat_id is the recipient or chat to message.',
)method
%Telegram -> result (obj $res):obj
line 24
处理来自Telegram API响应的结果,如果成功则返回响应,若检测到错误则返回失败消息。
if (!$res->ok) return $res
$data = $res->data
if (is_object($data) && ($data->ok ?? null) === false) return static::fail($data->description ?? 'Telegram API error', $res->status)
return $resmethod
%Telegram -> send ($chatId, $text, array $extra = []):obj
line 31
使用提供的聊天ID和文本向指定的Telegram聊天发送消息,并可以选择额外参数。
if ($m = $this->missing('bot_token')) return $m
return $this->result($this->post('sendMessage', ['chat_id' => $chatId, 'text' => $text] + $extra))method
%Telegram -> photo ($chatId, $photo, $caption = void, array $extra = []):obj
line 36
向指定的Telegram聊天发送照片,附带可选的标题和额外参数。
if ($m = $this->missing('bot_token')) return $m
$payload = ['chat_id' => $chatId, 'photo' => $photo]
if ($caption !== void) $payload['caption'] = $caption
return $this->result($this->post('sendPhoto', $payload + $extra))method
%Telegram -> document ($chatId, $document, $caption = void, array $extra = []):obj
line 43
向指定的Telegram聊天发送文档,可选地包括标题和其他参数。
if ($m = $this->missing('bot_token')) return $m
$payload = ['chat_id' => $chatId, 'document' => $document]
if ($caption !== void) $payload['caption'] = $caption
return $this->result($this->post('sendDocument', $payload + $extra))method
%Telegram -> updates (int $offset = 0, int $limit = 100):obj
line 50
从Telegram bot API获取更新,允许通过'offset'和'limit'参数进行分页。
if ($m = $this->missing('bot_token')) return $m
return $this->result($this->get('getUpdates', ['offset' => $offset, 'limit' => $limit]))object
%TokenStore
/phlo/resources/connectors/TokenStore.phlo
static
TokenStore :: path ($key):string
line 10
TokenStore::$path 属性定义了存储令牌数据的文件路径,该路径基于提供的键的经过清理的版本格式化为 JSON 文件。
data.'tokens/'.preg_replace('/[^a-z0-9_.-]+/i', us, (string)$key).'.json'static
TokenStore :: read ($key):array
line 12
通过键从TokenStore读取令牌,如果文件存在且可访问,则返回令牌数组。
$file = static::path($key)
if (!is_file($file)) return []
@chmod(data.'tokens', 0700)
@chmod($file, 0600)
return (array)json_read($file, true)static
TokenStore :: write ($key, array $token):void
line 20
该方法将令牌写入指定文件中的安全目录,确保目录和文件具有适当的权限。
$dir = data.'tokens'
is_dir($dir) || mkdir($dir, 0700, true)
@chmod($dir, 0700)
$file = static::path($key)
json_write($file, $token)
@chmod($file, 0600)static
TokenStore :: valid (array $token):bool
line 29
通过确保访问令牌存在且未过期(允许在过期前有30秒的缓冲)来检查访问令牌是否有效。
($token['access_token'] ?? void) !== void && (int)($token['expires_at'] ?? 0) > time() + 30static
TokenStore :: store ($res, $refresh):array
line 31
存储访问令牌、刷新令牌和过期时间以用于身份验证。
$token = [
'access_token' => $res['access_token'],
'refresh_token' => $res['refresh_token'] ?? $refresh,
'expires_at' => time() + (int)($res['expires_in'] ?? 3600),
]
return $tokenstatic
TokenStore :: lock ($key)
line 42
TokenStore::$lock 管理基于文件的锁定机制,用于令牌存储,确保在操作期间对令牌文件的独占访问。
$dir = data.'tokens'
is_dir($dir) || mkdir($dir, 0700, true)
$lock = @fopen(static::path($key).'.lock', 'c')
if (!$lock || !flock($lock, LOCK_EX)){
$lock && fclose($lock)
return null
}
return $lockstatic
TokenStore :: access ($key, $tokenUrl, $clientId, $clientSecret, array $seed = []):?string
line 53
从 TokenStore 中检索访问令牌,如有必要,使用刷新令牌进行刷新。
$token = static::read($key)
if (static::valid($token)) return $token['access_token']
$lock = static::lock($key)
if (!$lock) return null
try {
$token = static::read($key)
if (!($token['refresh_token'] ?? null) && ($seed['refresh_token'] ?? null)){
$token = ['refresh_token' => $seed['refresh_token']]
static::write($key, $token)
}
if (static::valid($token)) return $token['access_token']
$refresh = $token['refresh_token'] ?? null
if (!$refresh || !$tokenUrl || !$clientId) return null
$res = OAuth2::refresh($tokenUrl, $clientId, $clientSecret, $refresh)
if (!($res['access_token'] ?? null)) return null
$token = static::store($res, $refresh)
static::write($key, $token)
return $token['access_token']
} finally {
flock($lock, LOCK_UN)
fclose($lock)
}object
%Twilio
/phlo/resources/connectors/chat/Twilio.phlo
const
Twilio :: section
line 11
在Phlo应用程序中定义Twilio集成的部分。
'Twilio'method
%Twilio -> base
line 13
构建用于访问 Twilio API 的基础 URL,使用配置中的账户 SID。
'https://api.twilio.com/2010-04-01/Accounts/'.($this->config['account_sid'] ?? void)method
%Twilio -> headers
line 15
使用配置中提供的账户 SID 和身份验证令牌检索 Twilio API 请求所需的头部信息。
[static::basic($this->config['account_sid'] ?? void, $this->config['auth_token'] ?? void)]static
Twilio :: fields
line 17
定义用于配置 Twilio 集成的字段,包括账户 SID、发送者号码和可选的消息服务 SID,以及身份验证令牌。
arr(
section: 'Twilio',
config: arr(
account_sid: 'Account SID (ACxxxx)',
from_number: 'Sender number in E.164, e.g. +31600000000 (use this or messaging_service_sid)',
messaging_service_sid: 'Messaging Service SID (optional alternative to from_number)',
),
secret: arr(auth_token: 'Auth token'),
)method
%Twilio -> sms ($to, $body, array $extra = []):obj
line 27
使用Twilio的API发送SMS消息,配置中需要提供from_number或messaging_service_sid。
if ($m = $this->missing('account_sid', 'auth_token')) return $m
$from = $this->config['from_number'] ?? void
$service = $this->config['messaging_service_sid'] ?? void
if ($from === void && $service === void) return static::fail('Twilio from_number or messaging_service_sid required')
$fields = ['To' => $to, 'Body' => $body] + $extra
if ($service !== void) $fields['MessagingServiceSid'] = $service
else $fields['From'] = $from
return $this->form('Messages.json', $fields)method
%Twilio -> message ($sid):obj
line 38
使用指定的消息 SID 从 Twilio 检索消息。
if ($m = $this->missing('account_sid', 'auth_token')) return $m
return $this->get('Messages/'.$sid.'.json')