The correct title of this article is dAmn. The initial letter is capitalized due to technical limitations.

dAmn (the deviantART Message Network, or deviantART Messaging Network) is deviantART's real-time messaging network. Since its beginning, it has become one of the most popular communication features of deviantART.

History

This section is a stub. You can help Botdom Documentation by expanding it by clicking the edit button at the right.

dAmn was launched on August 7, 2004, when deviantART upgraded to version 4.

Official client

This section is a stub. You can help Botdom Documentation by expanding it by clicking the edit button at the right.

dAmn's official client is run in a web browser using either a Mozilla Firefox extension, Flash or Java, and accompanied with JavaScript. The client is present at the chat subdomain of deviantart.com.

Authtokens

Any clients wishing to connect to dAmn need to provide an authtoken in the login packet. More information on this can be found here.

Tablumps

dAmn uses tablumps to format different elements in the chat. More information can be found at this page.

Protocol

dAmn has a raw protocol system, which makes building a bot much easier. dAmn runs on chat.deviantart.com (54.68.114.41), TCP port 3900.

This section aims to guide you through the protocol and each packet that you can send or receive. Everything is seen from the client's point of view. All characters will be spelled out in this guide, however in languages like PHP, you might need to type \n instead of line breaks seen in packets. Variables will be shown in bold italics in the code. We will show every variable's meaning (unless it's already shown in a paragraph before or the meaning is very obvious). Optional parts are displayed in a grey color.

Basic packet format

Basic Explanation

The basic format of a dAmn packet looks like this:

packetname mainparam
some=variables
somemore=variables (Any characters can be used here)
Main content is placed here.

Where mainparam is a parameter that's very relevant to the packet's subject, e.g. a username or chat room. Also, as said, remember that all packets end in a pure NULL character which is sometime represented as \0, \000, \0x00 or <php-inline>chr(0)</php-inline>. Most packets also need a line feed (aka Unix line break \n) before the NULL, however packets where the last part is distributed to the chat room (the send packet being the best example) do not need this.

If you used \n instead of line breaks, the example packet above would look like this:

packetname mainparam\nsome=variables\nsomemore=variables (Any characters can be used here)\n\nMain content is placed here.

In raw format, chat room names are formatted chat:name where name is the name of the chat room. Private chat room names are formatted pchat:user1:user2 where user1 and user2 are the names of the users who are in the private room. The usernames are sorted alphabetically, so e.g. "Albert" would go before "Zack".

Official Way

While looking at the source code for the official client, This is how it is officially broken down:

cmd param
arg1=value1
arg2=value2
body

Some packets insert a sub-packet into the body (recv is one of them) and those sub-packets are formatted (and can be parsed by the official parser) just like their enclosing packet. There are times when a sub-packet will contain only arguments and a body and not have the cmd/param at the start. Also, param is optional. See dAmn Packet Parser for an example of an easy way to parse packets.

Grammar

For those of you who like having grammars to work with, here is a simple thing based on the notation used at Python.org.
<bnf>
key ::= <any character excluding argument_separator, whitespace, and null>*
value ::= <any character excluding newlines and null>*
body ::= <([^\0])>*
command ::= key
parameter ::= value

dAmnClient (handshake)

The variable version is the version of the protocol which you are going to use. Only the newest version will work, if you use an older version, you will get disconnected. The current protocol version that is used is 0.3 (as of April 8 2008).

The agent variable is required. This is used to tell the server which kind of client/agent is used to connect to the server. Examples could be dAmn WebClient 0.7.pre-1 or futurism/beta 0.3. It is not your deviantART username. In addition to this, you can set any other variable you want. It is unknown whether the server takes action on these variables or saves them anywhere. In 0.1, variables weren't available in this packet.

You have to wait for a dAmnServer (handshake response) packet before you can continue logging in.

login

After handshaking, you use this packet to log in to the server.

login username
pk=authtoken

The username being the username you want to log in with, obviously, and the authtoken being your user account's dA authtoken. This is a hash value which changes every time you log in (unless you're using reusetoken) or log out. When you've logged in, you can see it in the cookie you receive from deviantART. In Firefox, this can be done by going to Tools > Settings > Privacy > View cookies and browsing. The cookie is a URL encoded list of variables, and the authtoken is one of those. It can also be seen in the source code when using the official dAmn client. Look for this: dAmn_Login( "username", "authtoken" );

After sending this packet, you have to wait for a server login packet in return before you can continue.

join

To join a chat room, send this packet:

join chat:chatroom

Very simple. chatroom is of course the name of the chat room you wish to join. To join a private chat, send this packet:

join pchat:user1:user2

Again very simple, the two users are the names of the users who should chat, which means one of those are you. They are sorted alphabetically.

part

Parting a chat room is almost the same as above:

part chat:chatroom

part pchat:user1:user2

pong

This is a very simple packet. As you'll learn later, the server occasionally sends a ping packet to check your connection. When it does that, simply return with this packet:

pong

However, if you want, you can also send this packet whenever you wish.

send

