Skip to content

Cookie preferences

We use cookies for our own analytics, to see how our campaigns perform and, if you allow it, to load content from other services such as the Google site search. We never sell your data. Necessary cookies keep the site working and cannot be switched off. See our Cookie Policy for details and our Privacy Policy for how we handle personal data.

Security, load balancing and remembering your cookie choice.

Show us which pages people read, how they find the site and where they get stuck, so we can improve it (Google Analytics, Microsoft Clarity).

Show us which of our ad campaigns bring visitors to the site and remember the campaign or partner link you arrived from (Google Ads, LinkedIn, Meta, partner program). We do not use these cookies to build advertising profiles.

Load the site search from Google when you use it. Google sets its own cookies and shows ads in the search results.

© 2026 The ThingsBoard Authors
22.6k Try for free

ThingsBoard Cloud

Choose your data region

Your data stays in the region you choose, for residency and compliance. No credit card required.

Rather run it yourself? Install on your own servers

Google Cloud Pub/Sub Integration

Pub/Sub Integration connects ThingsBoard to Google Cloud Pub/Sub as a subscriber. It receives messages from a pull subscription, and an uplink data converter transforms each message into device or asset data, including telemetry and attributes.

Use Pub/Sub Integration when:

  • Devices or backend services publish data to a Pub/Sub topic.
  • One subscription carries data for many devices: the converter sets the target device for each message.
  • Message attributes identify the device or describe the data: the converter receives them as metadata.
  1. Receive data. A publisher sends a message to a topic. Pub/Sub delivers it to the pull subscription, and the integration receives it over a streaming pull connection.
  2. Decode the payload. The uplink converter identifies the device or asset and extracts attributes and telemetry.
  3. Process the message. ThingsBoard processes the converted data through the Rule Engine. If Allow create devices or assets is enabled, ThingsBoard can create an entity that does not exist yet.
  4. Acknowledge the message. The integration acknowledges each message after processing, including a message that fails conversion. Pub/Sub does not deliver it again.
  • Access to ThingsBoard or ThingsBoard Cloud with integrations enabled for your tenant.
  • Permission to create integrations and data converters, and to edit rule chains to publish data back to Pub/Sub.
  • A Google Cloud project where you can enable APIs and create Pub/Sub topics, subscriptions, and service accounts.

Enable the API, create a topic with a pull subscription, and create a service account key in the Google Cloud console.

  1. Open your project, click Search in the top toolbar, and search for Cloud Pub/Sub API.
  2. Select Cloud Pub/Sub API in the results.
  3. Click Enable. If the API is already enabled, skip this step.
  4. Check that the API page shows Status: Enabled.
  1. Search for Pub/Sub and open it.
  2. On the Topics page, click Create topic.
  3. Enter a Topic ID, for example tb-uplink. Keep Add a default subscription selected: it creates the pull subscription tb-uplink-sub.
  4. Click Create.
  5. On the topic’s Subscriptions tab, open tb-uplink-sub and check that its state is Active and its delivery type is Pull.

The integration authenticates with a service account key. To receive messages, the account needs the Pub/Sub Subscriber role.

  1. Search for Service Accounts and open it.
  2. Click Create service account.
  3. Enter a name, for example tb-pubsub, and click Create and continue.
  4. In Permissions, select the Pub/Sub Subscriber role, then click Continue and Done.
  5. Click the email of the new service account.
  6. On the Keys tab, click Add key ⇾ Create new key.
  7. Select JSON and click Create. The browser downloads the key file.
  8. Check that the key appears as Active on the Keys tab.

You now have the values for the integration:

Value Example Source
Project ID tb-pubsub-integration Project selector or the Project info card on the dashboard
Subscription ID tb-uplink-sub Last segment of the subscription name
Service Account key file tb-pubsub-integration-1a2b3c4d5e6f.json Downloaded key file

Create the uplink converter, assign it to a new Pub/Sub integration, and publish a test message.

