Skip to main content

Powerlink (Fireberry)

Powerlink — also branded Fireberry — is an Israeli CRM. This page documents Texter’s Powerlink adapter (func_type: crm): params, crmConfig, and what lands on crmData.

Official doc hubs (for deeper reference):

Field names and queries

Use the API field names from the customer’s org (often lowercase: accountname, telephone1, statuscode, custom pcfsystemfield…). In query bodies, string literals must use single quotes — see the Rest-API Query section and the adapter’s customQuery comment.


Powerlink’s REST API uses a numeric object type in the path (GitHub README — Create / Update; see also Fireberry REST API for the current product reference):

  • Create: POST https://api.powerlink.co.il/api/record/{ObjectType} with a JSON body of field names → values.
  • Update: PUT https://api.powerlink.co.il/api/record/{ObjectType}/{id} with the fields to patch.
  • Read (search): POST https://api.powerlink.co.il/api/query with objecttype, query, fields, paging — not the same as /record/{n}, but objecttype uses the same numbering.

Documented examples in the README include Account = 1, Contact = 2, Cases = 5. The Texter adapter also uses these object types in code:

ObjectTypeEntity (typical)Used in adapter
1AccountnewAccount, changeStatus, lookups, assignChat
2ContactContact query; newAccount creates/finds contact via createContact helper
4OpportunitynewOpportunity
5Case (ticket)openTicket
7Note / activityaddActivity, syncActivityData (notes)
9Users (system users)addActivity, assignChat (load users by email)
10TaskopenTask, closeTicket

And more. Custom entities use other numbers (e.g. 1000+) — your customer’s Powerlink admin / API docs list them.


CRM config (crmConfig)

These values are set once per customer environment (not in public bot YAML). token is required for all API calls. The customer creates or copies the TokenID in Fireberry/Powerlink under Settings → Tools → API forms (direct link).

FieldRequiredDefault (if unset)Use
tokenYesTokenID header for https://api.powerlink.co.il/.... Obtained in-app: Settings → Tools → API forms.
inboxUrlYesBase URL for Texter Inbox links inside description / task text (newOpportunity, openTicket, openTask, closeTicket).
idFieldNoMaps a custom Account field to what Texter shows as ID in the CRM panel.
showDuplicatesNofalseIf true, may append a duplicate marker to crmData.phone when multiple matches exist.
displayExistingDataNoIf true and dataFields is set, getCustomerDetails can still succeed when Powerlink finds no account/contact — see below.
dataFieldsNoUsed with displayExistingData: maps contact.crmData paths → CRM panel fields — see below.
contactQueryFieldsNomobilephone1, mobilephone2, telephone1Array of phone fields used in contact query.
accountQueryFieldsNotelephone1Array of phone fields used in account query.
accountFieldsNo*Field list for the account query.
originatingLeadCodeNo5New account (newAccount).
newAccountStatusCodeNo0New account statuscode.
taskTypeCodeNo6openTask / closeTicket tasktypecode.

displayExistingData and dataFields

Normally getCustomerDetails fails when no Account or Contact matches the chat phone. If displayExistingData is true and dataFields is an object, the adapter does not treat that as failure: it builds crmData from whatever is already on the chat’s contact.crmData (e.g. values saved earlier in the flow or from another integration).

dataFields is not a list of Powerlink API names. It has exactly four keysname, phone, id, accountId — and each value is a path into contact.crmData (lodash-style, so dotted paths work for nested keys). The adapter reads those paths and fills the CRM panel’s name, phone, id, and account id. If accountId resolves to a value, a deepLink to that Powerlink account is added.

Fallbacks: missing name → chat title; missing phone → chat E.164 phone; missing id / accountId → empty string.

Example (customer env JSON — not bot YAML):
if contact.crmData might look like

{ "customer_display_name": "…", "wa_phone": "…", "loyalty_number": "…", "pl_account_guid": "…" }

you could set:

"displayExistingData": true,
"dataFields": {
"name": "customer_display_name",
"phone": "wa_phone",
"id": "loyalty_number",
"accountId": "pl_account_guid"
}

Adapter functions

getCustomerDetails

