-
-
Notifications
You must be signed in to change notification settings - Fork 47
async-http block by Cloudflare but Net::HTTP and Faraday doesn't #190
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Can you try again using lower case headers, e.g. |
I had tried I also changed the user agent, which is unrelated to the user agent that is sent to Discord. Sync do
Async::HTTP::Internet.post(
Async::HTTP::Endpoint.parse("https://discord.com/api/v#{API_VERSION}/channels/#{CHANNEL_ID}/messages"),
{
'Content-Type' => 'application/json',
'Authorization' => "Bot #{ENV['DISCORD_BOT_TOKEN']}",
'User-Agent' => 'Faraday 2.17.2' # use Faraday user-agent is not work
},
{ content: "Hello World" }.to_json
)
end |
Faraday and Net::HTTP both only support HTTP/1 so that may be a difference. What response are you getting back? |
Just got 400 bad request message from Cloudflare
|
Okay, I'll investigate. |
Okay, I set up my own discord bot, and while I couldn't get it to work fully, I did seem to make progress and found some issues with the original code. API_VERSION = 10
CHANNEL_ID = "..."
DISCORD_BOT_TOKEN = "... your token here ..."
Sync do
url = "https://discord.com/api/v#{API_VERSION}/channels/#{CHANNEL_ID}/messages"
response = Async::HTTP::Internet.post(url,
headers: {
'authorization' => "Bot #{DISCORD_BOT_TOKEN}",
'user-agent' => 'AsyncDiscordBot (https://socketry.io/ v0.1.0)',
'content-type' => 'application/json',
},
body: {content: "Hello World"}.to_json
)
pp response, response.read
end
Are you able to try using a string URL and let me know if you can make progress? |
I still got 400 response
The Discord client is a simple Ruby wrapper with module Discord
class Client
CLIENT_VERSION = '0.1.0'
API_VERSION = 10
USER_AGENT = "DiscordBot (https://example.com, 0.1.0) Ruby/#{RUBY_VERSION}".freeze
def initialize(token:)
@token = token
end
def default_headers
{
'Authorization' => "Bot #{@token}",
'Content-Type' => 'application/json',
'User-Agent' => USER_AGENT
}
end
::Protocol::HTTP::Methods.each do |verb|
define_method(verb.downcase) do |path, headers = nil, body = nil, &block|
url = "https://discord.com/api/v#{API_VERSION}#{path}"
Async::HTTP::Internet.instance.call(verb, url, default_headers.merge(headers || {}), body, &block)
end
end
end
end |
I was getting a 401 response - I think the bot was not authorised to access the channel. I will try your wrapper. If you are on discord, maybe we can chat about it? |
Updated: The module Discord
class Client
CLIENT_VERSION = '0.1.0'
API_VERSION = 10
USER_AGENT = "DiscordBot (https://example.com, 0.1.0) Ruby/#{RUBY_VERSION}".freeze
def initialize(token:)
@token = token
end
def default_headers
{
'Authorization' => "Bot #{@token}",
'Content-Type' => 'application/json',
'User-Agent' => USER_AGENT
}
end
::Protocol::HTTP::Methods.each do |verb|
define_method(verb.downcase) do |path, headers = nil, body = nil, &block|
url = "https://discord.com/api/v#{API_VERSION}#{path}"
- Async::HTTP::Internet.instance.call(verb, url, default_headers.merge(headers || {}), body, &block)
+ Async::HTTP::Internet.send(verb, url, default_headers.merge(headers || {}), body, &block)
end
end
end
end I find I can use the below code to send a message correctly 🤔 Sync {
Async::HTTP::Internet.post("https://discord.com/api/v10/channels/#{CHANNEL_ID}/messages", {
'Content-Type' => 'application/json',
'Authorization': "Bot #{BOT_TOKEN}"
}, {
content: "Hello, World!"
}.to_json)
} Maybe I have something wrong with my wrapper. |
Thanks your screenshot was extremely helpful. |
Please give me a moment to check your code. |
I was equally confused by the old interface of |
Finally, the wrapper uses an incorrect method name - ::Protocol::HTTP::Methods.each do |verb|
+ ::Protocol::HTTP::Methods.each do |name, verb|
define_method(verb.downcase) do |path, headers = nil, body = nil, &block|
define_method(verb.downcase) do |path, headers = nil, body = nil, &block|
url = "https://discord.com/api/v#{API_VERSION}#{path}"
Async::HTTP::Internet.instance.call(name, url, headers: default_headers.merge(headers || {}), body:, &block)
end
end |
I am trying to build a Discord application, the document explains the user agent is necessary to prevent Cloudflare from returning 400 errors.
To make a PoC I write below Ruby code.
The response is 400 bad request from Cloudflare.
However, if using
Net::HTTP
(ref: discorb) orFaraday
is works correctly.On my website, if the bot filter is enabled the
Net::HTTP
isn't work. But Discord still acceptsNet::HTTP
requests, I guess there are some behaviors detected by Cloudflare and blocked it.The text was updated successfully, but these errors were encountered: