Canny Source

Ingest your event data from Canny into RudderStack.

Canny is a customer feedback management tool which captures, organizes, and analyzes product feedback in one place to help you make informed product decisions.

This guide will help you set up Canny as a source in RudderStack.

Get started

  1. Go to your RudderStack dashboard and click Add Source. From the list of Event Streams sources, select Canny.
  2. Assign a name to your source and click Continue.
  3. Your Canny source is now configured. Go to the Settings tab of the source and note the Webhook URL:
Canny source webhook URL
  1. Log in to your Canny account. In the top-right side, select the Settings option under your profile followed by API & Webhooks.
  2. Enter the Webhook URL under Webhooks section:
Canny source webhook URL
  1. Click Add.

Event transformation

RudderStack ingests the Canny events after converting them into the RudderStack event format. It also maps the following properties from the Canny event payload to the RudderStack properties:

Canny propertyRudderStack propertyNotes
createdtimestamp,originalTimestamp-
objectpropertiesRudderStack excludes author/voter from the properties.
objectTypeproperties.objectType-
typeevent-
object.authorcontext.traitsRudderStack excludes userId and id.
object.author.userIduserId-
SHA-256 hash of object.author.emailanonymousIdOnly if userId is not present
SHA-256 hash of object.voter.emailanonymousIdOnly if userId is not present and type is vote.created/vote.deleted
object.voter.userIduserIdOnly if type is vote.created/vote.deleted
object.voter.idcontext.externalId[0].valueOnly if type is vote.created/vote.deleted
cannyUserIdcontext.externalId[0].type-
object.author.idcontext.externalId[0].id-

Canny supports ingesting the following events:

Canny eventsDescription
post.createdOccurs when a new post is created.
post.deletedOccurs when a post is deleted.
post.jira_issue_linkedOccurs when a Jira issue is linked to a post.
post.jira_issue_unlinkedOccurs when a Jira issue is unlinked from a post.
post.status_changedOccurs when a post’s status is changed.
comment.createdOccurs when a new comment is created.
comment.deletedOccurs when a comment is deleted.
vote.createdOccurs when a user votes on a post.
vote.deletedOccurs when a user unvotes on a post.

How RudderStack creates the event payload

This section details how RudderStack receives the data from Canny source and creates the resulting payload.

A sample payload sent by Canny is shown below:

{
    "created": "2022-07-28T10:52:46.294Z",
    "object": {
        "author": {
            "created": "2022-07-15T11:16:32.648Z",
            "email": "alex@example.com",
            "id": "1hKOmRA4el9Zt1WSfVJIVo4GRlm",
            "isAdmin": true,
            "name": "Alex Keener",
            "url": "https://rudder.canny.io/admin/users/alex-keener",
            "userID": null
        },
        "board": {
            "created": "2022-07-25T12:11:19.895Z",
            "id": "VJIVo4GRlm",
            "name": "features",
            "postCount": 13,
            "url": "https://rudder.canny.io/admin/board/features"
        },
        "by": null,
        "category": null,
        "commentCount": 0,
        "created": "2022-07-28T10:52:46.172Z",
        "customFields": [{
            "id": "62e1382",
            "name": "John",
            "value": "123"
        }],
        "details": "Array of images",
        "eta": null,
        "id": "62e26a",
        "imageURLs": [
            "https://canny.io/images/6371453a825c79351c52a6063c3af476.jpg",
            "https://canny.io/images/47db6ee5035bfb45ea87a74f2eb17928.jpg"
        ],
        "owner": null,
        "score": 1,
        "status": "open",
        "tags": [],
        "title": "Custom Fields Testing",
        "url": "https://rudder.canny.io/admin/board/features/p/custom-fields-testing"
    },
    "objectType": "post",
    "type": "post.created"
}

RudderStack transforms the above payload into the following payload:

{
    "anonymousId": "d6a9d06e8a464324d448003ff0467d971a55ca2950e11fc51faaec4e2850ecc6",
    "event": "post.created",
    "integrations": {
        "Canny": false
    },
    "context": {
        "library": {
            "name": "unknown",
            "version": "unknown"
        },
        "integration": {
            "name": "Canny",
            "version": "1.0.0"
        },
        "traits": {
        "created": "2022-07-15T11:16:32.648Z",
        "email": "alex@example.com",
        "isAdmin": true,
        "name": "Alexx Keener",
        "url": "https://rudder.canny.io/admin/users/alex-keener"
      },
        "externalId": [{
            "type": "cannyUserId",
            "id": "1hKOmRA4el9Zt1WSfVJIVo4GRlm"
        }]
    },
    "timestamp": "2022-07-28T10:52:46.294Z",
    "originalTimestamp": "2022-07-28T10:52:46.294Z",
    "type": "track",
    "properties": {
        "board": {
            "created": "2022-07-25T12:11:19.895Z",
            "id": "VJIVo4GRlm",
            "name": "features",
            "postCount": 13,
            "url": "https://rudder.canny.io/admin/board/features"
        },
        "by": null,
        "category": null,
        "commentCount": 0,
        "created": "2022-07-28T10:52:46.172Z",
        "customFields": [{
            "id": "62e1382",
            "name": "abc",
            "value": "123"
        }],
        "details": "Array of images",
        "eta": null,
        "id": "62e26a",
        "imageURLs": [
            "https://canny.io/images/6371453a825c79351c52a6063c3af476.jpg",
            "https://canny.io/images/47db6ee5035bfb45ea87a74f2eb17928.jpg"
        ],
        "objectType": "post",
        "owner": null,
        "score": 1,
        "status": "open",
        "tags": [],
        "title": "Custom Fields Testing",
        "url": "https://rudder.canny.io/admin/board/features/p/custom-fields-testing"
    }
}

Questions? Contact us by email or on Slack