Finds the account (and if needed the contact) for the chat’s phone: runs POST /api/query on accounts (object type 1) using phone variants on accountQueryFields, then contacts (type 2) if no account match.

When it runs: From bot YAML, and the CRM panel in the Texter UI can rely on the same kind of lookup when a chat is opened (phone must be present on the chat).

Basic

  powerlink_lookup:
type: func
func_type: crm
func_id: getCustomerDetails
on_complete: known_customer
on_failure: unknown_customer
ParamRequiredNotes
(none)Uses the chat’s E.164 phone only.

Result: success drives on_complete / on_failure. On match: exist, crmAccount, full crmData from Powerlink (+ id if idField). If no match but displayExistingData + dataFields: success with a small crmData only (see above). Else success: false.


newOpportunity

Creates an Opportunity (POST /api/record/4). If there is no crmData.accountid, an account is created first (minimal fields from chat + crmConfig; this step does not use this op’s params). Then params are merged into the opportunity body (same key in YAML replaces the default; values are stringified).

Most fields have sensible defaults — only pass params to override specific values.

FieldCodecrmConfigparams
nameפנייה מהווצאפ + chat titleYes
statuscode1Yes
descriptionChat messages + newline + Inbox linkinboxUrl (in link)Yes
accountidAfter create / from chatYes
Other Powerlink fieldsYes (e.g. pcfsystemfield…)

When it runs: e.g. logging a lead after intake.

Basic

  powerlink_new_opp:
type: func
func_type: crm
func_id: newOpportunity
on_complete: lead_logged
on_failure: lead_failed
ParamRequiredNotes
(any)NoOpportunity (type 4) fields.

Result: crmData.opportunityid, crmLastTicketId, crmLastObjectType (4) so later openTask / closeTicket can attach to the same “last object” chain.

Advanced

  powerlink_new_opp_with_fields:
type: func
func_type: crm
func_id: newOpportunity
params:
pcfsystemfield100: "WhatsApp"
on_complete: lead_logged

customQuery

Runs POST /api/query with a free-form query string (operators AND, OR, =, etc. — README query table) and an objecttype. Use this when getCustomerDetails is not enough: list rows of any entity, filter by fields, paginate (adapter uses page_size 50, page_number 1).

Basic

  powerlink_query:
type: func
func_type: crm
func_id: customQuery
params:
objectTypeCode: 1
query: "(telephone1 = '0500000000')"
fields: "*"
resultKey: "myRows"
on_complete: next_step
ParamRequiredNotes
queryYesPowerlink query; strings in single quotes per adapter + API expectations.
objectTypeCodeYesNumber (YAML: 1 not "1").
fieldsNoDefault *.
resultKeyNoKey on crmData for data.Data (default customQueryResult).

Result: { success: true, crmData: { [resultKey]: DataArray } }.


createRecord

POST /api/record/{recordNumber} (README). Body comes only from YAML: all keys stringified except recordNumber / descriptionField; if descriptionField is set, that named field gets the chat transcript.

When it runs: When you need to create a record on any Powerlink entity type not covered by the other ops.

Basic

  powerlink_create_generic:
type: func
func_type: crm
func_id: createRecord
params:
recordNumber: 5
subject: "Follow-up from WhatsApp"
descriptionField: "notetext"
on_complete: done
ParamRequiredNotes
recordNumberYesPositive integer — object type for /api/record/{recordNumber}.
descriptionFieldNoIf set, that field receives the chat session messages.
other keysNoOther fields on the new record.

Result: crmData = { ...contact.crmData, ...response.data.Record }.


newAccount

Creates an Account (POST /api/record/1) if crmData.accountid is missing; otherwise returns the existing account. Ensures a contact first and links primarycontactid. Optional company_node / name_node / email_node are node names — values come from userState, then those keys are stripped; all other params merge into the account body (same key replaces default).

FieldCodecrmConfigparams
telephone1Formatted chat phoneYes
accountnameChat titleYes
firstnameChat titleYes
emailaddress1(empty)Yes
originatingleadcodeoriginatingLeadCode or 5Yes
statuscodenewAccountStatusCode or 0Yes
primarycontactidFrom contact stepYes

