summaryrefslogtreecommitdiff
path: root/spec/Channel_Type_Text.xml
blob: c150e3e24edabe9de03587b97a4bde8a1ee1eead (plain)
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
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
<?xml version="1.0" ?>
<node name="/Channel_Type_Text" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
  <tp:copyright> Copyright © 2005-2011 Collabora Limited </tp:copyright>
  <tp:copyright> Copyright © 2005-2009 Nokia Corporation </tp:copyright>
  <tp:copyright> Copyright © 2006 INdT </tp:copyright>
  <tp:license xmlns="http://www.w3.org/1999/xhtml">
    <p>This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.</p>

<p>This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.</p>

<p>You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
  </tp:license>
  <interface name="im.telepathy.v1.Channel.Type.Text">
    <tp:requires interface="im.telepathy.v1.Channel"/>
    <tp:changed version="0.24.0">This interface used to have a bunch of
      clunky Telepathy.Properties. They have been removed in favour of
      D-Bus properties on the <tp:dbus-ref
      namespace='imt1.Channel.Interface'>Room1</tp:dbus-ref>, <tp:dbus-ref
      namespace='imt1.Channel.Interface'>Subject1</tp:dbus-ref> and
      <tp:dbus-ref namespace='imt1.Channel.Interface'>RoomConfig1</tp:dbus-ref>
      interfaces.</tp:changed>
    <tp:changed version="0.99.1">Deprecated methods and types have
      removed from this interface. Additionally, this interface has
      been merged with the old, now-removed, Messages interface as it
      was a requirement since version 0.21.5.</tp:changed>

    <tp:simple-type name="Message_ID" type="u" array-name="Message_ID_List">
      <tp:docstring>
        A unique-per-channel identifier for an incoming message. These
        SHOULD be allocated in a way that minimizes collisions (in particular,
        message IDs SHOULD NOT be re-used until all of the 32-bit integer
        space has already been used).
      </tp:docstring>
    </tp:simple-type>

    <method name="AcknowledgePendingMessages"
      tp:name-for-bindings="Acknowledge_Pending_Messages">
      <arg direction="in" name="IDs" type="au" tp:type="Message_ID[]">
        <tp:docstring>
          The IDs of the messages to acknowledge
        </tp:docstring>
      </arg>
      <tp:docstring>
        Inform the channel that you have handled messages by displaying them to
        the user (or equivalent), so they can be removed from the pending queue.
      </tp:docstring>
      <tp:possible-errors>
        <tp:error name="im.telepathy.v1.Error.InvalidArgument">
          <tp:docstring>
            A given message ID was not found, so no action was taken
          </tp:docstring>
        </tp:error>
      </tp:possible-errors>
    </method>

    <tp:enum name="Channel_Text_Send_Error" type="u">
      <tp:enumvalue suffix="Unknown" value="0">
        <tp:docstring>
        An unknown error occurred
        </tp:docstring>
      </tp:enumvalue>
      <tp:enumvalue suffix="Offline" value="1">
        <tp:docstring>
        The requested contact was offline
        </tp:docstring>
      </tp:enumvalue>
      <tp:enumvalue suffix="Invalid_Contact" value="2">
        <tp:docstring>
        The requested contact is not valid
        </tp:docstring>
      </tp:enumvalue>
      <tp:enumvalue suffix="Permission_Denied" value="3">
        <tp:docstring>
        The user does not have permission to speak on this channel
        </tp:docstring>
      </tp:enumvalue>
      <tp:enumvalue suffix="Too_Long" value="4">
        <tp:docstring>
        The outgoing message was too long and was rejected by the server
        </tp:docstring>
      </tp:enumvalue>
      <tp:enumvalue suffix="Not_Implemented" value="5">
        <tp:docstring>
        The channel doesn't support sending text messages to the requested
        contact
        </tp:docstring>
      </tp:enumvalue>
    </tp:enum>

    <tp:enum name="Channel_Text_Message_Type" type="u"
      array-name="Channel_Text_Message_Type_List">
      <tp:docstring>
        The type of message.
      </tp:docstring>

      <tp:enumvalue suffix="Normal" value="0">
        <tp:docstring>
        An ordinary chat message. Unknown types SHOULD be treated like this.
        </tp:docstring>
      </tp:enumvalue>

      <tp:enumvalue suffix="Action" value="1">
        <tp:docstring>
        An action which might be presented to the user as
        "* &lt;sender&gt; &lt;action&gt;", such as an IRC CTCP
        ACTION (typically selected by the "/me" command). For example, the
        text of the message might be "drinks more coffee".
        </tp:docstring>
      </tp:enumvalue>

      <tp:enumvalue suffix="Notice" value="2">
        <tp:docstring>
        A one-off or automated message not necessarily expecting a reply
        </tp:docstring>
      </tp:enumvalue>

      <tp:enumvalue suffix="Auto_Reply" value="3">
        <tp:docstring>
        An automatically-generated reply message.
        </tp:docstring>
      </tp:enumvalue>

      <tp:enumvalue suffix="Delivery_Report" value="4">
        <tp:docstring>
          A delivery report. See <tp:type>Message_Part</tp:type> for
          the format that delivery reports must take.
        </tp:docstring>
      </tp:enumvalue>

    </tp:enum>

    <property name="SupportedContentTypes" type="as" access="read"
      tp:name-for-bindings="Supported_Content_Types"
      tp:immutable="yes">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>A list of MIME types supported by this channel, with more preferred
          MIME types appearing earlier in the list. The list MAY include "*/*"
          to indicate that attachments with arbitrary MIME types can be sent.
          This list MUST NOT be empty, since all implementations
          MUST accept messages containing a single "text/plain" part.</p>

        <p>Items in this list MUST be normalized to lower-case.</p>

        <p>Some examples of how this property interacts with the
          <tp:member-ref>MessagePartSupportFlags</tp:member-ref>:</p>

        <dl>
          <dt>A simple IM implementation: only plain text messages are
            allowed</dt>
          <dd>SupportedContentTypes = ['text/plain'],
            MessagePartSupportFlags = 0</dd>

          <dt>Formatted text with a plain text alternative is allowed (see the
            HTML interface draft)</dt>
          <dd>SupportedContentTypes = ['text/html', 'text/plain'],
            MessagePartSupportFlags = 0</dd>

          <dt>JPEG or PNG images may be sent, but without any attached
            text</dt>
          <dd>SupportedContentTypes = ['text/plain', 'image/jpeg',
            'image/png'], MessagePartSupportFlags = 0</dd>

          <dt>Unformatted text to which an optional JPEG or PNG image may be
            attached</dt>
          <dd>SupportedContentTypes = ['text/plain', 'image/jpeg',
            'image/png'], MessagePartSupportFlags = One_Attachment</dd>

          <dt>Formatted text to which arbitrarily many images may be
            attached</dt>
          <dd>SupportedContentTypes = ['text/html', 'text/plain', 'image/jpeg',
            'image/png', 'image/x-ms-bmp'], MessagePartSupportFlags =
            One_Attachment | Multiple_Attachments</dd>

          <dt>A full SIP implementation: arbitrary MIME messages are
            allowed</dt>
          <dd>SupportedContentTypes = ['*/*'], MessagePartSupportFlags =
            One_Attachment | Multiple_Attachments</dd>
        </dl>
      </tp:docstring>
    </property>

    <property name="MessageTypes" type="au"
      tp:type="Channel_Text_Message_Type[]" access="read"
      tp:name-for-bindings="Message_Types"
      tp:immutable="yes">
      <tp:added version="0.21.5"/>
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>A list of message types which may be sent on this channel.</p>
      </tp:docstring>
    </property>

    <property name="MessagePartSupportFlags" type="u"
      tp:type="Message_Part_Support_Flags" access="read"
      tp:name-for-bindings="Message_Part_Support_Flags"
      tp:immutable="yes">
      <tp:docstring>
        Flags indicating the level of support for message parts on this
        channel.
      </tp:docstring>
    </property>

    <tp:flags name="Message_Part_Support_Flags"
      value-prefix="Message_Part_Support_Flag" type="u">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Flags indicating the level of support for message parts on this
          channel. They are designed such that setting more flags always
          implies that the channel has more capabilities.</p>

        <p>If no flags are set, this indicates that messages may contain
          a single message part whose content-type is any of the types
          from SupportedContentTypes, possibly with some alternatives.</p>

        <p>There is no flag indicating support for alternatives. This is
          because the SendMessage implementation can always accept messages
          containing alternatives, even if the underlying protocol does not,
          by deleting all alternatives except the first (most preferred)
          that is supported.</p>

        <tp:rationale>
          Each of the flags so far implies the previous flag, so we could
          have used a simple enumeration here; however, we've defined
          the message-part support indicator as a flag set for future
          expansion.
        </tp:rationale>

        <p>See <tp:member-ref>SupportedContentTypes</tp:member-ref> for some
          examples.</p>
      </tp:docstring>

      <tp:flag suffix="One_Attachment" value="1">
        <tp:docstring>
          <tp:member-ref>SendMessage</tp:member-ref> will accept messages
          containing a textual message body,
          plus a single attachment of any type listed in the
          SupportedContentTypes property. It does not make sense for this
          flag to be set if Message_Part_Support_Flag_Data_Only is not also set
          (because the connection manager can trivially provide an empty text
          part if necessary).
        </tp:docstring>
      </tp:flag>
      <tp:flag suffix="Multiple_Attachments" value="2">
        <tp:docstring>
          SendMessage will accept messages containing a textual message body,
          plus an arbitrary number of attachments of any type listed in the
          SupportedContentTypes property. It does not make sense for this
          flag to be set if Message_Part_Support_Flag_One_Attachment is not
          also set.
        </tp:docstring>
      </tp:flag>
    </tp:flags>

    <tp:mapping name="Message_Part" array-name="Message_Part_List"
      array-depth="2">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Part of a message's content. In practice, this mapping never
          appears in isolation: incoming messages are represented by a list of
          <tp:type>Message_Part</tp:type> mappings in the
          <tp:member-ref>MessageReceived</tp:member-ref> signal, and outgoing
          messages are passed to <tp:member-ref>SendMessage</tp:member-ref> as
          a list of these mappings.</p>

        <p>The first part of the message contains "headers", which refer
          to the entire message. The second and subsequent parts contain the
          message's content, including plain text, formatted text and/or
          attached files. Well-known keys for the header and body parts are
          defined by the <tp:type>Message_Header_Key</tp:type> and
          <tp:type>Message_Body_Key</tp:type> types, respectively.  It is an
          error for a connection manager to put keys referring to the message
          as a whole in the second or subsequent Message_Part, or keys intended
          for body parts in the first Message_Part; clients MUST recover from
          this error by ignoring these mis-placed keys.</p>

        <tp:rationale>
          <p>Instead of representing messages as aa{sv} where the first
            dictionary is special (a dictionary of headers), we could have
            used a signature like (a{sv}aa{sv}) to separate out the headers
            and the body parts.</p>

          <p>However, this would make access to the messages more awkward.
            In Python, the syntax for access to a header field would remain
            <code>message[0]['message-type']</code>, but access to a body
            field in the second body part would change from
            <code>message[2]['content'] to message[1][1]['content']</code>. In
            GLib, the message would change from being a
            <code>GPtrArray(GHashTable)</code> to being a
            <code>GValueArray(GHashTable, GPtrArray(GHashTable))</code> which
            is rather inconvenient to dereference.</p>
        </tp:rationale>

        <p>In any group of parts with the same non-empty value for the
          <tt>alternative</tt> key (which represent alternative versions of the
          same content), more faithful versions of the intended message MUST
          come before less faithful versions (note that this order is the
          opposite of MIME <tt>multipart/alternative</tt> parts). Clients
          SHOULD display the first alternative that they understand.</p>

        <tp:rationale>
          <p>Specifying the preference order means that if the underlying
            protocol doesn't support alternatives, the CM can safely delete
            everything apart from the first supported alternative when
            sending messages.</p>

          <p>The order is the reverse of MIME because MIME's rationale for
            placing the "plainest" part first (legibility in pre-MIME UAs)
            does not apply to us, and placing the most preferred part
            first simplifies display (a client can iterate the message
            in order, display the first alternative that it understands,
            and skip displaying all subsequent parts with the same
            "alternative" key).</p>
        </tp:rationale>

        <p>Clients SHOULD present all parts that are not redundant
          alternatives in the order they appear in this array, possibly
          excluding parts that are referenced by another displayed part.
          It is implementation-specific how the parts are presented to the
          user.</p>

        <tp:rationale>
          <p>This allows CMs to assume that all parts are actually shown to
            the user, even if they are not explicitly referenced - we do
            not yet recommend formatted text, and there is no way for
            plain text to reference an attachment since it has no concept of
            markup or references. This also forces clients to do something
            sensible with messages that consist entirely of "attachments",
            with no "body" at all.</p>

          <p>For instance, when displaying the above example, a client that
            understands the HTML part should display the JPEG image once,
            between the two lines "Here is a photo of my cat:" and
            "Isn't it cute?"; it may additionally present the image in some
            way for a second time, after "Isn't it cute?", or may choose
            not to.</p>

          <p>A client that does not understand HTML, displaying the same
            message, should display the plain-text part, followed by the JPEG
            image.</p>
        </tp:rationale>

        <p>Connection managers, clients and extensions to this specification
          SHOULD NOT include <tp:type>Handle</tp:type>s as values in a
          Message_Part, except for <code>message-sender</code> in the
          header.</p>

        <tp:rationale>
          <p>Reference-counting handles in clients becomes problematic if
            the channel proxy cannot know whether particular map values
            are handles or not.</p>
        </tp:rationale>

        <h4>Example messages</h4>

        <p>A rich-text message, with an embedded image, might be represented
          as:</p>

          <pre>
