The script will fail if we process with a droplet object with no
.ip_address, which can sometimes happen if we just droplet.load().
Sometimes that gives droplet.ip_address set to None. If we wait in a
loop, we eventuall get the .ip_address set.
Initializing the Zulip client opens a long-lived TCP connection due to
connection pooling in urllib3. In Github Actions, the network kills
such requests after ~270s, making the later `send_message` call fail.
Use a singular call to `zulip.Client()` early on to verify the
credentials, and do not cache the resulting client object. Instead,
re-create it during the final step when it is needed, so we do not run
afoul of bad TCP connection state.
This would ideally be fixed via connection keepalive or retry at the
level of the Zulip module.