When it runs: e.g. after getCustomerDetailson_failure.

Basic

  powerlink_new_account:
type: func
func_type: crm
func_id: newAccount
on_complete: main_menu
on_failure: creation_failed
ParamRequiredNotes
company_nodeNoMaps to accountname.
name_nodeNoMaps to firstname.
email_nodeNoMaps to emailaddress1.
otherNoAny account field.

Result: crmData with accountid, phone, name, deepLink. If crmData.accountid already exists, returns that account without duplicating.

Advanced

  powerlink_register_lead:
type: func
func_type: crm
func_id: newAccount
params:
name_node: collect_display_name
company_node: collect_company
statuscode: 2
originatingleadcode: 6
on_complete: main_menu

openTicket

Creates a Case (POST /api/record/5). If there is no crmData.accountid, an account is created first (title only from chat; not from this op’s params). Then defaults are set and your params are merged (same key overwrites).

Most fields have sensible defaults — only pass params to override specific values.

FieldCodecrmConfigparams
titleפנייה מהווצאפYes
statuscode"1"Yes
descriptionTranscript + Inbox linkinboxUrl (in link)Yes
casetypecode"1"Yes
pcfsystemfield534Inbox URL + /contact/ + phoneinboxUrlYes
pcfsystemfield487"10" (WhatsApp)Yes
accountidNew or existingYes
contactidIf needed after createYes

When it runs: e.g. opening a support case from the bot.

Basic

  powerlink_open_case:
type: func
func_type: crm
func_id: openTicket
on_complete: done
ParamRequiredNotes
(any)NoCase (type 5) fields.

Result: crmData.casesid, crmLastTicketId, crmLastObjectType (5).


updateField

Updates one field on one record: PUT /api/record/{objecttypecode}/{objectid} with a body { [fieldname]: fieldvalue }.

When it runs: After getCustomerDetails — to patch a single field on an existing account or contact.

Basic

  powerlink_patch_field:
type: func
func_type: crm
func_id: updateField
params:
objecttypecode: 1
objectid: "%chat:crmData.accountid%"
fieldname: "description"
fieldvalue: "Updated from bot"
on_complete: done
ParamRequiredNotes
objecttypecodeYesTarget entity type (e.g. 1 account).
objectidYesRecord id.
fieldnameYesSingle field API name.
fieldvalueYesNew value (must be present; falsy can fail validation in code).

Result: { success: true } on API success.


changeStatus

Sets the account’s statuscode only: PUT /api/record/1/{accountid} using crmData.accountid from the chat. Use crmGetFields (or Powerlink UI) to map labels → numeric codes.

When it runs: After getCustomerDetails — to update the account status.

Basic

  powerlink_set_status:
type: func
func_type: crm
func_id: changeStatus
params:
crmStatusCode: 2
on_complete: done
ParamRequiredNotes
(prerequisite)crmData.accountid must be on the chat.
crmStatusCodeYesValue for statuscode on the account.

Result: { success: true } on API success.


openTask

Creates a Task (POST /api/record/10). Defaults below; then params are merged when crmData exists on the chat. Value crmData_someKey → replaced with crmData.someKey before send.

Most fields have sensible defaults — only pass params to override specific values.

FieldCodecrmConfigparams
subject"צ'ט עם לקוח בווצאפ - משימה לביצוע"Yes
objecttitleChat title (or account name when linked to account)Yes
statuscode1Yes
descriptionInbox linkinboxUrlYes
objectidLast ticket id, else account/contact idYes
objecttype1Yes
objecttypecodeWith account/contact fallbackYes
tasktypecodetaskTypeCode or 6Yes

When it runs: e.g. after openTicket / newOpportunity.

Basic

  powerlink_open_task:
type: func
func_type: crm
func_id: openTask
on_complete: done
ParamRequiredNotes
(any)NoTask fields. Any value of crmData_<key> is replaced at runtime with crmData.<key> — e.g. ownerid: crmData_ownerid pulls the owner from crmData.

Result: lastMessageStoredInCRMTimestamp, crmData.lastRecordId.

Advanced

  powerlink_task_with_crm:
