Thông báo đẩy (Dialogflow)

Khám phá trong Dialogflow

Nhấp vào Tiếp tục để nhập mẫu Thông báo của chúng tôi vào Dialogflow. Sau đó, hãy làm theo các bước bên dưới để triển khai và kiểm thử mẫu:

  1. Nhập tên nhân viên hỗ trợ rồi tạo một nhân viên hỗ trợ Dialogflow mới cho mẫu.
  2. Sau khi nhập xong nhân viên hỗ trợ, hãy nhấp vào Chuyển đến nhân viên hỗ trợ.
  3. Trên trình đơn điều hướng chính, hãy chuyển đến mục Thực hiện đơn hàng.
  4. Bật Inline Editor (Trình chỉnh sửa cùng dòng), sau đó nhấp vào Deploy (Triển khai). Trình chỉnh sửa chứa mã mẫu.
  5. Trên trình đơn điều hướng chính, hãy chuyển đến phần Tích hợp, rồi nhấp vào Trợ lý Google.
  6. Trong cửa sổ phụ xuất hiện, hãy bật tính năng Auto-preview changes (Tự động xem trước các thay đổi) rồi nhấp vào Test (Kiểm thử) để mở Trình mô phỏng hành động.
  7. Trong trình mô phỏng, hãy nhập Talk to my test app để kiểm tra mẫu!

Hành động của bạn có thể đẩy thông báo cho người dùng bất cứ khi nào có liên quan, chẳng hạn như gửi lời nhắc khi gần đến hạn thực hiện một việc cần làm.

Trong hướng dẫn này, chúng tôi sẽ tham khảo mẫu các mẹo về Actions on Google để hướng dẫn bạn cách thiết lập thông báo đẩy cho Hành động của mình. Khi người dùng gọi Hành động này, ứng dụng sẽ hỏi xem họ có muốn nghe mẹo về cách phát triển Hành động này hay không. Người dùng có thể chọn một danh mục cụ thể hoặc được chọn ngẫu nhiên cho tiền boa hoặc họ có thể chọn nghe mẹo gần đây nhất.

Nền tảng được hỗ trợ

Thông báo đẩy có trên thiết bị Android và iOS (bạn phải cài đặt ứng dụng Trợ lý để nhận thông báo đẩy trên thiết bị iOS). Các tính năng này hiện không được hỗ trợ trên loa kích hoạt bằng giọng nói, màn hình thông minh hoặc các nền tảng khác.

Điều kiện tiên quyết

Bạn phải định cấu hình ít nhất một trong các Hành động trong dự án Hành động của mình làm ý định kích hoạt và ý định này sẽ được gọi khi người dùng nhấn vào một thông báo nhận được từ Trợ lý.

Bạn không thể định cấu hình Hành động của mình để kích hoạt Ý định chào mừng mặc định qua thông báo đẩy.

Thiết lập bảng điều khiển

Cách thêm tính năng hỗ trợ cho thông báo đẩy vào Hành động của bạn:

  1. Chuyển đến Bảng điều khiển Actions rồi chuyển đến phần Build > Actions (Tạo > Thao tác).

  2. Nhấp vào Hành động khớp với ý định kích hoạt bổ sung mà bạn muốn bật thông báo đẩy.

    Đối với mẫu mẹo về Hành động trên Google, bạn cần chọn "tell_latest_tip".

  3. Di chuyển xuống phần Mức độ tương tác của người dùng rồi bật tuỳ chọn Bạn có muốn gửi thông báo đẩy không.

  4. Nhập Tiêu đề nội dung.

    Đối với mẫu mẹo về Actions on Google, tiêu đề có thể là "Đã thêm tiền boa mới".

  5. Nhấp vào Lưu.

Nhập

Để phục vụ mục đích của các phần tiếp theo, trong mã phương thức thực hiện, bạn cần khai báo các lệnh nhập sau:

Dialogflow
const {
  dialogflow,
  UpdatePermission,
  Suggestions,
} = require('actions-on-google');
SDK Hành động
const {
  actionssdk,
  UpdatePermission,
  Suggestions,
} = require('actions-on-google');