[
  {
    'message-token': '9de9546a-3400-4419-a505-3ea270cb834c',
    'message-sender': 42,
    'message-sent': 1210067943,
    'message-received': 1210067947,
    'message-type': 0,              # = Channel_Text_Message_Type_Normal
    'pending-message-id': 437,
  },
  { 'alternative': 'main',
    'content-type': 'text/html',
    'content': 'Here is a photo of my cat:&lt;br /&gt;' +
               '&lt;img src="cid:catphoto" alt="lol!" /&gt;' +
               '&lt;br /&gt;Isn't it cute?',
  },
  { 'alternative': 'main',
    'content-type': 'text/plain',
    'content': 'Here is a photo of my cat:\n[IMG: lol!]\nIsn't it cute?',
  },
  { 'identifier': 'catphoto',
    'content-type': 'image/jpeg',
    'size': 101000,
    'needs-retrieval': True,
  },
]</pre>

        <p>telepathy-ring, Nokia's GSM connection manager, represents vCards
          sent via SMS as:</p>

        <pre>
[
  {
    'message-token': '9de9546a-3400-4419-a505-3ea270cb834c',
    'message-sender': 42,
    'message-sent': 1210067943,
    'message-received': 1210067947,
    'message-type': 0,              # = Channel_Text_Message_Type_Normal
    'pending-message-id': 437,
  },
  { 'content-type': 'text/x-vcard',
    'content': [ 0x66, 0x69, 0x71, ...], # vCard data as an array of bytes
  },
]</pre>

        <h3>Delivery reports</h3>

        <div>
          <p>Delivery reports are also represented as messages with the
            <tt>message-type</tt> header mapping to
            <tp:type>Channel_Text_Message_Type</tp:type> Delivery_Report.
            Delivery reports SHOULD contain the <tt>message-sender</tt> header,
            mapping to the intended recipient of the original message, if
            possible; other headers specific to delivery reports are defined by
            the <tp:type>Delivery_Report_Header_Key</tp:type> type. The second
            and subsequent parts, if present, are a human-readable report from
            the IM service.</p>

          <p>The result of attempting to send delivery reports using
            <tp:member-ref>SendMessage</tp:member-ref> is currently
            undefined.</p>

          <h4>Example delivery reports</h4>

          <dl>
            <dt>A minimal delivery report indicating permanent failure of the
              sent message whose token was
              <code>b9a991bd-8845-4d7f-a704-215186f43bb4</code> for an unknown
              reason</dt>
            <dd><pre>
