Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 41 additions & 9 deletions zulip/integrations/twitter/twitter-bot
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,6 @@ for status in statuses[::-1][:opts.limit_tweets]:
# https://twitter.com/eatevilpenguins/status/309995853408530432
composed = "%s (%s)" % (status.user.name, status.user.screen_name)
url = "https://twitter.com/%s/status/%s" % (status.user.screen_name, status.id)
# This contains all strings that could have caused the tweet to match our query.
text_to_check = [status.text, status.user.screen_name]
text_to_check.extend(url.expanded_url for url in status.urls)

Expand Down Expand Up @@ -259,14 +258,47 @@ for status in statuses[::-1][:opts.limit_tweets]:
elif opts.twitter_name:
subject = composed

message = {
"type": "stream",
"to": [opts.stream],
"subject": subject,
"content": url
}

ret = client.send_message(message)
# If the tweet is a retweet then check if the original tweet has been sent before
# and try to edit it, else post new message with the original tweet.
# This contains all strings that could have caused the tweet to match our query.
message_id = 0
edit_message = False
if status.retweeted_status is not None:
try:
message_id = config_internal.getint('twitter', str(status.retweeted_status.id))
edit_message = True
except (NoOptionError, NoSectionError):
edit_message = False
url = (status.retweeted_status.urls[0].expanded_url + "\n") + ("Retweets: %s" % (status.retweeted_status.retweet_count,))
else:
url = url + "\nRetweets: " + str(status.retweet_count)
# If we are editing message it implies the current tweet is a retweet
# and has been posted before. Hence try to edit the older tweet and
# change its number of retweets but if it has passed its edit time
# do nothing.
if edit_message is True:
message_data = {
"message_id": message_id,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

message_id exists only when the try code above doesn't raise an exception, which means it only exists within that scope. Shouldn't message_id be initialized to have a default value of 0 first?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added accordingly.

"content": url,
}
ret = client.update_message(message_data)

if edit_message is False:
message = {
"type": "stream",
"to": [opts.stream],
"subject": subject,
"content": url
}

ret = client.send_message(message)
if ret['result'] == 'success':
if 'twitter' not in config_internal.sections():
config_internal.add_section('twitter')
if status.retweeted_status is None:
config_internal.set('twitter', str(status.id), str(ret['id']))
else:
config_internal.set('twitter', str(status.retweeted_status.id), str(ret['id']))
Copy link
Contributor

@rht rht Mar 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means that the config file content will grow larger with the number of retweeted messages? What about reading the tweet count from the message body instead?

Copy link
Collaborator Author

@orientor orientor Mar 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I am using it as a kind of database to store the message id of the message in which that tweet was published. I am reading the tweet count from the message body. I am storing the message id so that I can later edit that message if I get its retweet.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the message id should be stored in a separate dedicated key-value database?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that would be better. Can you suggest what I should use for the key-value database?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't come up with any solution on top of my head. Haven't seen any being used by python-zulip-api bots before. But if other bots will become more complex to require a db, they might be using the same db we would use here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After a quick search, I found pickledb, a nosql key-value db in pure python. Unfortunately I can't be decisive about this, given that there are several alternatives. Maybe we should discuss in czo.


if ret['result'] == 'error':
# If sending failed (e.g. no such stream), abort and retry next time
Expand Down