The uplink converter reads the message data and maps it to ThingsBoard entities and data. Pub/Sub Integration uses the Generic converter: you write the decoder in TBEL or JavaScript. For converter types and the full decoder reference, see Uplink data converter.

  1. Go to Integrations ⇾ Data converters and click + Add data converter ⇾ Create new converter.

  2. Converter type — keep Uplink.

  3. Integration type — select Pub/Sub.

  4. Name — enter a name, for example Pub/Sub Uplink Converter.

  5. Main decoding configuration — the editor opens with the default decoder below. Keep it for JSON messages: it takes the device name and type from deviceName and deviceType, stores serialNumber as an attribute, and stores the other fields as telemetry. The timestamp comes from ts (Unix milliseconds) or timestamp (ISO 8601); without them, the decoder uses the server time. The editor opens in TBEL; use the TBEL / JS toggle to switch to JavaScript.

    // Decode an uplink message from a buffer
    // payload - array of bytes
    // metadata - key/value object
    /** Decoder **/
    // decode payload to JSON
    var data = decodeToJson(payload);
    // --- Device name and type ---
    var deviceName = data.deviceName != null ? data.deviceName : 'Unknown Device';
    var deviceType = data.deviceType != null ? data.deviceType : 'default';
    // var customerName = 'Customer C';
    // var groupName = 'thermostat devices';

    To adapt:

    • Device name in a message attribute — read it from metadata, for example var deviceName = metadata.deviceId;.
    • Device name in another field — replace data.deviceName, for example with data.id.
    • Other attributes — add keys to attributeKeyList, for example "firmwareVersion".
    • Assets instead of devices — uncomment assetName and assetType, and use them in the result instead of deviceName and deviceType.
    • Customer or group — uncomment customerName or groupName and add it to the result.
  6. Click Test decoder function and check the result (see Test the Decoder).

  7. Click Add.

Decoder Inputs

The decoder signature is function decoder(payload, metadata): object | object[].

Variable Type Content
payload byte array The message data.
metadata {[key: string]: string} integrationName, pubSubMsgId (the message ID assigned by Pub/Sub), every message attribute as a key, and the key–value pairs from the integration’s Metadata field. A message attribute overrides a Metadata pair with the same key.

Built-in helpers:

Function Result
decodeToJson(payload) Parses the bytes as JSON and returns an object.
decodeToString(payload) Converts the bytes to a UTF-8 string.
toFlatMap(obj, excludeKeys, flatNested) TBEL only. Returns a flat key–value map of obj, skipping excludeKeys. With flatNested set to true, nested objects become dot-separated keys. The JavaScript template defines its own toFlatMap(obj, result, excludeList), which writes into result.

For field renaming, nested values, and non-JSON payloads, see Common scripting patterns.

Test the Decoder

Click Test decoder function below the editor. The dialog opens with Payload content type set to JSON and this sample payload:

{
"deviceName": "Thermometer",
"deviceType": "thermostat",
"serialNumber": "SN-12345",
"temperature": 25.5
}

Click Test. The Output panel shows:

{
"deviceName": "Thermometer",
"deviceType": "thermostat",
"attributes": {
"serialNumber": "SN-12345"
},
"telemetry": {
"ts": 1791807972006,
"values": {
"temperature": 25.5
}
}
}

ts is the current time, because the payload has neither ts nor timestamp. Check that deviceName is set and telemetry.values holds the expected keys. If the output is empty or shows an error, fix the decoder and test again.

The integration has no downlink, so the wizard skips the downlink converter step.

  1. Go to Integrations ⇾ Integrations and click + Add integration.
  2. Basic settings:
    • Integration type — select Pub/Sub.
    • Name — keep the default Pub/Sub integration or enter your own.
    • Enable integration and Allow create devices or assets — keep both on, so the device is created on its first uplink.
    • Click Next.
  3. Uplink data converter:
    • Click Select existing and choose Pub/Sub Uplink Converter.
    • Alternatively, click Create new to write a decoder here.
    • Click Next.
  4. Connection:
    • Project ID — enter your project ID, for example tb-pubsub-integration.
    • Subscription ID — enter tb-uplink-sub.
    • Service Account key file — click Browse file and select the key file, or click Use Secret storage and select a stored secret.
    • Leave the other parameters at their defaults. See Connection Settings for details.
  5. Click Add.
Parameter Description
Project ID ID of the Google Cloud project with the subscription.
Subscription ID Pull subscription to receive messages from. It must exist before the integration starts.
Service Account key file JSON key of a service account with the Pub/Sub Subscriber role on the subscription.
Execute remotely Runs the integration as a separate process outside the ThingsBoard cluster, for example in a network with restricted internet access. ThingsBoard generates an Integration key and Integration secret for it. See Remote Integration.
Description In Advanced settings. Free-text description.
Metadata In Advanced settings. Key–value pairs added to the metadata of every message from this integration.

The integration does not offer Check connection: check the integration status after you add it.