[{
# header
'message-sender': 123,
'message-type': Channel_Text_Message_Type_Delivery_Report,
'delivery-status': Delivery_Status_Permanently_Failed,
'delivery-token': 'b9a991bd-8845-4d7f-a704-215186f43bb4',
}
# no body
]</pre></dd>

            <dt>A delivery report where the failed message is echoed back to the
              sender rather than being referenced by ID, and the failure reason
              is that this protocol cannot send messages to offline contacts
              such as the contact with handle 123</dt>
            <dd><pre>
[{ # header
'message-sender': 123,
'message-type': Channel_Text_Message_Type_Delivery_Report,
'delivery-status': Delivery_Status_Temporarily_Failed,
'delivery-error': Channel_Text_Send_Error_Offline,
'delivery-echo':
    [{ # header of original message
    'message-sender': 1,
    'message-sent': 1210067943,
    },
    { # body of original message
    'content-type': 'text/plain',
    'content': 'Hello, world!',
    }]
  ],

# no body
]</pre></dd>

            <dt>A maximally complex delivery report: the server reports a
              bilingual human-readable failure message because the user sent
              a message "Hello, world!" with token
              <code>b9a991bd-8845-4d7f-a704-215186f43bb4</code> to a contact
              with handle 123, but that handle represents a contact who does not
              actually exist</dt>
            <dd><pre>
[{ # header
'message-sender': 123,
'message-type': Channel_Text_Message_Type_Delivery_Report,
'delivery-status': Delivery_Status_Permanently_Failed,
'delivery-error': Channel_Text_Send_Error_Invalid_Contact,
'delivery-token': 'b9a991bd-8845-4d7f-a704-215186f43bb4',
'delivery-echo':
    [{ # header of original message
    'message-sender': 1,
    'message-sent': 1210067943,
    },
    { # body of original message
    'content-type': 'text/plain',
    'content': 'Hello, world!',
    }]
  ],
},
{ # message from server (alternative in English)
'alternative': '404',
'content-type': 'text/plain',
'lang': 'en',
'content': 'I have no contact with that name',
},
{ # message from server (alternative in German)
'alternative': '404'.
'content-type': 'text/plain',
'lang': 'de',
'content', 'Ich habe keinen Kontakt mit diesem Namen',
}
]</pre></dd>

            <dt>A minimal delivery report indicating successful delivery
              of the sent message whose token was
              <code>b9a991bd-8845-4d7f-a704-215186f43bb4</code></dt>
            <dd><pre>
