messagebird / ruby-rest-api

MessageBird's REST API for Ruby
BSD 2-Clause "Simplified" License
37 stars 46 forks source link

New Access Key not working with REST API #89

Open spinosa opened 6 months ago

spinosa commented 6 months ago

The access keys I just created (at https://app.bird.com/settings/access-keys ) do not work with the REST API.

I can send a curl that includes the key in the header (Authorization: AccessKey ) and successfully sends an SMS. This uses the API at "https://api.bird.com"

But when I use the same key on the REST API ("https://rest.messagebird.com") I get an "incorrect access_key" error. I am using the official Ruby SDK (this one) to hit the REST API.

Do I need a different access key? Is the REST API still supported?

Example failing code:

client = MessageBird::Client.new(ACCESS_KEY)
client.balance

results in error: messagebird/client.rb:95:in `parse_body': Request not allowed (incorrect access_key) (error code: 2, parameter: access_key) (MessageBird::ErrorException)

tdegrunt commented 3 months ago

Did you get this to work? I've also tried to add a custom policy for the channels, but nothing seems to work with the Ruby client. Curl requests from the new API examples work though.

Screenshot 2024-06-27 at 09 44 25 Screenshot 2024-06-27 at 09 44 54
spinosa commented 3 months ago

I ended up creating a minimal client for my simple use case. Perhaps it will help you...

require "net/http"
require "json"

# The messagebird-rest-api gem uses the old REST api which isn't supported.
# There is no gem for the new API.
class BirdService
  MESSAGES_BASE_URL = "https://api.bird.com/workspaces/%{workspace_id}/channels/%{channel_id}/messages".freeze

  ACCESS_KEY = Rails.application.credentials.dig(:bird, :access_key)
  WORKSPACE_ID = Rails.application.credentials.dig(:bird, :workspace_id)
  SMS_CHANNEL_ID = Rails.application.credentials.dig(:bird, :sms_channel_id)

  def initialize(workspace_id, channel_id, access_token)
    @workspace_id = workspace_id
    @channel_id = channel_id
    @access_token = access_token
  end

  @@client = BirdService.new(WORKSPACE_ID, SMS_CHANNEL_ID, ACCESS_KEY)

  def self.client
    @@client
  end

  def send_sms(receiver_number, message_text)
    uri = URI(format(MESSAGES_BASE_URL, workspace_id: @workspace_id, channel_id: @channel_id))

    request_body = {
      receiver: {
        contacts: [
          { identifierValue: receiver_number }
        ]
      },
      body: {
        type: "text",
        text: { text: message_text }
      }
    }

    begin
      response = Net::HTTP.post(uri, request_body.to_json, headers)

      if response.is_a?(Net::HTTPSuccess)
        handle_success(response)
      else
        handle_error(response)
      end
    rescue StandardError => e
      handle_exception(e)
    end
  end

  private

  def headers
    {
      "Content-Type" => "application/json",
      "Authorization" => "Bearer #{@access_token}"
    }
  end

  def handle_success(response)
    message_data = JSON.parse(response.body)
    message_id = message_data["id"]
    status = message_data["status"]
    created_at = message_data["createdAt"]

    puts "Message sent successfully!"
    puts "Message ID: #{message_id}"
    puts "Status: #{status}"
    puts "Created At: #{created_at}"
  end

  def handle_error(response)
    error_data = JSON.parse(response.body)
    error_message = error_data["error"] || "Unknown error"

    puts "Error sending message: #{response.code} - #{error_message}"
  end

  def handle_exception(exception)
    puts "Exception occurred while sending message: #{exception.message}"
  end
end
tdegrunt commented 3 months ago

Thank you! I did open a support case with Bird, I'm curious where that ends. There's more SDK's on this org, which all use the REST API, not sure what's going on.

Edit: Got an update that the REST API is considered legacy and new signups for this API are no longer possible.