integrations/trello: Improve the Trello script.
This commit makes a bunch of improvements: 1. Use format() for string formatting instead of the old style. 2. Stop returning stuff where we don't have to. 3. URL generation should not be done by the script, especially since our eventual goal is for the Zulip server to automatically generate a webhook URL. So the user should be able to supply the URL in the config file. Plus, this makes it easier to test the script with non-Zulip URLs (such as RequestBin). 4. Removed unnecessary arguments.
This commit is contained in:
parent
0f29e9f71b
commit
fa759fc97c
|
@ -1,16 +1,13 @@
|
||||||
# Easy Trello integration for Zulip
|
# A script that automates setting up a webhook with Trello
|
||||||
|
|
||||||
An easy Trello integration for Zulip
|
|
||||||
|
|
||||||
Usage :
|
Usage :
|
||||||
|
|
||||||
1. Fill the needed information in `zulip_trello_config.py` :
|
1. Fill the needed information in `zulip_trello_config.py` :
|
||||||
|
|
||||||
- The bot API KEY,
|
|
||||||
- The Trello API KEY,
|
- The Trello API KEY,
|
||||||
- The Trello TOKEN,
|
- The Trello TOKEN,
|
||||||
- The Zulip host
|
- The Zulip webhook URL
|
||||||
|
|
||||||
2. Execute the script :
|
2. Execute the script :
|
||||||
|
|
||||||
$ python zulip_trello.py <stream_name> <trello_board_name> <trello_board_id>
|
$ python zulip_trello.py <trello_board_name> <trello_board_id>
|
||||||
|
|
|
@ -10,63 +10,26 @@ import sys
|
||||||
import argparse
|
import argparse
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
# Import configuration
|
|
||||||
import zulip_trello_config as configuration
|
import zulip_trello_config as configuration
|
||||||
|
|
||||||
|
|
||||||
VERSION = '0.2'
|
def check_configuration() -> None:
|
||||||
|
|
||||||
|
|
||||||
# argument's settings
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'stream_name',
|
|
||||||
help='The stream to which to integrate Trello.'
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'trello_board_name',
|
|
||||||
help='The Trello board name.'
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'trello_board_id',
|
|
||||||
help='The Trello board short id.'
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
'-v',
|
|
||||||
'--version',
|
|
||||||
help='Display Version and exit',
|
|
||||||
action='version',
|
|
||||||
version='zulip_trello v'+VERSION
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def check_configuration() -> bool:
|
|
||||||
"""check_configuration
|
"""check_configuration
|
||||||
|
|
||||||
Check if configuration fields have been populated in
|
Check if configuration fields have been populated in
|
||||||
zulip_trello_config.py
|
zulip_trello_config.py
|
||||||
|
|
||||||
:returns: config imported from module zulip_trello_config
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
errors = []
|
errors = []
|
||||||
|
|
||||||
if not configuration.BOT_API_KEY:
|
|
||||||
errors.append('Error: BOT_API_KEY is not defined in zulip_trello_config.py')
|
|
||||||
|
|
||||||
if not configuration.TRELLO_API_KEY:
|
if not configuration.TRELLO_API_KEY:
|
||||||
errors.append('Error: TRELLO_API_KEY is not defined in zulip_trello_config.py')
|
errors.append('Error: TRELLO_API_KEY is not defined in zulip_trello_config.py')
|
||||||
|
|
||||||
if not configuration.TRELLO_TOKEN:
|
if not configuration.TRELLO_TOKEN:
|
||||||
errors.append('Error: TRELLO_TOKEN is not defined in zulip_trello_config.py')
|
errors.append('Error: TRELLO_TOKEN is not defined in zulip_trello_config.py')
|
||||||
|
|
||||||
if not configuration.ZULIP_HOST:
|
if not configuration.ZULIP_WEBHOOK_URL:
|
||||||
errors.append('Error: ZULIP_HOST is not defined in zulip_trello_config.py')
|
errors.append('Error: ZULIP_WEBHOOK_URL is not defined in zulip_trello_config.py')
|
||||||
|
|
||||||
if len(errors) > 0:
|
if len(errors) > 0:
|
||||||
for error in errors:
|
for error in errors:
|
||||||
|
@ -74,9 +37,6 @@ def check_configuration() -> bool:
|
||||||
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def get_model_id(options: argparse.Namespace) -> str:
|
def get_model_id(options: argparse.Namespace) -> str:
|
||||||
"""get_model_id
|
"""get_model_id
|
||||||
|
|
||||||
|
@ -88,7 +48,7 @@ def get_model_id(options: argparse.Namespace) -> str:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
trello_api_url = 'https://api.trello.com/1/board/%s' % (
|
trello_api_url = 'https://api.trello.com/1/board/{}'.format(
|
||||||
options.trello_board_id
|
options.trello_board_id
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -128,17 +88,10 @@ def get_webhook_id(options: argparse.Namespace, id_model: str) -> str:
|
||||||
data = {
|
data = {
|
||||||
'key': configuration.TRELLO_API_KEY,
|
'key': configuration.TRELLO_API_KEY,
|
||||||
'token': configuration.TRELLO_TOKEN,
|
'token': configuration.TRELLO_TOKEN,
|
||||||
'description': 'Webhook for Zulip integration (From Trello %s to Zulip %s)' % (
|
'description': 'Webhook for Zulip integration (From Trello {} to Zulip)'.format(
|
||||||
options.trello_board_name,
|
options.trello_board_name,
|
||||||
options.stream_name
|
|
||||||
),
|
|
||||||
'callbackURL': '%s' % (
|
|
||||||
'https://%s/api/v1/external/trello?api_key=%s&stream=%s' % (
|
|
||||||
configuration.ZULIP_HOST,
|
|
||||||
configuration.BOT_API_KEY,
|
|
||||||
options.stream_name
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
'callbackURL': configuration.ZULIP_WEBHOOK_URL,
|
||||||
'idModel': id_model
|
'idModel': id_model
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,52 +109,40 @@ def get_webhook_id(options: argparse.Namespace, id_model: str) -> str:
|
||||||
return webhook_info_json['id']
|
return webhook_info_json['id']
|
||||||
|
|
||||||
|
|
||||||
def log_webhook_info(options: argparse.Namespace, id_webhook: str) -> bool:
|
def log_webhook_info(options: argparse.Namespace, id_webhook: str) -> None:
|
||||||
"""log_webhook_info
|
"""log_webhook_info
|
||||||
|
|
||||||
Log webhook info in csv file for possible future use
|
Log webhook info in csv file for possible future use
|
||||||
|
|
||||||
:options: argparse.Namespace arguments
|
:options: argparse.Namespace arguments
|
||||||
:id_webhook: str Trello webhook id
|
:id_webhook: str Trello webhook id
|
||||||
|
|
||||||
:returns: bool
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
with open('zulip_trello_webhooks.csv', 'a') as webhooks_file:
|
with open('zulip_trello_webhooks.csv', 'a') as webhooks_file:
|
||||||
webhooks_file.write(
|
webhooks_file.write(
|
||||||
'%s,%s,%s\n' % (
|
'{},{}\n'.format(
|
||||||
options.stream_name,
|
|
||||||
options.trello_board_name,
|
options.trello_board_name,
|
||||||
id_webhook
|
id_webhook
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
return True
|
def create_webhook(options: argparse.Namespace) -> None:
|
||||||
|
|
||||||
|
|
||||||
def create_webhook(options: argparse.Namespace) -> bool:
|
|
||||||
"""create_webhook
|
"""create_webhook
|
||||||
|
|
||||||
Create Trello webhook
|
Create Trello webhook
|
||||||
|
|
||||||
:options: argparse.Namespace arguments
|
:options: argparse.Namespace arguments
|
||||||
|
|
||||||
:returns: bool
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# first, we need to get the idModel
|
# first, we need to get the idModel
|
||||||
print('Getting Trello idModel for the %s board...' % (options.trello_board_name))
|
print('Getting Trello idModel for the {} board...'.format(options.trello_board_name))
|
||||||
|
|
||||||
id_model = get_model_id(options)
|
id_model = get_model_id(options)
|
||||||
|
|
||||||
if id_model:
|
if id_model:
|
||||||
print('Success! The idModel is', id_model)
|
print('Success! The idModel is', id_model)
|
||||||
|
|
||||||
# Next, we need to create the webhook
|
|
||||||
print('Creating the webhook for the %s stream...' % (options.stream_name))
|
|
||||||
|
|
||||||
id_webhook = get_webhook_id(options, id_model)
|
id_webhook = get_webhook_id(options, id_model)
|
||||||
|
|
||||||
if id_webhook:
|
if id_webhook:
|
||||||
|
@ -211,26 +152,20 @@ def create_webhook(options: argparse.Namespace) -> bool:
|
||||||
# Log informations for possible future needs
|
# Log informations for possible future needs
|
||||||
print('Logging webhook information')
|
print('Logging webhook information')
|
||||||
|
|
||||||
was_logged = log_webhook_info(options, id_webhook)
|
log_webhook_info(options, id_webhook)
|
||||||
|
print('Success! The webhook for the {} Trello board was successfully created.'.format(
|
||||||
if was_logged:
|
options.trello_board_name))
|
||||||
print(
|
print('\nYou can find the webhooks information in the zulip_trello_webhooks.csv file.')
|
||||||
'Success! The webhook for the %s stream from the %s Trello board was successfully created.' % (
|
|
||||||
options.stream_name,
|
|
||||||
options.trello_board_name
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
print('\nYou can find the webhooks information in the zulip_trello_webhooks.csv file.')
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
options = parser.parse_args()
|
parser = argparse.ArgumentParser()
|
||||||
if check_configuration():
|
parser.add_argument('trello_board_name', help='The Trello board name.')
|
||||||
creation_status = create_webhook(options)
|
parser.add_argument('trello_board_id', help='The Trello board short id.')
|
||||||
|
|
||||||
|
options = parser.parse_args()
|
||||||
|
check_configuration()
|
||||||
|
create_webhook(options)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -23,15 +23,6 @@
|
||||||
|
|
||||||
### REQUIRED CONFIGURATION ###
|
### REQUIRED CONFIGURATION ###
|
||||||
|
|
||||||
# It needs some API KEY and Token (from Zulip and Trello)
|
|
||||||
# For more information, please visit https://zulipchat.com/integrations/doc/trello
|
|
||||||
|
|
||||||
# BOT_API_KEY
|
|
||||||
#
|
|
||||||
# In Zulip, create a new bot for *incomming Webhook*.
|
|
||||||
# It will generate an API KEY
|
|
||||||
BOT_API_KEY = ""
|
|
||||||
|
|
||||||
# TRELLO_API_KEY
|
# TRELLO_API_KEY
|
||||||
#
|
#
|
||||||
# Visit https://trello.com/1/appkey/generate to generate
|
# Visit https://trello.com/1/appkey/generate to generate
|
||||||
|
@ -46,7 +37,7 @@ TRELLO_API_KEY = ""
|
||||||
# Take care to replace <TRELLO_API_KEY> with the appropriate value
|
# Take care to replace <TRELLO_API_KEY> with the appropriate value
|
||||||
TRELLO_TOKEN = ""
|
TRELLO_TOKEN = ""
|
||||||
|
|
||||||
# ZULIP_HOST
|
# ZULIP_WEBHOOK_URL
|
||||||
#
|
#
|
||||||
# The hostname of your Zulip application
|
# The webhook URL that Trello will query
|
||||||
ZULIP_HOST = ""
|
ZULIP_WEBHOOK_URL = ""
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
stream_name,trello_board_name,id_webhook
|
trello_board_name,id_webhook
|
||||||
|
|
|
Loading…
Reference in a new issue