404
72 | 73 |Page not found
74 | 75 | 76 |Page not found
74 | 75 | 76 |Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial.
91 |Cards are meant to increase interactivity during the chat. They can be used, for example to send a form that the bot would like an end user to respond to. In this instance, we are sending a blank card to the user, which is pretty much useless. This can
92 |from python.webex.v1.Card import Card
93 | from python.webex.v1.Bot import Bot
94 |
95 | bot = Bot()
96 |
97 | card = Card()
98 |
99 | bot.send_card(card=card, room_id="room-id")
100 |
101 | Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial.
103 |The card we just sent above is pretty much useless. If we are to send a card, the user needs to be able to interact with the card and the bot should be able to read whatever has been input on the user side.
104 |from python_webex.v1.Card import Card
105 | from python_webex.v1.Bot import Bot
106 |
107 | bot = Bot()
108 |
109 | bot.create_webhook(
110 | name='attachment-response-2', target_url="[your-bot-url]/attachment-response", resource="attachmentActions", event="created"
111 | )
112 |
113 | Card = Card()
114 | bot.send_card(card=card, room_id='room-id')
115 |
116 | Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial.
118 |Here, we create a webhook for the card responses. For instance, if one fills a form that has been sent on a card, the response will be sent to the specific webhook.
119 |from python_webex.v1.Card import Card
120 | from python_webex.v1.Bot import Bot
121 |
122 | bot = Bot()
123 |
124 | bot.create_webhook(
125 | name='attachment-response-2', target_url="[your-bot-url]/attachment-response", resource="attachmentActions", event="created"
126 | )
127 |
128 |
129 | Note: always make sure to setup this webhook to be whatever link you will be using and append /attachment-response to it. For example, if you are using 'https://abc.com', your value on target_url will be 'https://abc.com/attachment-response'
130 |Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial.
132 |Now, what happens when the user has filled a card form and the response has been sent to the webhook, how do we get the information about the card that has been filled from our end?
133 |Here is how:
134 |from python_webex.v1.Card import Card
135 | from python_webex.v1.Bot imporrt Bot
136 | from pprint import pprint
137 | from python_webex import webhook
138 |
139 | bot = Bot()
140 | card = Card()
141 |
142 |
143 | card.add_input_text(
144 | input_id="first-name-input", input_placeholder="First Name"
145 | )
146 |
147 | card.add_input_text(
148 | input_id="last-name-input", input_placeholder="Last Name"
149 | )
150 |
151 | card.add_submit_action_btn(
152 | title="Submit"
153 | )
154 |
155 | message = bot.send_card(card=card, room_id="room-id")
156 | message_id = message.json()['id']
157 |
158 | @bot.attachment_response(message_id=message_id)
159 | def respond_to_card(msg):
160 | pprint(msg)
161 |
162 | webhook.bot = bot
163 |
164 | if __name__ == "__main__":
165 | webhook.app.run(debug=True)
166 |
167 |
168 |
169 | A python3 library meant to help you create a cisco webex teams bot and take advantage of some of the features available to these bots. 80 | Most of the python libraries setup for webex have been lacking in terms of connecting you to a webhook and this aims at solving that
81 |The following are items this documentation assumes you already have installed: 83 | - virtualenv 84 | - python3 85 | - ngrok
86 |to initialize the virtual environment, run the following command in your Command Line or Command Prompt
88 |virtualenv venv
89 |
90 | then we activate it:
91 |Windows
92 |venv\Scripts\activate
93 |
94 | Linux
95 |source venv/bin/activate
96 |
97 | and there, you have your virtual environment setup and ready for action
98 |while still in your activated virtual environment, run the following command to install python_webex_bot via pip:
100 |pip install python_webex_bot
101 |
102 | then download ngrok which will be used in the concurrent steps
103 |Lets get a simple bot up, running and responsive on our local machine.
105 |If you haven't already, create your Webex account. 107 | Then head on to create your bot
108 |You should be provided with an access token for the bot.
109 |Take this access token and place it in your environment variable as auth_token.
110 |this can be done via your Command prompt or Command Line as:
111 |export auth_token=my_auth_token
112 |
113 | If you're on Windows, run the following on the command prompt:
114 |set auth_token=my_auth_token
115 |
116 | replace my_auth_token with your bots access token
117 |This is a crutial part of running your bot as the python_webex_bot library uses this to identify your bot
118 |If you still have some questions on environment variables, why we need them and how to use them, this may be a good start
119 |in a different terminal from the one used in steps 1 and 2, navigate to the folder where you have the ngrok placed.
121 |Then run the following command:
122 |ngrok http 5000
123 |
124 | This should produce an output similar to the one shown below:
125 |Session Status online
126 | Session Expires 7 hours, 59 minutes
127 | Update update available (version 2.3.25, Ctrl-U to update)
128 | Version 2.3.18
129 | Region United States (us)
130 | Web Interface http://127.0.0.1:4040
131 | Forwarding http://87a942a1.ngrok.io -> http://localhost:5000
132 | Forwarding https://87a942a1.ngrok.io -> http://localhost:5000
133 |
134 | Connections ttl opn rt1 rt5 p50 p90
135 | 0 0 0.00 0.00 0.00 0.00
136 |
137 | Now you are ready for the quest
138 |Create a python file where you intend to run the bot. In my case, I will name my file run.py
copy and paste the following code:
141 |from python_webex.v1.Bot import Bot
142 | from python_webex import webhook
143 |
144 | bot = Bot() # the program will automatically know the bot being referred to y the auth_token
145 |
146 | # create a webhook to expose it to the internet
147 | # rememer that url we got from step 2, this is where we use it. In my case it was http://87a942a1.ngrok.io.
148 | # We will be creating a webhook that will be listening when messages are sent
149 | bot.create_webhook(
150 | name="quickstart_webhook", target_url="http://87a942a1.ngrok.io", resource="messages", event="created"
151 | )
152 |
153 | # we create a function that responds when someone says hi
154 | # the room_id will automatically be filled with the webhook. Do not forget it
155 | @bot.on_hears("hi")
156 | def greet_back(room_id=None):
157 | return bot.send_message(room_id=room_id, text="Hi, how are you doing?")
158 |
159 | # We create a default response in case anyone types anything else that we have not set a response for
160 | # this is done using * [ don't ask me what happend when someone sends '*' as the message, that's on my TODO]
161 | @bot.on_hears("*")
162 | def default_response(room_id=None):
163 | return bot.send_message(room_id=room_id, text="Sorry, could not understand that")
164 |
165 |
166 | # make the webhook know the bot to be listening for, and we are done
167 | webhook.bot = bot
168 |
169 | if __name__ == "__main__":
170 | webhook.app.run(debug=True) # don't keep debug=True in production
171 |
172 | Now, when we text our bot "hi", it will respond with "Hi, how are you doing?"
173 |And when we text anything else, like "When can we meet up?" it will respond with "Sorry, I could not understand that"
174 | 175 |Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial.
105 |Want to send a message from your bot to a specific room? No worries, here is how:
106 |from python_webex.v1.Bot import Bot
107 |
108 | bot = Bot()
109 |
110 | bot.send_message(to_person_email='person-email@gmail.com', text='This is some text')
111 | # or
112 | bot.send_message(room_id='someroomid', text='This is the text')
113 |
114 | # you can use either `room_id` will be given priority over `to_person_email` when both are used at the same time.
115 |
116 | Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial.
118 |To attach a files when sending a message, do this:
119 |from python_webex.v1.Bot import Bot
120 |
121 | bot = Bot()
122 |
123 | bot.send_message(room_id='room-id', text='I am sending a file', files=['https://image.shutterstock.com/image-photo/white-transparent-leaf-on-mirror-260nw-1029171697.jpg'])
124 |
125 | Note the files parameter may be a list, but only one field is allowed. Why Exactly? No Idea, ask Webex. And also you can only keep URI's on the files field and not a path to a file in a local directory.
126 |Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial.
128 |When we want to style our messages e.g using bold, italivs and so on, we can use markups. Have a look here to read more about how markups work.
129 |So, this is how we can send a markup:
130 |from python_webex.v1.Bot import Bot
131 |
132 | bot = Bot()
133 |
134 | markdown = """
135 | *This is italic*\n
136 | **This is bold**\n
137 | `This looks like code`
138 | """
139 | bot.send_markdown(
140 | to_person_email="some-email@gmail.com", markdown = markdown
141 | )
142 |
143 | Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial.
145 |This lists all the messages that have been received by the bot on a specific room.
146 |This is how we can get these details:
147 |from python_webex.v1.Bot import Bot
148 | from pprint import pprint
149 |
150 | bot = Bot()
151 |
152 | pprint(bot.get_messages(room_id="room-id").json())
153 |
154 | Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial.
156 |Gets a list of all messages sent in 1:1 rooms. This is basically a list of all the bot's DMs with a particular individual, done by providing the person's ID.
157 |This is how this is done:
158 |from python_webex.v1.Bot import Bot
159 | from pprint import pprint
160 |
161 | bot = Bot()
162 |
163 | pprint(bot.get_direct_messages(person_id="person-id").json())
164 |
165 | Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial.
167 |Gives you details about a specific message with ID message-id
168 |from python_webex.v1.Bot import Bot
169 | from pprint import pprint
170 |
171 | bot = Bot()
172 |
173 | pprin(bot.get_message_details(message_id="message-id").json())
174 |
175 | Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial.
177 |Deletes a specific message with ID message-id
178 |from python_webex.v1.Bot import Bot
179 | from pprint import pprint
180 |
181 | bot = Bot()
182 |
183 | bot.delete_message(message_id='message-id')
184 |
185 | Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial.
187 |If your bot need to be constantly listening for incoming messages, you need to set up a webhook. To set up a webhook, you need an address that is available via the public internet. You can use ngrok for this.
188 |If you have ngrok downloaded, type ./ngrok http 5000
if you are on Linux. Otherwise, type ngrok.exe http 5000
if you are on Windows. This will give you an output as such:
Session Expires 7 hours, 6 minutes
190 | Version 2.3.35
191 | Region United States (us)
192 | Web Interface http://127.0.0.1:4040
193 | Forwarding http://cff51342.ngrok.io -> http://localhost:5000
194 | Forwarding https://cff51342.ngrok.io -> http://localhost:5000
195 |
196 | Now, you can open up your text editor and type in the following:
197 |from python_webex.v1.Bot import Bot
198 | from python_webex import webhook
199 |
200 | bot = Bot()
201 | bot.create_webhook(
202 | name='some-normal-webhook', target_url='https://cff51342.ngrok.io', resource='messages', event='created'
203 | )
204 |
205 | webhook.bot = bot
206 |
207 | if __name__ == "__main__":
208 | webhook.app.run(debug=True)
209 |
210 | You willl now be constantly listening for any incoming message via the message that has been sent to the bot.
211 |Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples 213 | on this tutorial.
214 |When you receive a message, it normally comes with text. The following is how to set a default response whatever text is sent to the bot:
215 |from python_webex.v1.Bot import Bot
216 |
217 | bot = Bot()
218 |
219 | @bot.on_hears("*")
220 | def default_on_hears_function(room_id=None):
221 | bot.send_message(room_id=room_id, text="This is the default response for the message that has been sent")
222 |
223 | Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples 225 | on this tutorial.
226 |You want your bot to receive files? So do many other people.
227 |We need to have a way to handle how these files are received and handled. So here is how we set the default function for handling incoming files:
228 |from python_webex.v1.Bot import Bot
229 | from python_webex import webhook
230 |
231 | bot = Bot()
232 |
233 | @bot.set_default_file_response()
234 | def default_file_response(files, room_id=None):
235 | bot.send_message(room_id=room_id, text='this is the default response for an attached file')
236 |
237 | webhook.bot = bot
238 |
239 | if __name__ == "__main__":
240 | webhook.app.run(debug=True)
241 |
242 |
243 | If you need to attach anything in the response, refer to the previous tutorial about attaching files with messages
244 |Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples 246 | on this tutorial.
247 |What do you do when someone send you a file attached with a specific set of text, and you do know what you need your bot to do at this point:
248 |from python_webex.v1.Bot import Bot
249 | from python_webex import webhook
250 |
251 | bot = Bot()
252 |
253 | @bot.set_file_action("This is me")
254 | def custom_response(room_id=None, files=None):
255 | print(files)
256 | bot.send_message(room_id=room_id, text="You look amazing")
257 |
258 | webhook.bot = bot
259 |
260 | if __name__ == "__main__":
261 | webhook.app.run(debug=True)
262 |
263 |
264 | In def custom_response(room_id=None, files=None):
, files represent a list of the files being sent to the bot.
Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on here.
93 |What we are aiming to do here is to get all the rooms that the bot is currently in. All from group rooms to individual rooms, we get all the details. Let us look at what we have to do:
94 |from python_webex.v1.Bot import Bot
95 |
96 | bot = Bot()
97 |
98 | all_rooms_response = bot.get_all_rooms()
99 |
100 | all_rooms = all_rooms_response.json()
101 |
102 | print(all_rooms)
103 |
104 |
105 | If everything works out fine you should see the following output:
106 |{
107 | 'items': [
108 | {
109 | 'title': 'room-title',
110 | 'ownerId': 'consumer',
111 | 'id': 'room-id',
112 | 'teamId': 'team-id', # this will show if it is a group room
113 | 'lastActivity': '2019-03-29T07:36:12.214Z',
114 | 'created': '2019-03-29T07:34:21.521Z',
115 | 'isLocked': False,
116 | 'creatorId': 'creator-id',
117 | 'type': 'group'
118 | }
119 | ]
120 | }
121 |
122 | Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial.
124 |This gets the details of a specific room, we can use the output from here and get a single rooms ID. We will call the room ID room_id
125 |We will use this room_id to get the details of that specific room, here is how:
126 |from python_webex.v1.Bot import Bot
127 |
128 | bot = Bot()
129 |
130 | room_id = 'someroomid'
131 |
132 | room_details_response = bot.get_room_details(room_id=room_id)
133 |
134 | room_details = room_details_response.json()
135 |
136 | print(room_details)
137 |
138 |
139 | You should see an output similar to this:
140 |{
141 | 'creatorId': 'creator-id',
142 | 'lastActivity': '2019-03-29T07:36:12.214Z',
143 | 'id': 'room-id',
144 | 'title': 'Discussion',
145 | 'created': '2019-03-29T07:34:21.521Z',
146 | 'type': 'group',
147 | 'ownerId': 'consumer',
148 | 'isLocked': False,
149 | 'teamId': 'team-id' # if the room is a team
150 | }
151 |
152 |
153 | Use this information wisely.
154 |Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial.
156 |Some of the functionality for creating a room is still being worked on, bear with us.
157 |The following should work for creating a room:
158 |from python_webex.v1.Bot import Bot
159 |
160 | bot = Bot()
161 |
162 | bot.create_room(title="Bot's room with best friend", team_id="team-id", room_type="something either 'direct' or 'group'")
163 |
164 | Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial.
166 |Currently, we can only edit the title of a room. To do so, run the following script:
167 |from python_webex.v1.Bot import Bot
168 |
169 | bot = Bot()
170 |
171 | room_id = 'room-id'
172 |
173 | bot.update_room_details(room_id=room_id, title='New Title')
174 |
175 | Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial.
177 |Let us wreck some havock and delete a room.
178 |This can be done through:
179 |from python_webex.v1.Bot import Bot
180 |
181 | bot = Bot()
182 |
183 | room_id = 'room-id'
184 |
185 | bot.delete_room(room_id=room_id)
186 |
187 |
188 | ' + escapeHtml(summary) +'
' + noResultsText + '
'); 52 | } 53 | } 54 | 55 | function doSearch () { 56 | var query = document.getElementById('mkdocs-search-query').value; 57 | if (query.length > min_search_length) { 58 | if (!window.Worker) { 59 | displayResults(search(query)); 60 | } else { 61 | searchWorker.postMessage({query: query}); 62 | } 63 | } else { 64 | // Clear results for short queries 65 | displayResults([]); 66 | } 67 | } 68 | 69 | function initSearch () { 70 | var search_input = document.getElementById('mkdocs-search-query'); 71 | if (search_input) { 72 | search_input.addEventListener("keyup", doSearch); 73 | } 74 | var term = getSearchTermFromLocation(); 75 | if (term) { 76 | search_input.value = term; 77 | doSearch(); 78 | } 79 | } 80 | 81 | function onWorkerMessage (e) { 82 | if (e.data.allowSearch) { 83 | initSearch(); 84 | } else if (e.data.results) { 85 | var results = e.data.results; 86 | displayResults(results); 87 | } else if (e.data.config) { 88 | min_search_length = e.data.config.min_search_length-1; 89 | } 90 | } 91 | 92 | if (!window.Worker) { 93 | console.log('Web Worker API not supported'); 94 | // load index in main thread 95 | $.getScript(joinUrl(base_url, "search/worker.js")).done(function () { 96 | console.log('Loaded worker'); 97 | init(); 98 | window.postMessage = function (msg) { 99 | onWorkerMessage({data: msg}); 100 | }; 101 | }).fail(function (jqxhr, settings, exception) { 102 | console.error('Could not load worker.js'); 103 | }); 104 | } else { 105 | // Wrap search in a web worker 106 | var searchWorker = new Worker(joinUrl(base_url, "search/worker.js")); 107 | searchWorker.postMessage({init: true}); 108 | searchWorker.onmessage = onWorkerMessage; 109 | } 110 | -------------------------------------------------------------------------------- /docs/site/search/search_index.json: -------------------------------------------------------------------------------- 1 | {"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"python_webex_bot A python3 library meant to help you create a cisco webex teams bot and take advantage of some of the features available to these bots. Most of the python libraries setup for webex have been lacking in terms of connecting you to a webhook and this aims at solving that Installation and setup The following are items this documentation assumes you already have installed: - virtualenv - python3 - ngrok Step 1: setup the virtual environment to initialize the virtual environment, run the following command in your Command Line or Command Prompt virtualenv venv then we activate it: Windows venv\\Scripts\\activate Linux source venv/bin/activate and there, you have your virtual environment setup and ready for action Step 2: install python_webex_bot while still in your activated virtual environment, run the following command to install python_webex_bot via pip: pip install python_webex_bot then download ngrok which will be used in the concurrent steps Quickstart Lets get a simple bot up, running and responsive on our local machine. Step 1: Create the bot on Cisco Webex If you haven't already, create your Webex account. Then head on to create your bot You should be provided with an access token for the bot. Take this access token and place it in your environment variable as auth_token. this can be done via your Command prompt or Command Line as: export auth_token=my_auth_token If you're on Windows , run the following on the command prompt: set auth_token=my_auth_token replace my_auth_token with your bots access token This is a crutial part of running your bot as the python_webex_bot library uses this to identify your bot If you still have some questions on environment variables, why we need them and how to use them, this may be a good start Step 2: setup ngrok in a different terminal from the one used in steps 1 and 2, navigate to the folder where you have the ngrok placed. Then run the following command: ngrok http 5000 This should produce an output similar to the one shown below: Session Status online Session Expires 7 hours, 59 minutes Update update available (version 2.3.25, Ctrl-U to update) Version 2.3.18 Region United States (us) Web Interface http://127.0.0.1:4040 Forwarding http://87a942a1.ngrok.io -> http://localhost:5000 Forwarding https://87a942a1.ngrok.io -> http://localhost:5000 Connections ttl opn rt1 rt5 p50 p90 0 0 0.00 0.00 0.00 0.00 Now you are ready for the quest Step 3: create the python file and run it Create a python file where you intend to run the bot. In my case, I will name my file run.py copy and paste the following code: from python_webex.v1.Bot import Bot from python_webex import webhook bot = Bot() # the program will automatically know the bot being referred to y the auth_token # create a webhook to expose it to the internet # rememer that url we got from step 2, this is where we use it. In my case it was http://87a942a1.ngrok.io. # We will be creating a webhook that will be listening when messages are sent bot.create_webhook( name=\"quickstart_webhook\", target_url=\"http://87a942a1.ngrok.io\", resource=\"messages\", event=\"created\" ) # we create a function that responds when someone says hi # the room_id will automatically be filled with the webhook. Do not forget it @bot.on_hears(\"hi\") def greet_back(room_id=None): return bot.send_message(room_id=room_id, text=\"Hi, how are you doing?\") # We create a default response in case anyone types anything else that we have not set a response for # this is done using * [ don't ask me what happend when someone sends '*' as the message, that's on my TODO] @bot.on_hears(\"*\") def default_response(room_id=None): return bot.send_message(room_id=room_id, text=\"Sorry, could not understand that\") # make the webhook know the bot to be listening for, and we are done webhook.bot = bot if __name__ == \"__main__\": webhook.app.run(debug=True) # don't keep debug=True in production Now, when we text our bot \"hi\", it will respond with \"Hi, how are you doing?\" And when we text anything else, like \"When can we meet up?\" it will respond with \"Sorry, I could not understand that\"","title":"python_webex_bot"},{"location":"#python_webex_bot","text":"A python3 library meant to help you create a cisco webex teams bot and take advantage of some of the features available to these bots. Most of the python libraries setup for webex have been lacking in terms of connecting you to a webhook and this aims at solving that","title":"python_webex_bot"},{"location":"#installation-and-setup","text":"The following are items this documentation assumes you already have installed: - virtualenv - python3 - ngrok","title":"Installation and setup"},{"location":"#step-1-setup-the-virtual-environment","text":"to initialize the virtual environment, run the following command in your Command Line or Command Prompt virtualenv venv then we activate it: Windows venv\\Scripts\\activate Linux source venv/bin/activate and there, you have your virtual environment setup and ready for action","title":"Step 1: setup the virtual environment"},{"location":"#step-2-install-python_webex_bot","text":"while still in your activated virtual environment, run the following command to install python_webex_bot via pip: pip install python_webex_bot then download ngrok which will be used in the concurrent steps","title":"Step 2: install python_webex_bot"},{"location":"#quickstart","text":"Lets get a simple bot up, running and responsive on our local machine.","title":"Quickstart"},{"location":"#step-1-create-the-bot-on-cisco-webex","text":"If you haven't already, create your Webex account. Then head on to create your bot You should be provided with an access token for the bot. Take this access token and place it in your environment variable as auth_token. this can be done via your Command prompt or Command Line as: export auth_token=my_auth_token If you're on Windows , run the following on the command prompt: set auth_token=my_auth_token replace my_auth_token with your bots access token This is a crutial part of running your bot as the python_webex_bot library uses this to identify your bot If you still have some questions on environment variables, why we need them and how to use them, this may be a good start","title":"Step 1: Create the bot on Cisco Webex"},{"location":"#step-2-setup-ngrok","text":"in a different terminal from the one used in steps 1 and 2, navigate to the folder where you have the ngrok placed. Then run the following command: ngrok http 5000 This should produce an output similar to the one shown below: Session Status online Session Expires 7 hours, 59 minutes Update update available (version 2.3.25, Ctrl-U to update) Version 2.3.18 Region United States (us) Web Interface http://127.0.0.1:4040 Forwarding http://87a942a1.ngrok.io -> http://localhost:5000 Forwarding https://87a942a1.ngrok.io -> http://localhost:5000 Connections ttl opn rt1 rt5 p50 p90 0 0 0.00 0.00 0.00 0.00 Now you are ready for the quest","title":"Step 2: setup ngrok"},{"location":"#step-3-create-the-python-file-and-run-it","text":"Create a python file where you intend to run the bot. In my case, I will name my file run.py copy and paste the following code: from python_webex.v1.Bot import Bot from python_webex import webhook bot = Bot() # the program will automatically know the bot being referred to y the auth_token # create a webhook to expose it to the internet # rememer that url we got from step 2, this is where we use it. In my case it was http://87a942a1.ngrok.io. # We will be creating a webhook that will be listening when messages are sent bot.create_webhook( name=\"quickstart_webhook\", target_url=\"http://87a942a1.ngrok.io\", resource=\"messages\", event=\"created\" ) # we create a function that responds when someone says hi # the room_id will automatically be filled with the webhook. Do not forget it @bot.on_hears(\"hi\") def greet_back(room_id=None): return bot.send_message(room_id=room_id, text=\"Hi, how are you doing?\") # We create a default response in case anyone types anything else that we have not set a response for # this is done using * [ don't ask me what happend when someone sends '*' as the message, that's on my TODO] @bot.on_hears(\"*\") def default_response(room_id=None): return bot.send_message(room_id=room_id, text=\"Sorry, could not understand that\") # make the webhook know the bot to be listening for, and we are done webhook.bot = bot if __name__ == \"__main__\": webhook.app.run(debug=True) # don't keep debug=True in production Now, when we text our bot \"hi\", it will respond with \"Hi, how are you doing?\" And when we text anything else, like \"When can we meet up?\" it will respond with \"Sorry, I could not understand that\"","title":"Step 3: create the python file and run it"},{"location":"cards/","text":"Cards Create & Send Blank Card Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. Cards are meant to increase interactivity during the chat. They can be used, for example to send a form that the bot would like an end user to respond to. In this instance, we are sending a blank card to the user, which is pretty much useless. This can from python.webex.v1.Card import Card from python.webex.v1.Bot import Bot bot = Bot() card = Card() bot.send_card(card=card, room_id=\"room-id\") Add text items on the card Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. The card we just sent above is pretty much useless. If we are to send a card, the user needs to be able to interact with the card and the bot should be able to read whatever has been input on the user side. from python_webex.v1.Card import Card from python_webex.v1.Bot import Bot bot = Bot() bot.create_webhook( name='attachment-response-2', target_url=\"[your-bot-url]/attachment-response\", resource=\"attachmentActions\", event=\"created\" ) Card = Card() bot.send_card(card=card, room_id='room-id') Create Card Webhook Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. Here, we create a webhook for the card responses. For instance, if one fills a form that has been sent on a card, the response will be sent to the specific webhook. from python_webex.v1.Card import Card from python_webex.v1.Bot import Bot bot = Bot() bot.create_webhook( name='attachment-response-2', target_url=\"[your-bot-url]/attachment-response\", resource=\"attachmentActions\", event=\"created\" ) Note: always make sure to setup this webhook to be whatever link you will be using and append /attachment-response to it. For example, if you are using 'https://abc.com', your value on target_url will be 'https://abc.com/attachment-response' Listen for response on card Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. Now, what happens when the user has filled a card form and the response has been sent to the webhook, how do we get the information about the card that has been filled from our end? Here is how: from python_webex.v1.Card import Card from python_webex.v1.Bot imporrt Bot from pprint import pprint from python_webex import webhook bot = Bot() card = Card() card.add_input_text( input_id=\"first-name-input\", input_placeholder=\"First Name\" ) card.add_input_text( input_id=\"last-name-input\", input_placeholder=\"Last Name\" ) card.add_submit_action_btn( title=\"Submit\" ) message = bot.send_card(card=card, room_id=\"room-id\") message_id = message.json()['id'] @bot.attachment_response(message_id=message_id) def respond_to_card(msg): pprint(msg) webhook.bot = bot if __name__ == \"__main__\": webhook.app.run(debug=True)","title":"Cards"},{"location":"cards/#cards","text":"","title":"Cards"},{"location":"cards/#create-send-blank-card","text":"Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. Cards are meant to increase interactivity during the chat. They can be used, for example to send a form that the bot would like an end user to respond to. In this instance, we are sending a blank card to the user, which is pretty much useless. This can from python.webex.v1.Card import Card from python.webex.v1.Bot import Bot bot = Bot() card = Card() bot.send_card(card=card, room_id=\"room-id\")","title":"Create & Send Blank Card"},{"location":"cards/#add-text-items-on-the-card","text":"Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. The card we just sent above is pretty much useless. If we are to send a card, the user needs to be able to interact with the card and the bot should be able to read whatever has been input on the user side. from python_webex.v1.Card import Card from python_webex.v1.Bot import Bot bot = Bot() bot.create_webhook( name='attachment-response-2', target_url=\"[your-bot-url]/attachment-response\", resource=\"attachmentActions\", event=\"created\" ) Card = Card() bot.send_card(card=card, room_id='room-id')","title":"Add text items on the card"},{"location":"cards/#create-card-webhook","text":"Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. Here, we create a webhook for the card responses. For instance, if one fills a form that has been sent on a card, the response will be sent to the specific webhook. from python_webex.v1.Card import Card from python_webex.v1.Bot import Bot bot = Bot() bot.create_webhook( name='attachment-response-2', target_url=\"[your-bot-url]/attachment-response\", resource=\"attachmentActions\", event=\"created\" ) Note: always make sure to setup this webhook to be whatever link you will be using and append /attachment-response to it. For example, if you are using 'https://abc.com', your value on target_url will be 'https://abc.com/attachment-response'","title":"Create Card Webhook"},{"location":"cards/#listen-for-response-on-card","text":"Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. Now, what happens when the user has filled a card form and the response has been sent to the webhook, how do we get the information about the card that has been filled from our end? Here is how: from python_webex.v1.Card import Card from python_webex.v1.Bot imporrt Bot from pprint import pprint from python_webex import webhook bot = Bot() card = Card() card.add_input_text( input_id=\"first-name-input\", input_placeholder=\"First Name\" ) card.add_input_text( input_id=\"last-name-input\", input_placeholder=\"Last Name\" ) card.add_submit_action_btn( title=\"Submit\" ) message = bot.send_card(card=card, room_id=\"room-id\") message_id = message.json()['id'] @bot.attachment_response(message_id=message_id) def respond_to_card(msg): pprint(msg) webhook.bot = bot if __name__ == \"__main__\": webhook.app.run(debug=True)","title":"Listen for response on card"},{"location":"messages/","text":"Messages Create Message Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. Want to send a message from your bot to a specific room? No worries, here is how: from python_webex.v1.Bot import Bot bot = Bot() bot.send_message(to_person_email='person-email@gmail.com', text='This is some text') # or bot.send_message(room_id='someroomid', text='This is the text') # you can use either `room_id` will be given priority over `to_person_email` when both are used at the same time. Attach files with message Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. To attach a files when sending a message, do this: from python_webex.v1.Bot import Bot bot = Bot() bot.send_message(room_id='room-id', text='I am sending a file', files=['https://image.shutterstock.com/image-photo/white-transparent-leaf-on-mirror-260nw-1029171697.jpg']) Note the files parameter may be a list, but only one field is allowed. Why Exactly? No Idea, ask Webex. And also you can only keep URI's on the files field and not a path to a file in a local directory. Send message with Markdown Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. When we want to style our messages e.g using bold, italivs and so on, we can use markups. Have a look here to read more about how markups work. So, this is how we can send a markup: from python_webex.v1.Bot import Bot bot = Bot() markdown = \"\"\" *This is italic*\\n **This is bold**\\n `This looks like code` \"\"\" bot.send_markdown( to_person_email=\"some-email@gmail.com\", markdown = markdown ) Get messages Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. This lists all the messages that have been received by the bot on a specific room. This is how we can get these details: from python_webex.v1.Bot import Bot from pprint import pprint bot = Bot() pprint(bot.get_messages(room_id=\"room-id\").json()) Get Direct Messages Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. Gets a list of all messages sent in 1:1 rooms. This is basically a list of all the bot's DMs with a particular individual, done by providing the person's ID. This is how this is done: from python_webex.v1.Bot import Bot from pprint import pprint bot = Bot() pprint(bot.get_direct_messages(person_id=\"person-id\").json()) Get Message Details Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. Gives you details about a specific message with ID message-id from python_webex.v1.Bot import Bot from pprint import pprint bot = Bot() pprin(bot.get_message_details(message_id=\"message-id\").json()) Delete Message Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. Deletes a specific message with ID message-id from python_webex.v1.Bot import Bot from pprint import pprint bot = Bot() bot.delete_message(message_id='message-id') Setup Webhook for incoming messages Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. If your bot need to be constantly listening for incoming messages, you need to set up a webhook. To set up a webhook, you need an address that is available via the public internet. You can use ngrok for this. If you have ngrok downloaded, type ./ngrok http 5000 if you are on Linux . Otherwise, type ngrok.exe http 5000 if you are on Windows . This will give you an output as such: Session Expires 7 hours, 6 minutes Version 2.3.35 Region United States (us) Web Interface http://127.0.0.1:4040 Forwarding http://cff51342.ngrok.io -> http://localhost:5000 Forwarding https://cff51342.ngrok.io -> http://localhost:5000 Now, you can open up your text editor and type in the following: from python_webex.v1.Bot import Bot from python_webex import webhook bot = Bot() bot.create_webhook( name='some-normal-webhook', target_url='https://cff51342.ngrok.io', resource='messages', event='created' ) webhook.bot = bot if __name__ == \"__main__\": webhook.app.run(debug=True) You willl now be constantly listening for any incoming message via the message that has been sent to the bot. Set default action for incoming message Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. When you receive a message, it normally comes with text. The following is how to set a default response whatever text is sent to the bot: from python_webex.v1.Bot import Bot bot = Bot() @bot.on_hears(\"*\") def default_on_hears_function(room_id=None): bot.send_message(room_id=room_id, text=\"This is the default response for the message that has been sent\") Set default listener for incoming files Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. You want your bot to receive files? So do many other people. We need to have a way to handle how these files are received and handled. So here is how we set the default function for handling incoming files: from python_webex.v1.Bot import Bot from python_webex import webhook bot = Bot() @bot.set_default_file_response() def default_file_response(files, room_id=None): bot.send_message(room_id=room_id, text='this is the default response for an attached file') webhook.bot = bot if __name__ == \"__main__\": webhook.app.run(debug=True) If you need to attach anything in the response, refer to the previous tutorial about attaching files with messages Set listener for specific text attached with file Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. What do you do when someone send you a file attached with a specific set of text, and you do know what you need your bot to do at this point: from python_webex.v1.Bot import Bot from python_webex import webhook bot = Bot() @bot.set_file_action(\"This is me\") def custom_response(room_id=None, files=None): print(files) bot.send_message(room_id=room_id, text=\"You look amazing\") webhook.bot = bot if __name__ == \"__main__\": webhook.app.run(debug=True) In def custom_response(room_id=None, files=None): , files represent a list of the files being sent to the bot.","title":"Messages"},{"location":"messages/#messages","text":"","title":"Messages"},{"location":"messages/#create-message","text":"Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. Want to send a message from your bot to a specific room? No worries, here is how: from python_webex.v1.Bot import Bot bot = Bot() bot.send_message(to_person_email='person-email@gmail.com', text='This is some text') # or bot.send_message(room_id='someroomid', text='This is the text') # you can use either `room_id` will be given priority over `to_person_email` when both are used at the same time.","title":"Create Message"},{"location":"messages/#attach-files-with-message","text":"Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. To attach a files when sending a message, do this: from python_webex.v1.Bot import Bot bot = Bot() bot.send_message(room_id='room-id', text='I am sending a file', files=['https://image.shutterstock.com/image-photo/white-transparent-leaf-on-mirror-260nw-1029171697.jpg']) Note the files parameter may be a list, but only one field is allowed. Why Exactly? No Idea, ask Webex. And also you can only keep URI's on the files field and not a path to a file in a local directory.","title":"Attach files with message"},{"location":"messages/#send-message-with-markdown","text":"Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. When we want to style our messages e.g using bold, italivs and so on, we can use markups. Have a look here to read more about how markups work. So, this is how we can send a markup: from python_webex.v1.Bot import Bot bot = Bot() markdown = \"\"\" *This is italic*\\n **This is bold**\\n `This looks like code` \"\"\" bot.send_markdown( to_person_email=\"some-email@gmail.com\", markdown = markdown )","title":"Send message with Markdown"},{"location":"messages/#get-messages","text":"Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. This lists all the messages that have been received by the bot on a specific room. This is how we can get these details: from python_webex.v1.Bot import Bot from pprint import pprint bot = Bot() pprint(bot.get_messages(room_id=\"room-id\").json())","title":"Get messages"},{"location":"messages/#get-direct-messages","text":"Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. Gets a list of all messages sent in 1:1 rooms. This is basically a list of all the bot's DMs with a particular individual, done by providing the person's ID. This is how this is done: from python_webex.v1.Bot import Bot from pprint import pprint bot = Bot() pprint(bot.get_direct_messages(person_id=\"person-id\").json())","title":"Get Direct Messages"},{"location":"messages/#get-message-details","text":"Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. Gives you details about a specific message with ID message-id from python_webex.v1.Bot import Bot from pprint import pprint bot = Bot() pprin(bot.get_message_details(message_id=\"message-id\").json())","title":"Get Message Details"},{"location":"messages/#delete-message","text":"Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. Deletes a specific message with ID message-id from python_webex.v1.Bot import Bot from pprint import pprint bot = Bot() bot.delete_message(message_id='message-id')","title":"Delete Message"},{"location":"messages/#setup-webhook-for-incoming-messages","text":"Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. If your bot need to be constantly listening for incoming messages, you need to set up a webhook. To set up a webhook, you need an address that is available via the public internet. You can use ngrok for this. If you have ngrok downloaded, type ./ngrok http 5000 if you are on Linux . Otherwise, type ngrok.exe http 5000 if you are on Windows . This will give you an output as such: Session Expires 7 hours, 6 minutes Version 2.3.35 Region United States (us) Web Interface http://127.0.0.1:4040 Forwarding http://cff51342.ngrok.io -> http://localhost:5000 Forwarding https://cff51342.ngrok.io -> http://localhost:5000 Now, you can open up your text editor and type in the following: from python_webex.v1.Bot import Bot from python_webex import webhook bot = Bot() bot.create_webhook( name='some-normal-webhook', target_url='https://cff51342.ngrok.io', resource='messages', event='created' ) webhook.bot = bot if __name__ == \"__main__\": webhook.app.run(debug=True) You willl now be constantly listening for any incoming message via the message that has been sent to the bot.","title":"Setup Webhook for incoming messages"},{"location":"messages/#set-default-action-for-incoming-message","text":"Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. When you receive a message, it normally comes with text. The following is how to set a default response whatever text is sent to the bot: from python_webex.v1.Bot import Bot bot = Bot() @bot.on_hears(\"*\") def default_on_hears_function(room_id=None): bot.send_message(room_id=room_id, text=\"This is the default response for the message that has been sent\")","title":"Set default action for incoming message"},{"location":"messages/#set-default-listener-for-incoming-files","text":"Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. You want your bot to receive files? So do many other people. We need to have a way to handle how these files are received and handled. So here is how we set the default function for handling incoming files: from python_webex.v1.Bot import Bot from python_webex import webhook bot = Bot() @bot.set_default_file_response() def default_file_response(files, room_id=None): bot.send_message(room_id=room_id, text='this is the default response for an attached file') webhook.bot = bot if __name__ == \"__main__\": webhook.app.run(debug=True) If you need to attach anything in the response, refer to the previous tutorial about attaching files with messages","title":"Set default listener for incoming files"},{"location":"messages/#set-listener-for-specific-text-attached-with-file","text":"Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. What do you do when someone send you a file attached with a specific set of text, and you do know what you need your bot to do at this point: from python_webex.v1.Bot import Bot from python_webex import webhook bot = Bot() @bot.set_file_action(\"This is me\") def custom_response(room_id=None, files=None): print(files) bot.send_message(room_id=room_id, text=\"You look amazing\") webhook.bot = bot if __name__ == \"__main__\": webhook.app.run(debug=True) In def custom_response(room_id=None, files=None): , files represent a list of the files being sent to the bot.","title":"Set listener for specific text attached with file"},{"location":"rooms/","text":"Rooms Get all rooms Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on here. What we are aiming to do here is to get all the rooms that the bot is currently in. All from group rooms to individual rooms, we get all the details. Let us look at what we have to do: from python_webex.v1.Bot import Bot bot = Bot() all_rooms_response = bot.get_all_rooms() all_rooms = all_rooms_response.json() print(all_rooms) If everything works out fine you should see the following output: { 'items': [ { 'title': 'room-title', 'ownerId': 'consumer', 'id': 'room-id', 'teamId': 'team-id', # this will show if it is a group room 'lastActivity': '2019-03-29T07:36:12.214Z', 'created': '2019-03-29T07:34:21.521Z', 'isLocked': False, 'creatorId': 'creator-id', 'type': 'group' } ] } Get room details Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. This gets the details of a specific room, we can use the output from here and get a single rooms ID. We will call the room ID room_id We will use this room_id to get the details of that specific room, here is how: from python_webex.v1.Bot import Bot bot = Bot() room_id = 'someroomid' room_details_response = bot.get_room_details(room_id=room_id) room_details = room_details_response.json() print(room_details) You should see an output similar to this: { 'creatorId': 'creator-id', 'lastActivity': '2019-03-29T07:36:12.214Z', 'id': 'room-id', 'title': 'Discussion', 'created': '2019-03-29T07:34:21.521Z', 'type': 'group', 'ownerId': 'consumer', 'isLocked': False, 'teamId': 'team-id' # if the room is a team } Use this information wisely. Create Room Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. Some of the functionality for creating a room is still being worked on, bear with us. The following should work for creating a room: from python_webex.v1.Bot import Bot bot = Bot() bot.create_room(title=\"Bot's room with best friend\", team_id=\"team-id\", room_type=\"something either 'direct' or 'group'\") Update Room Details Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. Currently, we can only edit the title of a room. To do so, run the following script: from python_webex.v1.Bot import Bot bot = Bot() room_id = 'room-id' bot.update_room_details(room_id=room_id, title='New Title') Delete a room Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. Let us wreck some havock and delete a room. This can be done through: from python_webex.v1.Bot import Bot bot = Bot() room_id = 'room-id' bot.delete_room(room_id=room_id)","title":"Rooms"},{"location":"rooms/#rooms","text":"","title":"Rooms"},{"location":"rooms/#get-all-rooms","text":"Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on here. What we are aiming to do here is to get all the rooms that the bot is currently in. All from group rooms to individual rooms, we get all the details. Let us look at what we have to do: from python_webex.v1.Bot import Bot bot = Bot() all_rooms_response = bot.get_all_rooms() all_rooms = all_rooms_response.json() print(all_rooms) If everything works out fine you should see the following output: { 'items': [ { 'title': 'room-title', 'ownerId': 'consumer', 'id': 'room-id', 'teamId': 'team-id', # this will show if it is a group room 'lastActivity': '2019-03-29T07:36:12.214Z', 'created': '2019-03-29T07:34:21.521Z', 'isLocked': False, 'creatorId': 'creator-id', 'type': 'group' } ] }","title":"Get all rooms"},{"location":"rooms/#get-room-details","text":"Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. This gets the details of a specific room, we can use the output from here and get a single rooms ID. We will call the room ID room_id We will use this room_id to get the details of that specific room, here is how: from python_webex.v1.Bot import Bot bot = Bot() room_id = 'someroomid' room_details_response = bot.get_room_details(room_id=room_id) room_details = room_details_response.json() print(room_details) You should see an output similar to this: { 'creatorId': 'creator-id', 'lastActivity': '2019-03-29T07:36:12.214Z', 'id': 'room-id', 'title': 'Discussion', 'created': '2019-03-29T07:34:21.521Z', 'type': 'group', 'ownerId': 'consumer', 'isLocked': False, 'teamId': 'team-id' # if the room is a team } Use this information wisely.","title":"Get room details"},{"location":"rooms/#create-room","text":"Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. Some of the functionality for creating a room is still being worked on, bear with us. The following should work for creating a room: from python_webex.v1.Bot import Bot bot = Bot() bot.create_room(title=\"Bot's room with best friend\", team_id=\"team-id\", room_type=\"something either 'direct' or 'group'\")","title":"Create Room"},{"location":"rooms/#update-room-details","text":"Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. Currently, we can only edit the title of a room. To do so, run the following script: from python_webex.v1.Bot import Bot bot = Bot() room_id = 'room-id' bot.update_room_details(room_id=room_id, title='New Title')","title":"Update Room Details"},{"location":"rooms/#delete-a-room","text":"Always remember that you need to have already set the value auth_token as your bot's Access token before you run this any of the other examples on this tutorial. Let us wreck some havock and delete a room. This can be done through: from python_webex.v1.Bot import Bot bot = Bot() room_id = 'room-id' bot.delete_room(room_id=room_id)","title":"Delete a room"}]} -------------------------------------------------------------------------------- /docs/site/search/worker.js: -------------------------------------------------------------------------------- 1 | var base_path = 'function' === typeof importScripts ? '.' : '/search/'; 2 | var allowSearch = false; 3 | var index; 4 | var documents = {}; 5 | var lang = ['en']; 6 | var data; 7 | 8 | function getScript(script, callback) { 9 | console.log('Loading script: ' + script); 10 | $.getScript(base_path + script).done(function () { 11 | callback(); 12 | }).fail(function (jqxhr, settings, exception) { 13 | console.log('Error: ' + exception); 14 | }); 15 | } 16 | 17 | function getScriptsInOrder(scripts, callback) { 18 | if (scripts.length === 0) { 19 | callback(); 20 | return; 21 | } 22 | getScript(scripts[0], function() { 23 | getScriptsInOrder(scripts.slice(1), callback); 24 | }); 25 | } 26 | 27 | function loadScripts(urls, callback) { 28 | if( 'function' === typeof importScripts ) { 29 | importScripts.apply(null, urls); 30 | callback(); 31 | } else { 32 | getScriptsInOrder(urls, callback); 33 | } 34 | } 35 | 36 | function onJSONLoaded () { 37 | data = JSON.parse(this.responseText); 38 | var scriptsToLoad = ['lunr.js']; 39 | if (data.config && data.config.lang && data.config.lang.length) { 40 | lang = data.config.lang; 41 | } 42 | if (lang.length > 1 || lang[0] !== "en") { 43 | scriptsToLoad.push('lunr.stemmer.support.js'); 44 | if (lang.length > 1) { 45 | scriptsToLoad.push('lunr.multi.js'); 46 | } 47 | if (lang.includes("ja") || lang.includes("jp")) { 48 | scriptsToLoad.push('tinyseg.js'); 49 | } 50 | for (var i=0; i < lang.length; i++) { 51 | if (lang[i] != 'en') { 52 | scriptsToLoad.push(['lunr', lang[i], 'js'].join('.')); 53 | } 54 | } 55 | } 56 | loadScripts(scriptsToLoad, onScriptsLoaded); 57 | } 58 | 59 | function onScriptsLoaded () { 60 | console.log('All search scripts loaded, building Lunr index...'); 61 | if (data.config && data.config.separator && data.config.separator.length) { 62 | lunr.tokenizer.separator = new RegExp(data.config.separator); 63 | } 64 | 65 | if (data.index) { 66 | index = lunr.Index.load(data.index); 67 | data.docs.forEach(function (doc) { 68 | documents[doc.location] = doc; 69 | }); 70 | console.log('Lunr pre-built index loaded, search ready'); 71 | } else { 72 | index = lunr(function () { 73 | if (lang.length === 1 && lang[0] !== "en" && lunr[lang[0]]) { 74 | this.use(lunr[lang[0]]); 75 | } else if (lang.length > 1) { 76 | this.use(lunr.multiLanguage.apply(null, lang)); // spread operator not supported in all browsers: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator#Browser_compatibility 77 | } 78 | this.field('title'); 79 | this.field('text'); 80 | this.ref('location'); 81 | 82 | for (var i=0; i < data.docs.length; i++) { 83 | var doc = data.docs[i]; 84 | this.add(doc); 85 | documents[doc.location] = doc; 86 | } 87 | }); 88 | console.log('Lunr index built, search ready'); 89 | } 90 | allowSearch = true; 91 | postMessage({config: data.config}); 92 | postMessage({allowSearch: allowSearch}); 93 | } 94 | 95 | function init () { 96 | var oReq = new XMLHttpRequest(); 97 | oReq.addEventListener("load", onJSONLoaded); 98 | var index_path = base_path + '/search_index.json'; 99 | if( 'function' === typeof importScripts ){ 100 | index_path = 'search_index.json'; 101 | } 102 | oReq.open("GET", index_path); 103 | oReq.send(); 104 | } 105 | 106 | function search (query) { 107 | if (!allowSearch) { 108 | console.error('Assets for search still loading'); 109 | return; 110 | } 111 | 112 | var resultDocuments = []; 113 | var results = index.search(query); 114 | for (var i=0; i < results.length; i++){ 115 | var result = results[i]; 116 | doc = documents[result.ref]; 117 | doc.summary = doc.text.substring(0, 200); 118 | resultDocuments.push(doc); 119 | } 120 | return resultDocuments; 121 | } 122 | 123 | if( 'function' === typeof importScripts ) { 124 | onmessage = function (e) { 125 | if (e.data.init) { 126 | init(); 127 | } else if (e.data.query) { 128 | postMessage({ results: search(e.data.query) }); 129 | } else { 130 | console.error("Worker - Unrecognized message: " + e); 131 | } 132 | }; 133 | } 134 | -------------------------------------------------------------------------------- /docs/site/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 |Here is the text
67 | The TextBlock attributes and their explanations can be found at: https://adaptivecards.io/schemas/adaptive-card.json#/definitions/TextBlock 68 | """ 69 | def add_text_block( 70 | self, text: str, is_subtle: bool = False, size: str = "default", weight: str = "default", wrap: bool = False 71 | ): 72 | element = { 73 | "type": "TextBlock", 74 | "text": text, 75 | "isSubtle": is_subtle, 76 | "size": size, 77 | "weight": weight, 78 | "wrap": wrap 79 | } 80 | self.__add_element(element) 81 | 82 | 83 | """ 84 | add_input_text() adds the traditional text fields as they are used in normal forms. interprated as when it comes to html 85 | The various attribute values can be found at: https://adaptivecards.io/schemas/adaptive-card.json#/definitions/Input.Text 86 | Have a look at the URL above for more details on how the field is used 87 | """ 88 | def add_input_text( 89 | self, input_id:str, input_is_multiline:bool = False, input_max_length:int = None, input_placeholder: str = None, input_value: str = None 90 | ): 91 | self.check_if_id_exists(input_id) 92 | element = { 93 | "id": input_id, 94 | "type": "Input.Text", 95 | "isMultiline": input_is_multiline 96 | } 97 | 98 | if input_max_length is not None: element["maxLength"] = input_max_length 99 | if input_placeholder is not None: element["placeholder"] = input_placeholder 100 | if input_value is not None: element["value"] = input_value 101 | self.__add_element(element) 102 | 103 | """ 104 | add_submit_action_btn() adds the button that submits the 'form' that has been sent as a message. Works like the element in html. 105 | """ 106 | def add_submit_action_btn( 107 | self, title: str = "submit" 108 | ): 109 | self.check_if_submit_button_exists() 110 | action = { 111 | "type": "Action.Submit", 112 | "title": title 113 | } 114 | self.__add_action(action) 115 | 116 | 117 | """ 118 | The various attribute values can be found at: https://adaptivecards.io/schemas/adaptive-card.json#/definitions/Input.ChoiceSet 119 | """ 120 | def add_input_choiceset( 121 | self, input_id: str, input_choices:list=[], input_is_multiselect: bool = False, input_value:str = None 122 | ): 123 | self.check_if_id_exists(input_id) 124 | element = { 125 | "id": input_id, 126 | "type": "Input.ChoiceSet", 127 | "choices": input_choices, 128 | "isMultiSelect": input_is_multiselect 129 | } 130 | 131 | if input_value is not None: element["value"] = input_value 132 | self.__add_element(element) 133 | -------------------------------------------------------------------------------- /python_webex/v1/Message.py: -------------------------------------------------------------------------------- 1 | from python_webex.v1.Card import Card 2 | import requests 3 | import sys 4 | 5 | class Message: 6 | """ 7 | Message requests uses URL https://api.ciscospark.com/v1/messages 8 | 9 | Enables us to interact with the Messages in the Cisco Webex platform. 10 | sending messages, listing your messages etc. 11 | """ 12 | 13 | def send_message( 14 | self, 15 | to_person_email:str = None, 16 | room_id:str = None, 17 | text:str = None, 18 | markdown:str = None, 19 | files: list=[], # we attach normal files (images, PDFs etc...) 20 | attachments: list=[] # This is mainly used for cards that will be sent as part of the messages 21 | ): 22 | """ 23 | Allows for one to send a message to a room 24 | details on the rooms URL parameters can be found in https://developer.webex.com/docs/api/v1/messages/create-a-message 25 | 'files' is a list of the files(images, audios etc) you want to send to the user, if the user wants to attach files with the message 26 | 27 | ---- 28 | Arguments 29 | @ room_id: string => This is the ID of the room you are sending the message to 30 | @ text: string => The text being sent in the message 31 | @ files: list of string => A list of files you want to sell. Each element in the list is a directory path to the file. 32 | e.g files=['/this/is/my/path/this_image.jpg', 'this/is/my/second/path/this_pdf.pdf'] 33 | """ 34 | if room_id == None and to_person_email == None: 35 | sys.exit("either 'room_id', 'person_email' or 'toPersonId' must be present") 36 | 37 | if text == None and markdown == None: 38 | sys.exit("'text' or 'markdown' must be present") 39 | 40 | 41 | url_route = "messages" 42 | 43 | data = { 44 | "text": text, 45 | } 46 | 47 | # specify receiver of the message 48 | if room_id is not None: 49 | data["roomId"] = room_id 50 | elif to_person_email is not None: 51 | data["toPersonEmail"] = to_person_email 52 | 53 | if markdown != None: 54 | data["markdown"] = markdown 55 | 56 | if len(files) > 0: 57 | data["files"] = files 58 | 59 | if len(attachments) > 0: 60 | data["attachments"] = attachments 61 | 62 | data = requests.post( self.URL + url_route, headers=self.headers, json=data ) 63 | return data 64 | 65 | 66 | 67 | """ 68 | Message requests uses URL https://api.ciscospark.com/v1/messages 69 | 70 | Enables sending of markdown data such as lists, links, code formatted messages etc 71 | """ 72 | def send_markdown(self, to_person_email:str = None, room_id:str = None, markdown:str = None): 73 | """ 74 | ---- 75 | Arguments 76 | @ to_person_email => Email of the person we are sending the marked down message to 77 | @ room_id: str => ID of the room where the markdown is being sent to 78 | @ text: str => text to be sent to the user. This will be shown without a markdown in case 79 | the client device does not support rich text 80 | 81 | @ markdown: str => string with markdown information. For formatting information, we should 82 | use https://dev-preview.webex.com/formatting-messages.html 83 | """ 84 | if room_id == None and to_person_email == None: 85 | sys.exit("'room_id' or 'to_person_email' must be present") 86 | 87 | if markdown == None: 88 | sys.exit("'markdown' is a required field") 89 | 90 | return self.send_message(to_person_email=to_person_email, markdown=markdown, room_id=room_id) 91 | 92 | 93 | 94 | def send_card( 95 | self, 96 | card: Card, 97 | room_id: str = None, 98 | to_person_email: str = None, 99 | markdown: str="[This is the default markdown title]" 100 | ): 101 | """ 102 | Cars are elements that can hold forms and improve interactivity of the messages. 103 | For example, if you are using a bot to monitor your networking devices, this will require you to login the networking devices first. 104 | You can send a form for one to login to the networking devices. 105 | """ 106 | 107 | data = self.send_message( 108 | to_person_email = to_person_email, 109 | attachments = card.content, 110 | room_id = room_id, 111 | markdown = markdown 112 | ) 113 | 114 | return data 115 | 116 | 117 | def get_attachment_response(self, attachment_id: str): 118 | """ 119 | Gets the response for when an attachment has been sent 120 | """ 121 | url_route = "attachment/actions/{}".format(attachment_id) 122 | 123 | response = requests.get(self.URL + url_route, headers=self.headers) 124 | return response.json() 125 | 126 | def get_messages(self, room_id=None): 127 | """ 128 | gets all the messages sent and received in a specific room 129 | details on the list-messages URL parameters can be found in https://developer.webex.com/docs/api/v1/messages/list-messages 130 | """ 131 | 132 | if room_id == None: 133 | sys.exit("'room_id' is a required field") 134 | 135 | url_route = "messages" 136 | 137 | params = { 138 | "roomId": room_id 139 | } 140 | data = requests.get( self.URL + url_route, headers=self.headers, params=params ) 141 | return data 142 | 143 | def get_direct_messages(self, person_id=None): 144 | """ 145 | gets a list of all the messages sent in 1 to 1 rooms. This is basically a list all the DMs :) 146 | details on the list-direct-messages URL parameters can be found in https://developer.webex.com/docs/api/v1/messages/list-direct-messages 147 | """ 148 | 149 | if person_id == None: 150 | sys.exit("'person_id' is a mandatory field") 151 | 152 | url_route = "messages" 153 | 154 | params = { 155 | "personId": person_id 156 | } 157 | data = requests.get( self.URL + url_route + "/direct", headers=self.headers, params=params ) 158 | return data 159 | 160 | def get_message_details(self, message_id=None): 161 | """ 162 | gets details of a specific message 163 | e.g roomId, roomType, created, mentionedPeople ... 164 | details on the get message details URL parameters can be found in https://developer.webex.com/docs/api/v1/messages/get-message-details 165 | """ 166 | 167 | if message_id == None: 168 | sys.exit("'message_id' is a required field") 169 | 170 | url_route = "messages/" + message_id 171 | 172 | data = requests.get( self.URL + url_route, headers=self.headers) 173 | return data 174 | 175 | def delete_message(self, message_id=None): 176 | """ 177 | deletes a message with ID messageId 178 | details on the delete message URL can be found in https://developer.webex.com/docs/api/v1/messages/delete-a-message 179 | """ 180 | 181 | if message_id == None: 182 | sys.exit("'message_id' is not a required field") 183 | 184 | url_route = "messages/" + message_id 185 | 186 | data = requests.delete( self.URL + url_route, headers=self.headers ) 187 | return data 188 | -------------------------------------------------------------------------------- /python_webex/v1/People.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import requests 3 | 4 | 5 | class People: 6 | 7 | def get_people(self, email=None): 8 | """ 9 | gets a list of people with a particular attribute 10 | uses https://api.ciscospark.com/people - GET request 11 | """ 12 | 13 | if email is None: 14 | sys.exit("'email' is a required field") 15 | 16 | url_route = "people" 17 | 18 | params = { 19 | "email": email 20 | } 21 | data = requests.get(self.URL + url_route, headers=self.headers, params=params) 22 | return data 23 | 24 | def get_person_details(self, person_id=None): 25 | """ 26 | returns specific information of the person with ID personId 27 | uses https://api.ciscospark.com/people/{ personId } - GET request 28 | API reference can be found in: https://developer.webex.com/docs/api/v1/people/get-person-details 29 | """ 30 | 31 | if person_id is None: 32 | sys.exit("'personId' is a required field") 33 | 34 | url_route = "people" 35 | 36 | data = requests.get(self.URL + url_route + "/" + person_id, headers=self.headers) 37 | return data 38 | 39 | def get_own_details(self): 40 | """ 41 | gets the bots own information 42 | uses https://api.ciscospark.com/people - GET request 43 | API reference can be found in: https://developer.webex.com/docs/api/v1/people/get-my-own-details 44 | """ 45 | 46 | url_route = "people/me" 47 | 48 | data = requests.get(self.URL + url_route, headers=self.headers) 49 | return data 50 | -------------------------------------------------------------------------------- /python_webex/v1/Room.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import sys 3 | 4 | 5 | class Room: 6 | 7 | def get_all_rooms(self): 8 | """ 9 | Gives a list of all the rooms the specific bot is in 10 | this request uses url https://api.ciscospark.com/rooms 11 | details on the rooms URL can be found in: https://developer.webex.com/docs/api/v1/rooms/list-rooms 12 | """ 13 | url_route = "rooms" 14 | data = requests.get(self.URL + url_route, headers=self.headers) 15 | return data 16 | 17 | def create_room(self, title=None, team_id=None, room_type=None): 18 | """ 19 | Creates a room within a team, also known as a space. This will be within the team with ID teamId 20 | this request uses url https://api.ciscospark.com - POST request 21 | details on the create rooms can be found in https://developer.webex.com/docs/api/v1/rooms/create-a-room 22 | """ 23 | 24 | if title is None: 25 | sys.exit("'title' is a required field") 26 | 27 | if team_id is None: 28 | sys.exit("'teamId; is a required field") 29 | 30 | url_route = "rooms" 31 | 32 | json = { 33 | "teamId": team_id, 34 | "title": title 35 | } 36 | 37 | if room_type is not None: 38 | json["type"] = room_type 39 | 40 | data = requests.post(self.URL + url_route, json=json, headers=self.headers) 41 | return data 42 | 43 | def get_room_details(self, room_id=None): 44 | """ 45 | GETS DETAILS OF A PARTICULAR ROOM 46 | request uses url https://api.ciscospark.com/{roomId} - GET request 47 | details on the get room details can be found in https://developer.webex.com/docs/api/v1/rooms/get-room-details 48 | """ 49 | 50 | if room_id is None: 51 | sys.exit("'roomId' is a required field") 52 | 53 | url_route = "rooms" 54 | 55 | data = requests.get(self.URL + url_route + "/" + room_id, headers=self.headers) 56 | return data 57 | 58 | def update_room_details(self, room_id=None, title=None): 59 | """ 60 | UDPATES THE DETAILS OF A PARTICULAR ROOM based on the **kwargs given by the user 61 | request uses url https://api.ciscospark.com/{roomId} - PUT request 62 | details on the update room details can be found in https://developer.webex.com/docs/api/v1/rooms/update-a-room 63 | """ 64 | 65 | if room_id is None: 66 | sys.exit("'roomId' is a required field") 67 | 68 | elif title is None: 69 | sys.exit("'title' is a required field") 70 | 71 | json = { 72 | "title": title 73 | } 74 | 75 | url_route = "rooms" 76 | 77 | data = requests.put(self.URL + url_route + '/' + room_id, json=json, headers=self.headers) 78 | return data 79 | 80 | def delete_room(self, room_id=None): 81 | """ 82 | DELETES A ROOM with ID roomId 83 | uses url https://api.ciscospark.com/v1/rooms/{roomId} 84 | details on the delete room can be found in https://developer.webex.com/docs/api/v1/rooms/delete-a-room 85 | """ 86 | 87 | if room_id is None: 88 | sys.exit("'roomId' is a required field") 89 | 90 | url_route = "rooms" 91 | data = requests.delete(self.URL + url_route + "/" + room_id, headers=self.headers) 92 | return data 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /python_webex/v1/Webhook.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import sys 3 | 4 | class Webhook: 5 | 6 | def get_all_webhooks(self): 7 | """ 8 | GETS A LIST OF ALL THE WEBHOOKS CURRENTLY CONNECTED TO YOUR BOT 9 | uses the https://api.ciscospark.com/v1/webhooks - GET request 10 | details on the list webhooks URL can be found in https://developer.webex.com/docs/api/v1/webhooks/list-webhooks 11 | """ 12 | 13 | url_route = "webhooks" 14 | 15 | data = requests.get(self.URL + url_route, headers=self.headers) 16 | 17 | return data 18 | 19 | def create_webhook(self, name=None, target_url=None, resource=None, event=None): 20 | """ 21 | Enables one to create a webhook that will be listening to events sent to the bot 22 | uses the https://api.ciscospark.com/v1/webhooks - POST request 23 | details on create webhooks URL can be found in https://developer.webex.com/docs/api/v1/webhooks/create-a-webhook 24 | """ 25 | 26 | url_route = "webhooks" 27 | 28 | if name is None: 29 | sys.exit("'name' is a required field") 30 | 31 | elif target_url is None: 32 | sys.exit("'targetUrl' is a required field") 33 | 34 | elif resource is None: 35 | sys.exit("'resource' is a required field") 36 | 37 | elif event is None: 38 | sys.exit("'event' is a required field") 39 | 40 | # check for if a webhook with this URL already exists for this particular bot 41 | # cause apparently Cisco does not do that for us when creating webhooks. But tis all good :) 42 | existing_webhooks = self.get_all_webhooks().json() 43 | for webhook in existing_webhooks['items']: 44 | if webhook['targetUrl'] == target_url: 45 | return self.get_webhook_details(webhook_id=webhook['id']) 46 | 47 | json = { 48 | "name": name, "targetUrl": target_url, "resource": resource, "event": event 49 | } 50 | 51 | data = requests.post(self.URL + url_route, headers=self.headers, json=json) 52 | return data 53 | 54 | def delete_webhook(self, webhook_id=None): 55 | """ 56 | Deletes a webhook that has ID webhookId 57 | uses the https://api.ciscospark.com/webhooks - DELETE request 58 | details on delete webhooks URL can be found in https://developer.webex.com/docs/api/v1/webhooks/delete-a-webhook 59 | """ 60 | 61 | url_route = "webhooks" 62 | 63 | if webhook_id is None: 64 | sys.exit("'webhookId' is a required field") 65 | 66 | data = requests.delete(self.URL + url_route + "/" + webhook_id, headers=self.headers) 67 | return data 68 | 69 | def update_webhook(self, webhook_id=None, name=None, target_url=None): 70 | """ 71 | 'name' is the updated name of the webhook 72 | 'targetUrl' is the updated targetUrl of the webhook 73 | 74 | Edit a webhook with ID of webhookId 75 | uses the https://api.ciscospark.com/webhooks - PUT request 76 | details on edit webhook URL can be found in https://developer.webex.com/docs/api/v1/webhooks/update-a-webhook 77 | """ 78 | 79 | url_route = "webhooks" 80 | 81 | if webhook_id is None: 82 | sys.exit("'webhookId' is a required field") 83 | 84 | elif name is None: 85 | sys.exit("'name' is a required field") 86 | 87 | elif target_url is None: 88 | sys.exit("'targetUrl' is a required field") 89 | 90 | json = { 91 | "name": name, "targetUrl": target_url 92 | } 93 | 94 | data = requests.put(self.URL + url_route + "/" + webhook_id, json=json, headers=self.headers) 95 | return data 96 | 97 | def get_webhook_details(self, webhook_id=None): 98 | """ 99 | Get the details of a single webhook with id of webhookId 100 | uses https://api.ciscospark.com/webhooks/{roomId} - GET request 101 | details on get webhook details URL can be found in https://developer.webex.com/docs/api/v1/webhooks/get-webhook-details 102 | """ 103 | 104 | url_route = "webhooks" 105 | 106 | if webhook_id is None: 107 | sys.exit("'webhookId' is a required field") 108 | 109 | data = requests.get(self.URL + url_route, headers=self.headers) 110 | return data 111 | -------------------------------------------------------------------------------- /python_webex/v1/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Paul-weqe/python_webex_bot/3381d0a094f01a78145fa730cdf31d7be1cb174e/python_webex/v1/__init__.py -------------------------------------------------------------------------------- /python_webex/webhook/__init__.py: -------------------------------------------------------------------------------- 1 | from python_webex.webhook.handlers import MessageReceivingHandler, AttachmentReceivingHandler 2 | from flask import Flask, request 3 | 4 | 5 | app = Flask(__name__) 6 | bot = None 7 | 8 | 9 | @app.route("/", methods=[ 'GET', 'POST' ]) 10 | def index(): 11 | json_data = request.get_json() 12 | message_id = json_data[ "data" ][ "id" ] 13 | message_info = bot.get_message_details( message_id=message_id ).json() 14 | 15 | handler = MessageReceivingHandler(bot, message_info) 16 | handler.handle_message() 17 | response = "incoming message handled" 18 | return response 19 | 20 | @app.route("/attachment-response", methods=["GET", "POST"]) 21 | def attachment_response(): 22 | json_data = request.get_json() 23 | message_id = json_data['data']['messageId'] 24 | message_info = bot.get_attachment_response(json_data['data']['id']) 25 | 26 | handler = AttachmentReceivingHandler(bot, message_info, message_id) 27 | handler.handle_attachment() 28 | 29 | response = "incoming attachment handled" 30 | return response 31 | -------------------------------------------------------------------------------- /python_webex/webhook/handlers.py: -------------------------------------------------------------------------------- 1 | """Explanation of the route handlers 2 | 3 | 4 | This module takes care of handling logic of data from the '@app.route's in the webhook/__init__.py file 5 | webhook/__init__.py file mainly deals with getting requests and messages from the sender, 6 | while this route_handlers.py mainly deals with the logic after receiving this information. 7 | This mainly has to do with cleaning up the webhook/__init__.py which was rather messy. 8 | 9 | Attributes: 10 | # Bot below refers to Bot class from python_webex.v1.Bot 11 | - bot(Bot): an instance of the bot that we are dealing with when running our program. 12 | - message_info(dictionary): a dictionary of all the details that were gotten from the message sent. 13 | For more information, you can have a look at the 14 | 15 | Todo: 16 | * 17 | """ 18 | from python_webex.v1.Bot import Bot 19 | import json 20 | 21 | 22 | class MessageReceivingHandler: 23 | 24 | def __init__(self, bot, message_info): 25 | self.bot = bot 26 | self.message_info = message_info 27 | 28 | def handle_message(self): 29 | # looks for in case there was a file(image, document etc) attached in the message. 30 | if 'files' in self.message_info: 31 | self.handle_messages_with_files() 32 | return None 33 | 34 | # handles when a normal message is sent with text in the message 35 | # and a way to handle the text received has been defined by the bot programmer. 36 | elif self.message_info[ "text" ].strip() != "" and self.message_info[ "text" ] in self.bot.hears_to_function: 37 | self.handle_messages_without_file_and_with_text() 38 | return None 39 | 40 | # handles when a normal message is sent with text in the message 41 | # but a way to handle the text received has not been defined by the bot programmer 42 | elif self.message_info["text"].strip() != "" and self.message_info[ "text" ] not in self.bot.hears_to_function: 43 | 44 | # make sure the bot is not hearing its own messages 45 | sender_email = self.message_info["personEmail"] 46 | bot_emails = json.loads(self.bot.get_own_details().text)["emails"] 47 | if sender_email not in bot_emails: 48 | self.handle_messages_without_file_and_without_text() 49 | return None 50 | 51 | 52 | def handle_messages_with_files(self): 53 | """ 54 | function handles when messages are sent with file attachments (images, documents etc) 55 | """ 56 | # loop for when the file attached(image, document..etc) is sent with a text accomanied. 57 | # for example, if an image is sent with caption "Felt cure, might delete later" 58 | # this is considered a file attachment with a text alongside 59 | if "text" in self.message_info: 60 | self.handle_messages_with_file_and_text() 61 | 62 | elif self.bot.default_attachment is not None: 63 | self.handle_messages_with_files_and_without_text_and_with_default_attachment_set() 64 | 65 | else: 66 | self.handle_messages_without_file_and_without_text() 67 | 68 | def handle_messages_with_file_and_text(self): 69 | message_text = self.message_info["text"] 70 | 71 | if self.message_info['text'] in self.bot.hears_file_to_function: 72 | 73 | # handles when the bot has been programmed to handle messages with files 74 | # and the specific text that is being sent to the bot. 75 | # looks for if the function has message_info specified; and this is used in mapping of 76 | # the message information 77 | if 'message_info' in self.bot.hears_file_to_function[message_text].__code__.co_varnames: 78 | self.bot.hears_file_to_function[message_text]( 79 | files = self.message_info['files'], 80 | room_id = self.message_info['roomId'], 81 | message_info = self.message_info 82 | ) 83 | 84 | else: 85 | self.bot.hears_file_to_function[message_text]( 86 | files = self.message_info['files'], 87 | room_id = self.message_info['roomId'] 88 | ) 89 | 90 | 91 | elif "*" in self.bot.hears_file_to_function: 92 | 93 | if 'message_info' in self.bot.hears_to_function["*"].__code__.co_varnames: 94 | self.bot.hears_file_to_function["*"]( 95 | files = self.message_info["files"], 96 | room_id = self.message_info['roomId'], 97 | message_info = self.message_info 98 | ) 99 | 100 | else: 101 | self.bot.hears_file_to_function["*"]( 102 | files = self.message_info["files"], 103 | room_id = self.message_info["roomId"] 104 | ) 105 | 106 | else: 107 | return "Default response for file sent with text not set" 108 | 109 | def handle_messages_without_file_and_with_text(self): 110 | message_text = self.message_info["text"] 111 | 112 | if 'message_info' in self.bot.hears_to_function[message_text].__code__.co_varnames: 113 | self.bot.hears_to_function[message_text]( 114 | room_id = self.message_info["roomId"], 115 | message_info = self.message_info 116 | ) 117 | 118 | else: 119 | self.bot.hears_to_function[message_text](room_id=self.message_info["roomId"]) 120 | 121 | def handle_messages_without_file_and_without_text(self): 122 | if 'message_info' in self.bot.hears_to_function["*"].__code__.co_varnames: 123 | self.bot.hears_to_function["*"]( 124 | room_id = self.message_info["roomId"], 125 | message_info = self.message_info 126 | ) 127 | else: 128 | self.bot.hears_to_function["*"]( 129 | room_id=self.message_info["roomId"] 130 | ) 131 | 132 | def handle_messages_with_files_and_without_text_and_with_default_attachment_set(self): 133 | if 'message_info' in self.bot.default_attachment.__code__.co_varnames: 134 | self.bot.default_attachment( 135 | files = self.message_info['files'], 136 | room_id = self.message_info['roomId'], 137 | message_info = self.message_info 138 | ) 139 | 140 | else: 141 | self.bot.default_attachment( 142 | files = self.message_info['files'], 143 | room_id = self.message_info['roomId'] 144 | ) 145 | 146 | class AttachmentReceivingHandler: 147 | 148 | def __init__(self, bot, message_info, message_id): 149 | self.bot = bot 150 | self.message_info = message_info 151 | self.message_id = message_id 152 | 153 | def handle_attachment(self): 154 | if self.message_id in self.bot.attachment_response_to_function: 155 | self.handle_response_of_known_attachment() 156 | else: 157 | self.handle_default_response_for_attachments() 158 | 159 | def handle_response_of_known_attachment(self): 160 | response = self.bot.attachment_response_to_function[self.message_id](self.message_info) 161 | 162 | def handle_default_response_for_attachments(self): 163 | room_id = self.message_info["roomId"] 164 | self.bot.send_message( 165 | room_id=room_id, 166 | text="The bot has not been configured to handle this form's submission. Be patient" 167 | ) 168 | -------------------------------------------------------------------------------- /python_webex_bot: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | echo "hey there, this is my first pip package" -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | bleach==5.0.1 2 | certifi==2023.7.22 3 | cffi==1.15.1 4 | chardet==3.0.4 5 | charset-normalizer==2.1.1 6 | click==7.1.2 7 | commonmark==0.9.1 8 | cryptography==42.0.4 9 | docutils==0.19 10 | Flask==2.3.2 11 | ghp-import==2.1.0 12 | idna==3.7 13 | importlib-metadata==4.12.0 14 | itsdangerous==1.1.0 15 | jaraco.classes==3.2.2 16 | jeepney==0.8.0 17 | Jinja2==3.1.4 18 | keyring==23.9.1 19 | Markdown==3.3.7 20 | MarkupSafe==1.1.1 21 | mergedeep==1.3.4 22 | mkdocs==1.3.1 23 | more-itertools==8.14.0 24 | packaging==21.3 25 | pkginfo==1.8.3 26 | pycparser==2.21 27 | Pygments==2.15.0 28 | pyparsing==3.0.9 29 | python-dateutil==2.8.2 30 | PyYAML==6.0 31 | pyyaml_env_tag==0.1 32 | readme-renderer==37.1 33 | requests==2.32.0 34 | requests-toolbelt==0.9.1 35 | rfc3986==2.0.0 36 | rich==12.5.1 37 | SecretStorage==3.3.3 38 | six==1.16.0 39 | twine==4.0.1 40 | urllib3==1.26.19 41 | virtualenv==16.4.3 42 | watchdog==2.1.9 43 | webencodings==0.5.1 44 | Werkzeug==3.0.3 45 | zipp==3.8.1 46 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | required = None 4 | with open('requirements.txt') as f: 5 | required = f.read().splitlines() 6 | 7 | 8 | with open("README.md", "r") as fh: 9 | long_description = fh.read() 10 | 11 | setuptools.setup( 12 | name="python_webex_bot", 13 | version="0.901", 14 | 15 | scripts=["python_webex_bot"], 16 | author="Paul-weqe", 17 | description="Enable sending markdown in messges", 18 | long_description=long_description, 19 | long_description_content_type="text/markdown", 20 | url="https://github.com/Paul-weqe/python_webex_bot", 21 | packages=setuptools.find_packages(), 22 | install_requires=[ 23 | "certifi", 24 | "chardet", 25 | "click", 26 | "Flask", 27 | "idna", 28 | "itsdangerous", 29 | "Jinja2", 30 | "MarkupSafe", 31 | "requests", 32 | "urllib3", 33 | "Werkzeug" 34 | ], 35 | classifiers=[ 36 | "Programming Language :: Python :: 3", 37 | "License :: OSI Approved :: MIT License", 38 | "Operating System :: OS Independent" 39 | ], 40 | ) 41 | --------------------------------------------------------------------------------