-
Notifications
You must be signed in to change notification settings - Fork 0
/
ReminderAPI.cs
324 lines (244 loc) · 13.2 KB
/
ReminderAPI.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
using Newtonsoft.Json;
using Microsoft.WindowsAzure.Storage.Table;
using Microsoft.WindowsAzure.Storage;
using System.Collections.Generic;
using System.Linq;
using Twilio.Rest.Api.V2010.Account;
using Twilio.Types;
namespace RemindJames
{
public static class ReminderAPI
{
[FunctionName("GetReminders")]
public static async Task<IActionResult> GetReminders(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "reminder")] HttpRequest req,
[Table("reminders", Connection = "AzureWebJobsStorage")] CloudTable remindersTable,
ILogger log)
{
var query = new TableQuery<ReminderTableEntity>();
var segment = await remindersTable.ExecuteQuerySegmentedAsync(query, null);
var result = segment.Select(Mappings.ToModel)
.OrderBy(x=> x.HourSort);
log.LogInformation($"Get All Reminders returned {result?.Count() ?? 0} record(s)");
return new OkObjectResult(result);
}
[FunctionName("GetReminderCurrent")]
public static async Task<IActionResult> GetReminderCurrent(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "remindercurrent")]HttpRequest req,
[Table("reminders", Connection = "AzureWebJobsStorage")] CloudTable reminderTable,
ILogger log)
{
string hour = Utilities.GetEasternDateTime(log).AddMinutes(5).Hour.ToString();
var findOperation = TableOperation.Retrieve<ReminderTableEntity>(Mappings.PartitionKey, hour);
var findResult = await reminderTable.ExecuteAsync(findOperation);
if (findResult.Result == null)
{
log.LogInformation($"Get reminder not found for hour {hour}");
return new NotFoundResult();
}
var existingRow = (ReminderTableEntity)findResult.Result;
log.LogInformation($"Getting current reminder found for hour {hour} with message {existingRow.Message}");
return new OkObjectResult(existingRow.ToModel());
}
[FunctionName("GetReminderByHour")]
public static IActionResult GetReminderByHour(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "reminder/{hour}")]HttpRequest req,
[Table("reminders", Mappings.PartitionKey, "{hour}", Connection = "AzureWebJobsStorage")] ReminderTableEntity reminder,
ILogger log, string hour)
{
if (reminder == null)
{
log.LogInformation($"Get reminder not found for hour {hour}");
return new NotFoundResult();
}
log.LogInformation($"Getting reminder found by {hour} with message {reminder.Message}");
return new OkObjectResult(reminder.ToModel());
}
[FunctionName("CreateReminder")]
public static async Task<IActionResult> CreateReminder(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "reminder")]HttpRequest req,
[Table("reminders", Connection = "AzureWebJobsStorage")] IAsyncCollector<ReminderTableEntity> reminderTable,
ILogger log)
{
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
var input = JsonConvert.DeserializeObject<ReminderModel>(requestBody);
// need to sanitize?
await reminderTable.AddAsync(input.ToTableEntity());
log.LogInformation($"Creating Reminder for hour {input.Hour} with message {input.Message}");
return new OkObjectResult(input);
}
[FunctionName("UpdateReminder")]
public static async Task<IActionResult> UpdateReminder(
[HttpTrigger(AuthorizationLevel.Anonymous, "put", Route = "reminder/{hour}")]HttpRequest req,
[Table("reminders", Connection = "AzureWebJobsStorage")] CloudTable reminderTable,
[SignalR(HubName = "ReminderHub")] IAsyncCollector<SignalRMessage> signalRMessages,
ILogger log, string hour)
{
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
var updatedReminder = JsonConvert.DeserializeObject<ReminderModel>(requestBody);
// get row by id
var findOperation = TableOperation.Retrieve<ReminderTableEntity>(Mappings.PartitionKey, hour);
var findResult = await reminderTable.ExecuteAsync(findOperation);
// check if not found
if (findResult.Result == null) { return new NotFoundResult(); }
// update existing reminder
var existingReminder = (ReminderTableEntity)findResult.Result;
existingReminder.Message = updatedReminder.Message;
// replace in table
var replaceOperation = TableOperation.Replace(existingReminder);
await reminderTable.ExecuteAsync(replaceOperation);
log.LogInformation($"Updating reminder hour {updatedReminder.Hour} with message {updatedReminder.Message}");
var returnReminder = existingReminder.ToModel();
// send client update
await signalRMessages.AddAsync(
new SignalRMessage
{
Target = "updateReminder",
Arguments = new[] { returnReminder }
});
return new OkObjectResult(returnReminder);
}
[FunctionName("Up")]
public static async Task<IActionResult> Up(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "reset")]HttpRequest req,
[Table("reminders", Connection = "AzureWebJobsStorage")] CloudTable remindersTable,
ILogger log)
{
// batch operations - https://stackoverflow.com/a/53293614/1366033
var query = new TableQuery<ReminderTableEntity>();
var result = await remindersTable.ExecuteQuerySegmentedAsync(query, null);
// Create the batch operation.
TableBatchOperation batchDeleteOperation = new TableBatchOperation();
foreach (var row in result)
{
batchDeleteOperation.Delete(row);
}
// Execute the batch operation.
await remindersTable.ExecuteBatchAsync(batchDeleteOperation);
// Create the batch operation.
TableBatchOperation batchInsertOperation = new TableBatchOperation();
ReminderModel[] defaultRecords = new [] {
new ReminderModel("8", "Wake Up"),
new ReminderModel("9", "Wake Up Now!"),
new ReminderModel("10", "Food, Teeth, Wallet, Check"),
new ReminderModel("11", "Survey Says..... go to school"),
new ReminderModel("12", "Now What!?!?!"),
new ReminderModel("13", "Shoot Mah Goot!!"),
new ReminderModel("14", "Sometimes you play your cards, sometimes you don't"),
new ReminderModel("15", "Frida Says 'Hi'"),
new ReminderModel("16", "Enjoy a small break"),
new ReminderModel("17", "Do your homework"),
new ReminderModel("18", "Do your homework"),
new ReminderModel("19", "Call gram/the fam and say hi"),
new ReminderModel("20", "Did you eat dinner yet?"),
new ReminderModel("21", "Screen's Off bud"),
new ReminderModel("22", "Seriously, go to bed"),
};
foreach (var rec in defaultRecords)
{
batchInsertOperation.Insert(rec.ToTableEntity());
}
// Execute the batch operation.
await remindersTable.ExecuteBatchAsync(batchInsertOperation);
log.LogInformation($"Resetting entire table and adding {defaultRecords?.Count() ?? 0} record(s)");
return new OkResult();
}
}
public static class ReminderFuncs {
[FunctionName("SendReminder")]
public static async Task SendReminder(
[TimerTrigger("0 0 * * * *")]TimerInfo myTimer,
[Table("reminders", Connection = "AzureWebJobsStorage")] CloudTable reminderTable,
[TwilioSms(AccountSidSetting = "TwilioAccountSid",AuthTokenSetting = "TwilioAuthToken", From = "+16177670668")] IAsyncCollector<CreateMessageOptions> messages,
[SignalR(HubName = "ReminderHub")] IAsyncCollector<SignalRMessage> signalRMessages,
ILogger log)
{
// get id (hour)
string hour = Utilities.GetEasternDateTime(log).AddMinutes(5).Hour.ToString();
// get row by id
var findOperation = TableOperation.Retrieve<ReminderTableEntity>(Mappings.PartitionKey, hour);
var findResult = await reminderTable.ExecuteAsync(findOperation);
// check if not found
if (findResult.Result == null) { return; }
// grab current text
var existingRow = (ReminderTableEntity)findResult.Result;
var message = existingRow.Message;
// if we got something, let's do some updates
if (!string.IsNullOrEmpty(message)) {
// clear current reminder text
var existingReminder = (ReminderTableEntity)findResult.Result;
existingReminder.Message = "";
// update existing reminder
var replaceOperation = TableOperation.Replace(existingReminder);
await reminderTable.ExecuteAsync(replaceOperation);
// create sms message
var reminderPhone = Environment.GetEnvironmentVariable("ReminderNumber");
var smsMessage = new CreateMessageOptions(new PhoneNumber(reminderPhone))
{
Body = message
};
await messages.AddAsync(smsMessage);
log.LogInformation($"Sending reminder for hour {hour} with message {message}");
// send client update
var returnReminder = existingReminder.ToModel();
var signalRMessage = new SignalRMessage
{
Target = "updateReminder",
Arguments = new[] { returnReminder }
};
await signalRMessages.AddAsync(signalRMessage);
}
}
[FunctionName("InvokeMessage")]
public static async Task InvokeMessage(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "InvokeMessage")] HttpRequest req,
[Table("reminders", Connection = "AzureWebJobsStorage")] CloudTable reminderTable,
[TwilioSms(AccountSidSetting = "TwilioAccountSid",AuthTokenSetting = "TwilioAuthToken", From = "+16177670668")] IAsyncCollector<CreateMessageOptions> messages,
ILogger log)
{
string message = req.Query["message"];
string hour = req.Query["hour"];
if (message == null) {
if (hour == null) {
hour = Utilities.GetEasternDateTime(log).AddMinutes(5).Hour.ToString();
}
var findOperation = TableOperation.Retrieve<ReminderTableEntity>(Mappings.PartitionKey, hour);
var findResult = await reminderTable.ExecuteAsync(findOperation);
if (findResult.Result == null)
{
return;
}
var existingRow = (ReminderTableEntity)findResult.Result;
message = existingRow.Message;
}
if (!string.IsNullOrEmpty(message)) {
var reminderPhone = Environment.GetEnvironmentVariable("ReminderNumber");
var smsMessage = new CreateMessageOptions(new PhoneNumber(reminderPhone))
{
Body = message
};
await messages.AddAsync(smsMessage);
log.LogInformation($"Invoking reminder for hour {hour} with message {message}");
}
}
}
public static class SignalRFuncs {
[FunctionName("Negotiate")]
public static SignalRConnectionInfo GetSignalRInfo(
[HttpTrigger(AuthorizationLevel.Anonymous, Route = "negotiate")] HttpRequest req,
[SignalRConnectionInfo(HubName = "ReminderHub")] SignalRConnectionInfo connectionInfo)
{
return connectionInfo;
}
}
}