> ## Documentation Index
> Fetch the complete documentation index at: https://docs.b3.fun/llms.txt
> Use this file to discover all available pages before exploring further.

# Edit Channel Message

> Edit an existing message in a channel



## OpenAPI

````yaml /openapi/basement.json post /launcher/edit-channel-message
openapi: 3.0.0
info:
  title: B3 Basement API
  description: >-
    Welcome to the Basement.fun documentation! This guide will help you
    integrate your game with our platform using B3's API. By following these
    steps, you'll discover how to effortlessly connect your game and unlock a
    range of exciting features and functionalities.


    See more documentation at [https://docs.b3.fun](https://docs.b3.fun)


    ## **Authorization**


    To call the APIs, there are two steps of authorization. The launcherJwt (A
    JSON-Web-Token that links to the specific user's session with the game
    (passed in the request body), and the client secret (passed as Authorization
    header)


    ##### Obtaining a Launcher JWT For:


    1. Embedded games in launcher, or external web games: the launcher loads the
    link of the game with an additional query parameter which contains the
    token. Easy.

    i.e if the game's target is `example.com` the launcher will load
    `example.com/?token=`.


    2. External non-web games (Telegram, desktop, etc.): to get a JWT and
    maintain the session, you must manually create a session and call the
    heartbeat API to keep it alive.


    1. Call CreateUnverifiedChannel to create a new session for the user.

    2. Get the "signRequest" value from the response and have your user sign it
    with their wallet.

    3. Call VerifyUnverifiedChannel with the user's sign hash to verify their
    presence. Get the launcherJwt from its response and use for all other API
    calls.

    4. Keep the session alive by calling RenewChannelHeartbeat at least once
    every 3 minutes. Capture authentication errors from the APIs and repeat from
    a if the JWT has expired.


    ## Session Management (Important for external games)


    In order for B3 to accurately measure user metrics of the game, and to
    provide the APIs via valid sessions that use JWT for authorization, we
    require the user context to continuously keep the session alive using the
    heartbeat APIs.


    - For embedded games: We manually maintain the session, no required
    integration on the game's side.

    - For external WEB games: When your game is opened in a new window, we pass
    the session JWT as an additional query parameter. You can either use it to
    manually call the heartbeat API every 3 minutes, OR, simply use our already
    made script which does this all automatically for you.

    - Simply add the following HTML code to all the html pages of your game:
    `<script src="https://cdn.basement.fun/heartbeat-script.js"
    type="text/javascript"></script>`

    - For external non-web games (i.e Telegram), follow the instructions of
    "Obtaining a Launcher JWT For: [external non-web games]"


    ## Payload Verification - Anti client-side request forgery


    By default, requests going to the backend from your client-side game, will
    appear in the devtools window of the browser. Devtools lets users easily
    edit and resend requests, which means that anyone with a basic technical
    knowledge could edit outgoing requests, and increase their scores, or
    otherwise modify their data.


    To ensure that is not possible, we offer a feature flag for games,
    "launcherSignatureVerification" (can be turned on in dashboard), which adds
    an additional layer of authentication with each request.


    **How to sign requests using launcher signature verification:**


    1. Take your game's secret, hash it using MD5, and store it in the game.

    2. For each request to the basement API, construct and include the following
    headers:

    1. "X-Request-Nonce": a random string, identifier for the specific request.
    (we recommend up to 32 randomly selected characters)

    2. "X-Request-Signature": this is the MD5 hash of the nonce prepended to the
    md5 of the game's secret ( = MD5(nonce + MD5(gameSecret))


    With this enabled, each request signature is unique, and validated to ensure
    the it is useable only once. Now if a user attempts to modify a request and
    resend it with the same signature, they will be flagged as potential
    cheater, and the request will fail.
  version: 1.0.0
  contact:
    url: https://docs.b3.fun
servers:
  - url: https://api.basement.fun
    description: Production server
security: []
paths:
  /launcher/edit-channel-message:
    post:
      summary: Edit Channel Message
      description: Edit an existing message in a channel
      parameters:
        - name: X-Request-Nonce
          in: header
          required: false
          schema:
            type: string
          description: Random string identifier for request (for signature verification)
        - name: X-Request-Signature
          in: header
          required: false
          schema:
            type: string
          description: MD5 hash for request verification
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EditChannelMessageRequest'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageResponse'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    EditChannelMessageRequest:
      type: object
      required:
        - launcherJwt
        - messageId
        - newContent
      properties:
        launcherJwt:
          type: string
        messageId:
          type: string
        newContent:
          type: string
    MessageResponse:
      type: object
      properties:
        _id:
          type: string
        channelId:
          type: string
        senderId:
          type: string
        content:
          type: string
        createdAt:
          type: integer
          format: int64
        updatedAt:
          type: integer
          format: int64
    ErrorResponse:
      type: object
      properties:
        name:
          type: string
        message:
          type: string
        code:
          type: integer
        className:
          type: string
        data:
          type: object
          properties:
            success:
              type: boolean
            error:
              type: string

````