Here we're getting to what you may call the real stuff! You use this packet to send messages to a chat room. Mainly, there are three types of messages which you can send, which are defined by the middle part of the packet. (Actually, the send packet is used for many things, but we're going to cover the message related actions in this section.)

Based on testing done by doofsmack, it seems that if the message sub-packet (anything after the send chat:chatroom) is larger than 8192 bytes, the message is rejected and you are disconnected. All your sent messages are received back like all the other messages, so there's no need to show the message when sending it.

msg

This is the "ordinary" one that sends a normal message.

send chat:chatroom
msg main
content

Again, chatroom is the chat room in which you want to say something. As in all other places, it can also be in the pchat:user1:user2 format. And the content variable is simply the stuff you want to send!

action

Other than using the send command to send messages, you also use it for /me actions. This only requires a slight change in the packet:

send chat:chatroom
action main
content

Which will output /me content.

npmsg

And the last thing you can send is the npmsg (non parsed message) type:

send chat:chatroom
npmsg main
content

Non parsed messages don't contain anything that is parsed (like tags, emoticons, etc.) That's what you send when you hold the shift button while entering your message on the official dAmn client.

promote

Now that we've really gotten into it, we'd like to do more! Here's the packet you use to promote people:

send chat:chatroom
promote usernameprivclass

In this one, username is the name of the user you want promoted. If you specify a privclass, the user will go directly to that privclass if you have the privileges to do so. If you don't specify any, the person will be promoted to the privclass directly above the one he's currently in.

demote

Demoting is basically the same procedure as above.

send chat:chatroom
demote usernameprivclass

Again, username being the name of the user you want promoted. If you specify a privclass, the user will go directly to that privclass if you have the privileges to do so. If you don't specify any, the person will be demoted to the privclass directly below the one he's currently in.

ban

And if the annoying guys just keep coming back, you can ban them from the chatroom with this packet:

send chat:chatroom
ban username

This will ban username from chatroom. Note: One line break is required at the end

unban

This is basically the same as ban.

send chat:chatroom
unban username

This will promote (or demote) username from chatroom to the guest privclass, even if he wasn't originally banned.

kick

You can kick people out from the room (if you have sufficient privileges) with this packet:

kick chat:chatroom
u=usernamereason

This will kick username from chatroom with the reason reason. The reason can be empty.

get

property

Use this command to receive properties for a special room if you haven't already received them.

get chat:chatroom
p=property

Where property can be either title, topic, privclasses or members. It will then send you a property packet in return. You should receive those automatically when you join a room, but you can use this command to request them again.

userinfo

You can also use this packet to get information about a user.

get login:username
p=info

This will return a property packet with the information you'll need to know about username and its connection to dAmn. This is the equivalent of doing a /whois on dAmn.

set

Now that you know how to get a property, this packet lets you set a property:

set chat:chatroom
p=propertyvalue

This sets the property (which can be either title or topic) to value in chatroom if you have sufficient privileges.

admin

This packet lets you perform admin commands if you have the privileges, just like the /admin command or chatroom settings window in the official dAmn client:

send chat:chatroom
admin
command

Where command is the admin command you want to execute. Example: update privclass Members +smilies.

disconnect

This packet allows you to quit dAmn gracefully. It asks the server to disconnect you. The server replies with a part packet per room the user is joined to, followed by a disconnect packet.

disconnect

All rooms that you leave will show your reason for leaving as "quit".

Based on testing done by plaguethenet it appears that you cannot set the reason for disconnecting.

kill

This packet is used by dAmn admins to kill a connection.

kill login:usernamereason

The reason is optional. If username doesn't exist or is not online, or if you do not have the required privileges, you receive an error packet with the reason why it didn't work.

Server packets

This are the packets that go from the server to the client.

dAmnServer (handshake)

This packet is very simple. If the dAmn protocol version which you selected in your dAmnClient packet is supported by the server, it will return it here in the variable version. If you received this packet, you successfully handshaked and you're ready to log in!

login

When you've send your log in packet, the server will respond with this packet.

This packet will simply tell you whether your login as username was successful. We know of these values which event can have:

ok

Your login was successful!

authentication failed

Your username / authtoken combination wasn't correct.

not privileged

Unfortunately, you've been banned from the dAmn service.

too many connections

You have too many connections open (Limit is 20 connections per username.)

Furthermore, this packet also sends information about the account you're logging into. The values of symbol, realname, and typename are self-explanatory. In almost all instances gpc will equal guest unless you are a dAmn admin.

join

event determines whether your join was successful. We know of these values event can have:

ok

You've successfully joined chatroom.

not privileged

You're banned from this room, or it's a private room.

chatroom doesn't exist

Self-explanatory. The room you're trying to join doesn't exist.

bad namespace

The name of the room you are trying to join uses bad characters that can't be in a room name.

Like everywhere else, the chatroom variable can also be in the pchat:user1:user2 format.

part

Like above, when you've tried to part a room, you'll receive this packet in return which determines whether your part was successful.

part chat:chatroom
e=eventr=reason

We know of these values event can have:

ok

You've successfully parted chatroom.