Publish a test message to the topic, then confirm that ThingsBoard decoded it and created the device.

  1. Go to Pub/Sub ⇾ Topics and open tb-uplink.

  2. On the Messages tab, click Publish message.

  3. Paste the payload into Message body and click Publish.

    {
    "deviceName": "Sensor A1",
    "deviceType": "thermostat",
    "temperature": 23.5,
    "humidity": 60
    }
  4. Check that the console shows Message published.

  • Integration events — go to Integrations ⇾ Integrations, open the integration, and click the Events tab. The uplink appears with status OK. Click ⋅⋅⋅ in the Message column to see the message data.
  • Converter events — open Pub/Sub Uplink Converter in Integrations ⇾ Data converters and click the Events tab. In shows the message data, Out shows the decoded result, and Metadata shows integrationName, pubSubMsgId, and the message attributes.
  • Device — go to Devices & assets ⇾ Devices. The integration has created Sensor A1 with the thermostat profile. Open it and check temperature and humidity on the Latest telemetry tab.

The integration does not send data to Pub/Sub. To publish ThingsBoard data to a topic — for example, a command for a device or an event for a cloud function — add a GCP Pub/Sub node to a rule chain. The node publishes the message data as is, and it works without the integration.

Use a separate topic, so the integration does not receive its own messages.

  1. Go to Pub/Sub ⇾ Topics and click Create topic.
  2. Enter tb-downlink as the Topic ID. Keep Add a default subscription selected: you read the published messages from tb-downlink-sub.
  3. Click Create.

The Pub/Sub Subscriber role does not allow publishing. Grant the service account the Pub/Sub Publisher role on the new topic.

  1. Open the tb-downlink topic, go to the Permissions tab, and click Add principal.
  2. In New principals, enter the service account email, for example tb-pubsub@tb-pubsub-integration.iam.gserviceaccount.com.
  3. In Assign roles, select Pub/Sub Publisher and click Save.

To keep uplink and downlink credentials apart, create a second service account with only the Pub/Sub Publisher role and use its key in the node.

  1. Go to Data processing ⇾ Rule chains and open the Root Rule Chain.
  2. From the External section, drag a gcp pubsub node onto the canvas.
  3. Set the node fields:
    • Name — for example, Publish to Pub/Sub.
    • GCP project ID — your project ID, for example tb-pubsub-integration.
    • Topic name — tb-downlink.
    • GCP service account key file — the key file of the service account.
    • Message attributes — optional. Values can use ${metadataKey} for a message metadata value and $[messageKey] for a message data value, for example deviceName = ${deviceName}.
    • Click Add.
  4. Connect the message type switch node to the gcp pubsub node with the Attributes Updated relation.
  5. Click Apply changes.

On success, the node adds the messageId returned by Pub/Sub to the message metadata. On failure, it routes the message through the Failure relation with the reason in metadata.error.

  1. Go to Devices & assets ⇾ Devices, select Sensor A1, and open the Attributes tab.
  2. Select Shared attributes and click +.
  3. Set Key to temperatureUploadFrequency, Type to Integer, Value to 60, and click Add. ThingsBoard publishes the message.
  • Rule node events — turn on debug mode for the gcp pubsub node before the test. On its Events tab, the event has the Success relation. Data shows {"temperatureUploadFrequency":60}, and Metadata shows messageId.
  • Google Cloud console — go to Pub/Sub ⇾ Subscriptions, open tb-downlink-sub, and on the Messages tab click Pull. The message appears with its body.
Symptom Cause Fix
Integration does not start The key file is not a valid service account key. Create a new JSON key and upload it.
No uplinks arrive Wrong Project ID or Subscription ID, messages go to another topic, or the subscription uses push delivery or has expired. Copy both IDs from the Google Cloud console and publish to the subscription’s topic. Set Delivery type to Pull. Recreate an expired subscription.
Same, with correct settings The service account lacks the Pub/Sub Subscriber role, is disabled, or the Cloud Pub/Sub API is disabled. Grant the role, enable the account, and enable the API.
Converter error; the message is gone The data is not valid JSON, or the decoder fails on it. The integration has already acknowledged the message. Check In and Error in the converter events, fix the decoder, and publish again.
Device not created deviceName is empty, or Allow create devices or assets is off. Check Out in the converter events and the integration settings.
Node routes to Failure with PERMISSION_DENIED The node’s service account lacks Pub/Sub Publisher on the topic. Grant the role on tb-downlink.
Node has no events The rule chain does not reach the gcp pubsub node. Check the Attributes Updated relation and turn on debug mode for the node.

To read debug events, open the integration or converter, click Events, and select an event: In is the received data, Out is the converter result, and Error holds the error text.