type: func
func_type: crm
func_id: openTask
params:
ownerid: crmData_ownerid
on_complete: done

closeTicket

Logs the closed chat as a Task (POST /api/record/10). No params. Uses chat transcript, crmLastTicketId / crmData, and crmConfig.

FieldCodecrmConfigparams
subject"צ'ט עם לקוח בווצאפ - " + {{last message time}}No
objecttitleChat / account titleNo
statuscode10 (done)No
descriptionInbox link + transcriptinboxUrlNo
objectid / objecttype / objecttypecodeFrom last ticket or account/contactNo
tasktypecodetaskTypeCode or 6No

When it runs: e.g. when a chat is resolved.

Basic

  powerlink_close_log:
type: func
func_type: crm
func_id: closeTicket
on_complete: done
ParamRequiredNotes
(none)

Result: lastMessageStoredInCRMTimestamp, crmData.lastRecordId.


crmGetFields

Fetches picklist values for account statuscode: GET .../metadata/records/1/fields/statuscode/values. Use to populate choices or validate changeStatus / newAccount codes.

When it runs: When configuring changeStatus and you need to look up the numeric code for a given status label.

Basic

  powerlink_statuses:
type: func
func_type: crm
func_id: crmGetFields
on_complete: use_statuses
ParamRequiredNotes
(none)No params.

Result: { data: { statuses: [...] } } on success; else { success: false }.


addActivity

Note on the account (POST /api/record/7). Account must already exist (phone lookup). Only YAML keys text (required) and email (optional owner lookup) — no free-form merge.

When it runs: After getCustomerDetails — to add a note to the account record.

FieldCodecrmConfigparams
objecttypecode1 (account)No
objectidAccount id from queryNo
notetextYes (text)
owneridWhen email matches a useremail in YAML (not ownerid)

Basic

  powerlink_add_note:
type: func
func_type: crm
func_id: addActivity
params:
email: "agent@example.com"
text: "Customer asked about delivery"
on_complete: done
ParamRequiredNotes
emailNoIf set and matched on GET /api/record/9, sets ownerid.
textYesMaps to notetext.

Result: { success: true, record: {...} }; also upserts into Texter’s activities store in code.


assignChat

Sets account owner by PUT /api/record/1/{accountid} with ownerid from the user list (GET /api/record/9) where emailaddress1 equals params.email.

When it runs: After getCustomerDetails — to assign the account to a specific Powerlink user.

Basic

  powerlink_assign:
type: func
func_type: crm
func_id: assignChat
params:
email: "owner@example.com"
on_complete: done
ParamRequiredNotes
(prerequisite)crmData.accountid must be on the chat.
emailYesMust match a user’s emailaddress1.

Result: { success: true }.


getCustomerCustomObject - Legacy

Same transport as customQuery (POST /api/query), but the query string can include placeholders crmData[key] and botData[key] replaced from contact.crmData and userState[key].text. If rows are returned, the adapter also builds customQueryList for choice UIs using hard-coded field names in code (subject, scheduledstart, pcfsystemfield466) — only suitable if your object matches that shape; otherwise use customQuery or extend the product.

Basic

  powerlink_custom_object:
type: func
func_type: crm
func_id: getCustomerCustomObject
params:
objecttypecode: 1000
fields: "*"
query: "(accountid = crmData[accountid])"
on_complete: pick_row
ParamRequiredNotes
objecttypecodeYesobjecttype in the query body.
queryYesAfter placeholder replacement.
fieldsNoDefault *.

Result: crmData includes customQueryList plus merged responseData and contact.crmData.


Ask the customer to open API forms (TokenID) while signed into Fireberry/Powerlink (Settings → Tools → API forms) and provide the token Texter should store server-side.

You / the customer should agree on:

TopicNotes
tokenTokenID from Settings → Tools → API forms - https://api.powerlink.co.il/app/settings/tools/apiforms
inboxUrlTexter Inbox base URL for links in descriptions.
Phone fieldsaccountQueryFields / contactQueryFields if defaults don’t match the org.
Object typesConfirm numeric ids for custom entities when using createRecord / customQuery.
TaskstaskTypeCode for openTask / closeTicket.