not joined

You haven't joined this room.

bad namespace

The name of the room you are trying to part uses bad characters that can't be in a room name.

In addition, there's also a reason parameter, which appears when you've been forced to part by the server or a Message Network Administrator. We know of these values reason can have:

bad msg

You were disconnected because your message had characters that are not supported, or your sub-packet wasn't correct.

bad data

You sent a packet that can't be used or doesn't exist.

msg too big

The message you were trying to send was longer than 8192 bytes.

killed:reason

A message network administrator closed your connection with reason.

property

This packet is sent by the server to set an object's property.

property chat:chatroom
p=propertyby=who set the topic/titlets=time topic/title was setvalue

This assigns value to chatroom's property. We know of these values property can have:

topic

chatroom's topic.

title

chatroom's title.

privclasses

chatroom's privclasses.

members

The list of people currently in chatroom. Includes the same information present in the join packet that's a subpacket of recv.

login:username

Whois information for username.

We'll write more about each property in a later section. You usually get the first four properties when you join a room, but they can also be received using the get packet. The last one is request-only.

This packet is relatively easy to parse, ns and channel require special handling, but each conn subpacket is a seperate connection.

It should also be noted that this packet will not show pchats that the user has joined, only chats from the normal namespace will be included.

recv

This is where stuff really happens! You use this server packet to receive messages of many kinds, determined by the value part of the packet.

msg

This is the packet you use to receive ordinary messages.

recv chat:chatroom
msg main
from=usernamecontent

This indicates that username has said content in chatroom. (And of course chatroom can be in the pchat:user1:user2 format.) When you send npmsgs, they will also end up here, however with unparsed emoticons and tags (which are html encoded with &gt;, &lt;, &amp;, etc).

action

This is the packet you use to receive /me actions.

recv chat:chatroom
action main
from=usernamecontent

This indicates that username has content'd in chatroom.

join

This is the packet you receive when someone else joins one of the rooms you are in.

This indicates that username has joined chatroom; show is either a 1 or 0 indicating whether the client should display a join notification. Furthermore, this packet will also send you information about username in the body.

The body is a subpacket which contains nothing but arguments, most of them self-explanatory. privclass is the user's privclass in the chatroom, icon is the icon number of the user, symbol is the user's symbol, realname is the user's tag line set on their profile page, typename is the type of deviant the user set themselves as on their profile page, and gpc is the global privclass of the user. The global privclass indicates if the user is a normal deviant ("guest") or if they have administrator privileges (such as "MN@ Operator"). The icon number indicates two things: the extension of the avatar and the cache buster to use when requesting it. This is the algorithm, as displayed using simplified code directly from the official dAmn client (JavaScript), to calculate both of these:

part

Like above, this is the packet you receive when someone else parts one of the rooms you are in.

recv chat:chatroom
part usernamer=reason

This indicates that username has parted chatroom with or without a reason. If it's blank, the user has only parted this chatroom, but still has a connection open. If there's a reason, username's connection was also closed at the same time as the part happened. We know of these values reason can have:

A message network administrator closed the users connection with reason.

privchg

This is the packet you receive when someone gets promoted, demoted, banned or unbanned.

recv chat:chatroom
privchg username
by=username2
pc=privclass
i=show

This indicates that username was moved to privclass by username2. show indicates whether the client should display a notification, and is either 0 or 1.

kicked

This is the packet you receive when someone else gets kicked.

recv chat:chatroom
kicked username
by=username2
i=showreason

This indicates that username has been kicked from chatroom by username2 with reason, which can be empty. show indicates whether the client should display a notification, and it either 0 or 1.

admin

This is the packet you receive when someone does admin commands. They are different for each admin command. If the order of the privclasses in a room is changed the server sends a privclass property packet along with the admin packet.

create & update

This is the packet you receive when someone creates or updates a privclass.

If action is rename, then this indicates that username renamed the privclass previousprivclassname to privclassname. If the action is move, then this indicates that username moved all users from the privclass previousprivclassname to privclassname, and the original privclass still exists. The parameter usersaffected then shows how many deviants were actually moved in the admin action. This parameter only exists if action is move.

privclass

This is an error packet received after attempting to use the admin command in a channel.

recv chat:chatroom
admin privclass
p=action
e=errorcommand

command is the admin command that was sent by the client.

kicked

This is the packet you receive if you get kicked (not if anyone else does).

kicked chat:chatroom
by=usernamereason

This indicates that username kicked you from chatroom with the reason reason, which can be empty.

ping

To check your connection, the server will send you the ping packet.

ping

When you receive this packet, it is required that you send a pong packet in return, or you will be disconnected (timed out) by the server. The time it waits before disconnecting you seems to be 48 seconds. If there is no successful interaction between your client and the server within 96 seconds then it is likely that your client has been disconnected from the server. However, the maximum time it usually takes for a connection to time out appears to be around two minutes.

disconnect

This is the packet you receive if you fail to connect (or end up disconnecting) to the dAmn service somehow.

disconnect
e=event

event indicates why you were disconnected. We know of these values event can have: