# Buggy code
def main():
    module = AnsibleModule(
        argument_spec=dict(
            component=dict(required=True, aliases=["name"]),
            version=dict(required=True),
            token=dict(required=True, no_log=True),
            state=dict(required=True, choices=["started", "finished", "failed"]),
            hosts=dict(
                required=False, default=[socket.gethostname()], aliases=["host"]
            ),
            env=dict(required=False),
            owner=dict(required=False),
            description=dict(required=False),
            message=dict(required=False),
            source_system=dict(required=False, default="ansible"),
            validate_certs=dict(default="yes", type="bool"),
            url=dict(required=False, default="https://api.bigpanda.io"),
        ),
        supports_check_mode=True,
    )

    token = module.params["token"]
    state = module.params["state"]
    url = module.params["url"]

    # Build the common request body
    body = dict()
    for k in ("component", "version", "hosts"):
        v = module.params[k]
        if v is not None:
            body[k] = v

    if not isinstance(body["hosts"], list):
        body["hosts"] = [body["hosts"]]

    # Insert state-specific attributes to body
    if state == "started":
        for k in ("source_system", "env", "owner", "description"):
            v = module.params[k]
            if v is not None:
                body[k] = v

        request_url = url + "/data/events/deployments/start"
    else:
        message = module.params["message"]
        if message is not None:
            body["errorMessage"] = message

        if state == "finished":
            body["status"] = "success"
        else:
            body["status"] = "failure"

        request_url = url + "/data/events/deployments/end"

    # Build the deployment object we return
    deployment = dict(token=token, url=url)
    deployment.update(body)
    if "errorMessage" in deployment:
        message = deployment.pop("errorMessage")
        deployment["message"] = message

    # If we're in check mode, just exit pretending like we succeeded
    if module.check_mode:
        module.exit_json(changed=True, **deployment)

    # Send the data to bigpanda
    data = json.dumps(body)
    headers = {"Authorization": "Bearer %s" % token, "Content-Type": "application/json"}
    try:
        response, info = fetch_url(module, request_url, data=data, headers=headers)
        if info["status"] == 200:
            module.exit_json(changed=True, **deployment)
        else:
            module.fail_json(msg=json.dumps(info))
    except Exception as e:
        module.fail_json(msg=to_native(e), exception=traceback.format_exc())


# Traceback (TypeError)
The full traceback is:
Traceback (most recent call last):
File "/home/kevin/.ansible/tmp/ansible-tmp-1536342721.9100335-54055516095596/AnsiballZ_datadog_monitor.py", line 113, in <module>
_ansiballz_main()
File "/home/kevin/.ansible/tmp/ansible-tmp-1536342721.9100335-54055516095596/AnsiballZ_datadog_monitor.py", line 105, in _ansiballz_main
invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
File "/home/kevin/.ansible/tmp/ansible-tmp-1536342721.9100335-54055516095596/AnsiballZ_datadog_monitor.py", line 48, in invoke_module
imp.load_module('__main__', mod, module, MOD_DESC)
File "/usr/lib64/python3.6/imp.py", line 235, in load_module
return load_source(name, filename, file)
File "/usr/lib64/python3.6/imp.py", line 170, in load_source
module = _exec(spec, sys.modules[name])
File "<frozen importlib._bootstrap>", line 618, in _exec
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/tmp/ansible_datadog_monitor_payload_2zuzk2lj/__main__.py", line 343, in <module>
File "/tmp/ansible_datadog_monitor_payload_2zuzk2lj/__main__.py", line 179, in main
File "/tmp/ansible_datadog_monitor_payload_2zuzk2lj/ansible_datadog_monitor_payload.zip/ansible/module_utils/basic.py", line 900, in __init__
File "/tmp/ansible_datadog_monitor_payload_2zuzk2lj/ansible_datadog_monitor_payload.zip/ansible/module_utils/basic.py", line 2242, in _log_invocation
File "/tmp/ansible_datadog_monitor_payload_2zuzk2lj/ansible_datadog_monitor_payload.zip/ansible/module_utils/basic.py", line 2200, in log
TypeError: send() got multiple values for keyword argument 'MESSAGE'

# Fixed code
def main():
    module = AnsibleModule(
        argument_spec=dict(
            component=dict(required=True, aliases=["name"]),
            version=dict(required=True),
            token=dict(required=True, no_log=True),
            state=dict(required=True, choices=["started", "finished", "failed"]),
            hosts=dict(
                required=False, default=[socket.gethostname()], aliases=["host"]
            ),
            env=dict(required=False),
            owner=dict(required=False),
            description=dict(required=False),
            deployment_message=dict(
                required=False,
                aliases=["message"],
                deprecated_aliases=[dict(name="message", version="2.14")],
            ),
            source_system=dict(required=False, default="ansible"),
            validate_certs=dict(default="yes", type="bool"),
            url=dict(required=False, default="https://api.bigpanda.io"),
        ),
        supports_check_mode=True,
    )

    token = module.params["token"]
    state = module.params["state"]
    url = module.params["url"]

    # Build the common request body
    body = dict()
    for k in ("component", "version", "hosts"):
        v = module.params[k]
        if v is not None:
            body[k] = v

    if not isinstance(body["hosts"], list):
        body["hosts"] = [body["hosts"]]

    # Insert state-specific attributes to body
    if state == "started":
        for k in ("source_system", "env", "owner", "description"):
            v = module.params[k]
            if v is not None:
                body[k] = v

        request_url = url + "/data/events/deployments/start"
    else:
        message = module.params["message"]
        if message is not None:
            body["errorMessage"] = message

        if state == "finished":
            body["status"] = "success"
        else:
            body["status"] = "failure"

        request_url = url + "/data/events/deployments/end"

    # Build the deployment object we return
    deployment = dict(token=token, url=url)
    deployment.update(body)
    if "errorMessage" in deployment:
        message = deployment.pop("errorMessage")
        deployment["message"] = message

    # If we're in check mode, just exit pretending like we succeeded
    if module.check_mode:
        module.exit_json(changed=True, **deployment)

    # Send the data to bigpanda
    data = json.dumps(body)
    headers = {"Authorization": "Bearer %s" % token, "Content-Type": "application/json"}
    try:
        response, info = fetch_url(module, request_url, data=data, headers=headers)
        if info["status"] == 200:
            module.exit_json(changed=True, **deployment)
        else:
            module.fail_json(msg=json.dumps(info))
    except Exception as e:
        module.fail_json(msg=to_native(e), exception=traceback.format_exc())