I need some help with Discord.Net. I have the following command written down:
[Command("project", RunMode=RunMode.Async)]
public async Task Project(string action, string id="")
{
switch(action)
{
case "post":
{
StringCreator tagger = new StringCreator();
string index = tagger.Get(5);
var project=await Context.Guild.CreateTextChannelAsync("project-id-" + index);
var message = await project.SendMessageAsync("What language is this project in?");
var rMessage = message.Id;
await message.AddReactionAsync(new Emoji("🇬🇧"));
await message.AddReactionAsync(new Emoji("🇮🇱"));
await message.AddReactionAsync(new Emoji("🇷🇴"));
break;
}
}
Now I tried making an event like this:
public async Task OnReactionAddedEvent(SocketReaction reaction)
{
if (reaction.Emote.Name == "🇬🇧")
{
vars.projectLang = "English";
}
if (reaction.Emote.Name == "🇮🇱")
{
vars.projectLang = "Hebrew";
}
if (reaction.Emote.Name == "🇷🇴")
{
vars.projectLang = "Romanian";
}
}
If I try to use it like this, just before the break in my command function:
_discord.ReactionAdded += OnReactionAddedEvent;
I tried editing my Event Method to take the marameter as cacheable but with no luck:
public async Task OnReactionAddedEvent(Cacheable<SocketReaction> reaction)
{
if (reaction.Emote.Name == "🇬🇧")
{
vars.projectLang = "English";
}
if (reaction.Emote.Name == "🇮🇱")
{
vars.projectLang = "Hebrew";
}
if (reaction.Emote.Name == "🇷🇴")
{
vars.projectLang = "Romanian";
}
}
Whatever I do, when declaring it in the command method, the whole statement shows up as an error. I'm at a loss, please help. Thank you in advance!
Related
This is Task Code
public async Task Demo(int row_index, CancellationToken token)
{
Task t1 = Task.Run(() =>
{
ChromeOptions chromeOptions = new ChromeOptions();
ChromeDriverService chromeDriverService = ChromeDriverService.CreateDefaultService();
chromeDriverService.SuppressInitialDiagnosticInformation = true;
chromeDriverService.HideCommandPromptWindow = true;
this.chrome[row_index] = new ChromeDriver(chromeDriverService, chromeOptions);
this.chrome[row_index].Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(59.0);
Dologin(row_index);
//Lay Ten Fb
chrome[row_index].Url = "https://facebook.com/profile";
var conchim = chrome[row_index].FindElementByCssSelector("#fb-timeline-cover-name > a");
this.dataGridView1.Rows[row_index].Cells["trangthai"].Value = "Tiến Hành Lấy Tên Facebook";
foreach (DataGridViewRow r in dataGridView1.Rows)
{
string value1 = r.Cells[0].Value.ToString() ?? string.Empty;
if (value1 == tkfacebook)
{
r.Cells[4].Value = conchim.Text;
break;
}
}
},token);
}
This is Code Run Task And Cancel Task.
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token;
public async void HandleValue(DataGridViewCell cell, int row_index)
{
switch (cell.Value.ToString())
{
case "Bắt đầu":
bool flag7 = Convert.ToInt32(this.txtClickStart.Value) > Convert.ToInt32(this.txtClickEnd.Value);
if (radioButton1.Checked && !flag7)
{
cell.Value = "Kết Thúc";
token = source.Token;
await Demo(row_index,token);
}
if (flag7)
{
this.dataGridView1.Rows[row_index].Cells["trangthai"].Value = "Cài đặt thời gian không đúng";
MessageBox.Show(new Form
{
TopMost = true
}, "Cài đặt thời gian không đúng, hãy cài đặt lại!", "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Hand);
return;
}
bool flag3 = !radioButton1.Checked || !radioButton1.Checked && !radioButton2.Checked;
if (flag3)
{
MessageBox.Show("Vui Lòng Chọn Trình Duyệt Để Bắt Đầu Chạy");
}
break;
case "Kết Thúc":
source.Cancel();
chrome[row_index].Quit();
cell.Value = "Bắt đầu";
this.dataGridView1.Rows[row_index].Cells["trangthai"].Value = "Bạn đã chọn kết thúc làm việc";
break;
}
}
Thread is not working so i do Task . But it still Run when i already Do Task Cancel. ...............
source.Cancel();
Make Post Longger to Avablie To Post . Dont Care this Rows ..dfsdfsdfsddfsddsadasdsadasdsadasdasdassdasdasdasdasdasdasdasdasdasdadda
If you aim to cancel the execution of logic, then you need to check IsCancellationRequested flag.
while(!token.IsCancellationRequested)
{
//whatever logic you want run should be placed here. This logic won't be
//executed after you call Cancel()
}
Above logic will continue to execute your logic until you called Cancel() on token source. You can find some example 1 and 2.
Your Code for Demo should include a check on the cancelation-Token. Try something like this:
Task t1 = Task.Run(() =>
{
ChromeOptions chromeOptions = new ChromeOptions();
ChromeDriverService chromeDriverService = ChromeDriverService.CreateDefaultService();
chromeDriverService.SuppressInitialDiagnosticInformation = true;
chromeDriverService.HideCommandPromptWindow = true;
this.chrome[row_index] = new ChromeDriver(chromeDriverService, chromeOptions);
this.chrome[row_index].Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(59.0);
Dologin(row_index);
//Lay Ten Fb
chrome[row_index].Url = "https://facebook.com/profile";
var conchim = chrome[row_index].FindElementByCssSelector("#fb-timeline-cover-name > a");
this.dataGridView1.Rows[row_index].Cells["trangthai"].Value = "Tiến Hành Lấy Tên Facebook";
foreach (DataGridViewRow r in dataGridView1.Rows)
{
if (token.IsCancellationRequested)
{
Console.WriteLine("Task was cancelled by user.");
token.ThrowIfCancellationRequested();
}
string value1 = r.Cells[0].Value.ToString() ?? string.Empty;
if (value1 == tkfacebook)
{
r.Cells[4].Value = conchim.Text;
break;
}
}
},token);
Please also refer the example here:
https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.iscancellationrequested?view=netframework-4.8
I was trying the multi-language chat bot in bot framework. https://github.com/Microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/17.multilingual-bot.
I was successful in translating ordinary message with no attachment. But I'm having a problem with attachment like herocard or suggestedcard.
var reply = stepContext.Context.Activity.CreateReply();
var card = new HeroCard();
card.Buttons = new List<CardAction>()
{
new CardAction() { Title = "1. All lights are green.", Type = ActionTypes.ImBack, Value = "All lights are green." },
new CardAction() { Title = "2. DSL light is OFF/Red/Blinking Green.", Type = ActionTypes.ImBack, Value = "DSL light is OFF/Red/Blinking Green." },
new CardAction() { Title = "3. Internet light is OFF/Red/Amber or blinking red and green.", Type = ActionTypes.ImBack, Value = "Internet light is OFF/Red/Amber or blinking red and green." },
new CardAction() { Title = "4. Power light is OFF/Red/Amber or blinking.", Type = ActionTypes.ImBack, Value = "Power light is OFF/Red/Amber or blinking." },
};
reply.Attachments = new List<Attachment>() { card.ToAttachment() };
reply.AttachmentLayout = AttachmentLayoutTypes.List;
var options = new PromptOptions()
{
Prompt = reply,
};
await stepContext.Context.SendActivityAsync(reply, cancellationToken);
Thanks!
You need to check if there are any attachments. I have some middleware that sets the speak on message and use the following code:
if (string.IsNullOrEmpty(message.Text))
{
if (message.Attachments[0].Content is HeroCard attachment)
{
message.Speak = TextToSpeechHelper.ConvertTextToSpeechText(attachment.Text);
}
}
else
{
message.Speak = TextToSpeechHelper.ConvertTextToSpeechText(message.Text);
}
You'd have to adjust it to set the text and translate.
Below is a full example of what my middleware is. Keep in mind this middleware sets the speak to the text and sets the input hint.
public class TextToSpeechMiddleware : IMiddleware
{
private readonly IEnumerable<string> ignoreList;
public TextToSpeechMiddleware(string speakIgnore)
{
ignoreList = GetSpeakIgnore(speakIgnore);
}
public Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken))
{
turnContext.OnSendActivities(OnSendActivities);
turnContext.OnUpdateActivity(OnUpdateActivity);
return next(cancellationToken);
}
private static IEnumerable<string> GetSpeakIgnore(string value)
{
string[] ignoreList = value.Split(';');
return ignoreList.Select(i => i.Trim())
.Where(i => !string.IsNullOrEmpty(i));
}
private Task<ResourceResponse> OnUpdateActivity(ITurnContext turnContext, Activity activity, Func<Task<ResourceResponse>> next)
{
ConvertTextToSpeech(activity);
return next();
}
private Task<ResourceResponse[]> OnSendActivities(ITurnContext turnContext, List<Activity> activities, Func<Task<ResourceResponse[]>> next)
{
foreach (Activity currentActivity in activities.Where(a => a.Type == ActivityTypes.Message))
{
ConvertTextToSpeech(currentActivity);
}
return next();
}
private void ConvertTextToSpeech(Activity message)
{
Activity initialMessage = message;
try
{
if (message.Type == ActivityTypes.Message)
{
bool ignoredSpeak = false;
if (string.IsNullOrEmpty(message.Speak))
{
if (string.IsNullOrEmpty(message.Text))
{
if (message.Attachments[0].Content is HeroCard attachment)
{
message.Speak = TextToSpeechHelper.ConvertTextToSpeechText(attachment.Text);
}
}
else
{
message.Speak = TextToSpeechHelper.ConvertTextToSpeechText(message.Text);
}
message.Speak = message.Speak.Trim();
if (ignoreList.Where(i => message.Speak.ToLower().StartsWith(i.ToLower())).Count() != 0)
{
message.Speak = null;
ignoredSpeak = true;
}
}
else if (string.IsNullOrWhiteSpace(message.Speak))
{
message.Speak = " ";
}
if ((!string.IsNullOrEmpty(message.Speak) && (message.Speak.EndsWith("?") || message.Speak.StartsWith("Is this correct?")))
|| (!string.IsNullOrEmpty(message.Text) && message.Text.EndsWith("?"))
|| ignoredSpeak)
{
message.InputHint = InputHints.ExpectingInput;
}
// IOs won't work with expecting input
if (message.Recipient.Name.EndsWith(":ios"))
{
message.InputHint = InputHints.AcceptingInput;
}
}
// Logic needed to increase speech speed.
// if (!string.IsNullOrEmpty(message.Speak))
// {
// message.Speak = #"<speak version='1.0' " + "xmlns='http://www.w3.org/2001/10/synthesis' xml:lang='en-GB'><prosody rate=\"1.5\">" + message.Speak + "</prosody></speak>";
// }
}
catch (Exception)
{
message = initialMessage;
}
}
}
I have written an app that goes through our own properties and scraps the data. To make sure I don't run through the same URLs, I am using a MySQL database to store the URL, flag it once its processed. All this was being done in a single thread and it's fine if I had only few thousand entries. But I have few hundred thousand entries that I need to parse so I need to make changes in the code (I am newbie in multithreading in general). I found an example and was trying to copy the style but doesn't seem to work. Anyone know what the issue is with the following code?
EDIT: Sorry didn't mean to make people guess the issue but was stupid of me to include the exception. Here is the exception
"System.InValidCastException: 'Specified cast is not valid.'"
When I start the process it collects the URLs from the database and then never hits DoWork method
//This will get the entries from the database
List<Mappings> items = bot.GetUrlsToProcess(100);
if (items != null)
{
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
Worker.Done = new Worker.DoneDelegate(WorkerDone);
foreach (var item in items)
{
urls.Add(item.Url);
WaitingTasks.Enqueue(new Task(id => new Worker().DoWork((int)id, item.Url, token), item.Url, token));
}
LaunchTasks();
}
static async void LaunchTasks()
{
// keep checking until we're done
while ((WaitingTasks.Count > 0) || (RunningTasks.Count > 0))
{
// launch tasks when there's room
while ((WaitingTasks.Count > 0) && (RunningTasks.Count < MaxRunningTasks))
{
Task task = WaitingTasks.Dequeue();
lock (RunningTasks) RunningTasks.Add((int)task.AsyncState, task);
task.Start();
}
UpdateConsole();
await Task.Delay(300); // wait before checking again
}
UpdateConsole(); // all done
}
static void UpdateConsole()
{
Console.Write(string.Format("\rwaiting: {0,3:##0} running: {1,3:##0} ", WaitingTasks.Count, RunningTasks.Count));
}
static void WorkerDone(int id)
{
lock (RunningTasks) RunningTasks.Remove(id);
}
public class Worker
{
public delegate void DoneDelegate(int taskId);
public static DoneDelegate Done { private get; set; }
public async void DoWork(object id, string url, CancellationToken token)
{
if (token.IsCancellationRequested) return;
Content obj;
try
{
int tries = 0;
bool IsUrlProcessed = true;
DateTime dtStart = DateTime.Now;
string articleDate = string.Empty;
try
{
ScrapeWeb bot = new ScrapeWeb();
SearchApi searchApi = new SearchApi();
SearchHits searchHits = searchApi.Url(url, 5, 0);
if (searchHits.Hits.Count() == 0)
{
obj = await bot.ReturnArticleObject(url);
if (obj.Code != HttpStatusCode.OK)
{
Console.WriteLine(string.Format("\r Status is {0}", obj.Code));
tries = itemfound.UrlMaxTries + 1;
IsUrlProcessed = false;
itemfound.HttpCode = obj.Code;
}
else
{
string title = obj.Title;
string content = obj.Contents;
string description = obj.Description;
Articles article = new Articles();
article.Site = url.GetSite();
article.Content = content;
article.Title = title;
article.Url = url.ToLower();
article.Description = description;
string strThumbNail = HtmlHelper.GetImageUrl(url, obj.RawResponse);
article.Author = HtmlHelper.GetAuthor(url, obj.RawResponse);
if (!string.IsNullOrEmpty(strThumbNail))
{
//This condition needs to be added to remove ?n=<number> from EP thumbnails
if (strThumbNail.Contains("?"))
{
article.ImageUrl = strThumbNail.Substring(0, strThumbNail.IndexOf("?")).Replace("http:", "https:");
}
else
article.ImageUrl = strThumbNail.Replace("http:", "https:");
}
else
{
article.ImageUrl = string.IsNullOrEmpty(strThumbNail) ? article.Url.GetDefaultImageUrls() : strThumbNail.Replace("http:", "https:");
}
articleDate = HtmlHelper.GetPublishDate(url, obj.RawResponse);
if (string.IsNullOrEmpty(articleDate))
article.Pubdate = DateTime.Now;
else
article.Pubdate = DateTime.Parse(articleDate);
var client = new Index(searchApi);
var result = client.Upsert(article);
itemfound.HttpCode = obj.Code;
if (result)
{
itemfound.DateCreated = DateTime.Parse(articleDate);
itemfound.DateModified = DateTime.Parse(articleDate);
UpdateItem(itemfound);
}
else
{
tries = itemfound.UrlMaxTries + 1;
IsUrlProcessed = false;
itemfound.DateCreated = DateTime.Parse(articleDate);
itemfound.DateModified = DateTime.Parse(articleDate) == null ? DateTime.Now : DateTime.Parse(articleDate);
UpdateItem(itemfound, tries, IsUrlProcessed);
}
}
}
else
{
tries = itemfound.UrlMaxTries + 1;
IsUrlProcessed = true;
itemfound.HttpCode = HttpStatusCode.OK;
itemfound.DateCreated = DateTime.Parse(articleDate);
itemfound.DateModified = DateTime.Parse(articleDate) == null ? DateTime.Now : DateTime.Parse(articleDate);
}
}
catch (Exception e)
{
tries = itemfound.UrlMaxTries + 1;
IsUrlProcessed = false;
itemfound.DateCreated = DateTime.Parse(articleDate);
itemfound.DateModified = DateTime.Parse(articleDate) == null ? DateTime.Now : DateTime.Parse(articleDate);
}
finally
{
DateTime dtEnd = DateTime.Now;
Console.WriteLine(string.Format("\r Total time taken to process items is {0}", (dtEnd - dtStart).TotalSeconds));
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
Done((int)id);
}
}
All this code is based from Best multi-thread approach for multiple web requests this link. Can someone tell me how to get this approach running?
I think the problem is in the way you're creating your tasks:
new Task(id => new Worker().DoWork((int)id, item.Url, token), item.Url, token)
This Task constructor overload expected Action<object> delegate. That means id will be typed as object and you need to cast it back to something useful first.
Parameters
action
Type: System.Action<Object>
The delegate that represents the code to execute in the task.
state
Type: System.Object
An object representing data to be used by the action.
cancellationToken
Type: System.Threading.CancellationToken
-The CancellationToken that that the new task will observe.
You decided to cast it to int by calling (int)id, but you're passing item.Url as the object itself. I can't tell you 100% what the type of Url is but I don't expect Url-named property to be of type int.
Based on what #MarcinJuraszek said I just went back to my code and added an int as I couldn't find another way to resolve it. Here is the change I made
int i=0
foreach (var item in items)
{
urls.Add(item.Url);
WaitingTasks.Enqueue(new Task(id => new Worker().DoWork((string)id, item.Url, token), item.Url, token));
i++;
}
I have two dialogs called from root dialog based on the prompt response.
Both dialogs internally prepare request and call a service class. Weird thing is one dialog resumes with response from service but the other though receives response from service is not resuming.
Below method works fine and resumes the call at if (searchResult != null && searchResult.Item1 != null)
public virtual async Task MessageRecievedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
var message = await result;
if (message.Text == "quit")
{
context.Done<object>(null);
}
else
{
try
{
var srm = new CoveoRestSearchService.CoveoSearchRequestModel
{
Query = message.Text,
EnableDidYouMean = true,
QuerySource = CoveoRestSearchService.Constants.SWEATERSSOURCE
};
var searchResult = await csp.PerformSearch(srm);
if (searchResult != null && searchResult.Item1 != null)
{
await CardUtil.showHeroCard(message, searchResult.Item1);
}
else
{
await context.PostAsync($"No search results for {message.Text} found");
}
await PostSearchUsageAnalyticsToCoveo(context, srm, searchResult.Item2);
}
catch (Exception e)
{
Debug.WriteLine($"Error when searching : {e.Message}");
}
finally {
context.Wait(MessageRecievedAsync);
}
}
}
This below one though looks identical is not resuming the if (response != null)
public virtual async Task MessageRecievedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
var message = await result;
if (message.Text == "quit")
{
context.Done<object>(null);
}
else
{
try
{
var currentDate = DateTime.UtcNow;
string toDate = currentDate.ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
string fromDate = currentDate.AddDays(-7).ToString("yyyy-MM-ddTHH:mm:ss.fffZ");
MetricsQuery = MetricsQuery.Replace("{fromISODate}", fromDate);
MetricsQuery = MetricsQuery.Replace("{toISODate}", toDate);
MetricsQuery = MetricsQuery.Replace("{term}", message.Text);
var response = await cuawc.MetricSearchUsageToCoveoAsync(MetricsQuery
.Replace(" ", "%20")
.Replace("!=", "!%3D")
.Replace("==", "%3D%3D")
.Replace(":", "%3A"));
if (response != null)
{
var message_from_bot = context.MakeMessage();
}
//message_from_bot.Attachments = new List<Attachments>();
await context.PostAsync("Please enter the search term for metrics");
}
catch (Exception e)
{
Debug.WriteLine($"Error when pulling metrics : {e.Message}");
}
finally
{
context.Wait(MessageRecievedAsync);
}
}
}
Struggling from past 2 days to figure what is wrong!!
i've translated the quickblox's sample app for Xamarin forms in Xamarin iOS and Android native.
Everything works "except" that the retrieving of the message fails.
I send the message from one client, and the event is catched from the other chat occupant:
XMPP: DispatchEvents ====> <message id="580735ed335fb760ae0017ec" xmlns="jabber:client" from="18029700-46533#chat.quickblox.com/1220770403-quickblox-68179" type="chat" to="18976912-46533#chat.quickblox.com"><extraParams xmlns="jabber:client"><save_to_history>1</save_to_history><dialog_id>5800aea1a28f9a1c1f000010</dialog_id><message_id>580735ed335fb760ae0017ec</message_id><date_sent>1476867565</date_sent></extraParams><body>test+message</body><thread>5800aea1a28f9a1c1f000010</thread></message>
XMPP: OnMessageReceived ====> From: 18029700 To: 18976912 Body: DateSent 1476867565 FullXmlMessage: <message id="580735ed335fb760ae0017ec" xmlns="jabber:client" from="18029700-46533#chat.quickblox.com/1220770403-quickblox-68179" type="chat" to="18976912-46533#chat.quickblox.com"><extraParams xmlns="jabber:client"><save_to_history>1</save_to_history><dialog_id>5800aea1a28f9a1c1f000010</dialog_id><message_id>580735ed335fb760ae0017ec</message_id><date_sent>1476867565</date_sent></extraParams><body>test+message</body><thread>5800aea1a28f9a1c1f000010</thread></message>
as you can see the Body part into the event OnMessageReceived is empty!
But the html part in the end of this snippet contains the message "test+message"
this is the PrivateChat Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using QbChat.Pcl.Repository;
using Quickblox.Sdk.GeneralDataModel.Models;
using Quickblox.Sdk.Modules.ChatXmppModule;
using Quickblox.Sdk.Modules.UsersModule.Models;
using UIKit;
using Xmpp.Im;
namespace KeepInTouch.iOS
{
public partial class PrivateChat : BaseChat
{
PrivateChatManager privateChatManager;
public PrivateChat(string dialogId, string nibname) : base(dialogId, nibname) { }
public async override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
AppDelegate.R.NavController.SetNavigationBarHidden(true, true);
await MessageProvider.Reconnect();
}
public override void ViewDidLoad()
{
base_tb_chat = tb_chat;
base_txt_chat = txt_chat;
base.ViewDidLoad();
view_top.BackgroundColor = UIColor.FromPatternImage(UIImage.FromFile("navbar_top_kit.png"));
tb_chat.TableFooterView = new UIView();
IsBusyIndicatorVisible = true;
var dialog = Database.Instance().GetDialog(dialogId);
var opponentId = dialog.OccupantIds.Split(',').Select(int.Parse).First(id => id != QbChat.UserId);
ChatXmppClient xmpc = QbChat.QbProvider.GetXmppClient();
privateChatManager = xmpc.GetPrivateChatManager(opponentId, dialogId);
privateChatManager.MessageReceived += OnMessageReceived;
DialogName = dialog.Name;
//xmpc.MessageReceived += OnMessageReceived;
btn_chat.TouchUpInside += async delegate {
await SendMessageCommandExecute();
txt_chat.Text = "";
};
txt_chat.ShouldReturn += (textField) => {
textField.ResignFirstResponder();
return true;
};
txt_chat.EditingChanged += async delegate {
MessageText = txt_chat.Text;
await MessageProvider.Reconnect();
};
btn_back.TouchUpInside += delegate {
DismissViewController(false, null);
};
IsBusyIndicatorVisible = true;
Task.Factory.StartNew(async () => {
var users = await QbChat.QbProvider.GetUsersByIdsAsync(dialog.OccupantIds);
var opponentUser = users.FirstOrDefault(u => u.Id != QbChat.UserId);
if (opponentUser != null && opponentUser.BlobId.HasValue) {
await QbChat.QbProvider.GetImageAsync(opponentUser.BlobId.Value).ContinueWith((task, result) => {
//var bytes =
task.ConfigureAwait(true).GetAwaiter().GetResult();
}, TaskScheduler.FromCurrentSynchronizationContext());
}
opponentUsers = new List<User> { opponentUser };
await LoadMessages();
InvokeOnMainThread(() =>
IsBusyIndicatorVisible = false
);
});
}
async void OnMessageReceived(object sender, MessageEventArgs messageEventArgs)
{
if (messageEventArgs.MessageType == MessageType.Chat ||
messageEventArgs.MessageType == MessageType.Groupchat) {
string decodedMessage = System.Net.WebUtility.UrlDecode(messageEventArgs.Message.MessageText);
var messageTable = new MessageTable();
messageTable.SenderId = messageEventArgs.Message.SenderId;
messageTable.DialogId = messageEventArgs.Message.ChatDialogId;
messageTable.DateSent = messageEventArgs.Message.DateSent;
if (messageEventArgs.Message.NotificationType != 0) {
if (messageEventArgs.Message.NotificationType == NotificationTypes.GroupUpdate) {
if (messageEventArgs.Message.AddedOccupantsIds.Any()) {
var userIds = new List<int>(messageEventArgs.Message.AddedOccupantsIds);
userIds.Add(messageEventArgs.Message.SenderId);
var users = await QbChat.QbProvider.GetUsersByIdsAsync(string.Join(",", userIds));
var addedUsers = users.Where(u => u.Id != messageEventArgs.Message.SenderId);
var senderUser = users.First(u => u.Id == messageEventArgs.Message.SenderId);
messageTable.Text = senderUser.FullName + " added users: " + string.Join(",", addedUsers.Select(u => u.FullName));
} else if (messageEventArgs.Message.DeletedOccupantsIds.Any()) {
var userIds = new List<int>(messageEventArgs.Message.DeletedOccupantsIds);
var users = await QbChat.QbProvider.GetUsersByIdsAsync(string.Join(",", userIds));
messageTable.Text = string.Join(",", users.Select(u => u.FullName)) + " left this room";
}
//var dialogInfo = await QbChat.QbProvider.GetDialogAsync(messageEventArgs.Message.ChatDialogId);
//if (dialogInfo == null)
//{
// return;
//}
//var dialog = new DialogTable(dialogInfo);
//Database.Instance().SaveDialog(dialog);
}
} else {
messageTable.Text = decodedMessage;
}
await SetRecepientName(messageTable);
Messages.Add(messageTable);
InvokeOnMainThread(async () => {
tb_chat.ReloadData();
await ScrollList();
});
}
}
public async Task LoadMessages()
{
List<Message> messages;
try {
messages = await QbChat.QbProvider.GetMessagesAsync(dialogId);
} catch (Exception ex) {
Console.WriteLine(ex);
return;
}
if (messages != null) {
messages = messages.OrderBy(message => message.DateSent).ToList();
foreach (var message in messages) {
var chatMessage = new MessageTable();
chatMessage.DateSent = message.DateSent;
chatMessage.SenderId = message.SenderId;
chatMessage.MessageId = message.Id;
if (message.RecipientId.HasValue)
chatMessage.RecepientId = message.RecipientId.Value;
chatMessage.DialogId = message.ChatDialogId;
chatMessage.IsRead = message.Read == 1;
await SetRecepientName(chatMessage);
chatMessage.Text = System.Net.WebUtility.UrlDecode(message.MessageText);
InvokeOnMainThread(() =>
Messages.Add(chatMessage)
);
}
InvokeOnMainThread(async () => {
tb_chat.ReloadData();
await ScrollList();
});
}
}
async Task SendMessageCommandExecute()
{
var message = MessageText != null ? MessageText.Trim() : string.Empty;
if (!string.IsNullOrEmpty(message)) {
var m = new MessageTable();
m.SenderId = QbChat.UserId;
m.Text = message;
m.DialogId = dialogId;
m.RecepientFullName = "Me";
try {
await MessageProvider.Reconnect();
var encodedMessage = System.Net.WebUtility.UrlEncode(message);
privateChatManager.SendMessage(encodedMessage);
} catch (Exception ex) {
Console.WriteLine(ex);
return;
}
long unixTimestamp = DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1).Ticks;
unixTimestamp /= TimeSpan.TicksPerSecond;
m.DateSent = unixTimestamp;
m.ID = Database.Instance().SaveMessage(m);
var dialog = Database.Instance().GetDialog(dialogId);
dialog.LastMessage = m.Text;
dialog.LastMessageSent = DateTime.UtcNow;
Database.Instance().SaveDialog(dialog, true);
Messages.Add(m);
MessageText = "";
InvokeOnMainThread(async () => {
tb_chat.ReloadData();
await ScrollList();
});
}
}
public override void DidReceiveMemoryWarning()
{
base.DidReceiveMemoryWarning();
}
}
}
long story short the sdk receive the message but apparently fail to parse the body message. fire the handler but if empty don't call the privateChatManager.MessageReceived.
could anyone help please?
Thank you