Người dùng chọn tham gia

Trước khi có thể gửi thông báo đẩy cho người dùng, bạn phải yêu cầu họ chọn nhận thông báo. Bạn có thể làm việc này bằng cách cho họ thấy khối đề xuất để yêu cầu họ cấp quyền. Khi họ cấp quyền, bạn sẽ nhận được một mã nhận dạng người dùng cập nhật để gửi thông báo đẩy đến người dùng đó.

Hiện khối đề xuất để chọn sử dụng

Trước khi người dùng có thể nhận được thông báo đẩy từ Hành động của bạn, bạn phải cho họ thấy khối đề xuất để mời họ chọn nhận thông báo đẩy.

Đoạn mã sau đây sẽ gửi cho người dùng khối đề xuất "Cảnh báo cho tôi về các mẹo mới" cùng với phản hồi bằng văn bản.

Dialogflow Node.js
conv.ask('I can send you push notifications. Would you like that?');
conv.ask(new Suggestions('Send notifications'));
Node.js SDK Hành động
conv.ask(' I can send you push notifications. Would you like that?');
conv.ask(new Suggestions('Send notifications'));
Dialogflow Java
responseBuilder
    .add("I can send you push notifications. Would you like that?")
    .addSuggestions(new String[] {
        "Send notifications"
    });
Actions SDK Java
responseBuilder
    .add("I can send you push notifications. Would you like that?")
    .addSuggestions(new String[] {
        "Send notifications"
    });
Dialogflow JSON

Xin lưu ý rằng JSON dưới đây mô tả phản hồi webhook.

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "Hi! Welcome to Push Notifications!"
            }
          },
          {
            "simpleResponse": {
              "textToSpeech": "I can send you push notifications. Would you like that?"
            }
          }
        ],
        "suggestions": [
          {
            "title": "Send notifications"
          }
        ]
      }
    }
  }
}
Định dạng JSON cho SDK Hành động

Xin lưu ý rằng JSON dưới đây mô tả phản hồi webhook.

{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "possibleIntents": [
        {
          "intent": "actions.intent.TEXT"
        }
      ],
      "inputPrompt": {
        "richInitialPrompt": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "Hi! Welcome to Push Notifications!"
              }
            },
            {
              "simpleResponse": {
                "textToSpeech": " I can send you push notifications. Would you like that?"
              }
            }
          ],
          "suggestions": [
            {
              "title": "Send notifications"
            }
          ]
        }
      }
    }
  ]
}

Sau khi trẻ nhấn vào khối, bạn phải yêu cầu cấp quyền UPDATE. Mã sau đây cho bạn biết cách thực hiện việc này bằng hàm askForUpdatePermission của thư viện ứng dụng Node.js.

Dialogflow Node.js
  1. Mở nhân viên hỗ trợ của bạn trong bảng điều khiển Dialogflow rồi chọn ý định mà bạn đang thiết lập để cập nhật.
  2. Cuộn xuống phần Phản hồi và mở thẻ Trợ lý Google.
  3. Nhấp vào Thêm nội dung tin nhắn rồi chọn Khối đề xuất.
  4. Đặt nội dung cho khối thành nội dung thu hút người dùng chọn sử dụng. Trong mẫu mẹo về Actions on Google, chúng ta sẽ đặt khối này thành Cảnh báo cho tôi về các mẹo mới.
  5. Thêm một ý định Dialogflow khác, ví dụ như setup_push và đặt một hành động tương ứng, ví dụ: setup.push. Biểu thức của người dùng về ý định này phải khớp với văn bản của khối chọn tham gia, trong ví dụ Cảnh báo cho tôi về các mẹo mới.
Đoạn mã sau đây cho biết cách yêu cầu cấp quyền bằng cách sử dụng thư viện ứng dụng Actions on Google cho Node.js:
app.intent('Subscribe to Notifications', (conv) => {
  conv.ask(new UpdatePermission({
    intent: 'Notification',
  }));
});
Actions SDK Node.js

