Skip to content

Latest commit

 

History

History
339 lines (276 loc) · 13.8 KB

README.zh-tw.md

File metadata and controls

339 lines (276 loc) · 13.8 KB

Onfleet Node.js Wrapper

Build License Latest version Top language Dependencies Downloads

其他語言版本:
English
Français
Español

欲了解本開源專案的背景,請參閱我們的部落格,如果對於Onfleet應用程式介面或是我們產品有任何的問題,歡迎在此留言或直接聯繫 [email protected]

目錄

概要

node-onfleet 提供一個快速又便捷的方式,以獲取Onfleet應用程式介面內的資料。

安裝

npm install @onfleet/node-onfleet

若是使用TypeScript,則需另外安裝typed definition

npm install @types/onfleet__node-onfleet

感謝 @marcobeltempo 的開源贊助

我們選用了node-fetch當作我們HTTP請求的工具,它使用了原生的Fetch API,支援promise,跟其他工具組相比依賴性上也較低。

使用守則

在使用Onfleet應用程式介面之前,請先索取應用程式介面金鑰。創建應用程式介面金鑰的詳情,請洽Onfleet官方網站

將您的金鑰取代下面的api_key參數即可開始使用:

const onfleetApi = new Onfleet("<your_api_key>");

由於某些應用的執行逾時參數較低(例如Heroku的三十秒設定),您可以在創立物件時,提供一個低於70000ms、客製化的逾時參數:

const onfleetApi = new Onfleet("<your_api_key>", 30000);

作為可選字段,您可以引入一個用於 Bottleneck 的選項對象 Bottleneck.

const onfleetApi = new Onfleet("<your_api_key>", 30000, {
  LIMITER_RESERVOIR: 10,               // Default: 20
  LIMITER_WAIT_UPON_DEPLETION: 20000,  // Default: 10000
  LIMITER_MAX_CONCURRENT: 5,           // Default: 1
  LIMITER_MIN_TIME: 50,                // Default: 50
});

金鑰認證

當Onfleet物件成功被創建,表示您的應用程式介面金鑰是符合預期的。您可以嘗試使用verifyKey函式來測試您的金鑰是否合法,authentication這個endpoint會認證您的金鑰,回應為一布林值:

onfleetApi.verifyKey();  // Returns a boolean

當Onfleet物件成功被創建,而金鑰又是合法的,您會獲得訪問以下各endpoint資源的函式。欲獲得各endpoint資源的定義,請洽Onfleet官方應用程式介面文件

單元測試

npm test

使用Docker進行單元測試

docker-compose up --build

API速限

原則上API的速限為每秒鐘20次請求,詳情請參考官方文件。在此模組內我們也提供了限速,以避免您無意間超過了API請求的速限而導致帳號被禁的狀況。

請求回應

所有請求的回應皆為一Response物件的內容主體。

支援的CRUD操作

下面為各endpoint所支援的函式列表:

Entity GET POST PUT DELETE
Admins/Administrators get() create(obj)
matchMetadata(obj)
update(id, obj) deleteOne(id)
Containers get(id, 'workers')
get(id, 'teams')
get(id, 'organizations')
x insertTask(id, obj) x
Destinations get(id) create(obj)
matchMetadata(obj)
x x
Hubs get() create(obj) update(id, obj) x
Organization get()
get(id)
x x x
Recipients get(id)
get(name, 'name')
get(phone, 'phone')
create(obj)
matchMetadata(obj)
update(id, obj) x
Tasks get(query)
get(id)
get(shortId, 'shortId')
create(obj)
clone(id)
clone(id, obj)
forceComplete(id, obj)
batchCreate(obj)
batchCreateAsync(obj)
getBatch(id)
autoAssign(obj)
matchMetadata(obj)
update(id, obj) deleteOne(id)
Teams get()
get(id)
getWorkerEta(id, obj)
getTasks(id)
create(obj)
autoDispatch(id, obj)
update(id, obj) deleteOne(id)
Webhooks get() create(obj) x deleteOne(id)
Workers get()
get(query)
get(id)
getByLocation(obj)
getSchedule(id)
getTasks(id)
create(obj)
setSchedule(id, obj)
matchMetadata(obj)
getDeliveryManifest(obj)
update(id, obj)
insertTask(id, obj)
deleteOne(id)
Custom Fields get(integration) create(obj) update(obj) delete(obj)

GET 請求

展示所有資源的指令如下,回應的主體為包含一陣列的Promise物件:

get();
使用get展示所有資源的範例
onfleetApi.workers.get().then((results) => { /* ... */ });
onfleetApi.workers.get({ queryParams }).then((results) => { /* ... */ });

部分的endpoint有支援queryParam(查詢參數),詳情請參考Onfleet官方文件

onfleetApi.workers.get({ phones: "<phone_number>" }).then((results) => { /* ... */ });

onfleetApi.tasks.get({ from: "<from_time>", to: "<to_time>" }).then((results) => { /* ... */ });

查詢參數唯一的要求就是為一個JSON物件,舉例來說,{ 'analytics': 'true' }以及{ analytics: true }都會被接受

展示指定資源的指令如下,指定的參數預設為24碼的物件ID,如果提供額外的paramName(參數名稱)以及queryParam(查詢參數),則會根據參數做展示:

get(<parameter>, <paramName> (optional), <queryParam> (optional));

paramName可以是:

  • id
  • name
  • phone
  • shortId
使用get展示指定資源的範例
onfleetApi.workers.get("<24_digit_ID>").then((result) => { /* ... */ });
onfleetApi.workers.get("<24_digit_ID>", { analytics: true }).then((result) => { /* ... */ });

onfleetApi.tasks.get("<shortId>", "shortId").then((result) => { /* ... */ });

onfleetApi.recipients.get("<phone_number>", "phone").then((result) => { /* ... */ });
onfleetApi.recipients.get("<recipient_name>", "name").then((result) => { /* ... */ });
onfleetApi.recipients
  .get("<recipient_name>", "name", { skipPhoneNumberValidation: true })
  .then((result) => { /* ... */ });

onfleetApi.containers.get("<24_digit_ID>", "workers").then((result) => { /* ... */ });
onfleetApi.containers.get("<24_digit_ID>", "teams").then((result) => {{ /* ... */ });
onfleetApi.containers.get("<24_digit_ID>", "organizations").then((result) => { /* ... */ });

欲大量獲取某指定ID的task資料,請使用getBatch節點:

展示批量task資料的getBatch(id)資源範例
onfleetAPI.tasks.getBatch("<jobId>","jobId").then((result) => { /* ... */ });

欲使用地理位置來搜尋線上的worker,請使用getByLocation

getByLocation({ queryParams });
展示指定地理位置的getByLocation資源範例
const locationParams = {
  longitude: -122.404,
  latitude: 37.789,
  radius: 10000,
};

onfleetApi.workers.getByLocation(locationParams).then((results) => { /* ... */ });

POST 請求

提交某單一指定資源的指令如下:

create(<object>);
使用create提交指定資源的範例
const data = {
  name: "John Driver",
  phone: "+16173428853",
  teams: ["<team_ID>", "<team_ID> (optional)", ...],
  vehicle: {
    type: "CAR",
    description: "Tesla Model 3",
    licensePlate: "FKNS9A",
    color: "purple",
  },
};

onfleetApi.workers.create(data);
使用getDeliveryManifest提交指定資源的範例
const data = {
  hubId: "<hubId>", // Required
  workerId: "<workerId", // Required
  googleApiKey: "<google_direction_api_key>", // Optional
  startDate: "<startDate>", // Optional
  endDate: "<endDate>" // Optional
};

onfleetApi.workers.getDeliveryManifest(data);

其他延伸的POST請求包含了Tasks節點上的clone, forceComplete, batchCreate,batchCreateAsync, autoAssignWorkers節點上的setScheduleTeams節點上的autoDispatch,以及所有支持節點上的matchMetadata

onfleetApi.tasks.clone('<24_digit_ID>');
onfleetApi.tasks.forceComplete('<24_digit_ID>', { data });
onfleetApi.tasks.batchCreate({ data });
onfleetApi.tasks.batchCreateAsync({ data });
onfleetApi.tasks.autoAssign({ data });

onfleetApi.workers.setSchedule('<24_digit_ID>', { data });
onfleetAPI.workers.getDeliveryManifest({ data });

onfleetApi.teams.autoDispatch('<24_digit_ID>', { data });

onfleetApi.<entity_name_pluralized>.matchMetadata({ data });

參考資料:clone, forceComplete, batchCreate, autoAssign, setSchedule, getDeliveryManifest, matchMetadata, 以及autoDispatch

PUT 請求

取代(更新)某單一指定資源的指令如下:

update("<24_digit_ID>", { data });
使用update取代指定資源的範例
const newData = {
  name: "Jack Driver",
};

onfleetApi.workers.update("<24_digit_ID>", newData);
使用insertTask取代指定資源的範例
onfleetApi.workers.insertTask("<24_digit_ID>", { data }).then((result) => { /* ... */ });

DELETE 請求

刪除某單一指定資源的指令如下:

deleteOne("<24_digit_ID>");
使用deleteOne刪除指定資源的範例
onfleet.workers.deleteOne('<24_digit_ID>');

利用CRUD操作的範例

  • 展示所有存在的recipients:

    onfleetApi.tasks
      .get({ from: "1557936000000", to: "1558022400000" })
      .then((tasks) => {
        for (let task of tasks) {
          if (task.recipients[0] !== undefined) {
            // Do something with the recipients
          }
        }
      })
      .catch((err) => { /* ... */ });
  • async/await 函數的使用方式:

    async function findAllWorkers() {
      try {
        let response = await onfleetApi.workers.get();
        // Do something with the response
      }
      catch (err) { /* ... */ }
    }
    
    findAllWorkers();

錯誤的示範

  • 效率不佳的請求模型(請求中的請求),建議使用metadata:
    // DONT
    onfleetApi.workers
      .get()
      .then((workers) => {
        for (let worker of workers) {
          for (let metadataEntry of worker.metadata) {
            if (metadataEntry.name === "hasFreezer" && metadataEntry.value) {
              // Do something
            }
          }
        }
      })
      .catch((err) => { /* ... */ });
    
    // DO
    onfleetApi.workers
      .matchMetadata([{"name": "hasFreezer", "type": "boolean", "value": true}])
      .then((workers) => {
        for (let worker of workers) {
          // Do something
        }
      })
      .catch((err) => { /* ... */ });

返回頂端