Python Sample Upgrade for RCS Business Messaging
The rbm-api-examples repository on GitHub doesn’t get a lot of fanfare. No launch events, no blog posts from the comms team, no tweets from product managers. It just sits there—quietly being the first thing most developers touch when they start building an RCS Business Messaging agent.
I know this because I watched it happen for almost two years at Google. A developer would find the RBM documentation, click through to the samples, clone the repo, and—within about fifteen minutes—either succeed or give up. The Python sample was often the deciding factor.
So when the Python samples got a meaningful upgrade recently, I wanted to talk about what changed. And why it matters more than you’d think.
What Lives in rbm-api-examples #
The repository houses sample code in four languages: Python, Node.js, Java, and C#. Each sample demonstrates the core RBM API operations—sending messages, handling events, managing agents. They’re not production apps. They’re starting points.
The Python sample has always been the most popular by clone count (at least it was during my time). Python developers tend to prototype fast, and the RBM API is a REST API at heart—so Python’s requests-friendly ecosystem makes it a natural fit.
Authentication uses Google Cloud service account credentials. You create a service account in the Google Cloud Console, download the JSON key file, and point the sample at it. The sample then authenticates against rcsbusinessmessaging.googleapis.com and you’re off.
Simple in theory. Messy in practice.
The Authentication Pain Point #
Here’s what used to happen. A developer would clone the repo, install dependencies, try to run the sample—and hit an authentication error. Not because the code was wrong, but because the onboarding flow had gaps. The service account needed specific IAM roles. The RBM Developer Console required a separate agent creation step. The credentials JSON file had to be in the right path. And the sample’s README didn’t always make this sequence obvious.
I watched this pattern repeat dozens of times through support channels and GitHub issues. The fix was usually a two-line change in the developer’s setup, but finding those two lines took an hour of debugging.
The upgraded Python sample addresses this head-on. The authentication flow now includes better error messages when credentials are misconfigured—not just a stack trace, but an actual hint about what’s missing. The README walks through the prerequisites in order, with explicit checkboxes.
It sounds trivial. It isn’t.
API Versioning and Dependency Hygiene #
The other big change relates to API versioning. The RBM API has evolved over the past couple of years; endpoints have shifted, request schemas have gotten new optional fields, and the client libraries have kept pace (mostly). The Python sample was pinned to older library versions that still worked but didn’t expose newer API features.
The upgrade bumps the Google API client library and the google-auth package to current versions. This matters for two reasons.
First, newer versions of google-auth handle credential refresh more gracefully—fewer random 401 errors during long-running sessions.
Second, the updated client library exposes methods for the RBM Management API, which lets you programmatically create and manage agents and brands instead of clicking through the Developer Console.
I’ll be honest: the Management API is underused. Most developers don’t even know it exists. But if you’re building a platform that manages multiple RBM agents—think: a CPaaS provider or an enterprise with regional agents—programmatic agent management is essential. Having it visible in the sample code plants the seed.
What the Upgrade Looks Like in Practice #
Let me show you the before and after on the authentication setup. The old pattern looked roughly like this:
from google.oauth2 import service_account
credentials = service_account.Credentials.from_service_account_file(
'service_account_key.json',
scopes=['https://www.googleapis.com/auth/rcsbusinessmessaging']
)The new pattern adds validation and clearer scoping:
import os
from google.oauth2 import service_account
KEY_FILE = os.environ.get('RBM_CREDENTIALS', 'service_account_key.json')
if not os.path.exists(KEY_FILE):
raise FileNotFoundError(
f"Service account key not found at {KEY_FILE}. "
"Download it from the Google Cloud Console > IAM > Service Accounts."
)
credentials = service_account.Credentials.from_service_account_file(
KEY_FILE,
scopes=['https://www.googleapis.com/auth/rcsbusinessmessaging']
)Small difference, right? But that FileNotFoundError with the hint about where to download the key—that saves twenty minutes of confusion. And using an environment variable for the path means you’re not hardcoding credentials paths. A pattern that bites people when they deploy to staging or CI environments.
The sending flow also got cleaned up. The upgraded sample separates concerns more clearly: one module for authentication, one for message construction, one for sending. The old sample had everything in a single file. Splitting it makes the code easier to read and (more importantly) easier to copy individual pieces into your own project.
Why Sample Code Matters More Than Documentation #
I have a minor obsession with developer samples. Not documentation in general; specifically, the runnable examples that ship alongside an API.
Here’s my reasoning. Documentation tells you what an API can do. Samples show you how to do it. And when a developer is evaluating whether to invest time in a platform, they don’t read the docs first—they clone the sample and try to get it running.
If it works in under ten minutes, they’re hooked. If it doesn’t, they move on to whatever competitor has a working quickstart.
During my time running DevRel for Google Business Messages, I tracked this informally. The single best predictor of a developer completing the full onboarding flow—sample running, test message sent, agent submitted for launch—was whether the initial sample ran without errors on the first attempt.
Not whether the docs were comprehensive. Not whether the API was well-designed. Whether the sample worked.
That’s why I care about an upgrade to sample code that most people will never notice. The developers who do notice—the ones who clone the repo next week and have a working agent in eight minutes instead of forty—won’t write a thank-you note. They’ll just keep building.
And that’s the point.
What I’d Still Change #
Since I’m no longer on the inside, I can say this freely: the Python sample should ship with a Docker-based dev environment. Not everyone wants to manage Python virtual environments manually, and a docker-compose.yml that sets up the sample with all dependencies would eliminate an entire category of “works on my machine” issues.
I’d also love to see the sample include a webhook receiver out of the box. Right now, receiving inbound messages from users requires setting up an HTTPS endpoint—which means ngrok or a cloud deployment. A sample that includes a basic Flask webhook handler (with ngrok instructions) would close the loop on the demo experience.
But those are wishes, not complaints. The upgrade that shipped is solid, and it addresses the pain points I saw most frequently.
If you’re building with the RBM API in Python, go clone rbm-api-examples and give it a spin. The onboarding experience is genuinely better than it was six months ago.