Bạn nên định cấu hình giải pháp NLU để kích hoạt một hàm yêu cầu cấp quyền nếu biểu thức người dùng khớp với giá trị của lời nhắc chọn nhận thông báo đẩy. Dưới đây là một ví dụ rất cơ bản dựa trên việc so khớp chuỗi:

conv.ask(new UpdatePermission({
  intent: 'Notification',
}));
Dialogflow Java
  1. Mở nhân viên hỗ trợ của bạn trong bảng điều khiển Dialogflow rồi chọn ý định mà bạn đang thiết lập để cập nhật.
  2. Cuộn xuống phần Phản hồi và mở thẻ Trợ lý Google.
  3. Nhấp vào Thêm nội dung tin nhắn rồi chọn Khối đề xuất.
  4. Đặt nội dung cho khối thành nội dung thu hút người dùng chọn sử dụng. Trong mẫu mẹo về Actions on Google, chúng ta sẽ đặt khối này thành Cảnh báo cho tôi về các mẹo mới.
  5. Thêm một ý định Dialogflow khác, ví dụ như setup_push và đặt một hành động tương ứng, ví dụ: setup.push. Biểu thức của người dùng về ý định này phải khớp với văn bản của khối chọn tham gia, trong ví dụ Cảnh báo cho tôi về các mẹo mới.
Đoạn mã sau đây cho biết cách yêu cầu cấp quyền bằng cách sử dụng thư viện ứng dụng Java/Kotlin của Actions on Google:
@ForIntent("Subscribe to Notifications")
public ActionResponse subscribeToNotifications(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  responseBuilder.add(new UpdatePermission().setIntent("Notification"));
  return responseBuilder.build();
}
Actions SDK Java

Bạn nên định cấu hình giải pháp NLU để kích hoạt một hàm yêu cầu cấp quyền nếu biểu thức người dùng khớp với giá trị của lời nhắc chọn nhận thông báo đẩy. Dưới đây là một ví dụ rất cơ bản dựa trên việc so khớp chuỗi:

ResponseBuilder responseBuilder = getResponseBuilder(request);
responseBuilder.add(new UpdatePermission().setIntent("Notification"));
return responseBuilder.build();
Dialogflow JSON

Xin lưu ý rằng JSON dưới đây mô tả một phản hồi bằng webhook sử dụng Dialogflow.

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "systemIntent": {
        "intent": "actions.intent.PERMISSION",
        "data": {
          "@type": "type.googleapis.com/google.actions.v2.PermissionValueSpec",
          "permissions": [
            "UPDATE"
          ],
          "updatePermissionValueSpec": {
            "intent": "tell_latest_tip"
          }
        }
      }
    }
  }
}
Định dạng JSON cho SDK Hành động

Xin lưu ý rằng JSON ở bên dưới mô tả một phản hồi webhook sử dụng SDK Hành động.

{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "possibleIntents": [
        {
          "intent": "actions.intent.PERMISSION",
          "inputValueData": {
            "@type": "type.googleapis.com/google.actions.v2.PermissionValueSpec",
            "permissions": [
              "UPDATE"
            ],
            "updatePermissionValueSpec": {
              "intent": "tell_latest_tip"
            }
          }
        }
      ]
    }
  ]
}

Hoàn tất gói thuê bao

Để hoàn tất gói thuê bao từ webhook Node.js, bạn cần lưu mã thông báo của người dùng và ý định mà họ đã chọn. Cả hai đều được chuyển làm đối số nếu người dùng cấp quyền.

Nếu Hành động của bạn được tạo bằng Dialogflow, bạn cần:

  • Thêm một ý định xử lý actions_intent_PERMISSION.
  • Chỉ định tên Hành động của ý định thành tên mà webhook của bạn có thể lọc để sử dụng sau này.

Mã sau đây cho biết cách xử lý một ý định Dialogflow bằng ý định có tên finish_push_setup kèm theo tên Hành động là finish.push.setup:

