# Timeline: update

**Requires [authorization](https://developers.google.com/glass/v1/reference/timeline/update#auth)**

Updates a timeline item in place.
[See an example](https://developers.google.com/glass/v1/reference/timeline/update#examples).

This method supports an **/upload** URI and accepts uploaded media with the following characteristics:

- **Maximum file size:** 10MB
- **Accepted Media MIME types:** `audio/*` , `image/*` , `video/*`

## Request

### HTTP request

This method provides media upload functionality through two separate URIs. For more details, see the document on [media upload](https://developers.google.com/glass/media-upload).

- Upload URI, for media upload requests:

  ```
  PUT https://www.googleapis.com/upload/mirror/v1/timeline/id
  ```
- Metadata URI, for metadata-only requests:

  ```
  PUT https://www.googleapis.com/mirror/v1/timeline/id
  ```

### Parameters

| Parameter name | Value | Description |
|---|---|---|
| **Path parameters** |||
| `id` | `string` | The ID of the timeline item. |
| **Required query parameters** |||
| `uploadType` | `string` | The type of upload request to the **/upload** URI. Acceptable values are: - `media` - [Simple upload](https://developers.google.com/glass/media-upload#simple). Upload the media only, without any metadata. - `multipart` - [Multipart upload](https://developers.google.com/glass/media-upload#multipart). Upload both the media and its metadata, in a single request. - `resumable` - [Resumable upload](https://developers.google.com/glass/media-upload#resumable). Upload the file in a resumable fashion, using a series of at least two requests where the first request includes the metadata. |

### Authorization

This request requires authorization with at least one of the following scopes ([read more about authentication and authorization](https://developers.google.com/glass/authorization)).

| Scope |
|---|
| `https://www.googleapis.com/auth/glass.timeline` |
| `https://www.googleapis.com/auth/glass.location` |

### Request body

In the request body, supply a Timeline resource with the following properties as the metadata. For more information, see the document on [media upload](https://developers.google.com/glass/media-upload).

| Property name | Value | Description | Notes |
|---|---|---|---|
| **Optional Properties** ||||
| `bundleId` | `string` | The bundle ID for this item. Services can specify a bundleId to group many items together. They appear under a single top-level item on the device. | writable |
| `canonicalUrl` | `string` | A canonical URL pointing to the canonical/high quality version of the data represented by the timeline item. | writable |
| `creator` | `nested object` | The user or group that created this item. | writable |
| `displayTime` | `datetime` | The time that should be displayed when this item is viewed in the timeline, formatted according to RFC 3339. This user's timeline is sorted chronologically on display time, so this will also determine where the item is displayed in the timeline. If not set by the service, the display time defaults to the `updated` time. | writable |
| `html` | `string` | HTML content for this item. If both `text` and `html` are provided for an item, the `html` will be rendered in the timeline. **Allowed HTML elements** - You can use these elements in your timeline cards. - Headers: `h1, h2, h3, h4, h5, h6` - Images: `img` - Lists: `li, ol, ul` - HTML5 semantics: `article, aside, details, figure, figcaption, footer, header, nav, section, summary, time` - Structural: `blockquote, br, div, hr, p, span` - Style: `b, big, center, em, i, u, s, small, strike, strong, style, sub, sup` - Tables: `table, tbody, td, tfoot, th, thead, tr` **Blocked HTML elements**: These elements and their contents are removed from HTML payloads. - Document headers: `head, title` - Embeds: `audio, embed, object, source, video` - Frames: `frame, frameset` - Scripting: `applet, script` **Other elements**: Any elements that aren't listed are removed, but their contents are preserved. | writable |
| `isBundleCover` | `boolean` | Whether this item is a bundle cover. If an item is marked as a bundle cover, it will be the entry point to the bundle of items that have the same `bundleId` as that item. It will be shown only on the main timeline --- **not within the opened bundle** . On the main timeline, items that are shown are: - Items that have `isBundleCover` set to `true` - Items that do not have a `bundleId` In a bundle sub-timeline, items that are shown are: <!-- --> - Items that have the `bundleId` in question **AND** `isBundleCover` set to `false` | writable |
| `location` | `nested object` | The geographic location associated with this item. | writable |
| `menuItems[]` | `list` | A list of menu items that will be presented to the user when this item is selected in the timeline. | writable |
| `menuItems[].action` | `string` | Controls the behavior when the user picks the menu option. Allowed values are: - `CUSTOM` - Custom action set by the service. When the user selects this `menuItem`, the API triggers a notification to your [`callbackUrl`](https://developers.google.com/glass/subscriptions) with the [`userActions.type`](https://developers.google.com/glass/reference/subscriptions#notification.userActions.type) set to `CUSTOM` and the [`userActions.payload`](https://developers.google.com/glass/reference/subscriptions#notification.userActions.payload) set to the `ID` of this menu item. This is the default value. - Built-in actions: - `REPLY` - Initiate a reply to the timeline item using the voice recording UI. The `creator` attribute must be set in the timeline item for this menu to be available. - `REPLY_ALL` - Same behavior as `REPLY`. The original timeline item's `recipients` will be added to the reply item. - `DELETE` - Delete the timeline item. - `SHARE` - Share the timeline item with the available contacts. - `READ_ALOUD` - Read the timeline item's `speakableText` aloud; if this field is not set, read the `text` field; if none of those fields are set, this menu item is ignored. - `GET_MEDIA_INPUT` - Allow users to provide media payloads to Glassware from a menu item (currently, only transcribed text from voice input is supported). Subscribe to notifications when users invoke this menu item to receive the timeline item ID. Retrieve the media from the timeline item in the [payload](https://developers.google.com/glass/reference/timeline/insert#menuItems.payload) property. - `VOICE_CALL` - Initiate a phone call using the timeline item's `creator.phoneNumber` attribute as recipient. - `NAVIGATE` - Navigate to the timeline item's `location`. - `TOGGLE_PINNED` - Toggle the `isPinned` state of the timeline item. - `OPEN_URI` - Open the `payload` of the menu item in the browser. - `PLAY_VIDEO` - Open the `payload` of the menu item in the Glass video player. - `SEND_MESSAGE` - Initiate sending a message to the timeline item's `creator`: - If the `creator.phoneNumber` is set and Glass is connected to an Android phone, the message is an SMS. - Otherwise, if the `creator.email` is set, the message is an email. | writable |
| `menuItems[].id` | `string` | The ID for this menu item. This is generated by the application and is treated as an opaque token. | writable |
| `menuItems[].payload` | `string` | A generic payload whose meaning changes depending on this MenuItem's action. - When the action is `OPEN_URI`, the payload is the URL of the website to view. - When the action is `PLAY_VIDEO`, the payload is the streaming URL of the video - When the action is `GET_MEDIA_INPUT`, the payload is the text transcription of a user's speech input | writable |
| `menuItems[].removeWhenSelected` | `boolean` | If set to true on a `CUSTOM` menu item, that item will be removed from the menu after it is selected. | writable |
| `menuItems[].values[]` | `list` | For `CUSTOM` items, a list of values controlling the appearance of the menu item in each of its states. A value for the `DEFAULT` state must be provided. If the `PENDING` or `CONFIRMED` states are missing, they will not be shown. | writable |
| `menuItems[].values[].displayName` | `string` | The name to display for the menu item. If you specify this property for a built-in menu item, the default contextual voice command for that menu item is not shown. | writable |
| `menuItems[].values[].iconUrl` | `string` | URL of an icon to display with the menu item. | writable |
| `menuItems[].values[].state` | `string` | The state that this value applies to. Allowed values are: - `DEFAULT` - Default value shown when displayed in the `menuItems` list. - `PENDING` - Value shown when the `menuItem` has been selected by the user but can still be cancelled. - `CONFIRMED` - Value shown when the menuItem has been selected by the user and can no longer be cancelled. | writable |
| `notification` | `nested object` | Controls how notifications for this item are presented on the device. If this is missing, no notification will be generated. | writable |
| `notification.deliveryTime` | `datetime` | The time at which the notification should be delivered. | writable |
| `notification.level` | `string` | Describes how important the notification is. Allowed values are: - `DEFAULT` - Notifications of default importance. A chime will be played to alert users. | writable |
| `recipients[]` | `list` | A list of users or groups that this item has been shared with. | writable |
| `sourceItemId` | `string` | Opaque string you can use to map a timeline item to data in your own service. | writable |
| `speakableText` | `string` | The speakable version of the content of this item. Along with the `READ_ALOUD` menu item, use this field to provide text that would be clearer when read aloud, or to provide extended information to what is displayed visually on Glass. Glassware should also specify the speakableType field, which will be spoken before this text in cases where the additional context is useful, for example when the user requests that the item be read aloud following a notification. | writable |
| `speakableType` | `string` | A speakable description of the type of this item. This will be announced to the user prior to reading the content of the item in cases where the additional context is useful, for example when the user requests that the item be read aloud following a notification. This should be a short, simple noun phrase such as "Email", "Text message", or "Daily Planet News Update". Glassware are encouraged to populate this field for every timeline item, even if the item does not contain speakableText or text so that the user can learn the type of the item without looking at the screen. | writable |
| `text` | `string` | Text content of this item. | writable |
| `title` | `string` | The title of this item. | writable |

## Response

If successful, this method returns a [Timeline resource](https://developers.google.com/glass/v1/reference/timeline#resource) in the response body.

## Examples

**Note:** The code examples available for this method do not represent all supported programming languages (see the [client libraries page](https://developers.google.com/glass/tools-downloads/client-libraries) for a list of supported languages).

### Java

Uses the [Java client library](https://developers.google.com/glass/tools-downloads/client-libraries).

```java
import com.google.api.services.mirror.Mirror;
import com.google.api.services.mirror.model.NotificationConfig;
import com.google.api.services.mirror.model.TimelineItem;

import java.io.IOException;

public class MyClass {
  // ...

  /**
   * Update a timeline item in the user's Glass with an optional notification and attachment.
   * 
   * @param service Authorized Mirror service.
   * @param itemId ID of the timeline item to update.
   * @param newText timeline item's text.
   * @param newNotificationLevel Optional notification level, supported values
   *        are {@code null} and "AUDIO_ONLY".
   * @return Updated timeline item on success, {@code null} otherwise.
   */
  public static TimelineItem updateTimelineItem(Mirror service, String itemId, String newText,
      String newNotificationLevel) {
    try {
      // First retrieve the timeline item from the API.
      TimelineItem timelineItem = service.timeline().get(itemId).execute();
      // Update the timeline item's metadata.
      timelineItem.setText(newText);
      if (newNotificationLevel != null && newNotificationLevel.length() > 0) {
        timelineItem.setNotification(new NotificationConfig().setLevel(newNotificationLevel));
      } else {
        timelineItem.setNotification(null);
      }
      return service.timeline().update(itemId, timelineItem).execute();
    } catch (IOException e) {
      System.err.println("An error occurred: " + e);
      return null;
    }
  }

  // ...
}
```

### .NET

Uses the [.NET client library](https://developers.google.com/glass/tools-downloads/client-libraries).

```
using System;
using System.IO;

using Google.Apis.Mirror.v1;
using Google.Apis.Mirror.v1.Data;

public class MyClass {
  // ...

  /// <summary>
  /// Update a timeline item in the user's Glass with an optional
  /// notification and attachment.
  /// </summary>
  /// <param name='service'>Authorized Mirror service.</param>
  /// <param name='itemId'>ID of the timeline item to update.</param>
  /// <param name='newText'>Timeline Item's text content.</param>
  /// <param name='newNotificationLevel'>
  /// Optional notification level, supported values are null and
  /// "AUDIO_ONLY".
  /// </param>
  /// <returns>
  /// Updated timeline item on success, null otherwise.
  /// </returns>
  public static TimelineItem UpdateTimelineItem(MirrorService service,
      String itemId, String newText, String newNotificationLevel) {
    try {
      // First retrieve the timeline item from the API.
      TimelineItem timelineItem = service.Timeline.Get(itemId).Fetch();
      // Update the timeline item's metadata.
      timelineItem.Text = newText;
      if (!String.IsNullOrEmpty(newNotificationLevel)) {
        timelineItem.Notification = new NotificationConfig() {
          Level = newNotificationLevel
        };
      } else {
        timelineItem.Notification = null;
      }
      return service.Timeline.Update(timelineItem, itemId).Fetch();
    } catch (Exception e) {
      Console.WriteLine("An error occurred: " + e.Message);
      return null;
    }
  }

  // ...
}
```

### PHP

Uses the [PHP client library](https://developers.google.com/glass/tools-downloads/client-libraries).

```php
/**
 * Update a timeline item in the user's Glass with an optional
 * notification and attachment.
 *
 * @param Google_MirrorSservice $service Authorized Mirror service.
 * @param string $itemId ID of the timeline item to update.
 * @param string $newText timeline item's text (can be HTML content).
 * @param string $newNotificationLevel Optional notification level,
 *               supported values are {@code null} and "AUDIO_ONLY".
 * @return Google_TimelineItem Updated timeline item on success,
 *         null otherwise.
 */
function updateTimelineItem($service, $itemId, $newText, $newNotificationLevel) {
  try {
    $timelineItem = $service->timeline->get($itemId);
    $timelineItem->setText($newText);
    if ($notificationlevel != null) {
      $notification = new Google_NotificationConfig();
      $notification->setLevel($newNotificationLevel);
      $timelineItem->setNotification($notification);
    } else {
      $timelineItem->setNotification(null);
    }
    return $service->timeline->update($itemId, $timelineItem);
  } catch (Exception $e) {
    print 'An error occurred: ' . $e->getMessage();
    return null;
  }
}
```

### Python

Uses the [Python client library](https://developers.google.com/glass/tools-downloads/client-libraries).

```python
import io

from apiclient import errors
from apiclient.http import MediaIoBaseUpload
# ...

def update_timeline_item(service, item_id, new_text, 
                         new_notification_level=None):
  """Update a timeline item in the user's Glass.

  Args:
    service: Authorized Mirror service.
    item_id: ID of the timeline item to update.
    new_text: Timeline item's text (can be HTML content).
    new_content_type: Optional attachment's content type (supported content
                      types are 'image/*', 'video/*' and 'audio/*').
    new_attachment: Optional attachment as data string.
    new_notification_level: Optional notification level, supported values are
                            None and 'AUDIO_ONLY'.
  Returns:
    Updated timeline item on success, None otherwise.
  """
  try:
    # First retrieve the timeline item from the API.
    timeline_item = service.timeline().get(id=item_id).execute()
    # Update the timeline item's metadata.
    timeline_item['text'] = new_text
    if new_notification_level:
      timeline_item['notification'] = {'level': new_notification_level}
    elif 'notification' in timeline_item:
      timeline_item.pop('notification')
    return service.timeline().update(id=item_id, body=timeline_item).execute()
  except errors.HttpError, error:
    print 'An error occurred: %s' % error
    return None
```

### Ruby

Uses the [Ruby client library](https://developers.google.com/glass/tools-downloads/client-libraries).

```ruby
##
# Update a timeline item in the user's glass.
#
# @param [Google::APIClient] client
#   Authorized client instance.
# @param [String] item_id
#   ID of the timeline item to update.
# @param [String] new_text
#   Timeline item's new text.
# @param [String] new_notification_level
#   Optional new notification level, supported values are nil and 'AUDIO_ONLY'.
# @return [Google::APIClient::Schema::Mirror::V1::TimelineItem]
#   Updated timeline item instance if successful, nil otherwise.
def update_timeline_item(client, item_id, new_text, new_notification_level)
  mirror = client.discovered_api('mirror', 'v1')
  result = client.execute(
    :api_method => mirror.timeline.get,
    :parameters => { 'id' => item_id })
  if result.success?
    timeline_item = result.data
    timeline_item.text = new_text
    if new_notification_level
      timeline_item.notification = { 'level' => new_notification_level }
    else
      timeline_item.notification = nil
    end
    result = client.execute(
      :api_method => mirror.timeline.update,
      :body_object => timeline_item,
      :parameters => { 'id' => item_id })
    if result.success?
      return result.data
    end
  end
  puts "An error occurred: #{result.data['error']['message']}"
end
```

### Go

Uses the [Go client library](https://developers.google.com/glass/tools-downloads/client-libraries).

```go
import (
	"code.google.com/p/google-api-go-client/mirror/v1"
	"fmt"
)

// UpdateTimelineItem updates a timeline item in the user's timeline with an
// optional notification and attachment.
func UpdateTimelineItem(g *mirror.Service, itemId string, newNotificationLevel string) (
	*mirror.TimelineItem, error) {
	t, err := g.Timeline.Get(itemId).Do()
	if err != nil {
		fmt.Printf("An error occurred: %v\n", err)
		return nil, err
	}
	t.Text = newText
	if newNotificationLevel != "" {
		t.Notification = &mirror.NotificationConfig{Level: newNotificationLevel}
	} else {
		t.Notification = nil
	}
	r, err := g.Timeline.Update(itemId, t).Do()
	if err != nil {
		fmt.Printf("An error occurred: %v\n", err)
		return nil, err
	}
	return r, nil
}
```

### Raw HTTP

Does not use a client library.

```
PUT /mirror/v1/timeline/timeline item id HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer auth token
Content-Type: application/json
Content-Length: 26

{ "text": "Hello world" }
```