summaryrefslogtreecommitdiffstats
path: root/ansible_collections/community/general/plugins/modules/twilio.py
blob: 270320c4658000c705a1fa83c65d3f4fc03983cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#!/usr/bin/python
# -*- coding: utf-8 -*-

# Copyright (c) 2015, Matt Makai <matthew.makai@gmail.com>
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

from __future__ import absolute_import, division, print_function
__metaclass__ = type


DOCUMENTATION = '''
---
module: twilio
short_description: Sends a text message to a mobile phone through Twilio
description:
   - Sends a text message to a phone number through the Twilio messaging API.
notes:
   - This module is non-idempotent because it sends an email through the
     external API. It is idempotent only in the case that the module fails.
   - Like the other notification modules, this one requires an external
     dependency to work. In this case, you'll need a Twilio account with
     a purchased or verified phone number to send the text message.
extends_documentation_fragment:
   - community.general.attributes
attributes:
  check_mode:
    support: full
  diff_mode:
    support: none
options:
  account_sid:
    type: str
    description:
      - User's Twilio account token found on the account page.
    required: true
  auth_token:
    type: str
    description:
      - User's Twilio authentication token.
    required: true
  msg:
    type: str
    description:
      - The body of the text message.
    required: true
  to_numbers:
    type: list
    elements: str
    description:
      - One or more phone numbers to send the text message to, format C(+15551112222).
    required: true
    aliases: [ to_number ]
  from_number:
    type: str
    description:
      - The Twilio number to send the text message from, format C(+15551112222).
    required: true
  media_url:
    type: str
    description:
      - A URL with a picture, video or sound clip to send with an MMS
        (multimedia message) instead of a plain SMS.
    required: false

author: "Matt Makai (@makaimc)"
'''

EXAMPLES = '''
# send an SMS about the build status to (555) 303 5681
# note: replace account_sid and auth_token values with your credentials
# and you have to have the 'from_number' on your Twilio account
- name: Send a text message to a mobile phone through Twilio
  community.general.twilio:
    msg: All servers with webserver role are now configured.
    account_sid: ACXXXXXXXXXXXXXXXXX
    auth_token: ACXXXXXXXXXXXXXXXXX
    from_number: +15552014545
    to_number: +15553035681
  delegate_to: localhost

# send an SMS to multiple phone numbers about the deployment
# note: replace account_sid and auth_token values with your credentials
# and you have to have the 'from_number' on your Twilio account
- name: Send a text message to a mobile phone through Twilio
  community.general.twilio:
    msg: This server configuration is now complete.
    account_sid: ACXXXXXXXXXXXXXXXXX
    auth_token: ACXXXXXXXXXXXXXXXXX
    from_number: +15553258899
    to_numbers:
      - +15551113232
      - +12025551235
      - +19735559010
  delegate_to: localhost

# send an MMS to a single recipient with an update on the deployment
# and an image of the results
# note: replace account_sid and auth_token values with your credentials
# and you have to have the 'from_number' on your Twilio account
- name: Send a text message to a mobile phone through Twilio
  community.general.twilio:
    msg: Deployment complete!
    account_sid: ACXXXXXXXXXXXXXXXXX
    auth_token: ACXXXXXXXXXXXXXXXXX
    from_number: +15552014545
    to_number: +15553035681
    media_url: https://demo.twilio.com/logo.png
  delegate_to: localhost
'''

# =======================================
# twilio module support methods
#
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.six.moves.urllib.parse import urlencode
from ansible.module_utils.urls import fetch_url


def post_twilio_api(module, account_sid, auth_token, msg, from_number,
                    to_number, media_url=None):
    URI = "https://api.twilio.com/2010-04-01/Accounts/%s/Messages.json" \
        % (account_sid,)
    AGENT = "Ansible"

    data = {'From': from_number, 'To': to_number, 'Body': msg}
    if media_url:
        data['MediaUrl'] = media_url
    encoded_data = urlencode(data)

    headers = {'User-Agent': AGENT,
               'Content-type': 'application/x-www-form-urlencoded',
               'Accept': 'application/json',
               }

    # Hack module params to have the Basic auth params that fetch_url expects
    module.params['url_username'] = account_sid.replace('\n', '')
    module.params['url_password'] = auth_token.replace('\n', '')

    return fetch_url(module, URI, data=encoded_data, headers=headers)


# =======================================
# Main
#

def main():

    module = AnsibleModule(
        argument_spec=dict(
            account_sid=dict(required=True),
            auth_token=dict(required=True, no_log=True),
            msg=dict(required=True),
            from_number=dict(required=True),
            to_numbers=dict(required=True, aliases=['to_number'], type='list', elements='str'),
            media_url=dict(default=None, required=False),
        ),
        supports_check_mode=True
    )

    account_sid = module.params['account_sid']
    auth_token = module.params['auth_token']
    msg = module.params['msg']
    from_number = module.params['from_number']
    to_numbers = module.params['to_numbers']
    media_url = module.params['media_url']

    for number in to_numbers:
        r, info = post_twilio_api(module, account_sid, auth_token, msg,
                                  from_number, number, media_url)
        if info['status'] not in [200, 201]:
            body_message = "unknown error"
            if 'body' in info:
                body = module.from_json(info['body'])
                body_message = body['message']
            module.fail_json(msg="unable to send message to %s: %s" % (number, body_message))

    module.exit_json(msg=msg, changed=False)


if __name__ == '__main__':
    main()