Dialogflow Node.js
app.intent('Confirm Notifications Subscription', (conv) => {
  if (conv.arguments.get('PERMISSION')) {
    const updatesUserId = conv.arguments.get('UPDATES_USER_ID');
    // Store user ID in database for later use
    conv.close(`Ok, I'll start alerting you.`);
  } else {
    conv.close(`Ok, I won't alert you.`);
  }
});
Node.js SDK Hành động
app.intent('actions.intent.PERMISSION', (conv) => {
  if (conv.arguments.get('PERMISSION')) {
    const updatesUserId = conv.arguments.get('UPDATES_USER_ID');
    // Store user ID in database for later use
    conv.close(`Ok, I'll start alerting you.`);
  } else {
    conv.close(`Ok, I won't alert you.`);
  }
});
Dialogflow Java
@ForIntent("Confirm Notifications Subscription")
public ActionResponse confirmNotificationsSubscription(ActionRequest request) {
  // Verify the user has subscribed for push notifications
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  if (request.isPermissionGranted()) {
    Argument userId = request.getArgument(ConstantsKt.ARG_UPDATES_USER_ID);
    if (userId != null) {
      // Store the user's ID in the database
    }
    responseBuilder.add("Ok, I'll start alerting you.");
  } else {
    responseBuilder.add("Ok, I won't alert you.");
  }
  responseBuilder.endConversation();
  return responseBuilder.build();
}
Actions SDK Java
@ForIntent("actions.intent.PERMISSION")
public ActionResponse confirmNotificationsSubscription(ActionRequest request) {
  // Verify the user has subscribed for push notifications
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  if (request.isPermissionGranted()) {
    Argument userId = request.getArgument(ConstantsKt.ARG_UPDATES_USER_ID);
    if (userId != null) {
      // Store the user's ID in the database
    }
    responseBuilder.add("Ok, I'll start alerting you.");
  } else {
    responseBuilder.add("Ok, I won't alert you.");
  }
  responseBuilder.endConversation();
  return responseBuilder.build();
}
Dialogflow JSON

Xin lưu ý rằng JSON ở bên dưới mô tả một yêu cầu đối với webhook.

{
  "responseId": "ee9e7ed5-fa1a-48c6-aac7-f9fbe94f1f58-712767ed",
  "queryResult": {
    "queryText": "actions_intent_PERMISSION",
    "action": "confirm.subscription",
    "parameters": {},
    "allRequiredParamsPresent": true,
    "fulfillmentMessages": [
      {
        "text": {
          "text": [
            ""
          ]
        }
      }
    ],
    "outputContexts": [
      {
        "name": "projects/PROJECT_ID/agent/sessions/ABwppHGIgmmU3zBcYMF_vWoHaM4JUo3wniYBHdbUF25l63G7EQWjRnlne8Ar7AOcRHWn1lrEKGy8qdP0UXLcWDBq93k/contexts/actions_capability_screen_output"
      },
      {
        "name": "projects/PROJECT_ID/agent/sessions/ABwppHGIgmmU3zBcYMF_vWoHaM4JUo3wniYBHdbUF25l63G7EQWjRnlne8Ar7AOcRHWn1lrEKGy8qdP0UXLcWDBq93k/contexts/actions_capability_account_linking"
      },
      {
        "name": "projects/PROJECT_ID/agent/sessions/ABwppHGIgmmU3zBcYMF_vWoHaM4JUo3wniYBHdbUF25l63G7EQWjRnlne8Ar7AOcRHWn1lrEKGy8qdP0UXLcWDBq93k/contexts/actions_capability_media_response_audio"
      },
      {
        "name": "projects/PROJECT_ID/agent/sessions/ABwppHGIgmmU3zBcYMF_vWoHaM4JUo3wniYBHdbUF25l63G7EQWjRnlne8Ar7AOcRHWn1lrEKGy8qdP0UXLcWDBq93k/contexts/actions_capability_audio_output"
      },
      {
        "name": "projects/PROJECT_ID/agent/sessions/ABwppHGIgmmU3zBcYMF_vWoHaM4JUo3wniYBHdbUF25l63G7EQWjRnlne8Ar7AOcRHWn1lrEKGy8qdP0UXLcWDBq93k/contexts/actions_capability_web_browser"
      },
      {
        "name": "projects/PROJECT_ID/agent/sessions/ABwppHGIgmmU3zBcYMF_vWoHaM4JUo3wniYBHdbUF25l63G7EQWjRnlne8Ar7AOcRHWn1lrEKGy8qdP0UXLcWDBq93k/contexts/google_assistant_input_type_keyboard"
      },
      {
        "name": "projects/PROJECT_ID/agent/sessions/ABwppHGIgmmU3zBcYMF_vWoHaM4JUo3wniYBHdbUF25l63G7EQWjRnlne8Ar7AOcRHWn1lrEKGy8qdP0UXLcWDBq93k/contexts/actions_intent_permission",
        "parameters": {
          "PERMISSION": true,
          "text": "yes",
          "UPDATES_USER_ID": "ABwppHHssyPbvEBF1mgN7Ddwb7mkhiVohW9PZ--I_svqy7zFElA4DHkf9pn04UBd5gwZo26_RfXCQ8otcztyIfe6MCQ"
        }
      }
    ],
    "intent": {
      "name": "projects/PROJECT_ID/agent/intents/c7f7b30b-5b88-4bb5-b0b8-1cd0862d1dd2",
      "displayName": "Confirm Notifications Subscription"
    },
    "intentDetectionConfidence": 1,
    "languageCode": "en"
  },
  "originalDetectIntentRequest": {
    "source": "google",
    "version": "2",
    "payload": {
      "user": {
        "permissions": [
          "UPDATE"
        ],
        "locale": "en-US",
        "userVerificationStatus": "VERIFIED"
      },
      "conversation": {
        "conversationId": "ABwppHGIgmmU3zBcYMF_vWoHaM4JUo3wniYBHdbUF25l63G7EQWjRnlne8Ar7AOcRHWn1lrEKGy8qdP0UXLcWDBq93k",
        "type": "ACTIVE",
        "conversationToken": "[]"
      },
      "inputs": [
        {
          "intent": "actions.intent.PERMISSION",
          "rawInputs": [
            {
              "inputType": "KEYBOARD",
              "query": "yes"
            }
          ],
          "arguments": [
            {
              "name": "PERMISSION",
              "boolValue": true,
              "textValue": "true"
            },
            {
              "name": "text",
              "rawText": "yes",
              "textValue": "yes"
            },
            {
              "name": "UPDATES_USER_ID",
              "textValue": "ABwppHHssyPbvEBF1mgN7Ddwb7mkhiVohW9PZ--I_svqy7zFElA4DHkf9pn04UBd5gwZo26_RfXCQ8otcztyIfe6MCQ"
            }
          ]
        }
      ],
      "surface": {
        "capabilities": [
          {
            "name": "actions.capability.SCREEN_OUTPUT"
          },
          {
            "name": "actions.capability.ACCOUNT_LINKING"
          },
          {
            "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
          },
          {
            "name": "actions.capability.AUDIO_OUTPUT"
          },
          {
            "name": "actions.capability.WEB_BROWSER"
          }
        ]
      },
      "availableSurfaces": [
        {
          "capabilities": [
            {
              "name": "actions.capability.AUDIO_OUTPUT"
            },
            {
              "name": "actions.capability.SCREEN_OUTPUT"
            },
            {
              "name": "actions.capability.WEB_BROWSER"
            }
          ]
        }
      ]
    }
  },
  "session": "projects/PROJECT_ID/agent/sessions/ABwppHGIgmmU3zBcYMF_vWoHaM4JUo3wniYBHdbUF25l63G7EQWjRnlne8Ar7AOcRHWn1lrEKGy8qdP0UXLcWDBq93k"
}
Định dạng JSON cho SDK Hành động

Xin lưu ý rằng JSON ở bên dưới mô tả một yêu cầu đối với webhook.

