1.3.8 • Published 10 months ago

@onfleet/node-onfleet v1.3.8

Weekly downloads
1,739
License
MIT
Repository
github
Last release
10 months ago

Onfleet Node.js Wrapper

Build License Latest version Top language Dependencies Downloads

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

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

目錄

概要

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所支援的函式列表:

EntityGETPOSTPUTDELETE
Admins/Administratorsget()create(obj)matchMetadata(obj)update(id, obj)deleteOne(id)
Containersget(id, 'workers')get(id, 'teams')get(id, 'organizations')xinsertTask(id, obj)x
Destinationsget(id)create(obj)matchMetadata(obj)xx
Hubsget()create(obj)update(id, obj)x
Organizationget()get(id)xxx
Recipientsget(id)get(name, 'name')get(phone, 'phone')create(obj)matchMetadata(obj)update(id, obj)x
Tasksget(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)
Teamsget()get(id)getWorkerEta(id, obj)getTasks(id)create(obj)autoDispatch(id, obj)update(id, obj)deleteOne(id)
Webhooksget()create(obj)xdeleteOne(id)
Workersget()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 Fieldsget(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) => { /* ... */ });

返回頂端

1.3.8

10 months ago

1.3.7

11 months ago

1.3.6

11 months ago

1.3.5

11 months ago

1.3.4

1 year ago

1.3.3

2 years ago

1.3.2

3 years ago

1.3.1

3 years ago

1.3.0

3 years ago

1.2.10

3 years ago

1.2.9

4 years ago

1.2.8

4 years ago

1.2.7

4 years ago

1.2.61

4 years ago

1.2.6

4 years ago

1.2.5

4 years ago

1.2.4

4 years ago

1.2.3

4 years ago

1.2.2

4 years ago

1.2.1

4 years ago

1.2.0

4 years ago

1.1.1

5 years ago

1.1.0

5 years ago

1.0.9

5 years ago

1.0.8

5 years ago

1.0.7

5 years ago

1.0.5

6 years ago

1.0.4

6 years ago

1.0.3

6 years ago

1.0.2

6 years ago

1.0.1

6 years ago

1.0.0

6 years ago