zulip / python-zulip-api

Python library for the Zulip API.
https://zulip.com/api/
Apache License 2.0
353 stars 355 forks source link

send_message api giving error ""Missing 'num_before' argument"" #595

Open shritwikbhaduri opened 4 years ago

shritwikbhaduri commented 4 years ago

i am was just trying to test locally running zulip server by sending message to a stream using bot credentials with the following code: `import zulip import pprint as pp client = zulip.Client(config_file=".zuliprc", insecure=True)

result = client.get_user_by_id(9) print(result)

Send a stream message request = { "type": "stream", "to": "klasa_integration", "subject": "test", "content": "this is a test message" } result = client.send_message(request) pprint.pprint(result)`

and this is giving the following error: Insecure mode enabled. The server's SSL/TLS certificate will not be validated, making the HTTPS connection potentially insecure /Users/user1/.virtualenvs/disana/lib/python3.8/site-packages/urllib3/connectionpool.py:997: InsecureRequestWarning: Unverified HTTPS request is being made to host '192.168.0.110'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings warnings.warn( {'result': 'error', 'msg': "Missing 'num_before' argument", 'var_name': 'num_before', 'code': 'REQUEST_VARIABLE_MISSING'}

showell commented 4 years ago

Can you try this again? I am pretty sure you would only get that message when you call client.get_messages(), so I am wondering if you were looking at log messages that were in response to some other issue.

shritwikbhaduri commented 4 years ago

@showell hi, i found the issue, i was using generic bot api that's the reason it was showing this message. but even with the incoming bot it says this api is not allowed.. can you help me with this? it gives thefollowing error: {

'msg': 'This API is not available to incoming webhook bots.',
 'result': 'error'}

how do i know what all apis are available for bots?

timabbott commented 4 years ago

My guess for what's happening with client.send_message is that some software on your network is doing a redirect, which turns the HTTP POST request into an HTTP GET request. (And is why you're getting a GET /api/v1/messages error message using a function that does POST /api/v1/messages.

Generally, all API endpoints that make sense for bot users are available for them; things like display and notification settings are not.

timabbott commented 3 years ago

I would close this as not a bug. But I wonder if we should be doing something to disable redirect handling with how we're calling requests -- probably worth keeping this open until we've investigated that.

karlicoss commented 1 year ago

Had the same issue white trying to use the API

client = zulip.Client(site='http://localhost', email='whatever@whatever.com', api_key='REDACTED', insecure=True, verbose=True)

It helped to enable some debug logs

import http
http.client.HTTPConnection.debuglevel = 1

after that I got the following output while using client.send_message

send: b'POST /api/v1/messages HTTP/1.1\r\nHost: localhost\r\nUser-agent: ZulipPython/0.8.2 (Ubuntu; 22.04)\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\nContent-Length: 12\r\nContent-Type: application/x-www-form-urlencoded\r\nAuthorization: Basic REDACTED\r\n\r\n'
send: b'type=streami'
reply: 'HTTP/1.1 301 Moved Permanently\r\n'
header: Server: nginx/1.18.0 (Ubuntu)
header: Date: Thu, 02 Mar 2023 00:23:59 GMT
header: Content-Type: text/html
header: Content-Length: 178
header: Connection: keep-alive
header: Location: https://localhost/api/v1/messages
/usr/lib/python3/dist-packages/urllib3/connectionpool.py:1015: InsecureRequestWarning: Unverified HTTPS request is being made to host 'localhost'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  warnings.warn(
send: b'GET /api/v1/messages HTTP/1.1\r\nHost: localhost\r\nUser-agent: ZulipPython/0.8.2 (Ubuntu; 22.04)\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\nAuthorization: Basic REDACTED\r\n\r\n'
reply: 'HTTP/1.1 400 Bad Request\r\n'
header: Server: nginx/1.18.0 (Ubuntu)
header: Date: Thu, 02 Mar 2023 00:23:59 GMT
header: Content-Type: application/json
header: Content-Length: 115
header: Connection: keep-alive
header: Vary: Accept-Language
header: Content-Language: en
header: X-RateLimit-Limit: 200
header: X-RateLimit-Remaining: 197
header: X-RateLimit-Reset: 1677716699
header: Strict-Transport-Security: max-age=15768000
header: X-Frame-Options: DENY
header: Access-Control-Allow-Origin: *
header: Access-Control-Allow-Headers: Authorization
header: Access-Control-Allow-Methods: GET, POST, DELETE, PUT, PATCH, HEAD
Out[9]: 
{'result': 'error',
 'msg': "Missing 'num_before' argument",
 'var_name': 'num_before',
 'code': 'REQUEST_VARIABLE_MISSING'}

So @timabbott 's hunch was write, looks like something redirects to the GET request.

What helped me was pointing the client to use site='https://localhost' (instead of http://). After that it ended up as a single POST request, and succeeded.

Perhaps NGINX inside the container redirecting http:// to https:// or something like that? Not sure what's a proper solution here, but perhaps the client could warn if the endpoint is http and suggest to switch to https?