Skip to content
This repository has been archived by the owner on Aug 29, 2023. It is now read-only.

Commit

Permalink
Merge pull request #3 from momotaro98/feature/async-sendmessage
Browse files Browse the repository at this point in the history
Feature/async sendmessage
  • Loading branch information
momotaro98 authored Dec 22, 2018
2 parents 12dbaa0 + e10cbce commit 4620c7d
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 151 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,6 @@ Thumbs.db

# dotCover
*.dotCover

# Rider
.idea/
73 changes: 61 additions & 12 deletions ViberApiLib.Test/Test.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace ViberApiLib.Test
{
Expand All @@ -15,9 +16,28 @@ protected void SetUp()
api = new Api("testAuthToken", "testBotName", "testAvatarPath");
}

[Test]
public void TestSendMessages()
{
// Arrange
var userIdList = new List<string>{"user1", "user2", "user3"};
var taskList = new List<Task<string>>{};
// Act
foreach (var userid in userIdList)
{
Task<string> response = api.SendMessages(userid, "text");
taskList.Add(response);
}
// await Task.WhenAll(taskList); // An example usage for async method
var t = Task.WhenAll(taskList);
// Assert
Assert.IsInstanceOf<Task>(t);
}

[Test]
public void TestSubscribedRequest()
{
// Arrange
var reqData = @"{
""event"":""subscribed"",
""timestamp"":1457764197627,
Expand All @@ -31,7 +51,9 @@ public void TestSubscribedRequest()
},
""message_token"":4912661846655238145
}";
var req = api.ParseRequest(reqData.ToString());
// Act
var req = Api.ParseRequest(reqData.ToString());
// Assert
Assert.IsInstanceOf<SubscribedRequest>(req);
Assert.AreEqual(req.Event, "subscribed");
Assert.AreEqual(req.TimeStamp, "1457764197627");
Expand All @@ -50,13 +72,16 @@ public void TestSubscribedRequest()
[Test]
public void TestUnsubscribedRequest()
{
// Arrange
var reqData = @"{
""event"":""unsubscribed"",
""timestamp"":1457764197627,
""user_id"":""01234567890A="",
""message_token"":4912661846655238145
}";
var req = api.ParseRequest(reqData.ToString());
// Act
var req = Api.ParseRequest(reqData.ToString());
// Assert
Assert.IsInstanceOf<UnsubscribedRequest>(req);
Assert.AreEqual(req.Event, "unsubscribed");
Assert.AreEqual(req.TimeStamp, "1457764197627");
Expand All @@ -70,6 +95,7 @@ public void TestUnsubscribedRequest()
[Test]
public void TestMessageRequest()
{
// Arrange
var reqData = @"{
""event"":""message"",
""timestamp"":1457764197627,
Expand All @@ -93,7 +119,9 @@ public void TestMessageRequest()
""tracking_data"":""tracking data""
}
}";
var req = api.ParseRequest(reqData.ToString());
// Act
var req = Api.ParseRequest(reqData.ToString());
// Assert
Assert.IsInstanceOf<MessageRequest>(req);
Assert.AreEqual(req.Event, "message");
Assert.AreEqual(req.TimeStamp, "1457764197627");
Expand Down Expand Up @@ -123,13 +151,16 @@ public void TestMessageRequest()
[Test]
public void TestSeenRequest()
{
// Arrange
var reqData = @"{
""event"":""seen"",
""timestamp"":1457764197627,
""message_token"":4912661846655238145,
""user_id"":""01234567890A=""
}";
var req = api.ParseRequest(reqData.ToString());
// Act
var req = Api.ParseRequest(reqData.ToString());
// Assert
Assert.IsInstanceOf<SeenRequest>(req);
Assert.AreEqual(req.Event, "seen");
Assert.AreEqual(req.TimeStamp, "1457764197627");
Expand All @@ -143,6 +174,7 @@ public void TestSeenRequest()
[Test]
public void TestConversationStartedRequest()
{
// Arrange
var reqData = @"{
""event"":""conversation_started"",
""timestamp"":1457764197627,
Expand All @@ -159,7 +191,9 @@ public void TestConversationStartedRequest()
},
""subscribed"":false
}";
var req = api.ParseRequest(reqData.ToString());
// Act
var req = Api.ParseRequest(reqData.ToString());
// Assert
Assert.IsInstanceOf<ConversationStartedRequest>(req);
Assert.AreEqual(req.Event, "conversation_started");
Assert.AreEqual(req.TimeStamp, "1457764197627");
Expand All @@ -178,13 +212,16 @@ public void TestConversationStartedRequest()
[Test]
public void TestDeliveredRequest()
{
// Arrange
var reqData = @"{
""event"":""delivered"",
""timestamp"":1457764197627,
""message_token"":4912661846655238145,
""user_id"":""01234567890A=""
}";
var req = api.ParseRequest(reqData.ToString());
// Act
var req = Api.ParseRequest(reqData.ToString());
// Assert
Assert.IsInstanceOf<DeliveredRequest>(req);
Assert.AreEqual(req.Event, "delivered");
Assert.AreEqual(req.TimeStamp, "1457764197627");
Expand All @@ -198,14 +235,17 @@ public void TestDeliveredRequest()
[Test]
public void TestFailedRequest()
{
// Arrange
var reqData = @"{
""event"":""failed"",
""timestamp"":1457764197627,
""message_token"":4912661846655238145,
""user_id"":""01234567890A="",
""desc"":""failure description""
}";
var req = api.ParseRequest(reqData.ToString());
// Act
var req = Api.ParseRequest(reqData.ToString());
// Assert
Assert.IsInstanceOf<FailedRequest>(req);
Assert.AreEqual(req.Event, "failed");
Assert.AreEqual(req.TimeStamp, "1457764197627");
Expand All @@ -219,12 +259,15 @@ public void TestFailedRequest()
[Test]
public void TestWebhookRequest()
{
// Arrange
var reqData = @"{
""event"":""webhook"",
""timestamp"":1457764197627,
""message_token"":""241256543215""
}";
var req = api.ParseRequest(reqData.ToString());
// Act
var req = Api.ParseRequest(reqData.ToString());
// Assert
Assert.IsInstanceOf<WebhookRequest>(req);
Assert.AreEqual(req.Event, "webhook");
Assert.AreEqual(req.TimeStamp, "1457764197627");
Expand All @@ -233,6 +276,7 @@ public void TestWebhookRequest()
[Test]
public void TestRequestThrowsException()
{
// Arrange
// reqData is missing "event" element.
var reqData = @"{
""timestamp"":1457764197627,
Expand All @@ -246,11 +290,13 @@ public void TestRequestThrowsException()
},
""message_token"":4912661846655238145
}";
// Act
try
{
var req = api.ParseRequest(reqData.ToString());
var req = Api.ParseRequest(reqData.ToString());
// Assert
Assert.Fail();
}
} // Assert
catch (KeyNotFoundException ex)
{
Assert.IsTrue(ex.Message.Contains("Necessary key of Viber request, \"event\" is not in the request payload."));
Expand All @@ -264,6 +310,7 @@ public void TestRequestThrowsException()
[Test]
public void TestMessageThrowsException()
{
// Arrange
// reqData is missing "type" in "message".
var reqData = @"{
""event"":""message"",
Expand All @@ -287,11 +334,13 @@ public void TestMessageThrowsException()
""tracking_data"":""tracking data""
}
}";
// Act
try
{
var req = api.ParseRequest(reqData.ToString());
var req = Api.ParseRequest(reqData.ToString());
// Assert
Assert.Fail();
}
} // Assert
catch (KeyNotFoundException ex)
{
Assert.IsTrue(ex.Message.Contains("Necessary key of Viber message, \"type\" is not in the request payload."));
Expand Down
71 changes: 31 additions & 40 deletions ViberApiLib/Api.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,35 @@
using System.Collections.Generic;
using System.Net.Http;
using System.Security.Cryptography;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace ViberApiLib
{
public class Api
{
private string _authToken;
public string AuthToken
{
get { return _authToken; }
}
public string AuthToken { get; }

private string _botName;
public string BotName
{
get { return _botName; }
}
public string BotName { get; }

private string _avatarPath;
public string AvatarPath
{
get { return _avatarPath; }
}
public string AvatarPath { get; }

public Api(string authToken, string botName, string avatarPath)
{
_authToken = authToken;
_botName = botName;
_avatarPath = avatarPath;
AuthToken = authToken;
BotName = botName;
AvatarPath = avatarPath;
}

public string SendMessages(string userId, string text, string trackingData = "")
public async Task<string> SendMessages(string userId, string text, string trackingData = "")
{
var dictPayload = prepareSendMessagesPayload(message: text, receiver: userId, senderName: BotName, senderAvatar: AvatarPath, trackingData: trackingData);
string paylaod = JsonConvert.SerializeObject(dictPayload);
return PostRequest(Constants.SEND_MESSAGE, paylaod);
var dictPayload = PrepareSendMessagesPayload(message: text, receiver: userId, senderName: BotName, senderAvatar: AvatarPath, trackingData: trackingData);
var payload = JsonConvert.SerializeObject(dictPayload);
var response = await PostRequest(Constants.SEND_MESSAGE, payload);
return response;
}

public string SetWebhook(string url, List<string> event_types = null)
public async Task<string> SetWebhook(string url, List<string> event_types = null)
{
var dictPayload = new Dictionary<string, object>()
{
Expand All @@ -52,28 +42,28 @@ public string SetWebhook(string url, List<string> event_types = null)
{
dictPayload.Add("event_types", event_types);
}
string paylaod = JsonConvert.SerializeObject(dictPayload);
var result = PostRequest(Constants.SET_WEBHOOK, paylaod);
var payload = JsonConvert.SerializeObject(dictPayload);
var result = await PostRequest(Constants.SET_WEBHOOK, payload);
var values = JsonConvert.DeserializeObject<Dictionary<string, object>>(result);
if (values["status"].ToString() != "0")
{
return string.Format("Failed with status: {0}, massage: {1}", values["status"], values["status_message"]);
return $"Failed with status: {values["status"]}, massage: {values["status_message"]}";
}
return values["event_types"].ToString();
}

public bool VerifySignature(string requestData, string signature)
{
return signature == calculateMessageSignature(requestData);
return signature == CalculateMessageSignature(requestData);
}

public Request ParseRequest(string jsonRequest)
public static Request ParseRequest(string jsonRequest)
{
RequstFactory factory = new RequstFactory();
var factory = new RequstFactory();
return factory.Create(jsonRequest);
}

private Dictionary<string, object> prepareSendMessagesPayload(string message, string receiver, string senderName, string senderAvatar, string trackingData)
private Dictionary<string, object> PrepareSendMessagesPayload(string message, string receiver, string senderName, string senderAvatar, string trackingData)
{
return new Dictionary<string, object>()
{
Expand All @@ -91,22 +81,23 @@ private Dictionary<string, object> prepareSendMessagesPayload(string message, st
};
}

public string PostRequest(string endPoint, string payload)
public async Task<string> PostRequest(string endPoint, string payload)
{
HttpClient client = new HttpClient();
StringContent content = new StringContent(payload, System.Text.Encoding.UTF8, "application/json");
var client = new HttpClient();
var content = new StringContent(payload, System.Text.Encoding.UTF8, "application/json");
// post data to Viber API
HttpResponseMessage response = client.PostAsync(Constants.VIBER_BOT_API_URL + "/" + endPoint, content).Result;
return response.Content.ReadAsStringAsync().Result;
var apiResponse = await client.PostAsync(Constants.VIBER_BOT_API_URL + "/" + endPoint, content);
var response = await apiResponse.Content.ReadAsStringAsync();
return response;
}

private string calculateMessageSignature(string message)
private string CalculateMessageSignature(string message)
{
byte[] keyByte = new ASCIIEncoding().GetBytes(AuthToken);
byte[] messageBytes = new ASCIIEncoding().GetBytes(message);
var keyByte = new ASCIIEncoding().GetBytes(AuthToken);
var messageBytes = new ASCIIEncoding().GetBytes(message);

byte[] hashmessage = new HMACSHA256(keyByte).ComputeHash(messageBytes);
return string.Concat(Array.ConvertAll(hashmessage, x => x.ToString("x2")));
var hash = new HMACSHA256(keyByte).ComputeHash(messageBytes);
return string.Concat(Array.ConvertAll(hash, x => x.ToString("x2")));
}
}
}
Loading

0 comments on commit 4620c7d

Please sign in to comment.