{
  "user": {
    "permissions": [
      "UPDATE"
    ],
    "locale": "en-US",
    "userVerificationStatus": "VERIFIED"
  },
  "conversation": {
    "conversationId": "ABwppHEP6OAFZHkSGEiZ5HYM9qrlk8YtIH1DQmJ52cxXELSPvM-kSc_tMJ_5O6ITbgVJlY9i2FIsKWjE_HXLke48",
    "type": "NEW"
  },
  "inputs": [
    {
      "intent": "actions.intent.PERMISSION",
      "rawInputs": [
        {
          "inputType": "KEYBOARD",
          "query": "yes"
        }
      ],
      "arguments": [
        {
          "name": "PERMISSION",
          "boolValue": true,
          "textValue": "true"
        },
        {
          "name": "text",
          "rawText": "yes",
          "textValue": "yes"
        },
        {
          "name": "UPDATES_USER_ID",
          "textValue": "ABwppHFvBKC-tMYUsUjJkm3YECgZvd6A3sOc7KuQvO4ZdQX3bGLmyoQ41dh4Zmtlzv_kaOKBt1Sf6eRpNbayynrl"
        }
      ]
    }
  ],
  "surface": {
    "capabilities": [
      {
        "name": "actions.capability.AUDIO_OUTPUT"
      },
      {
        "name": "actions.capability.WEB_BROWSER"
      },
      {
        "name": "actions.capability.SCREEN_OUTPUT"
      },
      {
        "name": "actions.capability.ACCOUNT_LINKING"
      },
      {
        "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
      }
    ]
  },
  "availableSurfaces": [
    {
      "capabilities": [
        {
          "name": "actions.capability.AUDIO_OUTPUT"
        },
        {
          "name": "actions.capability.SCREEN_OUTPUT"
        },
        {
          "name": "actions.capability.WEB_BROWSER"
        }
      ]
    }
  ]
}

Gửi thông báo

Bạn có thể gửi thông báo đẩy cho người dùng bằng Actions API. Để sử dụng API này, bạn cần kích hoạt API trong dự án Google Cloud, đồng thời thiết lập và tải khoá tài khoản dịch vụ JSON xuống. Xem bước #8 trong hướng dẫn trong mã mẫu tại đây.

Sau đó, bạn có thể dùng thư viện ứng dụng OAuth2 của Google để trao đổi khoá tài khoản dịch vụ để lấy mã truy cập và sử dụng mã thông báo này để xác thực yêu cầu của bạn với Actions API.

Nhận khoá tài khoản dịch vụ

  1. Truy cập vào URL này, thay thế "example-project-1" ở cuối bằng mã dự án trong bảng điều khiển Actions: https://console.developers.google.com/apis/api/actions.googleapis.com/overview?project=example-project-1
  2. Nếu bạn thấy nút Enable (Bật), hãy nhấp vào nút đó. Nếu không, hãy chuyển sang bước 3.
  3. Truy cập vào URL này, thay thế "example-project-1" ở cuối bằng mã dự án của bạn trong bảng điều khiển Actions: https://console.developers.google.com/apis/credentials?project=example-project-1
  4. Nhấp vào Tạo thông tin xác thực > Khoá tài khoản dịch vụ.
  5. Nhấp vào hộp Chọn trong mục Tài khoản dịch vụ rồi nhấp vào Tài khoản dịch vụ mới.
  6. Đặt tên cho Tài khoản dịch vụ, chẳng hạn như "thông báo" và Vai trò của Chủ sở hữu dự án.
  7. Chọn loại khoá JSON rồi nhấp vào Create (Tạo). Khoá tài khoản dịch vụ JSON sẽ được tải xuống máy cục bộ của bạn.

Đổi khoá lấy mã truy cập và gửi thông báo

Để gửi thông báo thông qua Actions API, bạn cần trao đổi khoá tài khoản dịch vụ để lấy mã truy cập. Bạn nên sử dụng thư viện ứng dụng API của Google cho việc này. Trong loạt đoạn mã tiếp theo, chúng ta sẽ sử dụng thư viện ứng dụng Node.js API của Google.

  1. Cài đặt thư viện ứng dụng Google API và yêu cầu: npm install googleapis request --save
  2. Sử dụng mã sau để nhận mã truy cập từ khoá tài khoản dịch vụ và gửi thông báo đẩy:
