blob: 2d12de867b2a7658e83c435bc0ca14348931e625 [file] [log] [blame]
Denis Tosice7f4f9d2018-10-09 15:18:46 +02001"""Utility class for sending requests to BonD, adding and controlling bots."""
2
3from __future__ import absolute_import
4from __future__ import division
5from __future__ import print_function
6
7import json
8import requests
9
10from datetime import datetime
11from oauth2client.client import GoogleCredentials
12
13
14_BOND_API_URL = 'https://bond-pa.sandbox.googleapis.com'
15_HANGOUTS_API_URL = 'https://www.googleapis.com/hangouts/v1_meetings/'
16_MEETINGS_API_URL = 'https://meetings.googleapis.com'
17
18_TOKEN_TTL_SECONDS = 3500
19_SERVICE_CREDS_FILE = '/creds/service_accounts/bond_service_account.json'
20
21_BOT_CREDS_FILE = '/creds/service_accounts/bond_bot_credentials.json'
22
23
24class BondHttpApi(object):
25 """Utility class for sending requests to BonD for bots."""
26
27 def __init__(self):
28 self._bot_creds = self._GetBotCredentials()
29 self._last_token_request_time = None
30 self._last_token = None
31
32 def GetAvailableWorkers(self):
33 """Gets the number of available workers from a conference.
34
35 Returns:
36 GetNumOfAvailableWorkersResponse denoting failure or success of
37 the request.
38 """
39 token = self._GetAccessToken()
40 resp = requests.get(
41 '%s/v1/workers:count' % _BOND_API_URL,
42 headers={
43 'Content-Type': 'application/json',
44 'Authorization': 'Bearer %s' % token
45 })
46 return resp.text
47
48 def ExecuteScript(self, script, meeting_code):
49 """Executes the specified script.
50
51 Args:
52 script: Script to execute.
53 meeting_code: The meeting to execute the script for.
54
55 Returns:
56 RunScriptRequest denoting failure or success of the request.
57 """
58 token = self._GetAccessToken()
59
60 request_data = """{
61 "script": "%s",
62 "conference": {
63 "conference_code": "%s"
64 }}""" % (script, meeting_code)
65
66 resp = requests.post(
67 '%s/v1/conference/%s/script' % (_BOND_API_URL, meeting_code),
68 headers={
69 'Content-Type': 'application/json',
70 'Authorization': 'Bearer %s' % token,
71 },
72 data=request_data)
73 return resp.text
74
75 def AddBotsRequest(self, meeting_code, number_of_bots, ttl_secs):
76 """Adds a number of bots to a meeting for a specified period of time.
77
78 Args:
79 meeting_code: The meeting to join.
80 number_of_bots: The number of bots to add to the meeting.
81 ttl_secs: The time in seconds that the bots will stay in the meeting after
82 joining.
83
84 Returns:
85 AddBotsResponse denoting failure or success of the request.
86 """
87 token = self._GetAccessToken()
88
89 request_data = {
90 'num_of_bots': number_of_bots,
91 'ttl_secs': ttl_secs,
92 'video_call_options': {},
93 'media_options': {
94 'audio_file_path': "audio_32bit_48k_stereo.raw",
95 'mute_audio': True,
96 'video_file_path': "jamboard_two_far_video_hd.1280_720.yuv",
97 'video_fps': 30,
98 'mute_video': False
99 },
100 'backend_options': {
101 'mesi_apiary_url': _HANGOUTS_API_URL,
102 'mas_one_platform_url': _MEETINGS_API_URL
103 },
104 'conference': {
105 'conference_code': meeting_code
106 },
107 'bot_type': "MEETINGS",
108 'authentication_options': {
109 'is_anonymous': False,
110 'oauth_credentials': self._bot_creds
111 }
112 }
113
114 resp = requests.post(
115 '%s/v1/conference/%s/bots:add' % (_BOND_API_URL, meeting_code),
116 headers={
117 'Content-Type': 'application/json',
118 'Authorization': 'Bearer %s' % token
119 },
120 data=json.dumps(request_data))
121
122 return resp.text
123
124 def _GetAccessToken(self):
125 if self._last_token is None or self._CheckTokenExpired():
126 credentials = self._CreateApiCredentials()
127 scope = 'https://www.googleapis.com/auth/meetings'
128 credentials = credentials.create_scoped(scope)
129 self._last_token_request_time = datetime.now()
130 self._last_token = credentials.get_access_token().access_token
131 return self._last_token
132
133 def _CreateApiCredentials(self):
134 return GoogleCredentials.from_stream(_SERVICE_CREDS_FILE)
135
136 def _GetBotCredentials(self):
137 with open(_BOT_CREDS_FILE) as f:
138 return json.load(f)
139
140 def _CheckTokenExpired(self):
141 elapsed = datetime.now() - self._last_token_request_time
142 return elapsed.total_seconds() > _TOKEN_TTL_SECONDS