Help - Search - Members - Calendar
Full Version: c# sendMessage to a group-chat
Skype Community > English > Development, Betas and Skype Garage > Skype Public API
Dr.O
Hi,
I use c# and the skype4com api.

I know there is a sendMessage Method with 2 Parameters:
sendMessage(userhandle, message)

But this Method sends always a private message to the user i got from iChatMessage.
I need a Method where It sends the message to the same chat from where i got the userhandle.

An example:
have here a group chat with 4 persons
one person writes somthing -> now I have the userhandle
then I want to answer this person in the group chat (! not private)


edit:
I found a Method "sendTextMessage" in the api docs. Is this what I'm searching for? But I can't use it, because it is not availible via IntellieSense. What I have missed?


PLEASE HELP
Hours of work are going to waste... crying.png
TheUberOverlord
QUOTE(Dr.O @ Fri Mar 23 2007, 09:45) [snapback]375532[/snapback]

Hi,
I use c# and the skype4com api.

I know there is a sendMessage Method with 2 Parameters:
sendMessage(userhandle, message)

But this Method sends always a private message to the user i got from iChatMessage.
I need a Method where It sends the message to the same chat from where i got the userhandle.

An example:
have here a group chat with 4 persons
one person writes somthing -> now I have the userhandle
then I want to answer this person in the group chat (! not private)


CODE

private Chat chat;
chat = skype.get_Chat(ichatmessage.Chat.Name);
String MyMessage = "Hello, how is everyone?";
chat.SendMessage(MyMessage);

Dr.O
Great, thx a lot !!!

There is a little problem now I have not solved yet:

chat.SendMessage("test") sometimes writes 2 or more times "test" into the chat.
I have no loops, so I cannot understand why it writes more than one time...
TheUberOverlord
QUOTE(Dr.O @ Fri Mar 23 2007, 15:42) [snapback]375677[/snapback]

Great, thx a lot !!!

There is a little problem now I have not solved yet:

chat.SendMessage("test") sometimes writes 2 or more times "test" into the chat.
I have no loops, so I cannot understand why it writes more than one time...


In the real Skype Chat? or You see message status more than once?

You will receive a status for every message sent or received in a multi-chat to each user in the chat. These status messages can be:

https://developer.skype.com/Docs/Skype4COML...atMessageStatus

So you need to do something like this on a sent message, if you want to process only the first status received on a sent chat message:

CODE

if (LastSent == ichatmessage.Id.ToString())
            {
                return;
            }
LastSent = ichatmessage.Id.ToString();

Your code here........


I am sure that if you are sending a message more than once into the real Skype chat, that if you set a breakpoint, you will see you are in fact sending twice, maybe because you are not dealing with the multiple status messages you may be receiving for a single sent chat message into a Skype multi-chat properly, because you did not realize that you will get a status message from each Skype user in a multi-chat vs always one status when using a private chat.

Each message is assigned an ID #, so, you can tell if you have seen a status for a specific message already or not, on a chat by chat basis.

Example: If you have 4 people including you in a Skype multi-chat you can receive a sending and sent status for each Skype user in the multi-chat, the status will include the same message ID but there will be one for each person in the multi-chat. This allows you to determine who has or has not received the message yet on a per user basis. The same applies for a received and read status as well.

So for each sent message sent into a Skype multi-chat you will receive a status message for each of these on a message you sent into a multi-chat:

1. Sending ("To the Skype Cloud")
2. Sent ("Received by the Skype Cloud")
3. Received (Received by the specific Skype User")
4. Read ("The Skype user could receive a notification and not have opened the chat yet, once they do, you see this status")

Please remember, you will see these status messages from each and every user in the chat, which means, some may receive your sent message hours or days later, if they were logged off when you sent the message into the multi-chat.

These all will have the same message ID but will be from each Skype user in the multi-chat.

CODE

private void Skype_MessageStatus(IChatMessage ichatmessage, TChatMessageStatus Status)
        {
            if (Status == TChatMessageStatus.cmsRead)
            {
                return;
            }

            if (LastSent == ichatmessage.Id.ToString())
            {
                return;
            }

            try
            {
                if ((ichatmessage.Type == TChatMessageType.cmeSaid) && (ichatmessage.Chat.Name == MyChatName))
                {
                    switch (ichatmessage.Status)
                    {
                        case TChatMessageStatus.cmsSent:
                                                                                                Your Code here.....
                        case TChatMessageStatus.cmsReceived:
                                                                                                Your Code here......
                    }
                      LastSent = ichatmessage.Id.ToString();
                 {
             }
                                                


This allows you to avoid read status messages because they could come hours, even days later for any user in the multi-chat. It also allows you to process only the first sent message response, and to avoid sending, and receiving status messages being processed, as well. I left the default out in tha case statement but you get the idea.

TChatMessageType.cmeSaid confines the status messages to text messages sent and received so you don't look at people leaving the chat and joining the chat as well as other status messages that don't contain chat text. The code format on the board sucks, but I did my best to line things up to give you a basic idea of how to NOT process messages other that chat text sent/received and only process one text message sent/received for the entire multi-chat.

There is one downside to using this method, if everyone in this chat is offline for example, you will never receive a received status for example until on Skype user in the multi-chat comes online. But if you don't isolate what messages you want to process, you will be swamped. This isolates you to one copy of any sent/received message in a multi-chat. If you are going to support multiple multi-chats in progress at anytime, you would want to keep a LastSent for each one.

The reason why you return at the top of the message event handler for TChatMessageStatus.cmsRead is because if your program/Skype client was offline for days, and before you went offline you sent many chat messages that were not read before you went offline, you can cause an abend in your program, because you could get swamped with read status messages from days ago. Since you were offline, you would never receive the received status, but you would receive a read status for any message you sent before you went offline and all at once, as soon as your Skype client logged on, So this allows you to dump those as fast as possible to not possibly cause your program to abend.

So as you can see using this method, if you stopped/started the Skype client and your program, you would not receive any OLD stuff to process (Minus any read status messages"), since you have not sent a message yet, and in most cases, you should not receive a received message unless someone just sent a text message into the chat.

I guess what I am saying is it appears to me that sending, sent and received status messages don't queue up for you if you go away as a program/Skype Client, but you still do receive a read status message for ALL messages sent in the past.

I hope this makes sense, if not, please ask, because I know it is hard to grasp what is going on in multi-chats with the amount of status messages you can/will receive, and how to limit those to the ones you really want to process.
Dr.O
wow this is really hard to understand all details but I got it running - no doubled or multiple messages into real chat anymore.
I made a global variable string LastSent, but it confuses me because at the beginning
CODE
if (LastSent == ichatmessage.Id.ToString())
            {
                return;
            }

the LastSent variable has no value. Ok the compiler gives no error but in Java I think this would not be possible. New language - new surprises surprised.png
Also to have a return-statement in a void method surprised.png
But it works properly.


When I understand you properly the ichatMessage.Id is being resent everytime a user in a group-chat receives my message - the eventhandler catches this - so I have to filter these events out. This is done by
CODE

            if (LastSent == ichatmessage.Id.ToString()) {
                return;
            }


The other detail I have to study a few more hours wink.png

Only one left:
I put my code in the "case TChatMessageStatus.cmsReceived: {"
because I want to catch events from other users.

case .cmsSent means there can I put code for messages I have sent?

Here again a big thanks for your efforts !!!
Your help took me a huge step forward to program my skype trivia bot
TheUberOverlord
QUOTE(Dr.O @ Fri Mar 23 2007, 19:02) [snapback]375710[/snapback]

wow this is really hard to understand all details but I got it running.
I made a global variable string LastSent, but it confuses me because at the beginning
CODE
if (LastSent == ichatmessage.Id.ToString())
            {
                return;
            }

the LastSent variable has no value. Ok the compiler gives no error but in Java I think this would not be possible. New language - new surprises surprised.png
Also to have a return-statement in a void method surprised.png
But ok it works.
When I understand you properly the ichatMessage.Id is resend everytime a user in a group-chat receives my message - the eventhandler catches this - so I have to filter this events out. This is done by
CODE

            if (LastSent == ichatmessage.Id.ToString()) {
                return;
            }


The other detail I have to study a few more hours wink.png

Only one left:
I put my code in the "case TChatMessageStatus.cmsReceived: {"
because I want to catch events from other users.

case .cmsSent means there can I put code for messages I have sent?

Here again a big thanks for your efforts !!!
Your help takes ma u huge step forward


The first time LastSent won't have a value, but it will everytime after. If you look at the if statement where I say "Your Code" it is set when you did process a message, so that the same message ID won't be processed again.

You are very welcome.
TheUberOverlord
A good way to visualize what status messages are going to and from is to run this example C# program I created to display status messages along side your program:

IPB Image

http://share.skype.com/sites/devzone/2006/...r_skype4co.html

The full C# project can be dowloaded here:

http://testing.onlytherightanswers.com/Sky...y_ZOverLord.zip
Dr.O
now I'm at a point in my program where it is very tricky.
After implementing some webservices I'm now coding a multi multi-chat solution for my two modes:
the standard mode (where I only recognize actions like !weather town)
the trivia mode, where I have to accept all messages

Now its very difficult to implement this for a mult group-chat solution (where many groupchats are running in different "modes" at same time). I have tried string arrays (which is not good because I don't know at runtime how big the array would be in future runtime) and as next step dynamic ArrayLists to store informations for each chat like: chatname, isTrivia, timer. This is where I stand now.
But this whole situation would be much more easier if I could mark a channel as "trivia = true" with the api. Maybe a custom iChannelMessage.Chat setting or a setting which is not needed? Is this possible?



Edit: I got it running via 2dimensional arrays. its very cool but I dislike that arrays aren't dynamic. I'm going to ask my programming prof at university on thursday - he should be able to explain me how to navigate through arraylists.
The World Is Not Enough bigsmile.png
Dr.O
let us have a look at this case again:
CODE

case TChatMessageStatus.cmsSent:   Your Code here.....


LastSent = ichatmessage.id does not work for this case for a abort-condition when I put in code like this:
chat.sendMessage("test");
because when it is sent, the sent message will get a new id and the it jumps again (because of the new event) into the case .cmsSent and so on

it will result in an endless loop and it writes endless times "test" in the chat.
Do you have an idea how to prevent this?
TheUberOverlord
QUOTE(Dr.O @ Tue Apr 3 2007, 04:41) [snapback]379467[/snapback]

let us have a look at this case again:
CODE

case TChatMessageStatus.cmsSent:   Your Code here.....


LastSent = ichatmessage.id does not work for this case for a abort-condition when I put in code like this:
chat.sendMessage("test");
because when it is sent it will get a new id and the it jumps again into the case .cmsSent and so on

it will result in an endless loop and it writes endless times "test" in the chat.
Do you have an idea how to prevent this?


abort-condition?

Something is wrong with your code. As I stated, you may need to keep a LastSent on a per chat basis.

I have NO idea of what you are trying to do, besides create some kind of BOT, which is hard to GUESS what you are trying to use it for, but once you understand Skype Chat message Status Flow, it will become easier, if you use the C# status message example code along side your code ("You may want more detail displayed for ALL chat status messages so you can see everything that is going on, so make changes to it and re-compile"), you will be able to see the status message flow for chats and be able to avoid endless loops.

If you don't understand the Chat message status flow FIRST, you will have more than endless loop problems, so try first to understand the flow first, because there must be some reason why you are processing the same message twice and it should be easily isolated as to why using debug as well as the C# status message example code with a little modifications to display more chat message detail.
Dr.O
this is a abort-contition:
CODE
if (LastSent == ichatmessage.Id.ToString())
            {
                return;
            }

I have no better translation for this. In german It's called "Abbruch-Bedingung" and normally used in for/while/do while condition: something like for(int i = 0; i <= 4; i++)

Yes it is for a chat bot. This is what I'm doing:

somebody writes into the chat:
CODE
!trivia 20

(A trivia is something like a quiz-game, you have to find the right answer for a question)

now i work in "case TChatMessageStatus.cmsReceived:"
The sign "!" indicates me now comes a command: trivia
20 means 20 questions
The Bot writes into the Chat: A new trivia with 20 questions starts in 5 seconds
I store the chatname + isTrivia=1 + the count of questions into a string Array [,]. Of course for every chat where a trivia starts, so I can decide what todo for a specific chat.

Now what is on the todo-list:
1. the "public void Skype_MessageStatus(IChatMessage ichatmessage, TChatMessageStatus Status)" Method has to be recognize timerevents (somehow, i have no experience with timers, only some code samples from the MSDN Librarys for vs2005)
2. look into the string array and decide for what chat the timer was called(?) (or better a global timer for all chats?)(I could give the timer the name of the chatroom, so it shoulb be possible to give every chat its own timer)
3. randomly choose a question from the xml file
4. questcount-1 in the string-array
5. wait a specific time for the right answer
5.a) if not right -> give a hint
5.b) if right store points for right answer - maybe in a sql database
6. goto 3. until questcount != 0 or the trivia in this channel is stoped via command "!stop"

And now I have some problems:
how can I put/use a timer (also which kind of timer: system.timer or system.threading) in the "public void Skype_MessageStatus(IChatMessage ichatmessage, TChatMessageStatus Status)" Method? + these timer must work for a multi-multi chat solution

And next I thought a good way to write the first question( which I have stored in a xml-file) when I use .cmsSent and test if the message begins with "A new trivia"

Its so complicated for a beginner like me...at this poin I really need an advanced programmer who could have a look into my code. If someone would help me I'll send my project files...
TheUberOverlord
QUOTE(Dr.O @ Tue Apr 3 2007, 05:21) [snapback]379485[/snapback]

this is a abort-contition:
CODE
if (LastSent == ichatmessage.Id.ToString())
            {
                return;
            }

I have no better translation for this. In german It's called "Abbruch-Bedingung" and normally used in for/while/do while condition: something like for(int i = 0; i <= 4; i++)

Yes it is for a chat bot. This is what I'm doing:

somebody writes into the chat:
CODE
!trivia 20

(A trivia is something like a quiz-game, you have to find the right answer for a question)

now i work in "case TChatMessageStatus.cmsReceived:"
The sign "!" indicates me now comes a command: trivia
20 means 20 questions
The Bot writes into the Chat: A new trivia with 20 questions starts in 5 seconds
I store the chatname + isTrivia=1 + the count of questions into a string Array [,]. Of course for every chat where a trivia starts, so I can decide what todo for a specific chat.

Now what is on the todo-list:
1. the "public void Skype_MessageStatus(IChatMessage ichatmessage, TChatMessageStatus Status)" Method has to be recognize timerevents (somehow, i have no experience with timers, only some code samples from the MSDN Librarys for vs2005)
2. look into the string array and decide for what chat the timer was called(?) (or better a global timer for all chats?)(I could give the timer the name of the chatroom, so it shoulb be possible to give every chat its own timer)
3. randomly choose a question from the xml file
4. questcount-1 in the string-array
5. wait a specific time for the right answer
5.a) if not right -> give a hint
5.b) if right store points for right answer - maybe in a sql database
6. goto 3. until questcount != 0 or the trivia in this channel is stoped via command "!stop"

And now I have some problems:
how can I put/use a timer (also which kind of timer: system.timer or system.threading) in the "public void Skype_MessageStatus(IChatMessage ichatmessage, TChatMessageStatus Status)" Method? + these timer must work for a multi-multi chat solution

And next I thought a good way to write the first question( which I have stored in a xml-file) when I use .cmsSent and test if the message begins with "A new trivia"

Its so complicated for a beginner like me...at this poin I really need an advanced programmer who could have a look into my code. If someone would help me I'll send my project files...


This is complex. I think you need to learn about timers in C#, and do a basic design flow on paper, you can do this, it may seem frustrating learning these status messages and timer processing but it's the only way to learn really.

Try and get it working for one chat, maybe set a flag if it is already doing a triva don't start another one, once you get that going, move on to support multiple chats, take baby steps.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.