Dialogflow Node.js
const {google} = require('googleapis');
const request = require('request');

const jwtClient = new google.auth.JWT(
  serviceAccount.client_email, null, serviceAccount.private_key,
  ['https://www.googleapis.com/auth/actions.fulfillment.conversation'],
  null
);

jwtClient.authorize((err, tokens) => {
  if (!err) {
    request.post('https://actions.googleapis.com/v2/conversations:send', {
      auth: {
        bearer: tokens.access_token,
      },
      json: true,
      body: {
        customPushMessage: {
          userNotification: {
            title: 'Push Notification Title',
          },
          target: {
            userId: '<UPDATES_USER_ID>',
            intent: 'Notification Intent',
          },
        },
        isInSandbox: true,
      },
    }, (err, httpResponse, body) => {
      console.log(`${httpResponse.statusCode}: ${httpResponse.statusMessage}`);
    });
  }
});
Node.js SDK Hành động
const {google} = require('googleapis');
const request = require('request');

const jwtClient = new google.auth.JWT(
  serviceAccount.client_email, null, serviceAccount.private_key,
  ['https://www.googleapis.com/auth/actions.fulfillment.conversation'],
  null
);

jwtClient.authorize((err, tokens) => {
  if (!err) {
    request.post('https://actions.googleapis.com/v2/conversations:send', {
      auth: {
        bearer: tokens.access_token,
      },
      json: true,
      body: {
        customPushMessage: {
          userNotification: {
            title: 'Push Notification Title',
          },
          target: {
            userId: '<UPDATES_ORDER_ID>',
            intent: 'Notification Intent',
          },
        },
        isInSandbox: true,
      },
    }, (err, httpResponse, body) => {
      console.log(`${httpResponse.statusCode}: ${httpResponse.statusMessage}`);
    });
  }
});
Dialogflow Java
final class Notification {

  private final String title;

  Notification(String title) {
    this.title = title;
  }

  String getTitle() {
    return title;
  }
}

final class Target {

  private final String userId;
  private final String intent;
  private final String locale;

  Target(String userId, String intent, String locale) {
    this.userId = userId;
    this.intent = intent;
    this.locale = locale;
  }

  String getUserId() {
    return userId;
  }

  String getIntent() {
    return intent;
  }

  String getLocale() {
    return locale;
  }
}

final class PushMessage {

  private final Notification userNotification;
  private final Target target;

  PushMessage(Notification userNotification, Target target) {
    this.userNotification = userNotification;
    this.target = target;
  }

  Notification getUserNotification() {
    return userNotification;
  }

  Target getTarget() {
    return target;
  }
}

final class PushNotification {

  private final PushMessage customPushMessage;
  private boolean isInSandbox;

  PushNotification(PushMessage customPushMessage, boolean isInSandbox) {
    this.customPushMessage = customPushMessage;
    this.isInSandbox = isInSandbox;
  }

  PushMessage getCustomPushMessage() {
    return customPushMessage;
  }

  boolean getIsInSandbox() {
    return isInSandbox;
  }
}

private PushNotification createNotification(String title, String userId, String intent, String locale) {
  Notification notification = new Notification(title);
  Target target = new Target(userId, intent, locale);
  PushMessage message = new PushMessage(notification, target);
  boolean isInSandbox = true;
  return new PushNotification(message, isInSandbox);
}

private ServiceAccountCredentials loadCredentials() throws IOException {
  String actionsApiServiceAccountFile =
      this.getClass().getClassLoader().getResource("service-account.json").getFile();
  InputStream actionsApiServiceAccount = new FileInputStream(actionsApiServiceAccountFile);
  ServiceAccountCredentials serviceAccountCredentials =
      ServiceAccountCredentials.fromStream(actionsApiServiceAccount);
  return (ServiceAccountCredentials)
      serviceAccountCredentials.createScoped(
          Collections.singleton(
              "https://www.googleapis.com/auth/actions.fulfillment.conversation"));
}

