# Step 5: Write Code That Publishes a Platform Event Message

Follow instructions in this step to build a publisher client.

:::note
When you copy the code snippets in this page, ensure that the indentation starts from the comment block below the `with grpc.secure_channel` statement that you added in [Step 2: Build the Python Client](/docs/platform/pub-sub-api/guide/qs-build-python-client.md). In Python, code blocks are delimited by their indentation.
:::

Before you publish a custom platform event message, ensure that the platform event is defined in your org. You can view defined platform events in Setup on the Platform Events page.

For example, this image shows the definition of `Order_Event__e`. This event has two fields: `Order_Number__c` of type Text and `Has_Shipped__c` of type Checkbox.

![The Order Event detail page](https://a.sfdcstatic.com/developer-website/sfdocs/event-bus/media/pubsub-order-event-definition.png "The Order Event detail page")

1. Create a separate Python file, `publish.py`, for publishing so that you can run the publisher and subscriber clients independently. Include common code from the subscriber client that you created earlier. Include the import statements, code for creating the channel, the authentication code to build authmetadata, and the stub. Also, add this import statement: `from datetime import datetime, timedelta`

2. Get the topic name for the event that you want to publish. The topic format is `/event/EventName__e`. For example, for `Order_Event__e` the topic is `/event/Order_Event__e`. You use it in the next step.

3. Replace the `mypubtopic` placeholder value with your topic. Get the schema ID and schema for the event. To get the schema ID, call the `GetTopic` method and pass the topic name. Next, pass the schema ID to the `GetSchema` method, which returns the schema. Typically, you store the schema and reuse it if the schema ID hasn’t changed, but this example doesn’t do that for simplicity.

   ```python
   mypubtopic = '{your publish topic}'
   schemaid = stub.GetTopic(pb2.TopicRequest(topic_name=mypubtopic),
       metadata=authmetadata).schema_id
   # Typically, you store the schema and reuse it if the schema ID hasn't changed,
   # but this example doesn't do that for simplicity.
   schema = stub.GetSchema(pb2.SchemaRequest(schema_id=schemaid),
       metadata=authmetadata).schema_json
   ```

4. Create a function to encode the information that you want to send by using the schema.

   ```python
   def encode(schema, payload):
     schema = avro.schema.parse(schema)
     buf = io.BytesIO()
     encoder = avro.io.BinaryEncoder(buf)
     writer = avro.io.DatumWriter(schema)
     writer.write(payload, encoder)
     return buf.getvalue()
   ```

5. Create a function that creates a `PublishRequest`. Construct the payload by adding the event fields and values in the payload variable. Populate the values of the required system fields: `CreatedDate` and `CreatedById`. The `CreatedById` value isn’t validated. For `{event field}: {field value}`, list the event fields and values. For example, for Order_Event\_\_e, you can add:

   ```python
   "Order_Number__c": "100",
   "Has_Shipped__c": True
   ```

   The `req` variable contains the encoded payload, which is returned by the encode function. It also contains the schema ID.

   ```python
   def makePublishRequest(schemaid):
     dt = datetime.now() + timedelta(days=5)
     payload = {
       "CreatedDate": int(datetime.now().timestamp()),
       "CreatedById": '005R...', #Your user ID
       "{replace event field}": "{replace field value}"
     }
     req = {
       "schema_id": schemaid,
       "payload": encode(schema, payload)
     }

     return [req]
   ```

6. Make the publish call, and handle any acknowledgements that you get back.

   ```python
   publishresponse = stub.Publish(pb2.PublishRequest(
     topic_name=mypubtopic, events= makePublishRequest(schemaid)), metadata=authmetadata)
   ```

7. Modify your subscriber client, `PubSubAPIClient.py`, to susbribe to the platform event.

   ```python
   mysubtopic = "/event/Order_Event__e"
   ```

8. Run the client by entering this command on the command line.

   ```
   python3 publish.py
   ```

   If the publish request is successful, you receive a PublishResponse message containing the replay ID. The subscriber client receives and displays the event message.

   If the publish request wasn’t successful, you get an error similar to:

   ```
   results {
     error {
       code: PUBLISH
       msg: "com.salesforce.eventbus.exceptions.PublishException: Unsupported topic [/event/Tracker_Event__e]. Standard Volume event type is not supported."
     }
   }
   schema_id: "AKTsT5i0mDe_UF8qnC8Aig"
   ```