[{
# header
'message-sender': 123,
'message-type': Channel_Text_Message_Type_Delivery_Report,
'delivery-status': Delivery_Status_Delivered,
'delivery-token': 'b9a991bd-8845-4d7f-a704-215186f43bb4',
}
# no body
]</pre></dd>

          </dl>

        </div>
      </tp:docstring>

      <tp:member name="Key" type="s">
        <tp:docstring>
          A key, which SHOULD be one of the well-known keys specified by
          <tp:type>Message_Header_Key</tp:type>,
          <tp:type>Message_Body_Key</tp:type> or
          <tp:type>Delivery_Report_Header_Key</tp:type> if possible.
        </tp:docstring>
      </tp:member>

      <tp:member name="Value" type="v">
        <tp:docstring>
          The value corresponding to the given key, which SHOULD be one of the
          specified types for well-known keys.
        </tp:docstring>
      </tp:member>
    </tp:mapping>

    <tp:simple-type type="s" name="Message_Header_Key">
      <tp:added version="0.19.8"/>
      <tp:changed version="0.21.5">
        Removed <tt>protocol-token</tt>—which had never been implemented—and
        respecified <tt>message-token</tt> not to have unimplementable
        uniqueness guarantees.
      </tp:changed>

      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Well-known keys for the first <tp:type>Message_Part</tp:type> of a
          message, which contains metadata about the message as a whole, along
          with the corresponding value types. Some keys make sense for both
          incoming and outgoing messages, while others are only meaningful for
          one or the other.</p>

          <dl>
            <dt>message-token (s -
              <tp:type>Protocol_Message_Token</tp:type>)
            </dt>
            <dd>
              <p>An opaque identifier for the message, as used by the
                underlying protocol. For outgoing messages, this SHOULD be
                globally unique; for incoming messages, this is <em>not</em>
                guaranteed to uniquely identify a message, <em>even within the
                scope of a single channel or contact</em>; the only guarantee
                made is that two messages with different <tt>message-token</tt>
                headers are different messages.</p>

              <p>Clients wishing to determine whether a new message with the
                <tt>scrollback</tt> header matches a previously-logged message
                with the same <tt>message-token</tt> SHOULD compare the
                message's sender, contents, <tt>message-sent</tt> or
                <tt>message-received</tt> timestamp, etc. Note that, in XMPP,
                the server only supplies a timestamp for scrollback messages,
                not for messages received while you are in a room; thus,
                non-scrollback messages will lack a <tt>message-sent</tt>
                timestamp.</p>

              <tp:rationale>
                <p>In practice, most protocols do not provide globally-unique
                  identifiers for messages. Connection managers, being
                  stateless, do not have the necessary information — namely, IM
                  logs — to generate reliable unique tokens for messages.</p>

                <p>For instance, some XMPP clients (including Gabble) stamp
                  messages they send with unique identifiers, but others number
                  outgoing messages in a conversation from 1 upwards.</p>
              </tp:rationale>
            </dd>

            <dt>message-sent (x - <tp:type>Unix_Timestamp64</tp:type>)</dt>
            <dd>The time the message was sent (if unavailable, the time
              it arrived at a central server MAY be used). Omitted if no
              reasonable approximation is available; SHOULD always be present
              on outgoing messages.</dd>

            <dt>message-received (x - <tp:type>Unix_Timestamp64</tp:type>)</dt>
            <dd>The time the message was received locally. SHOULD always
              be present.</dd>

            <dt>message-sender (u - <tp:type>Contact_Handle</tp:type>)</dt>
            <dd>The contact who sent the message. If 0 or omitted, the contact
              who sent the message could not be determined.</dd>

            <dt>message-sender-id (s)</dt>
            <dd>The identifier of the contact who sent the message. If empty or
              omitted, the contact who sent the message could not be
              determined.</dd>

            <dt>sender-nickname (s)</dt>
            <dd>The nickname chosen by the sender of the message, which can be
              different for each message in a conversation.</dd>

            <dt>message-type (u - <tp:type>Channel_Text_Message_Type</tp:type>)
            </dt>
            <dd>The type of message; if omitted,
              Channel_Text_Message_Type_Normal MUST be assumed. MAY
              be omitted for normal chat messages.</dd>

            <dt>supersedes (s – <tp:type>Protocol_Message_Token</tp:type>)</dt>
            <dd>If present, this message supersedes a previous message,
              identified by its <tt>message-token</tt> header. The user
              interface MAY, for example, choose to replace the superseded
              message with this message, or grey out the superseded message.

              <tp:rationale>Skype, for example, allows the user to amend
                messages they have already sent (to correct typos,
                etc.).</tp:rationale>

              Connection Managers SHOULD represent repeatedly edited messages
              in the following form:
              <pre>
                message {token = a};
                message {token = b, supersedes = a};
                message {token = c, supersedes = a};
              </pre>

              <tp:rationale>The alternative form is:
                <pre>
                  message {token = a};
                  message {token = b, supersedes = a};
                  message {token = c, supersedes = b};
                </pre>
                but it is more difficult to implement in UIs/loggers, and it
                breaks irrecoverably if message b is lost. If a CM is forced
                to use this form, it should be tested extensively for
                interoperability with existing clients.
                </tp:rationale>

              Clients should deal gracefully if the original message gets
              lost, but one or more corrections to it get through:
              <pre>
                message {token = x} gets lost;
                message {token = y, supersedes = x};
                message {token = z, supersedes = x};
              </pre>

              <tp:rationale>This is the form that CMs will use to mean "I know
                that this message was edited, but I don't know what it
                originally said." It is often in the interests of the
                remote side for message x to be lost (e.g. to hide
                embarassing mistakes or sensitive information) so it might not
                be possible to retrieve it (even on protocols with reliable
                message-delivery guarantees).</tp:rationale></dd>

            <dt>original-message-sent (x - <tp:type>Unix_Timestamp64</tp:type>)</dt>
            <dd>The <tt>message-sent</tt> header of the message that this
              one supersedes.
              This key should only be present if <tt>supersedes</tt> is also
              present. It MAY be used as a hint to help clients locate the
              original message in its logs. If present, comparing the tuple
              (original-message-sent, supersedes) with (message-sent,
              message-token) SHOULD be enough to uniquely
              identify the original message.</dd>

            <dt>original-message-received (x - <tp:type>Unix_Timestamp64</tp:type>)</dt>
            <dd>The <tt>message-received</tt> header of the message that this
              one supersedes.
              This key should only be present if <tt>supersedes</tt> is also
              present. It MAY be used as a hint in a similar way to
              <tt>original-message-sent</tt>.</dd>

            <dt>pending-message-id (u - <tp:type>Message_ID</tp:type>)</dt>
            <dd>The incoming message ID. This MUST NOT be present on outgoing
              messages. Clients SHOULD NOT store this key - it is only valid
              for as long as the message remains unacknowledged.</dd>

            <dt>interface (s - <tp:type>DBus_Interface</tp:type>)</dt>
            <dd>This message is specific to the given interface, which
              is not Text. It SHOULD be ignored if that interface is
              not supported. (Note that an 'interface' key can also
              appear on the second and subsequent parts, where it
              indicates that that part (only) should be ignored if
              unsupported.)</dd>

            <dt>scrollback (b)</dt>
            <dd>If present and true, the incoming message was part of
              a replay of message history. This flag does not make sense
              on outgoing messages and SHOULD NOT appear there.</dd>

            <dt>rescued (b)</dt>
            <dd>If present and true, the incoming message has been seen in
              a previous channel during the lifetime of the Connection,
              but had not been acknowledged when that channel closed, causing
              an identical channel (in which the message now appears) to open.
              It does not make sense on outgoing messages, and SHOULD NOT
              appear there.</dd>
          </dl>

      </tp:docstring>
    </tp:simple-type>

    <tp:simple-type type="s" name="Message_Body_Key">
      <tp:added version="0.19.8"/>
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Well-known keys for the second and subsequent
          <tp:type>Message_Part</tp:type>s of a message, which contain the
          message content, along with the corresponding value types.</p>

          <dl>
            <dt>identifier (s —
              <tp:type>Protocol_Content_Identifier</tp:type>)</dt>
            <dd>An opaque identifier for this part.
              Parts of a message MAY reference other parts by treating
              this identifier as if it were a MIME Content-ID and using
              the cid: URI scheme.</dd>

            <dt>alternative (s)</dt>
            <dd>
              <p>If present, this part of the message is an alternative for
                all other parts with the same value for "alternative".
                Clients SHOULD only display one of them (this is expected to
                be used for XHTML messages in a future version of this
                specification).</p>

              <p>If omitted, this part is not an alternative for any other
                part.</p>

              <p>Parts of a message MAY reference the group of alternatives
                as a whole (i.e. a reference to whichever of them is chosen)
                by treating this identifier as if it were the MIME Content-ID
                of a multipart/alternative part, and using the cid: URI
                scheme.</p>
            </dd>

            <dt>content-type (s)</dt>
            <dd>
              <p>The MIME type of this part. See the documentation
                for <tp:member-ref>MessageReceived</tp:member-ref> and
                <tp:member-ref>MessageSent</tp:member-ref> for notes on the
                special status of "text/plain" parts.</p>

              <p>Connection managers MUST NOT signal parts without a
                'content-type' key; if a protocol provides no way to determine
                the MIME type, the connection manager is responsible for
                guessing it, but MAY fall back to "text/plain" for text and
                "application/octet-stream" for non-text.</p>

              <p>Clients MUST ignore parts without a 'content-type' key, which
                are reserved for future expansion.</p>

              <p>When sending messages, clients SHOULD normalize the
                content-type to lower case, but connection managers SHOULD NOT
                rely on this. When signalling sent or received messages,
                connection managers MUST normalize the content-type to lower
                case.</p>
            </dd>

            <dt>lang (s)</dt>
            <dd>The natural language of this part, identified by a
              RFC 3066 language tag.

              <tp:rationale>
                XMPP allows alternative-selection by language as well as
                by content-type.
              </tp:rationale>
            </dd>

            <dt>size (u)</dt>
            <dd>The size in bytes (if needs-retrieval is true, this MAY be an
              estimated or approximate size). SHOULD be omitted if 'content'
              is provided.

              <tp:rationale>
                There's no point in providing the size if you're already
                providing all the content.
              </tp:rationale>
            </dd>

            <dt>thumbnail (b)</dt>
            <dd>
              <p>This part is a thumbnail. To represent an image together with
                its thumbnail in a single message, there should be one part for
                the full image followed by a part for the thumbnail (following
                the “more complete versions first” requirement), with the same
                'alternative' value. For example:</p>

              <pre>