private String getAccessToken() throws IOException {
  AccessToken token = loadCredentials().refreshAccessToken();
  return token.getTokenValue();
}

public void sendNotification(String title, String userId, String intent, String locale) throws IOException {
  Preconditions.checkNotNull(title, "title cannot be null.");
  Preconditions.checkNotNull(userId, "userId cannot be null.");
  Preconditions.checkNotNull(intent, "intent cannot be null.");
  Preconditions.checkNotNull(locale, "locale cannot be null");
  PushNotification notification = createNotification(title, userId, intent, locale);

  HttpPost request = new HttpPost("https://actions.googleapis.com/v2/conversations:send");

  String token = getAccessToken();

  request.setHeader("Content-type", "application/json");
  request.setHeader("Authorization", "Bearer " + token);

  StringEntity entity = new StringEntity(new Gson().toJson(notification));
  entity.setContentType(ContentType.APPLICATION_JSON.getMimeType());
  request.setEntity(entity);
  HttpClient httpClient = HttpClientBuilder.create().build();
  httpClient.execute(request);
}
Actions SDK Java
final class Notification {

  private final String title;

  Notification(String title) {
    this.title = title;
  }

  String getTitle() {
    return title;
  }
}

final class Target {

  private final String userId;
  private final String intent;

  Target(String userId, String intent) {
    this.userId = userId;
    this.intent = intent;
  }

  String getUserId() {
    return userId;
  }

  String getIntent() {
    return intent;
  }
}

final class PushMessage {

  private final Notification userNotification;
  private final Target target;

  PushMessage(Notification userNotification, Target target) {
    this.userNotification = userNotification;
    this.target = target;
  }

  Notification getUserNotification() {
    return userNotification;
  }

  Target getTarget() {
    return target;
  }
}

final class PushNotification {

  private final PushMessage customPushMessage;
  private boolean isInSandbox;

  PushNotification(PushMessage customPushMessage, boolean isInSandbox) {
    this.customPushMessage = customPushMessage;
    this.isInSandbox = isInSandbox;
  }

  PushMessage getCustomPushMessage() {
    return customPushMessage;
  }

  boolean getIsInSandbox() {
    return isInSandbox;
  }
}

private PushNotification createNotification(String title, String userId, String intent) {
  Notification notification = new Notification(title);
  Target target = new Target(userId, intent);
  PushMessage message = new PushMessage(notification, target);
  boolean isInSandbox = true;
  return new PushNotification(message, isInSandbox);
}

private ServiceAccountCredentials loadCredentials() throws IOException {
  String actionsApiServiceAccountFile =
      this.getClass().getClassLoader().getResource("service-account.json").getFile();
  InputStream actionsApiServiceAccount = new FileInputStream(actionsApiServiceAccountFile);
  ServiceAccountCredentials serviceAccountCredentials =
      ServiceAccountCredentials.fromStream(actionsApiServiceAccount);
  return (ServiceAccountCredentials)
      serviceAccountCredentials.createScoped(
          Collections.singleton(
              "https://www.googleapis.com/auth/actions.fulfillment.conversation"));
}

private String getAccessToken() throws IOException {
  AccessToken token = loadCredentials().refreshAccessToken();
  return token.getTokenValue();
}

public void sendNotification(String title, String userId, String intent) throws IOException {
  Preconditions.checkNotNull(title, "title cannot be null.");
  Preconditions.checkNotNull(userId, "userId cannot be null.");
  Preconditions.checkNotNull(intent, "intent cannot be null.");
  PushNotification notification = createNotification(title, userId, intent);

  HttpPost request = new HttpPost("https://actions.googleapis.com/v2/conversations:send");

  String token = getAccessToken();

  request.setHeader("Content-type", "application/json");
  request.setHeader("Authorization", "Bearer " + token);

  StringEntity entity = new StringEntity(new Gson().toJson(notification));
  entity.setContentType(ContentType.APPLICATION_JSON.getMimeType());
  request.setEntity(entity);
  HttpClient httpClient = HttpClientBuilder.create().build();
  httpClient.execute(request);
}