[ ... ,
  { 'alternative': 'catphoto',
    'content-type': 'image/jpeg',
    'size': 150000,
    'content': [0xFF, 0xD8, ... 0xFF 0xD9],
  },
  { 'alternative': 'catphoto',
    'content-type': 'image/jpeg'
    'size': 1024,
    'thumbnail': True,
    'content': [0xFF, 0xD8, ... 0xFF 0xD9],
  },
  ...
]</pre>
            </dd>

            <dt>needs-retrieval (b)</dt>
            <dd>If false or omitted, the connection
              manager already holds this part in memory. If present and true,
              this part must be retrieved on demand (like MIME's
              <tt>message/external-body</tt>) by a mechanism to be defined later.

              <tp:rationale>The mechanism was meant to be the now-deprecated
                GetPendingMessageContent, but that didn't work
                out. It's worth leaving the header in in preparation
                for a future mechanism.
              </tp:rationale>
            </dd>

            <dt>truncated (b)</dt>
            <dd>The content available via the 'content' key has been truncated
              by the server or connection manager (equivalent to
              Channel_Text_Message_Flag_Truncated in the Text interface).
            </dd>

            <dt>content (s or ay)</dt>
            <dd>The part's content, if it is available and
              sufficiently small to include here (implies that
              'needs-retrieval' is false or omitted). Otherwise, omitted.
              If the part is human-readable text or HTML, the value for this
              key MUST be a UTF-8 string (D-Bus signature 's').
              If the part is not text, the value MUST be a byte-array
              (D-Bus signature 'ay'). If the part is a text-based format
              that is not the main body of the message (e.g. an iCalendar
              or an attached XML document), the value SHOULD be a UTF-8 string,
              transcoding from another charset to UTF-8 if necessary, but
              MAY be a byte-array (of unspecified character set) if
              transcoding fails or the source charset is not known.</dd>

              <!-- FIXME: "sufficiently small to include" is not currently
              defined; we should add some API so clients can tell the
                CM how large a message it should emit in the signal.-->

            <dt>interface (s - <tp:type>DBus_Interface</tp:type>)</dt>
            <dd>This part is specific to the given interface, which is
              not Text. It SHOULD be ignored if that interface is not
              supported. (Note that an 'interface' key can also appear
              on the first part, where it indicates that the entire
              message should be ignored if unsupported.)</dd>
          </dl>
      </tp:docstring>
    </tp:simple-type>

    <tp:simple-type type="s" name="Delivery_Report_Header_Key">
      <tp:added version="0.19.8"/>
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Well-known keys for the first <tp:type>Message_Part</tp:type> of a
          delivery report, along with the corresponding value types. Some of
          these are special-cases of headers defined by
          <tp:type>Message_Header_Key</tp:type>.</p>

          <dl>
            <dt>message-sender (u - <tp:type>Contact_Handle</tp:type>, as
              defined by <tp:type>Message_Header_Key</tp:type>)</dt>
            <dd>MUST be the intended recipient of the original message, if
              available (zero or omitted if the intended recipient is
              unavailable or is not a contact, e.g. a chatroom), even if the
              delivery report actually came from an intermediate server.</dd>

            <dt>message-type (u - <tp:type>Channel_Text_Message_Type</tp:type>,
              as defined by <tp:type>Message_Header_Key</tp:type>)</dt>
            <dd>MUST be Channel_Text_Message_Type_Delivery_Report.</dd>

            <dt>delivery-status (u - <tp:type>Delivery_Status</tp:type>)</dt>
            <dd>The status of the message. All delivery reports MUST contain
              this key in the first Message_Part.</dd>

            <dt>delivery-token (s - <tp:type>Protocol_Message_Token</tp:type>)</dt>

            <dd>
              <p>An identifier for the message to which this delivery report
                refers. MUST NOT be an empty string. Omitted if not
                available.</p>

              <p>Clients may match this against the token produced by the
                SendMessage method and MessageSent signal. A status report
                with no token could match any sent message, and a sent
                message with an empty token could match any status report.
                If multiple sent messages match, clients SHOULD use some
                reasonable heuristic.</p>

              <tp:rationale>
                In an ideal world, we could unambiguously match reports
                against messages; however, deployed protocols are not ideal,
                and not all reports and messages can be matched.
              </tp:rationale>
            </dd>

            <dt>delivery-error (u -
              <tp:type>Channel_Text_Send_Error</tp:type>)</dt>
            <dd>
              The reason for the failure. MUST be omitted if this was a
              successful delivery; SHOULD be omitted if it would be
              Channel_Text_Send_Error_Unknown.
            </dd>

            <dt>delivery-dbus-error (s -
              <tp:type>DBus_Error_Name</tp:type>)</dt>
            <dd>
              The reason for the failure, specified as a (possibly
              implementation-specific) D-Bus error. MUST be omitted if this was
              a successful delivery. If set, the 'delivery-error' key SHOULD be
              set to the closest available value.
            </dd>

            <dt>delivery-error-message (s)</dt>
            <dd>
              Debugging information on why the message could not be delivered.
              MUST be omitted if this was a successful delivery; MAY always be
              omitted.
            </dd>

            <dt>delivery-echo (aa{sv} - <tp:type>Message_Part[]</tp:type>)</dt>
            <dd>
              <p>The message content which can be omitted if no content
                is available. Content MAY have been truncated, message
                parts MAY have been removed, and message parts MAY
                have had their content removed (i.e. the message part
                metadata is present, but the 'content' key is
                not).</p>

              <tp:rationale>
                Some protocols, like XMPP, echo the failing message back to
                the sender. This is sometimes the only way to match it
                against the sent message, so we include it here.
              </tp:rationale>
            </dd>

          </dl>
      </tp:docstring>
    </tp:simple-type>

    <tp:simple-type type="s" name="Protocol_Message_Token"
                    array-name="Protocol_Message_Token_List">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>An opaque token used to identify messages in the underlying.
          protocol. As a special case, the empty string indicates that there
          is no particular identification for a message.</p>

        <p>CM implementations SHOULD use an identifier expected to be unique,
          such as a UUID, for outgoing messages (if possible).</p>

        <p>Some protocols can only track a limited number of messages
          in a small message-ID space (SMS messages are identified by a single
          byte), and some implementations send non-unique identifiers (some
          XMPP clients use very simple message IDs, such as an incrementing
          integer that resets to 1 at the beginning of each connection). As a
          result, clients MUST NOT assume that protocol tokens will not be
          re-used.</p>

        <p>In particular, clients SHOULD use a heuristic to assign delivery
          reports to messages, such as matching on message content or
          timestamp (if available), or assuming that the delivery report
          refers to the most recent message with that ID.</p>
      </tp:docstring>
    </tp:simple-type>

    <tp:simple-type name="Protocol_Content_Identifier" type="s">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>A protocol-specific identifier for a blob of content, as used for
          the <tt>identifier</tt> key in a <tp:type>Message_Part</tp:type>. The
          same identifier MAY be re-used if the same content, byte-for-byte,
          appears as a part of several messages.</p>

        <tp:rationale>
          <p>On XMPP, these identifiers might be Content-IDs for custom
            smileys implemented using <a
              href="http://xmpp.org/extensions/xep-0231.html">XEP-0232 Bits of
            Binary</a>; the same smiley might well appear in multiple
            messages.</p>
        </tp:rationale>
      </tp:docstring>
    </tp:simple-type>

    <method name="SendMessage" tp:name-for-bindings="Send_Message">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Submit a message to the server for sending.
          If this method returns successfully, the message has been submitted
          to the server and the <tp:member-ref>MessageSent</tp:member-ref>
          signal is emitted.</p>

        <p>This method MUST return before the MessageSent signal is
          emitted.</p>

        <tp:rationale>
          <p>This means that the process sending the message is the first
            to see the <tp:type>Protocol_Message_Token</tp:type>, and can
            relate the message to the corresponding
            <tp:member-ref>MessageSent</tp:member-ref> signal by comparing
            message tokens (if supported by the protocol).</p>
        </tp:rationale>

        <p>If this method fails, message submission to the server has failed
          and no signal on this interface (or the Text interface) is
          emitted.</p>

        <p>If this method succeeds, message submission to the server has
          succeeded, but the message has not necessarily reached its intended
          recipient. If a delivery failure is detected later, this is
          signalled by receiving a message whose <code>message-type</code>
          header maps to
          <tp:value-ref type="Channel_Text_Message_Type">Delivery_Report</tp:value-ref>.
          Similarly, if delivery is detected to have been successful
          (which is not possible in all protocols), a successful delivery
          report will be signalled.</p>
      </tp:docstring>

      <arg direction="in" type="aa{sv}" tp:type="Message_Part[]"
        name="Message">
        <tp:docstring>
          The message content, including any attachments or alternatives.
          This MUST NOT include the following headers, or any others that
          do not make sense for a client to specify:
          <code>message-sender</code>, <code>message-sender-id</code>,
          <code>message-sent</code>, <code>message-received</code>,
          <code>pending-message-id</code>.
        </tp:docstring>
      </arg>
      <arg direction="in" name="Flags" type="u"
        tp:type="Message_Sending_Flags">
        <tp:docstring>
          Flags affecting how the message is sent. The channel MAY ignore some
          or all flags, depending on
          <tp:member-ref>DeliveryReportingSupport</tp:member-ref>; the flags
          that were handled by the CM are provided in
          <tp:member-ref>MessageSent</tp:member-ref>.
        </tp:docstring>
      </arg>

      <arg direction="out" type="s" tp:type="Protocol_Message_Token"
        name="Token">
        <tp:docstring>
          An opaque token used to match any incoming delivery or failure
          reports against this message, or an empty string if the message
          is not readily identifiable.
        </tp:docstring>
      </arg>

      <tp:possible-errors>
        <tp:error name="im.telepathy.v1.Error.InvalidArgument">
          <tp:docstring>
            The requested message is malformed and cannot be sent.
          </tp:docstring>
        </tp:error>
        <tp:error name="im.telepathy.v1.Error.NotAvailable"/>
        <tp:error name="im.telepathy.v1.Error.PermissionDenied"/>
        <tp:error name="im.telepathy.v1.Error.NetworkError"/>
      </tp:possible-errors>
    </method>

    <tp:flags name="Message_Sending_Flags" value-prefix="Message_Sending_Flag"
      type="u">
      <tp:docstring>
        Flags altering the way a message is sent. The "most usual" action
        should always be to have these flags unset. Some indication of which
        flags are supported is provided by the
        <tp:member-ref>DeliveryReportingSupport</tp:member-ref> property.
      </tp:docstring>

      <tp:flag suffix="Report_Delivery" value="1">
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>Provide a successful delivery report if possible, even if this is
            not the default for this protocol. Ignored if delivery reports are
            not possible on this protocol.</p>

          <tp:rationale>
            <p>In some protocols, like XMPP, it is not conventional to request
              or send positive delivery notifications.</p>
          </tp:rationale>

          <p>Delivery failure reports SHOULD always be sent, but if this flag
            is present, the connection manager MAY also try harder to obtain
            failed delivery reports or allow them to be matched to outgoing
            messages.</p>
        </tp:docstring>
      </tp:flag>

      <tp:flag suffix="Report_Read" value="2">
        <tp:added version="0.19.9"/>
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>Provide a delivery report when the message is read by the
            recipient, even if this is not the default for this protocol.
            Ignored if read reports are not possible on this protocol.</p>
        </tp:docstring>
      </tp:flag>

      <tp:flag suffix="Report_Deleted" value="4">
        <tp:added version="0.19.9"/>
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>Provide a delivery report when the message is deleted by the
            recipient, even if this is not the default for this protocol.
            Ignored if such reports are not possible on this protocol.</p>
        </tp:docstring>
      </tp:flag>
    </tp:flags>

    <signal name="MessageSent" tp:name-for-bindings="Message_Sent">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>Signals that a message has been submitted for sending.</p>

        <p>This SHOULD be emitted as soon as the CM determines it's
          theoretically possible to send the message (e.g. the parameters are
          supported and correct).</p>

        <tp:rationale>
          <p>This signal allows a process that is not the caller of
            SendMessage to log sent messages.</p>
        </tp:rationale>
      </tp:docstring>

      <arg type="aa{sv}" tp:type="Message_Part[]" name="Content">
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>The message content (see <tp:type>Message_Part</tp:type> for full
            details). If the message that was passed to
            <tp:member-ref>SendMessage</tp:member-ref> has a formatted text
            part that the connection manager recognises, but no
            <tt>text/plain</tt> alternative, the CM MUST use the formatted text
            part to generate a <tt>text/plain</tt> alternative which is also
            included in this signal argument.</p>

          <p>The connection manager SHOULD include the
            <code>message-sender</code>, <code>message-sender-id</code> and
            <code>message-sent</code> headers in the representation of the
            message that is signalled here. If the channel has
            channel-specific handles, the <code>message-sender</code> and
            <code>message-sender-id</code> SHOULD reflect the sender that
            other contacts will see.</p>

          <p>If the connection manager can predict that the message will be
            altered during transmission, this argument SHOULD reflect what
            other contacts will receive, rather than being a copy of the
            argument to SendMessage (if the message is truncated,
            formatting or alternatives are dropped, etc., then the edited
            version SHOULD appear in this signal).</p>
        </tp:docstring>
      </arg>

      <arg name="Flags" type="u" tp:type="Message_Sending_Flags">
        <tp:docstring>
          <p>Flags affecting how the message was sent.  The flags might be a
            subset of those passed to SendMessage if the caller requested
            unsupported flags.</p>
        </tp:docstring>
      </arg>

      <arg name="Message_Token" type="s" tp:type="Protocol_Message_Token">
        <tp:docstring>
          An opaque token used to match any incoming delivery or failure
          reports against this message, or an empty string if the message
          is not readily identifiable.
        </tp:docstring>
      </arg>
    </signal>

    <property name="PendingMessages" type="aaa{sv}" access="read"
      tp:type="Message_Part[][]" tp:name-for-bindings="Pending_Messages">
      <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
        <p>A list of incoming messages that have neither been acknowledged nor
          rejected. Its items can be removed using
          <tp:member-ref>AcknowledgePendingMessages</tp:member-ref>.</p>

        <p>Change notification is via
          <tp:member-ref>MessageReceived</tp:member-ref> and
          <tp:member-ref>PendingMessagesRemoved</tp:member-ref>.</p>
      </tp:docstring>
    </property>

    <signal name="PendingMessagesRemoved"
      tp:name-for-bindings="Pending_Messages_Removed">
      <tp:docstring>
        The messages with the given IDs have been removed from the
        <tp:member-ref>PendingMessages</tp:member-ref> list. Clients SHOULD NOT
        attempt to acknowledge those messages.

        <tp:rationale>
          This completes change notification for the PendingMessages property
          (previously, there was change notification when pending messages
          were added, but not when they were removed).
        </tp:rationale>
      </tp:docstring>

      <arg name="Message_IDs" type="au" tp:type="Message_ID[]">
        <tp:docstring>
          The messages that have been removed from the pending message list.
        </tp:docstring>
      </arg>
    </signal>

    <signal name="MessageReceived" tp:name-for-bindings="Message_Received">
      <tp:docstring>
        Signals that a message has been received and added to the pending
        messages queue.
      </tp:docstring>

      <arg type="aa{sv}" tp:type="Message_Part[]" name="Message">
        <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
          <p>The message content, including any attachments or alternatives. If
            the incoming message contains formatted text without a plain text
            alternative, the connection manager MUST generate a
            <tt>text/plain</tt> alternative from the formatted text, and
            include it in this message (both here, and in the
            <tp:member-ref>PendingMessages</tp:member-ref> property).</p>
        </tp:docstring>
      </arg>
    </signal>

    <tp:enum name="Delivery_Status" value-prefix="Delivery_Status"
      plural="Delivery_Statuses" type="u">
      <tp:docstring>
        <p>The status of a message as indicated by a delivery report.</p>

        <p>If this enum is extended in future specifications, this should
          only be to add new, non-overlapping conditions (i.e. all failures
          should still be signalled as either Temporarily_Failed
          or Permanently_Failed). If additional detail is required (e.g.
          distinguishing between the various types of permanent failure) this
          will be done using additional
          <tp:type>Delivery_Report_Header_Key</tp:type>s.</p>
      </tp:docstring>

      <tp:enumvalue suffix="Unknown" value="0">
        <tp:docstring>
          The message's disposition is unknown.
          Clients SHOULD consider all messages to have status
          Delivery_Status_Unknown unless otherwise specified; connection
          managers SHOULD NOT signal this delivery status explicitly.
        </tp:docstring>
      </tp:enumvalue>

      <tp:enumvalue suffix="Delivered" value="1">
        <tp:docstring>
          The message has been delivered to the intended recipient.
        </tp:docstring>
      </tp:enumvalue>

      <tp:enumvalue suffix="Temporarily_Failed" value="2">
        <tp:docstring>
          Delivery of the message has failed. Clients SHOULD notify the user,
          but MAY automatically try sending another copy of the message.

          <tp:rationale>
            Similar to errors with type="wait" in XMPP; analogous to
            4xx errors in SMTP.
          </tp:rationale>
        </tp:docstring>
      </tp:enumvalue>

      <tp:enumvalue suffix="Permanently_Failed" value="3">
        <tp:docstring>
          Delivery of the message has failed. Clients SHOULD NOT try again
          unless by specific user action. If the user does not modify the
          message or alter configuration before re-sending, this error is
          likely to happen again.

          <tp:rationale>
            Similar to errors with type="cancel", type="modify"
            or type="auth" in XMPP; analogous to 5xx errors in SMTP.
          </tp:rationale>
        </tp:docstring>
      </tp:enumvalue>

      <tp:enumvalue suffix="Accepted" value="4">
        <tp:docstring>
          An intermediate server has accepted the message but the message
          has not been yet delivered to the ultimate recipient. The
          connection manager might send a Failed report or Delivered report
          later.

          <tp:rationale>
            Similar to "202 Accepted" success code in SIP; analogous to
            251 and 252 responses in SMTP.
          </tp:rationale>
        </tp:docstring>
      </tp:enumvalue>

      <tp:enumvalue suffix="Read" value="5">
        <tp:added version="0.19.9"/>
        <tp:docstring>
          The message has been read by the intended recipient.
        </tp:docstring>
      </tp:enumvalue>

      <tp:enumvalue suffix="Deleted" value="6">
        <tp:added version="0.19.9"/>
        <tp:docstring>
          The message has been deleted by the intended recipient. This MAY be
          signalled on its own if the message is deleted without being read, or
          after <code>Read</code> if the message was read before being deleted.
        </tp:docstring>
      </tp:enumvalue>
    </tp:enum>

    <tp:flags name="Delivery_Reporting_Support_Flags"
      value-prefix="Delivery_Reporting_Support_Flag" type="u">
      <tp:docstring>
        Flags indicating the level of support for delivery reporting on this
        channel, as found on the
        <tp:member-ref>DeliveryReportingSupport</tp:member-ref> property. Any
        future flags added to this set will conform to the
        convention that the presence of an extra flag implies that
        more operations will succeed. Note that CMs may always provide more
        reports than are requested in the
        <tp:type>Message_Sending_Flags</tp:type> passed to
        <tp:member-ref>SendMessage</tp:member-ref>.

        <tp:rationale>
          If senders want delivery reports, they should ask for them.  If they
          don't want delivery reports, they can just ignore them, so there's no
          need to have capability discovery for what will happen if a delivery
          report isn't requested.
        </tp:rationale>
      </tp:docstring>

      <tp:flag suffix="Receive_Failures" value="1">
        <tp:docstring>
          Clients MAY expect to receive negative delivery reports if
          Message_Sending_Flag_Report_Delivery is specified when sending.
        </tp:docstring>
      </tp:flag>

      <tp:flag suffix="Receive_Successes" value="2">
        <tp:docstring>
          Clients MAY expect to receive positive delivery reports if
          Message_Sending_Flag_Report_Delivery is specified when sending.
        </tp:docstring>
      </tp:flag>

      <tp:flag suffix="Receive_Read" value="4">
        <tp:added version="0.19.9"/>
        <tp:docstring>
          Clients MAY expect to receive <tp:type>Delivery_Status</tp:type>
          <code>Read</code> reports if Message_Sending_Flag_Report_Read
          is specified when sending.
        </tp:docstring>
      </tp:flag>

      <tp:flag suffix="Receive_Deleted" value="8">
        <tp:added version="0.19.9"/>
        <tp:docstring>
          Clients MAY expect to receive <tp:type>Delivery_Status</tp:type>
          <code>Deleted</code> reports if Message_Sending_Flag_Report_Deleted
          is specified when sending.
        </tp:docstring>
      </tp:flag>
    </tp:flags>

    <property name="DeliveryReportingSupport" access="read"
      tp:type="Delivery_Reporting_Support_Flags" type="u"
      tp:name-for-bindings="Delivery_Reporting_Support"
      tp:immutable="yes">
      <tp:docstring>
        A bitfield indicating features supported by this channel.
      </tp:docstring>
    </property>

    <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
      <p>A channel type for sending and receiving messages. This channel type
        is primarily used for textual messages, but can also be used for
        more general messages, including:</p>

      <ul>
        <li>messages with attachments (like MIME multipart/mixed)</li>
        <li>groups of alternatives (like MIME multipart/alternative)</li>
        <li>delivery reports, adding support for protocols where the
          message content is not echoed back to the sender on failure
          and for receiving positive acknowledgements, as well as
          ensuring that incoming delivery reports are not lost if no
          client is handling the channel yet;</li>
        <li>any extra types of message we need in future</li>
      </ul>

      <p>Incoming messages, outgoing messages, and delivery reports are all
        represented as lists of <tp:type>Message_Part</tp:type> structures,
        with a format reminiscent of e-mail.</p>

      <p>When a message is received, an identifier is assigned and a
        <tp:member-ref>MessageReceived</tp:member-ref> signal emitted,
        and the message is placed in a pending queue represented by the
        <tp:member-ref>PendingMessages</tp:member-ref> property.
        When the <tp:dbus-ref
          namespace="im.telepathy.v1.Client">Handler</tp:dbus-ref>
        for a channel has handled the message by showing it to the user
        (or equivalent), it should acknowledge the receipt of that message
        using the <tp:member-ref>AcknowledgePendingMessages</tp:member-ref>
        method, and the message will then be removed from the pending queue.
        Numeric identifiers for received messages may be reused over the
        lifetime of the channel. Only the <tp:dbus-ref
          namespace="im.telepathy.v1.Client">Handler</tp:dbus-ref>
        for a channel should acknowledge messages; <tp:dbus-ref
          namespace="im.telepathy.v1.Client">Observer</tp:dbus-ref>s
        (such as loggers) and <tp:dbus-ref
          namespace="im.telepathy.v1.Client">Approver</tp:dbus-ref>s
        for the channel may listen for incoming messages, and send
        messages of their own, but SHOULD NOT acknowledge messages.</p>

      <tp:rationale>
        <p>If observers were allowed to acknowledge messages, then messages
          might have been acknowledged before the handler even got to see the
          channel, and hence could not be shown to the user.</p>
      </tp:rationale>

      <p>Sending messages can be requested using the
        <tp:member-ref>SendMessage</tp:member-ref> method, which will return
        successfully when the message has been submitted for sending, or
        return an error with no signal emission if there is an immediate
        failure. If a message is submitted for sending but delivery of the
        message later fails, this is indicated by a delivery report, which
        is received in the same way as an incoming message. Outgoing
        messages are announced to other clients which may be
        interested in the channel by the
        <tp:member-ref>MessageSent</tp:member-ref> signal.</p>

      <p>Simple one-to-one chats (such as streams of private messages in
        XMPP or IRC) should be represented by a Text channel whose
        <tp:dbus-ref namespace="imt1.Channel">TargetEntityType</tp:dbus-ref>
        is <tp:value-ref type="Entity_Type">Contact</tp:value-ref>. The
        expected way to request such a channel is to set the <tp:dbus-ref
        namespace='imt1.Channel'>ChannelType</tp:dbus-ref>, <tp:dbus-ref
        namespace='imt1.Channel'>TargetEntityType</tp:dbus-ref>,
        and either <tp:dbus-ref
        namespace='imt1.Channel'>TargetHandle</tp:dbus-ref> or <tp:dbus-ref
        namespace='imt1.Channel'>TargetID</tp:dbus-ref> in a call to
        <tp:dbus-ref
        namespace='imt1.ChannelDispatcher'>EnsureChannel</tp:dbus-ref>.</p>

      <p>Named chat rooms whose identity can be saved and used again later
        (IRC channels, Jabber MUCs) are expected to be represented by Text
        channels with <tp:dbus-ref
        namespace="imt1.Channel">TargetEntityType</tp:dbus-ref> =
        <tp:value-ref type="Entity_Type">Room</tp:value-ref> and the
        <tp:dbus-ref namespace="imt1.Channel.Interface">Group1</tp:dbus-ref>
        interface. In protocols where a chatroom can be used as a continuation
        of one or more one-to-one chats, these channels should also have the
        <tp:dbus-ref namespace="imt1.Channel.Interface">Conference1</tp:dbus-ref>
        interface.</p>

      <p>Unnamed, transient chat rooms which cannot be rejoined by their
        unique identifier (e.g. a conversation on MSN which has, or once had,
        three or more participants) are expected to be represented by Text
        channels with <tp:dbus-ref
        namespace="imt1.Channel">TargetEntityType</tp:dbus-ref> = <tp:value-ref
        type="Entity_Type">None</tp:value-ref> (and hence <tp:dbus-ref
        namespace="imt1.Channel">TargetHandle</tp:dbus-ref> = 0),
        <tp:dbus-ref namespace="imt1.Channel.Interface">Group1</tp:dbus-ref>
        interface, and optionally the
        <tp:dbus-ref namespace="imt1.Channel.Interface">Conference1</tp:dbus-ref>
        interface.</p>

      <p>On protocols like MSN where a conversation with a user is actually
        just a nameless chat room starting with exactly two members, to which
        more members can be invited, the initial one-to-one conversation
        SHOULD be represented with <tp:dbus-ref
        namespace="imt1.Channel">TargetEntityType</tp:dbus-ref> =
        <tp:value-ref type="Entity_Type">Contact</tp:value-ref>. If a third
        participant
        joins or is invited, this SHOULD be represented by signalling
        a new <tp:dbus-ref
          namespace="imt1.Channel.Interface">Conference1</tp:dbus-ref> channel
        with the one-to-one channel in its <tp:dbus-ref
          namespace="imt1.Channel.Interface.Conference1"
          >InitialChannels</tp:dbus-ref>, migrating the underlying protocol
        object from the one-to-one channel to the Conference channel,
        and creating a new protocol-level conversation if the one-to-one
        channel is re-used. See the Conference interface for more details.</p>

      <tp:rationale>
        <p>This keeps the presentation of all one-to-one conversations
          uniform, and makes it easier to hand over a conversation from a
          1-1-specific UI to a more elaborate multi-user UI; while it does
          require UIs to understand Conference to follow the
          upgrade, UIs that will deal with XMPP need to understand Conference
          anyway.</p>
      </tp:rationale>

      <p>If a channel of type Text is closed while it has pending messages,
        the connection manager MUST allow this, but SHOULD open a new channel
        to deliver those messages, signalling it as a new channel with the
        <tp:dbus-ref
          namespace="imt1.Connection.Interface.Requests">NewChannel</tp:dbus-ref>
        signal. The new channel should resemble the old channel, but have
        <tp:dbus-ref namespace='imt1.Channel'>Requested</tp:dbus-ref> = FALSE
        regardless of its previous value; the <tp:dbus-ref
        namespace='imt1.Channel'>InitiatorHandle</tp:dbus-ref>
        and <tp:dbus-ref namespace='imt1.Channel'>InitiatorID</tp:dbus-ref>
        should correspond to the sender of one of the pending
        messages.</p>

      <tp:rationale>
        <p>In effect, this turns this situation, in which a client
          is likely to lose messages:</p>

        <ul>
          <li>UI window is closed</li>
          <li>message arrives</li>
          <li>text channel emits Received</li>
          <li>UI calls Close on text channel before it has seen the
            Received signal</li>
          <li>text channel emits Closed and closes</li>
        </ul>

        <p>into something nearly equivalent to this situation, which is
          fine:</p>

        <ul>
          <li>UI window is closed</li>
          <li>UI calls Close on text channel</li>
          <li>text channel emits Closed and closes</li>
          <li>message arrives</li>
          <li>new text channel is created, connection emits NewChannel</li>
          <li>(the same or a different) UI handles it</li>
        </ul>

        <p>Requested must be set to FALSE so the replacement channel
          will be handled by something.</p>

        <p>In practice, connection managers usually implement this by keeping
          the same internal object that represented the old channel, adjusting
          its properties, signalling that it was closed, then immediately
          re-signalling it as a new channel.</p>
      </tp:rationale>

      <p>As a result, Text channels SHOULD implement <tp:dbus-ref
          namespace="imt1">Channel.Interface.Destroyable1</tp:dbus-ref>.</p>

      <tp:rationale>
        <p>This "respawning" behaviour becomes problematic if there is no
          suitable handler for Text channels, or if a particular message
          repeatedly crashes the Text channel handler; a channel dispatcher
          can't just Close() the channel in these situations, because
          it will come back.</p>

        <p>In these situations, the channel dispatcher needs a last-resort
          way to destroy the channel and stop it respawning. It could either
          acknowledge the messages itself, or use the Destroyable interface;
          the Destroyable interface has the advantage that it's not
          channel-type-dependent, so the channel dispatcher only has to
          understand one extra interface, however many channel types
          eventually need a distinction between Close and Destroy.</p>
      </tp:rationale>

      <p>Opaquely-named rejoinable chatrooms (such as Skype rooms) are
        represented using the properties in the <tp:dbus-ref
        namespace="imt1.Channel.Interface">Room1</tp:dbus-ref>
        interface. Instructions and examples of how to request
        such channels are given in said interface's description.</p>

      <p>Although this specification supports formatted (rich-text)
        messages with unformatted alternatives, implementations SHOULD NOT
        attempt to send formatted messages until the Telepathy specification
        has also been extended to cover capability discovery for message
        formatting.</p>

      <tp:rationale>
        We intend to expose all rich-text messages as XHTML-IM, but on some
        protocols, formatting is an extremely limited subset of that format
        (e.g. there are protocols where foreground/background colours, font
        and size can be set, but only for entire messages).
        Until we can tell UIs what controls to offer to the user, it's
        unfriendly to offer the user controls that may have no effect.
      </tp:rationale>
    </tp:docstring>
  </interface>
</node>
<!-- vim:set sw=2 sts=2 et ft=xml: -->